t/helper/shipped_qty.t: diverse Kleinigkeiten
[kivitendo-erp.git] / t / helper / shipped_qty.t
1 use strict;
2 use Test::More;
3
4 use lib 't';
5 use Support::TestSetup;
6 use Carp;
7 use Test::Exception;
8 use Data::Dumper;
9 use SL::DB::Part;
10 use SL::DB::Inventory;
11 use SL::DB::TransferType;
12 use SL::DB::Order;
13 use SL::DB::DeliveryOrder;
14 use SL::DB::Customer;
15 use SL::DB::Vendor;
16 use SL::DB::RecordLink;
17 use SL::DB::DeliveryOrderItemsStock;
18 use SL::DB::Bin;
19 use SL::WH;
20 use SL::AM;
21 use SL::Dev::ALL;
22 use SL::Helper::ShippedQty;
23 use DateTime;
24
25 Support::TestSetup::login();
26
27 clear_up();
28
29 my ($customer, $vendor, @parts, $unit);
30
31 $customer = SL::Dev::CustomerVendor::create_customer(name => 'Testkunde'    )->save;
32 $vendor   = SL::Dev::CustomerVendor::create_vendor(  name => 'Testlieferant')->save;
33
34 my $default_sellprice = 10;
35 my $default_lastcost  =  4;
36
37 my ($wh) = SL::Dev::Inventory::create_warehouse_and_bins();
38 my $bin1 = SL::DB::Manager::Bin->find_by(description => "Bin 1");
39 my $bin2 = SL::DB::Manager::Bin->find_by(description => "Bin 2");
40
41 my %part_defaults = (
42     sellprice    => $default_sellprice,
43     warehouse_id => $wh->id,
44     bin_id       => $bin1->id
45 );
46
47 # create 3 parts to be used in test
48 for my $i ( 1 .. 4 ) {
49   SL::Dev::Part::create_part( %part_defaults, partnumber => $i, description => "part $i test" )->save;
50 };
51
52 my $part1 = SL::DB::Manager::Part->find_by( partnumber => '1' );
53 my $part2 = SL::DB::Manager::Part->find_by( partnumber => '2' );
54 my $part3 = SL::DB::Manager::Part->find_by( partnumber => '3' );
55 my $part4 = SL::DB::Manager::Part->find_by( partnumber => '4' );
56
57 my @part_ids; # list of all part_ids to run checks against
58 push( @part_ids, $_->id ) foreach ( $part1, $part2, $part3, $part4 );
59 my %default_transfer_params = ( wh => $wh, bin => $bin1, unit => 'Stck');
60
61
62 # test purchases first, so there is actually stock available when sales is tested
63
64 note("testing purchases, no fill_up");
65
66 my $purchase_order = SL::Dev::Record::create_purchase_order(
67   save       => 1,
68   orderitems => [ SL::Dev::Record::create_order_item(part => $part1, qty => 11),
69                   SL::Dev::Record::create_order_item(part => $part2, qty => 12),
70                   SL::Dev::Record::create_order_item(part => $part3, qty => 13),
71                 ]
72 );
73
74 Rose::DB::Object::Helpers::forget_related($purchase_order, 'orderitems');
75 $purchase_order->orderitems;
76
77 SL::Helper::ShippedQty
78   ->new(require_stock_out => 1)  # should make no difference while there is no delivery order
79   ->calculate($purchase_order)
80   ->write_to_objects;
81
82 is($purchase_order->orderitems->[0]->{shipped_qty}, 0, "first purchase orderitem has no shipped_qty");
83 ok(!$purchase_order->orderitems->[0]->{delivered},     "first purchase orderitem is not delivered");
84
85 my $purchase_orderitem_part1 = SL::DB::Manager::OrderItem->find_by( parts_id => $part1->id, trans_id => $purchase_order->id);
86
87 is($purchase_orderitem_part1->shipped_qty, 0, "OrderItem shipped_qty method ok");
88
89 is($purchase_order->closed,     0, 'purchase order is open');
90 ok(!$purchase_order->delivered,    'purchase order is not delivered');
91
92 note('converting purchase order to delivery order');
93 # create purchase delivery order from purchase order
94 my $purchase_delivery_order = $purchase_order->convert_to_delivery_order;
95 is($purchase_order->closed,    0, 'purchase order is open');
96 ok($purchase_order->delivered,    'purchase order is now delivered');
97
98 SL::Helper::ShippedQty
99   ->new(require_stock_out => 0)
100   ->calculate($purchase_order)
101   ->write_to_objects;
102
103 is($purchase_order->orderitems->[0]->{shipped_qty}, 11, "require_stock_out => 0: first purchase orderitem has shipped_qty");
104 ok($purchase_order->orderitems->[0]->{delivered},       "require_stock_out => 0: first purchase orderitem is delivered");
105
106 Rose::DB::Object::Helpers::forget_related($purchase_order, 'orderitems');
107 $purchase_order->orderitems;
108
109 SL::Helper::ShippedQty
110   ->new(require_stock_out => 1)
111   ->calculate($purchase_order)
112   ->write_to_objects;
113
114 is($purchase_order->orderitems->[0]->{shipped_qty}, 0,  "require_stock_out => 1: first purchase orderitem has no shipped_qty");
115 ok(!$purchase_order->orderitems->[0]->{delivered},      "require_stock_out => 1: first purchase orderitem is not delivered");
116
117 # ship items from delivery order
118 SL::Dev::Inventory::transfer_purchase_delivery_order($purchase_delivery_order);
119
120 Rose::DB::Object::Helpers::forget_related($purchase_order, 'orderitems');
121 $purchase_order->orderitems;
122
123 SL::Helper::ShippedQty
124   ->new(require_stock_out => 1, keep_matches => 1)  # shouldn't make a difference now after shipping
125   ->calculate($purchase_order)
126   ->write_to_objects;
127
128 is($purchase_order->orderitems->[0]->{shipped_qty}, 11, "require_stock_out => 1: first purchase orderitem has shipped_qty");
129 ok($purchase_order->orderitems->[0]->{delivered},       "require_stock_out => 1: first purchase orderitem is delivered");
130
131 my $purchase_orderitem_part2 = SL::DB::Manager::OrderItem->find_by(parts_id => $part1->id, trans_id => $purchase_order->id);
132
133 is($purchase_orderitem_part2->shipped_qty(require_stock_out => 1), 11, "OrderItem shipped_qty from helper ok");
134
135
136 note('testing sales, no fill_up');
137
138 my $sales_order = SL::Dev::Record::create_sales_order(
139   save       => 1,
140   orderitems => [ SL::Dev::Record::create_order_item(part => $part1, qty => 5),
141                   SL::Dev::Record::create_order_item(part => $part2, qty => 6),
142                   SL::Dev::Record::create_order_item(part => $part3, qty => 7),
143                 ]
144 );
145
146 Rose::DB::Object::Helpers::forget_related($purchase_order, 'orderitems');
147 $sales_order->orderitems;
148
149 SL::Helper::ShippedQty
150   ->new(require_stock_out => 1)  # should make no difference while there is no delivery order
151   ->calculate($sales_order)
152   ->write_to_objects;
153
154 is($sales_order->orderitems->[0]->{shipped_qty}, 0,  "first sales orderitem has no shipped_qty");
155 ok(!$sales_order->orderitems->[0]->{delivered},      "first sales orderitem is not delivered");
156
157 my $orderitem_part1 = SL::DB::Manager::OrderItem->find_by(parts_id => $part1->id, trans_id => $sales_order->id);
158 my $orderitem_part2 = SL::DB::Manager::OrderItem->find_by(parts_id => $part2->id, trans_id => $sales_order->id);
159
160 is($orderitem_part1->shipped_qty, 0, "OrderItem shipped_qty method ok");
161
162 # create sales delivery order from sales order
163 my $sales_delivery_order = $sales_order->convert_to_delivery_order;
164
165 SL::Helper::ShippedQty
166   ->new(require_stock_out => 0)
167   ->calculate($sales_order)
168   ->write_to_objects;
169
170 is($sales_order->orderitems->[0]->{shipped_qty}, 5, "require_stock_out => 0: first sales orderitem has shipped_qty");
171 ok($sales_order->orderitems->[0]->{delivered},      "require_stock_out => 0: first sales orderitem is delivered");
172
173 Rose::DB::Object::Helpers::forget_related($sales_order, 'orderitems');
174 $sales_order->orderitems;
175
176 SL::Helper::ShippedQty
177   ->new(require_stock_out => 1)
178   ->calculate($sales_order)
179   ->write_to_objects;
180
181 is($sales_order->orderitems->[0]->{shipped_qty}, 0,  "require_stock_out => 1: first sales orderitem has no shipped_qty");
182 ok(!$sales_order->orderitems->[0]->{delivered},      "require_stock_out => 1: first sales orderitem is not delivered");
183
184 # ship items from delivery order
185 SL::Dev::Inventory::transfer_sales_delivery_order($sales_delivery_order);
186
187 Rose::DB::Object::Helpers::forget_related($sales_order, 'orderitems');
188 $sales_order->orderitems;
189
190 SL::Helper::ShippedQty
191   ->new(require_stock_out => 1)
192   ->calculate($sales_order)
193   ->write_to_objects;
194
195 is($sales_order->orderitems->[0]->{shipped_qty}, 5, "require_stock_out => 1: first sales orderitem has no shipped_qty");
196 ok($sales_order->orderitems->[0]->{delivered},      "require_stock_out => 1: first sales orderitem is not delivered");
197
198 $orderitem_part1 = SL::DB::Manager::OrderItem->find_by(parts_id => $part1->id, trans_id => $sales_order->id);
199
200 is($orderitem_part1->shipped_qty(require_stock_out => 1), 5, "OrderItem shipped_qty from helper ok");
201
202
203 note('misc tests');
204 my $number_of_linked_items = SL::DB::Manager::RecordLink->get_all_count( where => [ from_table => 'orderitems', to_table => 'delivery_order_items' ] );
205 is ($number_of_linked_items , 6, "6 record_links for items, 3 from sales order, 3 from purchase order");
206
207 clear_up();
208
209 done_testing;
210
211 sub clear_up {
212   foreach ( qw(Inventory DeliveryOrderItem DeliveryOrder Price OrderItem Order Part Customer Vendor Bin Warehouse) ) {
213     "SL::DB::Manager::${_}"->delete_all(all => 1);
214   }
215 };