Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/controllers/items_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def index
@items = @items.active unless params[:include_inactive_items]

@item_categories = current_organization.item_categories.includes(:items).order('name ASC')
@kits = current_organization.kits.includes(item: {line_items: :item})
@kits = current_organization.kits.includes(kit_item: {line_items: :item})
@storages = current_organization.storage_locations.active.order(id: :asc)

@include_inactive_items = params[:include_inactive_items]
Expand Down
10 changes: 5 additions & 5 deletions app/controllers/kits_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ def show
end

def index
@kits = current_organization.kits.includes(item: {line_items: :item}).class_filter(filter_params)
@kits = current_organization.kits.includes(kit_item: {line_items: :item}).class_filter(filter_params)
@inventory = View::Inventory.new(current_organization.id)
unless params[:include_inactive_items]
@kits = @kits.active
Expand All @@ -16,8 +16,8 @@ def new
load_form_collections

@kit = current_organization.kits.new
@kit.item = current_organization.items.new
@kit.item.line_items.build
@kit.kit_item = current_organization.items.new
@kit.kit_item.line_items.build
end

def create
Expand All @@ -36,8 +36,8 @@ def create
kit_only_params = kit_params.except(:line_items_attributes)
@kit = Kit.new(kit_only_params)
load_form_collections
@kit.item ||= current_organization.items.new(kit_params.slice(:line_items_attributes))
@kit.item.line_items.build if @kit.item.line_items.empty?
@kit.kit_item ||= current_organization.items.new(kit_params.slice(:line_items_attributes))
@kit.kit_item.line_items.build if @kit.kit_item.line_items.empty?

render :new
end
Expand Down
6 changes: 3 additions & 3 deletions app/events/kit_allocate_event.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class KitAllocateEvent < Event
def self.event_line_items(kit, storage_location, quantity)
items = kit.item.line_items.map do |item|
items = kit.kit_item.line_items.map do |item|
EventTypes::EventLineItem.new(
quantity: item.quantity * quantity,
item_id: item.item_id,
Expand All @@ -11,8 +11,8 @@ def self.event_line_items(kit, storage_location, quantity)
end
items.push(EventTypes::EventLineItem.new(
quantity: quantity,
item_id: kit.item.id,
item_value_in_cents: kit.item.value_in_cents,
item_id: kit.kit_item.id,
item_value_in_cents: kit.kit_item.value_in_cents,
to_storage_location: storage_location,
from_storage_location: nil
))
Expand Down
6 changes: 3 additions & 3 deletions app/events/kit_deallocate_event.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class KitDeallocateEvent < Event
def self.event_line_items(kit, storage_location, quantity)
items = kit.item.line_items.map do |item|
items = kit.kit_item.line_items.map do |item|
EventTypes::EventLineItem.new(
quantity: item.quantity * quantity,
item_id: item.item_id,
Expand All @@ -11,8 +11,8 @@ def self.event_line_items(kit, storage_location, quantity)
end
items.push(EventTypes::EventLineItem.new(
quantity: quantity,
item_id: kit.item.id,
item_value_in_cents: kit.item.value_in_cents,
item_id: kit.kit_item.id,
item_value_in_cents: kit.kit_item.value_in_cents,
from_storage_location: storage_location,
to_storage_location: nil
))
Expand Down
26 changes: 26 additions & 0 deletions app/models/concrete_item.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# == Schema Information
#
# Table name: items
#
# id :integer not null, primary key
# active :boolean default(TRUE)
# additional_info :text
# barcode_count :integer
# distribution_quantity :integer
# name :string
# on_hand_minimum_quantity :integer default(0), not null
# on_hand_recommended_quantity :integer
# package_size :integer
# partner_key :string
# reporting_category :string
# type :string default("ConcreteItem"), not null
# value_in_cents :integer default(0)
# visible_to_partners :boolean default(TRUE), not null
# created_at :datetime not null
# updated_at :datetime not null
# item_category_id :integer
# kit_id :integer
# organization_id :integer
#
class ConcreteItem < Item
end
5 changes: 3 additions & 2 deletions app/models/item.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# package_size :integer
# partner_key :string
# reporting_category :string
# type :string default("ConcreteItem"), not null
# value_in_cents :integer default(0)
# visible_to_partners :boolean default(TRUE), not null
# created_at :datetime not null
Expand Down Expand Up @@ -105,11 +106,11 @@ def in_request?

def is_in_kit?(kits = nil)
if kits
kits.any? { |k| k.item.line_items.map(&:item_id).include?(id) }
kits.any? { |k| k.kit_item.line_items.map(&:item_id).include?(id) }
else
organization.kits
.active
.joins(item: :line_items)
.joins(kit_item: :line_items)
.where(line_items: { item_id: id}).any?
end
end
Expand Down
10 changes: 5 additions & 5 deletions app/models/kit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Kit < ApplicationRecord
include Valuable

belongs_to :organization
has_one :item, dependent: :restrict_with_exception
has_one :kit_item, dependent: :restrict_with_exception

scope :active, -> { where(active: true) }
scope :alphabetized, -> { order(:name) }
Expand All @@ -30,23 +30,23 @@ class Kit < ApplicationRecord
# @return [Boolean]
def can_deactivate?(inventory = nil)
inventory ||= View::Inventory.new(organization_id)
inventory.quantity_for(item_id: item.id).zero?
inventory.quantity_for(item_id: kit_item.id).zero?
end

def deactivate
update!(active: false)
item.update!(active: false)
kit_item.update!(active: false)
end

# Kits can't reactivate if they have any inactive items, because now whenever they are allocated
# or deallocated, we are changing inventory for inactive items (which we don't allow).
# @return [Boolean]
def can_reactivate?
item.line_items.joins(:item).where(items: { active: false }).none?
kit_item.line_items.joins(:kit_item).where(items: { active: false }).none?
end

def reactivate
update!(active: true)
item.update!(active: true)
kit_item.update!(active: true)
end
end
29 changes: 29 additions & 0 deletions app/models/kit_item.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# == Schema Information
#
# Table name: items
#
# id :integer not null, primary key
# active :boolean default(TRUE)
# additional_info :text
# barcode_count :integer
# distribution_quantity :integer
# name :string
# on_hand_minimum_quantity :integer default(0), not null
# on_hand_recommended_quantity :integer
# package_size :integer
# partner_key :string
# reporting_category :string
# type :string default("ConcreteItem"), not null
# value_in_cents :integer default(0)
# visible_to_partners :boolean default(TRUE), not null
# created_at :datetime not null
# updated_at :datetime not null
# item_category_id :integer
# kit_id :integer
# organization_id :integer
#
class KitItem < Item
# for now. Technically not optional, but since we will be changing this to be standalone (no kit),
# there isn't really a reason to enforce this at the moment.
belongs_to :kit, optional: true
end
1 change: 1 addition & 0 deletions app/services/kit_create_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def call
item_creation = ItemCreateService.new(
organization_id: organization.id,
item_params: {
type: 'KitItem',
line_items_attributes: line_items,
name: kit.name,
partner_key: item_housing_a_kit_base_item.partner_key,
Expand Down
2 changes: 1 addition & 1 deletion app/services/reports/adult_incontinence_report_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def distributed_kits_for_year

def total_distributed_kits_containing_adult_incontinence_items_per_month
kits = Kit.where(id: distributed_kits_for_year).select do |kit|
kit.item.items.adult_incontinence.exists?
kit.kit_item.items.adult_incontinence.exists?
end

total_assisted_adults = kits.sum do |kit|
Expand Down
2 changes: 1 addition & 1 deletion app/services/reports/children_served_report_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def children_served_with_kits_containing_disposables
kits_subquery = organization
.distributions
.for_year(year)
.joins(line_items: { item: { kit: { item: { line_items: :item} } }})
.joins(line_items: { item: { kit: { kit_item: { line_items: :item} } }})
.where("items_line_items.reporting_category = 'disposable_diapers'")
.select("DISTINCT ON (distributions.id, line_items.id, kits.id) line_items.quantity, items.distribution_quantity")
.to_sql
Expand Down
2 changes: 1 addition & 1 deletion app/views/kits/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<%= f.input_field :value_in_dollars, class: "form-control", min: 0 %>
<% end %>

<%= fields_for @kit.item do |ff| %>
<%= fields_for @kit.kit_item do |ff| %>
<fieldset style="margin-bottom: 2rem;" class='w-70'>
<legend>Items in this Kit</legend>
<div id="kit_line_items" class="line-item-fields" data-capture-barcode="true">
Expand Down
4 changes: 2 additions & 2 deletions app/views/kits/_table.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<td><%= kit.name %></td>
<td>
<ul>
<% kit.item.line_items.quantities_by_name.map do |id, item_hash| %>
<% kit.kit_item.line_items.quantities_by_name.map do |id, item_hash| %>
<li><%= "#{item_hash[:quantity]} #{item_hash[:name]}" %></li>
<% end %>
</ul>
Expand All @@ -26,7 +26,7 @@
<td class="text-right"> Quantity </td>
</tr>
</thead>
<% @inventory.all_items.select { |i| i.item_id == kit.item.id}.each do |item| %>
<% @inventory.all_items.select { |i| i.item_id == kit.kit_item.id}.each do |item| %>
<tr>
<td><%= @inventory.storage_location_name(item.storage_location_id) %></td>
<td class="text-right"><%= item.quantity %></td>
Expand Down
4 changes: 2 additions & 2 deletions app/views/kits/allocations.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
</thead>
<tbody>
<% if @inventory %>
<% @inventory.all_items.select { |i| i.item_id == @kit.item.id }.each do |ii| %>
<% @inventory.all_items.select { |i| i.item_id == @kit.kit_item.id }.each do |ii| %>
<tr id="storage_location_<%= ii.storage_location_id %>">
<td> <%= @inventory.storage_location_name(ii.storage_location_id) %> </td>
<td>
Expand Down Expand Up @@ -100,7 +100,7 @@
<td><%= @kit.name %></td>
<td data-base-quantity='-1' class='text-bold'></td>
</tr>
<% @kit.item.line_items.each do |li| %>
<% @kit.kit_item.line_items.each do |li| %>
<tr>
<td> <%= li.item.name %> </td>
<td data-base-quantity="<%= li.quantity %>" class='text-bold'></td>
Expand Down
11 changes: 11 additions & 0 deletions db/migrate/20260313201123_add_type_to_items.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class AddTypeToItems < ActiveRecord::Migration[8.0]
def up
add_column :items, :type, :string, default: 'ConcreteItem', null: false
Item.where.not(kit_id: nil).update_all(type: 'KitItem', updated_at: Time.zone.now)
Comment on lines +3 to +4
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice

end

def down
add_column :items, :type, :string, default: 'ConcreteItem', null: false
end

end
35 changes: 6 additions & 29 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[8.0].define(version: 2025_10_07_141240) do
ActiveRecord::Schema[8.0].define(version: 2026_03_13_201123) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_catalog.plpgsql"

Expand Down Expand Up @@ -231,21 +231,6 @@
t.index ["user_id"], name: "index_deprecated_feedback_messages_on_user_id"
end

create_table "diaper_drive_participants", id: :serial, force: :cascade do |t|
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated table drop -- is it incorrectly in the main branch, or is this a mistake in the PR?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's incorrectly in the main branch.

class RenameDiaperDriveParticipantToProductDriveParticipant < ActiveRecord::Migration[6.1]

t.string "contact_name"
t.string "email"
t.string "phone"
t.string "comment"
t.integer "organization_id"
t.datetime "created_at", precision: nil, null: false
t.datetime "updated_at", precision: nil, null: false
t.string "address"
t.string "business_name"
t.float "latitude"
t.float "longitude"
t.index ["latitude", "longitude"], name: "index_diaper_drive_participants_on_latitude_and_longitude"
end

create_table "distributions", id: :serial, force: :cascade do |t|
t.text "comment"
t.datetime "created_at", precision: nil, null: false
Expand Down Expand Up @@ -341,16 +326,6 @@
t.index ["partner_id"], name: "index_families_on_partner_id"
end

create_table "feedback_messages", force: :cascade do |t|
t.bigint "user_id"
t.string "message"
t.string "path"
t.datetime "created_at", precision: nil, null: false
t.datetime "updated_at", precision: nil, null: false
t.boolean "resolved"
t.index ["user_id"], name: "index_feedback_messages_on_user_id"
end

create_table "flipper_features", force: :cascade do |t|
t.string "key", null: false
t.datetime "created_at", precision: nil, null: false
Expand Down Expand Up @@ -433,6 +408,7 @@
t.integer "item_category_id"
t.text "additional_info"
t.string "reporting_category"
t.string "type", default: "ConcreteItem", null: false
t.index ["kit_id"], name: "index_items_on_kit_id"
t.index ["organization_id"], name: "index_items_on_organization_id"
t.index ["partner_key"], name: "index_items_on_partner_key"
Expand Down Expand Up @@ -519,9 +495,9 @@
t.boolean "signature_for_distribution_pdf", default: false
t.boolean "receive_email_on_requests", default: false, null: false
t.boolean "include_in_kind_values_in_exported_files", default: false, null: false
t.boolean "bank_is_set_up", default: false, null: false
t.string "reminder_schedule_definition"
t.boolean "include_packages_in_distribution_export", default: false, null: false
t.boolean "bank_is_set_up", default: false, null: false
t.index ["latitude", "longitude"], name: "index_organizations_on_latitude_and_longitude"
end

Expand All @@ -543,10 +519,11 @@
t.string "reminder_schedule_definition"
t.index ["name", "organization_id"], name: "index_partner_groups_on_name_and_organization_id", unique: true
t.index ["organization_id"], name: "index_partner_groups_on_organization_id"
t.check_constraint "deadline_day <= 28", name: "deadline_day_of_month_check"
t.check_constraint "reminder_day <= 28", name: "reminder_day_of_month_check"
end

add_check_constraint "partner_groups", "deadline_day <= 28", name: "deadline_day_of_month_check", validate: false
add_check_constraint "partner_groups", "reminder_day <= 28", name: "reminder_day_of_month_check", validate: false

create_table "partner_profiles", force: :cascade do |t|
t.bigint "essentials_bank_id"
t.integer "partner_id"
Expand Down
4 changes: 2 additions & 2 deletions db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -855,12 +855,12 @@ def seed_quantity(item_name, organization, storage_location, quantity)
complete_orgs.each do |org|
org.storage_locations.active.each do |storage_location|
org.kits.active.each do |kit|
next unless kit.item # Ensure kit has an associated item
next unless kit.kit_item # Ensure kit has an associated item

# Create inventory for each kit
InventoryItem.create!(
storage_location: storage_location,
item: kit.item,
item: kit.kit_item,
quantity: Faker::Number.within(range: 10..50)
)
end
Expand Down
Loading
Loading