7 use SL::Dev::Part qw(new_part new_assembly);
8 use SL::Dev::Inventory qw(create_warehouse_and_bins set_stock);
9 use SL::Dev::Record qw(create_sales_order);
11 use_ok 'Support::TestSetup';
13 use_ok 'SL::DB::Part';
14 use_ok 'SL::DB::Warehouse';
15 use_ok 'SL::DB::Inventory';
17 use_ok 'SL::Helper::Inventory';
19 Support::TestSetup::login();
21 my ($wh, $bin1, $bin2, $assembly1, $part1, $part2);
24 create_standard_stock();
27 # simple stock in, get_stock, get_onhand
34 is(SL::Helper::Inventory::get_stock(part => $part1), "25.00000", 'simple get_stock works');
35 is(SL::Helper::Inventory::get_onhand(part => $part1), "25.00000", 'simple get_onhand works');
37 # stock on some more, get_stock, get_onhand
40 parts_id => $part1->id,
42 transfer_type => 'stock',
43 dst_warehouse_id => $bin1->warehouse_id,
44 dst_bin_id => $bin1->id,
49 parts_id => $part1->id,
51 transfer_type => 'stock',
52 chargenumber => '298345',
53 dst_warehouse_id => $bin1->warehouse_id,
54 dst_bin_id => $bin1->id,
58 is(SL::Helper::Inventory::get_stock(part => $part1), "60.00000", 'normal get_stock works');
59 is(SL::Helper::Inventory::get_onhand(part => $part1), "60.00000", 'normal get_onhand works');
63 my @allocations = SL::Helper::Inventory::allocate(
68 is_deeply(\%{ $allocations[0] }, {
72 parts_id => $part1->id,
74 warehouse_id => $wh->id,
75 comment => undef, # comment is not a partition so is not set by allocate
76 for_object_id => undef,
77 }, 'allocation works');
79 # allocate something where more than one result will match
81 @allocations = SL::Helper::Inventory::allocate(
86 is_deeply(\@allocations, [
91 parts_id => $part1->id,
93 warehouse_id => $wh->id,
95 for_object_id => undef,
100 chargenumber => '298345',
101 parts_id => $part1->id,
103 warehouse_id => $wh->id,
105 for_object_id => undef,
107 ], 'complex allocation works');
109 # try to allocate too much
112 SL::Helper::Inventory::allocate(part => $part1, qty => 100)
114 "allocate too much dies");
119 create_standard_stock();
133 my @alloc1 = SL::Helper::Inventory::allocate(part => $part1, qty => 3);
134 my @alloc2 = SL::Helper::Inventory::allocate(part => $part2, qty => 3);
136 SL::Helper::Inventory::produce_assembly(
139 allocations => [ @alloc1, @alloc2 ],
143 chargenumber => "537",
146 is(SL::Helper::Inventory::get_stock(part => $assembly1), "3.00000", 'produce works');
147 is(SL::Helper::Inventory::get_stock(part => $part1), "2.00000", 'and consumes...');
148 is(SL::Helper::Inventory::get_stock(part => $part2), "7.00000", '..the materials');
150 # produce the same using auto_allocation
153 create_standard_stock();
166 SL::Helper::Inventory::produce_assembly(
173 chargenumber => "537",
176 is(SL::Helper::Inventory::get_stock(part => $assembly1), "3.00000", 'produce with auto allocation works');
177 is(SL::Helper::Inventory::get_stock(part => $part1), "2.00000", 'and consumes...');
178 is(SL::Helper::Inventory::get_stock(part => $part2), "7.00000", '..the materials');
180 # try to produce without allocations dies
183 SL::Helper::Inventory::produce_assembly(
189 chargenumber => "537",
191 }, "producing without allocations dies");
193 # try to produce with insufficient allocations dies
195 @alloc1 = SL::Helper::Inventory::allocate(part => $part1, qty => 1);
196 @alloc2 = SL::Helper::Inventory::allocate(part => $part2, qty => 1);
199 SL::Helper::Inventory::produce_assembly(
202 allocations => [ @alloc1, @alloc2 ],
206 chargenumber => "537",
208 }, "producing with insufficient allocations dies");
215 create_standard_stock();
230 SL::Helper::Inventory::produce_assembly(
236 chargenumber => "537",
237 bestbefore => DateTime->today->clone->add(days => -14), # expired 2 weeks ago
238 shippingdate => DateTime->today->clone->add(days => 1),
241 is(SL::Helper::Inventory::get_stock(part => $assembly1), "3.00000", 'produce with bestbefore works');
242 is(SL::Helper::Inventory::get_onhand(part => $assembly1), "3.00000", 'produce with bestbefore works');
243 is(SL::Helper::Inventory::get_stock(
245 bestbefore => DateTime->today,
246 ), undef, 'get_stock with bestbefore date skips expired');
248 local $::instance_conf->data->{show_bestbefore} = 1;
249 is(SL::Helper::Inventory::get_onhand(
251 ), undef, 'get_onhand with bestbefore skips expired as of today');
255 local $::instance_conf->data->{show_bestbefore} = 0;
256 is(SL::Helper::Inventory::get_onhand(
258 ), "3.00000", 'get_onhand without bestbefore finds all');
263 SL::DB::Manager::Order->delete_all(all => 1);
264 SL::DB::Manager::Inventory->delete_all(all => 1);
265 SL::DB::Manager::Assembly->delete_all(all => 1);
266 SL::DB::Manager::Part->delete_all(all => 1);
267 SL::DB::Manager::Bin->delete_all(all => 1);
268 SL::DB::Manager::Warehouse->delete_all(all => 1);
271 sub create_standard_stock {
272 ($wh, $bin1) = create_warehouse_and_bins();
273 $bin2 = SL::DB::Bin->new(description => "Bin 2", warehouse => $wh)->save;
276 $assembly1 = new_assembly(number_of_parts => 2)->save;
277 ($part1, $part2) = map { $_->part } $assembly1->assemblies;