diff --git a/app/controllers/kits_controller.rb b/app/controllers/kits_controller.rb index 5986696bae..a8c2e29eca 100644 --- a/app/controllers/kits_controller.rb +++ b/app/controllers/kits_controller.rb @@ -16,7 +16,8 @@ def new load_form_collections @kit = current_organization.kits.new - @kit.line_items.build + @kit.item = current_organization.items.new + @kit.item.line_items.build end def create @@ -33,7 +34,8 @@ def create @kit = Kit.new(kit_params) load_form_collections - @kit.line_items.build if @kit.line_items.empty? + @kit.item ||= current_organization.items.new + @kit.item.line_items.build if @kit.item.line_items.empty? render :new end @@ -87,12 +89,14 @@ def load_form_collections end def kit_params - params.require(:kit).permit( + kit_params = params.require(:kit).permit( :name, :visible_to_partners, - :value_in_dollars, - line_items_attributes: [:item_id, :quantity, :_destroy] + :value_in_dollars ) + item_params = params.require(:item) + .permit(line_items_attributes: [:item_id, :quantity, :_destroy]) + kit_params.to_h.merge(item_params.to_h) end def kit_adjustment_params diff --git a/app/events/kit_allocate_event.rb b/app/events/kit_allocate_event.rb index e2e397e5e4..6c71e3195d 100644 --- a/app/events/kit_allocate_event.rb +++ b/app/events/kit_allocate_event.rb @@ -1,6 +1,6 @@ class KitAllocateEvent < Event def self.event_line_items(kit, storage_location, quantity) - items = kit.line_items.map do |item| + items = kit.item.line_items.map do |item| EventTypes::EventLineItem.new( quantity: item.quantity * quantity, item_id: item.item_id, diff --git a/app/events/kit_deallocate_event.rb b/app/events/kit_deallocate_event.rb index dd0724f0b6..5ddc7366a4 100644 --- a/app/events/kit_deallocate_event.rb +++ b/app/events/kit_deallocate_event.rb @@ -1,6 +1,6 @@ class KitDeallocateEvent < Event def self.event_line_items(kit, storage_location, quantity) - items = kit.line_items.map do |item| + items = kit.item.line_items.map do |item| EventTypes::EventLineItem.new( quantity: item.quantity * quantity, item_id: item.item_id, diff --git a/app/models/item.rb b/app/models/item.rb index 15e7b1382c..7982075a84 100644 --- a/app/models/item.rb +++ b/app/models/item.rb @@ -27,6 +27,7 @@ class Item < ApplicationRecord include Filterable include Exportable include Valuable + include Itemizable after_initialize :set_default_distribution_quantity, if: :new_record? after_update :update_associated_kit_name, if: -> { kit.present? } @@ -45,12 +46,13 @@ class Item < ApplicationRecord validates :on_hand_minimum_quantity, numericality: { greater_than_or_equal_to: 0 } validates :package_size, numericality: { greater_than_or_equal_to: 0 }, allow_blank: true validates :reporting_category, presence: true, unless: proc { |i| i.kit } + validate -> { line_items_quantity_is_at_least(1) } - has_many :line_items, dependent: :destroy + has_many :used_line_items, dependent: :destroy, class_name: "LineItem" has_many :inventory_items, dependent: :destroy has_many :barcode_items, as: :barcodeable, dependent: :destroy - has_many :donations, through: :line_items, source: :itemizable, source_type: "::Donation" - has_many :distributions, through: :line_items, source: :itemizable, source_type: "::Distribution" + has_many :donations, through: :used_line_items, source: :itemizable, source_type: "::Donation" + has_many :distributions, through: :used_line_items, source: :itemizable, source_type: "::Distribution" has_many :request_units, class_name: "ItemUnit", dependent: :destroy scope :active, -> { where(active: true) } @@ -107,13 +109,13 @@ def is_in_kit?(kits = nil) else organization.kits .active - .joins(:line_items) + .joins(item: :line_items) .where(line_items: { item_id: id}).any? end end def can_delete?(inventory = nil, kits = nil) - can_deactivate_or_delete?(inventory, kits) && line_items.none? && !barcode_count&.positive? && !in_request? && kit.blank? + can_deactivate_or_delete?(inventory, kits) && used_line_items.none? && !barcode_count&.positive? && !in_request? && kit.blank? end # @return [Boolean] diff --git a/app/models/kit.rb b/app/models/kit.rb index 363407266f..87633f514d 100644 --- a/app/models/kit.rb +++ b/app/models/kit.rb @@ -28,9 +28,6 @@ class Kit < ApplicationRecord validates :name, presence: true validates :name, uniqueness: { scope: :organization } - validate :at_least_one_item - validate -> { line_items_quantity_is_at_least(1) } - # @param inventory [View::Inventory] # @return [Boolean] def can_deactivate?(inventory = nil) @@ -47,19 +44,11 @@ def deactivate # or deallocated, we are changing inventory for inactive items (which we don't allow). # @return [Boolean] def can_reactivate? - line_items.joins(:item).where(items: { active: false }).none? + item.line_items.joins(:item).where(items: { active: false }).none? end def reactivate update!(active: true) item.update!(active: true) end - - private - - def at_least_one_item - unless line_items.any? - errors.add(:base, 'At least one item is required') - end - end end diff --git a/app/services/kit_create_service.rb b/app/services/kit_create_service.rb index 7884d5d61c..8c5cda19c4 100644 --- a/app/services/kit_create_service.rb +++ b/app/services/kit_create_service.rb @@ -23,8 +23,13 @@ def call organization.transaction do # Create the Kit record + line_items = kit_params.delete(:line_items_attributes) @kit = Kit.new(kit_params_with_organization) @kit.save! + if line_items.blank? + @kit.errors.add(:base, 'At least one item is required') + raise ActiveRecord::RecordInvalid.new(@kit) + end # Find or create the BaseItem for all items housing kits item_housing_a_kit_base_item = KitCreateService.find_or_create_kit_base_item! @@ -33,6 +38,7 @@ def call item_creation = ItemCreateService.new( organization_id: organization.id, item_params: { + line_items_attributes: line_items, name: kit.name, partner_key: item_housing_a_kit_base_item.partner_key, kit_id: kit.id diff --git a/app/services/reports/diaper_report_service.rb b/app/services/reports/diaper_report_service.rb index 19cc76cec1..19a6f83434 100644 --- a/app/services/reports/diaper_report_service.rb +++ b/app/services/reports/diaper_report_service.rb @@ -61,13 +61,13 @@ def distributed_disposable_diapers_from_kits FROM distributions INNER JOIN line_items ON line_items.itemizable_type = 'Distribution' AND line_items.itemizable_id = distributions.id INNER JOIN items ON items.id = line_items.item_id - INNER JOIN kits ON kits.id = items.kit_id - INNER JOIN line_items AS kit_line_items ON kits.id = kit_line_items.itemizable_id + INNER JOIN line_items AS kit_line_items ON items.id = kit_line_items.itemizable_id INNER JOIN items AS kit_items ON kit_items.id = kit_line_items.item_id WHERE distributions.organization_id = ? AND EXTRACT(year FROM issued_at) = ? + AND items.kit_id IS NOT NULL AND kit_items.reporting_category = 'disposable_diapers' - AND kit_line_items.itemizable_type = 'Kit'; + AND kit_line_items.itemizable_type = 'Item'; SQL sanitized_sql = ActiveRecord::Base.send(:sanitize_sql_array, [sql_query, organization_id, year]) diff --git a/app/services/reports/period_supply_report_service.rb b/app/services/reports/period_supply_report_service.rb index 1e542bf06b..4383558531 100644 --- a/app/services/reports/period_supply_report_service.rb +++ b/app/services/reports/period_supply_report_service.rb @@ -114,13 +114,13 @@ def kit_items_calculation(itemizable_type, string_itemizable_type) FROM #{itemizable_type} INNER JOIN line_items ON line_items.itemizable_type = #{string_itemizable_type} AND line_items.itemizable_id = #{itemizable_type}.id INNER JOIN items ON items.id = line_items.item_id - INNER JOIN kits ON kits.id = items.kit_id - INNER JOIN line_items AS kit_line_items ON kits.id = kit_line_items.itemizable_id + INNER JOIN line_items AS kit_line_items ON items.id = kit_line_items.itemizable_id INNER JOIN items AS kit_items ON kit_items.id = kit_line_items.item_id WHERE #{itemizable_type}.organization_id = ? AND EXTRACT(year FROM issued_at) = ? + AND items.kit_id IS NOT NULL AND kit_items.reporting_category IN ('pads', 'tampons', 'period_liners', 'period_underwear', 'period_other') - AND kit_line_items.itemizable_type = 'Kit'; + AND kit_line_items.itemizable_type = 'Item'; SQL sanitized_sql = ActiveRecord::Base.send(:sanitize_sql_array, [sql_query, organization_id, year]) diff --git a/app/views/kits/_form.html.erb b/app/views/kits/_form.html.erb index dc250d5873..e5fe5ccac3 100644 --- a/app/views/kits/_form.html.erb +++ b/app/views/kits/_form.html.erb @@ -19,17 +19,19 @@ <%= f.input_field :value_in_dollars, class: "form-control", min: 0 %> <% end %> -
- Items in this Kit -
- <%= render 'line_items/line_item_fields', form: f %> -
- -
+ <%= fields_for @kit.item do |ff| %> +
+ Items in this Kit +
+ <%= render 'line_items/line_item_fields', form: ff %> +
+ +
+ <% end %>