Skip to content

Commit

Permalink
3609 updated inventory in out queries to fetch data from KitAllocation (
Browse files Browse the repository at this point in the history
#3737)

* updated inventory in logic to save line_items instead of only kits
* data migration added to fix kit_allocation inventory in
* invetory out queries updated to include kit_allocations inventory_out
* Inventory in queries updated to include kit_allocations inventory_in
* in_items and out_items scopes added for items_in and items_out queries
  • Loading branch information
zeeshan-haidar committed Aug 18, 2023
1 parent 46ec021 commit 1a38904
Show file tree
Hide file tree
Showing 17 changed files with 135 additions and 108 deletions.
3 changes: 2 additions & 1 deletion app/models/line_item.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class LineItem < ApplicationRecord
validates :item_id, presence: true
validates :quantity, numericality: { only_integer: true, less_than: MAX_INT, greater_than: MIN_INT }
scope :active, -> { joins(:item).where(items: { active: true }) }

scope :out_items, ->(storage_location_id, organization_id) { where("(distributions.storage_location_id = :id or (adjustments.storage_location_id= :id and line_items.quantity < 0) or transfers.from_id = :id or kit_allocations.storage_location_id = :id) and items.organization_id= :organization_id", id: storage_location_id, organization_id: organization_id) }
scope :in_items, ->(storage_location_id, organization_id) { where("(donations.storage_location_id = :id or purchases.storage_location_id = :id or (adjustments.storage_location_id = :id and line_items.quantity > 0) or transfers.to_id = :id or kit_allocations.storage_location_id = :id) and items.organization_id = :organization_id", id: storage_location_id, organization_id: organization_id) }
delegate :name, to: :item
end
5 changes: 3 additions & 2 deletions app/queries/items_in_query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ def call
LEFT OUTER JOIN purchases ON purchases.id = line_items.itemizable_id AND line_items.itemizable_type = 'Purchase'
LEFT OUTER JOIN items ON items.id = line_items.item_id
LEFT OUTER JOIN adjustments ON adjustments.id = line_items.itemizable_id AND line_items.itemizable_type = 'Adjustment'
LEFT OUTER JOIN transfers ON transfers.id = line_items.itemizable_id AND line_items.itemizable_type = 'Transfer'")
.where("(donations.storage_location_id = :id or purchases.storage_location_id = :id or (adjustments.storage_location_id = :id and line_items.quantity > 0) or transfers.to_id = :id) and items.organization_id = :organization_id", id: @storage_location.id, organization_id: @organization.id)
LEFT OUTER JOIN transfers ON transfers.id = line_items.itemizable_id AND line_items.itemizable_type = 'Transfer'
LEFT OUTER JOIN kit_allocations ON kit_allocations.id = line_items.itemizable_id AND line_items.itemizable_type = 'KitAllocation' AND kit_allocations.kit_allocation_type = 'inventory_in'")
.in_items(@storage_location.id, @organization.id)
.select("sum(line_items.quantity) as quantity, items.id AS item_id, items.name")
.group("items.name, items.id")
.order("items.name")
Expand Down
5 changes: 3 additions & 2 deletions app/queries/items_in_total_query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ def call
LEFT OUTER JOIN purchases ON purchases.id = line_items.itemizable_id AND line_items.itemizable_type = 'Purchase'
LEFT OUTER JOIN items ON items.id = line_items.item_id
LEFT OUTER JOIN adjustments ON adjustments.id = line_items.itemizable_id AND line_items.itemizable_type = 'Adjustment'
LEFT OUTER JOIN transfers ON transfers.id = line_items.itemizable_id AND line_items.itemizable_type = 'Transfer'")
.where("(donations.storage_location_id = :id or purchases.storage_location_id = :id or (adjustments.storage_location_id = :id and line_items.quantity > 0) or transfers.to_id = :id) and items.organization_id = :organization_id", id: @storage_location.id, organization_id: @organization.id)
LEFT OUTER JOIN transfers ON transfers.id = line_items.itemizable_id AND line_items.itemizable_type = 'Transfer'
LEFT OUTER JOIN kit_allocations ON kit_allocations.id = line_items.itemizable_id AND line_items.itemizable_type = 'KitAllocation' AND kit_allocations.kit_allocation_type = 'inventory_in'")
.in_items(@storage_location.id, @organization.id)
.sum("line_items.quantity")
end
# rubocop:enable Naming/MemoizedInstanceVariableName
Expand Down
8 changes: 4 additions & 4 deletions app/queries/items_out_query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ def initialize(organization:, storage_location:, filter_params: nil)

# rubocop:disable Naming/MemoizedInstanceVariableName
def call
@items ||= LineItem.joins("
@items ||= LineItem.joins("
LEFT OUTER JOIN distributions ON distributions.id = line_items.itemizable_id AND line_items.itemizable_type = 'Distribution'
LEFT OUTER JOIN items ON items.id = line_items.item_id
LEFT OUTER JOIN adjustments ON adjustments.id = line_items.itemizable_id AND line_items.itemizable_type = 'Adjustment'
LEFT OUTER JOIN transfers ON transfers.id = line_items.itemizable_id AND line_items.itemizable_type = 'Transfer'")
.where("(distributions.storage_location_id = :id or (adjustments.storage_location_id= :id and line_items.quantity < 0) or transfers.from_id = :id) and items.organization_id= :organization_id",
id: @storage_location.id, organization_id: @organization.id)
LEFT OUTER JOIN transfers ON transfers.id = line_items.itemizable_id AND line_items.itemizable_type = 'Transfer'
LEFT OUTER JOIN kit_allocations ON kit_allocations.id = line_items.itemizable_id AND line_items.itemizable_type = 'KitAllocation' AND kit_allocations.kit_allocation_type = 'inventory_out'")
.out_items(@storage_location.id, @organization.id)
.select("sum( case when line_items.quantity < 0 then -1*line_items.quantity else line_items.quantity END ) as quantity, items.id AS item_id, items.name")
.group("items.name, items.id")
.order("items.name")
Expand Down
9 changes: 5 additions & 4 deletions app/queries/items_out_total_query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ def initialize(organization:, storage_location:, filter_params: nil)

# rubocop:disable Naming/MemoizedInstanceVariableName
def call
@items ||= LineItem.joins("
@items ||= LineItem.joins("
LEFT OUTER JOIN distributions ON distributions.id = line_items.itemizable_id AND line_items.itemizable_type = 'Distribution'
LEFT OUTER JOIN items ON items.id = line_items.item_id
LEFT OUTER JOIN adjustments ON adjustments.id = line_items.itemizable_id AND line_items.itemizable_type = 'Adjustment'
LEFT OUTER JOIN transfers ON transfers.id = line_items.itemizable_id AND line_items.itemizable_type = 'Transfer'")
.where("(distributions.storage_location_id = :id or (adjustments.storage_location_id= :id and line_items.quantity < 0) or transfers.from_id = :id) and items.organization_id= :organization_id", id: @storage_location.id, organization_id: @organization.id)
.sum("case when line_items.quantity < 0 then -1*line_items.quantity else line_items.quantity END")
LEFT OUTER JOIN transfers ON transfers.id = line_items.itemizable_id AND line_items.itemizable_type = 'Transfer'
LEFT OUTER JOIN kit_allocations ON kit_allocations.id = line_items.itemizable_id AND line_items.itemizable_type = 'KitAllocation' AND kit_allocations.kit_allocation_type = 'inventory_out'")
.out_items(@storage_location.id, @organization.id)
.sum("case when line_items.quantity < 0 then -1*line_items.quantity else line_items.quantity END")
end
# rubocop:enable Naming/MemoizedInstanceVariableName
end
46 changes: 16 additions & 30 deletions app/services/allocate_kit_inventory_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,40 +36,26 @@ def allocate_inventory_items_and_increase_kit_quantity
end

def allocate_inventory_in_and_inventory_out
allocate_inventory_in
allocate_inventory_out
end

def allocate_inventory_out
kit_allocation = KitAllocation.find_or_create_by!(storage_location_id: storage_location.id, kit_id: kit.id,
organization_id: kit.organization.id, kit_allocation_type: "inventory_out")
line_items = kit_allocation.line_items
if line_items.present?
kit_content.each_with_index do |line_item, index|
line_item_record = line_items[index]
new_quantity = line_item_record[:quantity] + line_item[:quantity].to_i * -1
line_item_record.update!(quantity: new_quantity)
end
else
kit_content.each do |line_item|
kit_allocation.line_items.create!(item_id: line_item[:item_id], quantity: line_item[:quantity].to_i * -1)
kit_allocation_types = ["inventory_in", "inventory_out"]
kit_allocation_types.each do |kit_allocation_type|
kit_allocation = KitAllocation.find_or_create_by!(storage_location_id: storage_location.id, kit_id: kit.id,
organization_id: kit.organization.id, kit_allocation_type: kit_allocation_type)
line_items = kit_allocation.line_items
multiply_by = (kit_allocation_type == "inventory_out") ? -1 : 1
if line_items.present?
kit_content.each_with_index do |line_item, index|
line_item_record = line_items[index]
new_quantity = line_item_record[:quantity] + line_item[:quantity].to_i * multiply_by
line_item_record.update!(quantity: new_quantity)
end
else
kit_content.each do |line_item|
kit_allocation.line_items.create!(item_id: line_item[:item_id], quantity: line_item[:quantity].to_i * multiply_by)
end
end
end
end

def allocate_inventory_in
kit_allocation = KitAllocation.find_or_create_by!(storage_location_id: storage_location.id, kit_id: kit.id,
organization_id: kit.organization.id, kit_allocation_type: "inventory_in")
line_items = kit_allocation.line_items
if line_items.present?
kit_item = line_items.first
new_quantity = kit_item[:quantity] + increase_by
kit_item.update!(quantity: new_quantity)
else
kit_allocation.line_items.create!(associated_kit_item)
end
end

def set_error(error)
@error = error.message
end
Expand Down
59 changes: 21 additions & 38 deletions app/services/deallocate_kit_inventory_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,47 +34,30 @@ def deallocate_inventory_items
end

def deallocate_inventory_in_and_inventory_out
deallocate_inventory_in
deallocate_inventory_out
end

def deallocate_inventory_out
kit_allocation = KitAllocation.find_by(storage_location_id: storage_location.id, kit_id: kit.id,
organization_id: kit.organization.id, kit_allocation_type: "inventory_out")
if kit_allocation.present?
line_items = kit_allocation.line_items
kit_content.each_with_index do |line_item, index|
line_item_record = line_items[index]
new_quantity = line_item_record[:quantity] + line_item[:quantity].to_i
if new_quantity.to_i == 0
kit_allocation.destroy!
break
elsif new_quantity.to_i > 0
raise StandardError.new("Inconsistent inventory out")
else
line_item_record.update!(quantity: new_quantity)
kit_allocation_types = ["inventory_in", "inventory_out"]
kit_allocation_types.each do |kit_allocation_type|
kit_allocation = KitAllocation.find_by(storage_location_id: storage_location.id, kit_id: kit.id,
organization_id: kit.organization.id, kit_allocation_type: kit_allocation_type)
if kit_allocation.present?
multiply_by = (kit_allocation_type == "inventory_out") ? 1 : -1
line_items = kit_allocation.line_items
kit_content.each_with_index do |line_item, index|
line_item_record = line_items[index]
new_quantity = line_item_record[:quantity] + line_item[:quantity].to_i * multiply_by
if new_quantity.to_i == 0
kit_allocation.destroy!
break
elsif kit_allocation_type == "inventory_out" && new_quantity.to_i > 0
raise StandardError.new("Inconsistent inventory out")
elsif kit_allocation_type == "inventory_in" && new_quantity.to_i < 0
raise StandardError.new("Inconsistent inventory in")
else
line_item_record.update!(quantity: new_quantity)
end
end
end
else
raise Errors::KitAllocationNotExists
end
end

def deallocate_inventory_in
kit_allocation = KitAllocation.find_by(storage_location_id: storage_location.id, kit_id: kit.id,
organization_id: kit.organization.id, kit_allocation_type: "inventory_in")
if kit_allocation.present?
kit_item = kit_allocation.line_items.first
new_quantity = kit_item[:quantity].to_i - decrease_by
if new_quantity.to_i == 0
kit_allocation.destroy!
elsif new_quantity.to_i < 0
raise StandardError.new("Inconsistent inventory in")
else
kit_item.update!(quantity: new_quantity)
raise Errors::KitAllocationNotExists
end
else
raise Errors::KitAllocationNotExists
end
end

Expand Down
5 changes: 5 additions & 0 deletions db/migrate/20230712104746_level_up_invetory_in.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class LevelUpInvetoryIn < ActiveRecord::Migration[7.0]
def change
Rake::Task["kit_allocation:inventory_in"].invoke
end
end
2 changes: 1 addition & 1 deletion 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[7.0].define(version: 2023_06_16_055847) do
ActiveRecord::Schema[7.0].define(version: 2023_07_12_104746) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

Expand Down
17 changes: 17 additions & 0 deletions lib/tasks/level_up_inventory_in.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace :kit_allocation do
desc "Level up inventory in to inventory out in kit_allocations"
task inventory_in: :environment do |task|
KitAllocation.where(kit_allocation_type: "inventory_in").destroy_all
out_kit_allocations = KitAllocation.where(kit_allocation_type: "inventory_out")
out_kit_allocations.each do |out_kit_allocation|
in_kit_allocation = KitAllocation.create!(storage_location_id: out_kit_allocation.storage_location_id,
organization_id: out_kit_allocation.organization_id,
kit_id: out_kit_allocation.kit_id,
kit_allocation_type: "inventory_in")
out_kit_allocation.line_items.each do |line_item|
in_kit_allocation.line_items.create!(item_id: line_item.item_id, quantity: line_item.quantity * -1)
end
end
puts "Done..."
end
end
10 changes: 10 additions & 0 deletions spec/factories/kit_allocations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,15 @@
kit = Kit.find(instance.kit_id)
kit.update(organization_id: instance.organization_id)
end

trait :with_items do
after(:build) do |kit_allocation, evaluator|
kit = Kit.find(kit_allocation.kit_id)
multiply_by = (kit_allocation.kit_allocation_type == "inventory_in") ? 1 : -1
kit.line_items.each do |line_item|
kit_allocation.line_items << build(:line_item, quantity: line_item.quantity * multiply_by, item_id: line_item.item_id, itemizable: kit_allocation)
end
end
end
end
end
10 changes: 6 additions & 4 deletions spec/queries/items_in_query_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
create_list(:purchase, 2, :with_items, item: create(:item), item_quantity: 5, storage_location: storage_location)
create_list(:adjustment, 2, :with_items, item: create(:item), item_quantity: 5, storage_location: storage_location)
create_list(:transfer, 2, :with_items, item_quantity: 5, item: other_storage_location.inventory_items.first.item, from: other_storage_location, to: storage_location)
kit = create(:kit, :with_item, organization: @organization)
create(:kit_allocation, :with_items, kit_allocation_type: "inventory_in", kit_id: kit.id, storage_location: storage_location, organization_id: @organization.id)
end

it "returns a collection with the fields name, item_id, quantity" do
Expand All @@ -19,22 +21,22 @@
expect(subject.first).to be_respond_to(:item_id)
end

it "includes donations, purchases, adjustments, transfers among sources" do
expect(subject.to_a.size).to eq(4)
it "includes donations, purchases, adjustments, transfers, kit_allocations among sources" do
expect(subject.to_a.size).to eq(5)
end

it "does not count negative adjustments towards in-flow" do
shared_item = create(:item)
create(:donation, :with_items, item: shared_item, item_quantity: 10, storage_location: storage_location)
create(:adjustment, :with_items, item: shared_item, item_quantity: -10, storage_location: storage_location)
expect(subject.to_a.size).to eq(5)
expect(subject.to_a.size).to eq(6)
end

it "does not count transfers going in the negative direction" do
shared_item = create(:item)
create(:donation, :with_items, item: shared_item, item_quantity: 10, storage_location: storage_location)
create(:transfer, :with_items, item_quantity: 10, item: shared_item, from: storage_location, to: other_storage_location)
expect(subject.to_a.size).to eq(5)
expect(subject.to_a.size).to eq(6)
end
end
end
12 changes: 7 additions & 5 deletions spec/queries/items_in_total_query_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
create(:purchase, :with_items, item: create(:item), item_quantity: 10, storage_location: storage_location)
create(:adjustment, :with_items, item: create(:item), item_quantity: 10, storage_location: storage_location)
create(:transfer, :with_items, item_quantity: 10, item: other_storage_location.inventory_items.first.item, from: other_storage_location, to: storage_location)
kit = create(:kit, :with_item, organization: @organization)
create(:kit_allocation, :with_items, kit_allocation_type: "inventory_in", kit_id: kit.id, storage_location: storage_location, organization_id: @organization.id)
end

it "returns a sum total of all in-flows" do
expect(subject).to eq(40)
expect(subject).to eq(41)
end

it "counts shared items together" do
Expand All @@ -25,26 +27,26 @@
create(:donation, :with_items, item: shared_item, item_quantity: 100, storage_location: storage_location)
create(:purchase, :with_items, item: shared_item, item_quantity: 50, storage_location: storage_location)
create(:adjustment, :with_items, item: shared_item, item_quantity: 100, storage_location: storage_location)
expect(subject).to eq(490)
expect(subject).to eq(491)
end

it "does not count negative adjustments towards in-flow" do
create(:donation, :with_items, item: shared_item, item_quantity: 10, storage_location: storage_location)
create(:adjustment, :with_items, item: shared_item, item_quantity: -10, storage_location: storage_location)
expect(subject).to eq(50)
expect(subject).to eq(51)
end

it "does not count transfers going in the negative direction" do
create(:donation, :with_items, item: shared_item, item_quantity: 10, storage_location: storage_location)
create(:transfer, :with_items, item_quantity: 10, item: shared_item, from: storage_location, to: other_storage_location)
expect(subject).to eq(50)
expect(subject).to eq(51)
end

it "does not count donations, purchases, adjustments to other storage locations" do
create(:donation, :with_items, item: create(:item), item_quantity: 100, storage_location: other_storage_location)
create(:purchase, :with_items, item: create(:item), item_quantity: 10, storage_location: other_storage_location)
create(:adjustment, :with_items, item: create(:item), item_quantity: 10, storage_location: other_storage_location)
expect(subject).to eq(40)
expect(subject).to eq(41)
end
end
end
6 changes: 4 additions & 2 deletions spec/queries/items_out_query_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
create(:transfer, :with_items, item_quantity: 8, item: items[0], to: other_storage_location, from: storage_location)
create(:distribution, :with_items, item: items[1], item_quantity: 9, storage_location: storage_location)
create(:adjustment, :with_items, item: items[2], item_quantity: -10, storage_location: storage_location)
kit = create(:kit, :with_item, organization: @organization)
create(:kit_allocation, :with_items, kit_allocation_type: "inventory_out", kit_id: kit.id, storage_location: storage_location, organization_id: @organization.id)
end

it "returns a collection with the fields name, item_id, quantity" do
Expand All @@ -19,8 +21,8 @@
expect(subject.first).to be_respond_to(:item_id)
end

it "includes distributions, adjustments, transfers among sources" do
expect(subject.to_a.size).to eq(3)
it "includes distributions, adjustments, transfers and kit_allocations among sources" do
expect(subject.to_a.size).to eq(4)
end
end
end
4 changes: 3 additions & 1 deletion spec/queries/items_out_total_query_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
create(:transfer, :with_items, item_quantity: 10, item: items[0], to: other_storage_location, from: storage_location)
create(:distribution, :with_items, item: items[1], item_quantity: 10, storage_location: storage_location)
create(:adjustment, :with_items, item: items[2], item_quantity: -10, storage_location: storage_location)
kit = create(:kit, :with_item, organization: @organization)
create(:kit_allocation, :with_items, kit_allocation_type: "inventory_out", kit_id: kit.id, storage_location: storage_location, organization_id: @organization.id)
end

it "returns a sum total of all out-flows" do
expect(subject).to eq(30)
expect(subject).to eq(31)
end
end
end
Loading

0 comments on commit 1a38904

Please sign in to comment.