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
14 changes: 9 additions & 5 deletions app/controllers/kits_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion 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.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,
Expand Down
2 changes: 1 addition & 1 deletion 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.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,
Expand Down
12 changes: 7 additions & 5 deletions app/models/item.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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? }
Expand All @@ -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) }
Expand Down Expand Up @@ -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]
Expand Down
13 changes: 1 addition & 12 deletions app/models/kit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
6 changes: 6 additions & 0 deletions app/services/kit_create_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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!
Expand All @@ -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
Expand Down
6 changes: 3 additions & 3 deletions app/services/reports/diaper_report_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand Down
6 changes: 3 additions & 3 deletions app/services/reports/period_supply_report_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand Down
24 changes: 13 additions & 11 deletions app/views/kits/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,19 @@
<%= f.input_field :value_in_dollars, class: "form-control", min: 0 %>
<% end %>

<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">
<%= render 'line_items/line_item_fields', form: f %>
</div>
<div class="row links col-xs-12 justify-content-end">
<%= add_element_button "Add Another Item", container_selector: "#kit_line_items", id: "__add_line_item" do %>
<%= render 'line_items/line_item_fields', form: f, object: LineItem.new %>
<% end %>
</div>
</fieldset>
<%= fields_for @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">
<%= render 'line_items/line_item_fields', form: ff %>
</div>
<div class="row links col-xs-12 justify-content-end">
<%= add_element_button "Add Another Item", container_selector: "#kit_line_items", id: "__add_line_item" do %>
<%= render 'line_items/line_item_fields', form: ff, object: LineItem.new %>
<% end %>
</div>
</fieldset>
<% end %>

</div>
<div class="card-footer">
Expand Down
2 changes: 1 addition & 1 deletion 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.line_items.quantities_by_name.map do |id, item_hash| %>
<% kit.item.line_items.quantities_by_name.map do |id, item_hash| %>
<li><%= "#{item_hash[:quantity]} #{item_hash[:name]}" %></li>
<% end %>
</ul>
Expand Down
2 changes: 1 addition & 1 deletion app/views/kits/allocations.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
<td><%= @kit.name %></td>
<td data-base-quantity='-1' class='text-bold'></td>
</tr>
<% @kit.line_items.each do |li| %>
<% @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
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class MoveLineItemsFromKitsToItems < ActiveRecord::Migration[8.0]
def change
Item.where.not(kit_id: nil).each do |item|
LineItem.where(itemizable_type: 'Kit', itemizable_id: item.kit_id).
update_all(itemizable_type: 'Item', itemizable_id: item.id, updated_at: Time.current)
end
end
end
6 changes: 3 additions & 3 deletions spec/events/inventory_aggregate_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -436,9 +436,9 @@
})
inventory = InventoryAggregate.inventory_for(organization.id) # reload

kit.line_items = []
kit.line_items << build(:line_item, quantity: 20, item: item1, itemizable: kit)
kit.line_items << build(:line_item, quantity: 5, item: item2, itemizable: kit)
kit.item.line_items = []
kit.item.line_items << build(:line_item, quantity: 20, item: item1, itemizable: kit)
kit.item.line_items << build(:line_item, quantity: 5, item: item2, itemizable: kit)
KitDeallocateEvent.publish(kit, storage_location1.id, 2)

# 30 + (20*2) = 70, 10 + (5*2) = 20
Expand Down
5 changes: 3 additions & 2 deletions spec/factories/kits.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
organization

after(:build) do |instance, _|
if instance.line_items.blank?
instance.line_items << build(:line_item, item: create(:item, organization: instance.organization), itemizable: nil)
instance.item ||= build(:item, organization: instance.organization)
if instance.item.line_items.blank?
instance.item.line_items << build(:line_item, item: create(:item, organization: instance.organization), itemizable: nil)
end
end

Expand Down
21 changes: 8 additions & 13 deletions spec/models/kit_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,19 @@
).not_to be_valid
end

it "requires at least one item" do
kit.line_items = []
expect(kit).not_to be_valid
end

it "ensures the associated line_items are invalid with a nil quantity" do
kit.line_items << build(:line_item, quantity: nil)
expect(kit).not_to be_valid
kit.item.line_items << build(:line_item, quantity: nil)
expect(kit.item).not_to be_valid
end

it "ensures the associated line_items are invalid with a zero quantity" do
kit.line_items << build(:line_item, quantity: 0)
expect(kit).not_to be_valid
kit.item.line_items << build(:line_item, quantity: 0)
expect(kit.item).not_to be_valid
end

it "ensures the associated line_items are valid with a one quantity" do
kit.line_items << build(:line_item, quantity: 1)
expect(kit).to be_valid
kit.item.line_items << build(:line_item, quantity: 1)
expect(kit.item).to be_valid
end
end

Expand Down Expand Up @@ -90,11 +85,11 @@
context "Value >" do
describe ".value_per_itemizable" do
it "calculates values from associated items" do
kit.line_items = [
kit.item.line_items = [
create(:line_item, quantity: 1, item: create(:item, value_in_cents: 100)),
create(:line_item, quantity: 1, item: create(:item, value_in_cents: 90))
]
expect(kit.value_per_itemizable).to eq(190)
expect(kit.item.value_per_itemizable).to eq(190)
end
end

Expand Down
2 changes: 1 addition & 1 deletion spec/requests/kit_requests_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
it "cannot reactivate if it has an inactive item" do
kit.deactivate
expect(kit).not_to be_active
kit.line_items.first.item.update!(active: false)
kit.item.line_items.first.item.update!(active: false)

put reactivate_kit_url(kit)
expect(kit.reload).not_to be_active
Expand Down
2 changes: 2 additions & 0 deletions spec/services/kit_create_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
context 'when the parameters are valid' do
it 'should create a new Kit' do
expect { subject }.to change { Kit.all.count }.by(1)
kit = Kit.last
expect(kit.item.line_items.count).to eq(3)
end

it 'should create a new Item' do
Expand Down
12 changes: 6 additions & 6 deletions spec/services/reports/period_supply_report_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@
another_period_supplies_kit_item = create(:item, name: "Adult Tampons", reporting_category: :tampons, organization:)
purchased_period_supplies_kit_item = create(:item, name: "Liners", reporting_category: :period_liners, organization:)

period_supplies_kit.line_items.first.update!(item_id: period_supplies_kit_item.id, quantity: 5)
another_period_supply_kit.line_items.first.update!(item_id: another_period_supplies_kit_item.id, quantity: 5)
donated_period_supply_kit.line_items.first.update!(item_id: another_period_supplies_kit_item.id, quantity: 5)
purchased_period_supply_kit.line_items.first.update!(item_id: purchased_period_supplies_kit_item.id, quantity: 5)
period_supplies_kit.item.line_items.first.update!(item_id: period_supplies_kit_item.id, quantity: 5)
another_period_supply_kit.item.line_items.first.update!(item_id: another_period_supplies_kit_item.id, quantity: 5)
donated_period_supply_kit.item.line_items.first.update!(item_id: another_period_supplies_kit_item.id, quantity: 5)
purchased_period_supply_kit.item.line_items.first.update!(item_id: purchased_period_supplies_kit_item.id, quantity: 5)

pad_and_tampon_kit.line_items.first.update!(item_id: period_supplies_kit_item.id, quantity: 10)
pad_and_tampon_kit.line_items.first.update!(item_id: another_period_supplies_kit_item.id, quantity: 10)
pad_and_tampon_kit.item.line_items.first.update!(item_id: period_supplies_kit_item.id, quantity: 10)
pad_and_tampon_kit.item.line_items.first.update!(item_id: another_period_supplies_kit_item.id, quantity: 10)

period_supplies_kit_distribution = create(:distribution, organization: organization, issued_at: within_time)
another_period_supplies_kit_distribution = create(:distribution, organization: organization, issued_at: within_time)
Expand Down
10 changes: 5 additions & 5 deletions spec/system/kit_system_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@

item = Item.last
quantity_per_kit = 5
select item.name, from: "kit_line_items_attributes_0_item_id"
find(:css, '#kit_line_items_attributes_0_quantity').set(quantity_per_kit)
select item.name, from: "item_line_items_attributes_0_item_id"
find(:css, '#item_line_items_attributes_0_quantity').set(quantity_per_kit)

click_button "Save"

Expand Down Expand Up @@ -73,7 +73,7 @@

expect(page).to have_content("Barcode Added to Inventory")
# Check that item details have been filled in via javascript
expect(page).to have_field("kit_line_items_attributes_0_quantity", with: quantity)
expect(page).to have_field("item_line_items_attributes_0_quantity", with: quantity)
# Check that new field has been added via javascript
expect(page).to have_css(".line_item_section", count: 2)
end
Expand Down Expand Up @@ -216,8 +216,8 @@

item = Item.last
quantity_per_kit = 5
select item.name, from: "kit_line_items_attributes_0_item_id"
find(:css, '#kit_line_items_attributes_0_quantity').set(quantity_per_kit)
select item.name, from: "item_line_items_attributes_0_item_id"
find(:css, '#item_line_items_attributes_0_quantity').set(quantity_per_kit)

click_button "Save"

Expand Down