-
-
Notifications
You must be signed in to change notification settings - Fork 510
/
Copy pathdeallocate_kit_inventory_service.rb
101 lines (89 loc) · 2.83 KB
/
deallocate_kit_inventory_service.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
class DeallocateKitInventoryService
attr_reader :error
def initialize(kit:, storage_location:, decrease_by:)
@kit = kit
@storage_location = storage_location
@decrease_by = decrease_by
end
def deallocate
validate_storage_location
deallocate_inventory_items if error.nil?
rescue StandardError => e
Rails.logger.error "[!] #{self.class.name} failed to allocate items for a kit #{kit.name}: #{storage_location.errors.full_messages} [#{e.inspect}]"
set_error(e)
ensure
return self
end
private
attr_reader :kit, :storage_location, :decrease_by
def validate_storage_location
raise Errors::StorageLocationDoesNotMatch if storage_location.organization != kit.organization
end
def deallocate_inventory_items
ActiveRecord::Base.transaction do
storage_location.increase_inventory(kit_content)
storage_location.decrease_inventory(associated_kit_item)
deallocate_inventory_in_and_inventory_out
end
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)
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)
end
else
raise Errors::KitAllocationNotExists
end
end
def set_error(error)
@error = error.message
end
def kit_content
kit.to_a.map do |item|
item.merge({
quantity: item[:quantity] * decrease_by
})
end
end
def associated_kit_item
[
{
item_id: kit.item.id,
quantity: decrease_by
}
]
end
end