From 98bdc3f1706bcd35c6261734f372bf000b922953 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bernd=20Ble=C3=9Fmann?= Date: Mon, 6 Sep 2021 16:25:50 +0200 Subject: [PATCH] CsvImport Lieferscheine: Zusammenfassen von Lieferpositionen Wenn in mehreren Positionen Teilmengen einer Position eines Auftrags geliefert werden, dann diese Zusammenfassen. --- SL/Controller/CsvImport/DeliveryOrder.pm | 37 ++++++- t/controllers/csvimport/delivery_orders.t | 113 +++++++++++++++++++++- 2 files changed, 144 insertions(+), 6 deletions(-) diff --git a/SL/Controller/CsvImport/DeliveryOrder.pm b/SL/Controller/CsvImport/DeliveryOrder.pm index b66278721..b93455a4e 100644 --- a/SL/Controller/CsvImport/DeliveryOrder.pm +++ b/SL/Controller/CsvImport/DeliveryOrder.pm @@ -711,6 +711,10 @@ sub handle_order_sources { push @{ $entry->{errors} }, $::locale->text('Error: More than one source order found'); } + foreach my $order (@$orders) { + $self->{remaining_source_qtys_by_item_id} = { map { $_->id => $_->qty } @{ $order->items } }; + } + $record->{source_orders} = $orders; } @@ -722,9 +726,38 @@ sub handle_item_source { return if !@{ $record->{source_orders} }; + # Todo: units? + foreach my $order (@{ $record->{source_orders} }) { - $item->{source_item} = first { $item->parts_id == $_->parts_id && $item->qty == $_->qty} @{ $order->items_sorted }; - last if $item->{source_item}; + # First: Excact matches and source order position is still complete. + $item->{source_item} = first { + $item->parts_id == $_->parts_id + && $item->qty == $_->qty + && $self->{remaining_source_qtys_by_item_id}->{$_->id} == $_->qty + } @{ $order->items_sorted }; + if ($item->{source_item}) { + $self->{remaining_source_qtys_by_item_id}->{$item->{source_item}->id} -= $item->qty; + last; + } + + # Second: Smallest remaining order qty greater or equal delivery order qty. + $item->{source_item} = first { + $item->parts_id == $_->parts_id + && $self->{remaining_source_qtys_by_item_id}->{$_->id} >= $item->qty + } sort { $self->{remaining_source_qtys_by_item_id}->{$a->id} <=> $self->{remaining_source_qtys_by_item_id}->{$b->id} } @{ $order->items_sorted }; + if ($item->{source_item}) { + $self->{remaining_source_qtys_by_item_id}->{$item->{source_item}->id} -= $item->qty; + last; + } + + # Last: Overdelivery? + # $item->{source_item} = first { + # $item->parts_id == $_->parts_id + # } @{ $order->items_sorted }; + # if ($item->{source_item}) { + # $self->{remaining_source_qtys_by_item_id}->{$item->{source_item}->id} -= $item->qty; + # last; + # } } } diff --git a/t/controllers/csvimport/delivery_orders.t b/t/controllers/csvimport/delivery_orders.t index e7e791423..ca38c2dc0 100644 --- a/t/controllers/csvimport/delivery_orders.t +++ b/t/controllers/csvimport/delivery_orders.t @@ -1,4 +1,4 @@ -use Test::More tests => 15; +use Test::More tests => 28; use strict; @@ -117,7 +117,8 @@ clear_up; ordnumber => '1234', orderitems => [ create_order_item(part => $parts[0], qty => 3, sellprice => 70), create_order_item(part => $parts[1], qty => 10, sellprice => 50), - create_order_item(part => $parts[2], qty => 8, sellprice => 80) + create_order_item(part => $parts[2], qty => 8, sellprice => 80), + create_order_item(part => $parts[2], qty => 11, sellprice => 80) ] ) ); @@ -131,12 +132,23 @@ OrderItem;TestPart1;5 OrderItem;TestPart2;10 OrderItem;TestPart3;7 OrderItem;TestPart3;1 +OrderItem;TestPart3;11 EOL + 1; # make emacs happy + +# should be: +# delivery oder pos/qty <- order pos/qty +# 1/5 <- - +# 2/10 <- 2/10 +# 3/7 <- 3/7 +# 4/1 <- 3/1 +# 5/11 <- 4/11 + $entries = do_import($file); +$orders[0]->load; # reload order to get correct delivered status $entry = $entries->[0]; - is $entry->{object}->ordnumber, '1234', 'with source order: ordnumber'; my $linked = $orders[0]->linked_records(to => 'DeliveryOrder'); @@ -159,11 +171,104 @@ ok($linked->[0]->id == $orders[0]->items_sorted->[1]->id, 'with source order: sa $entry = $entries->[3]; $linked = $entry->{object}->linked_records(from => 'OrderItem'); -ok(scalar @$linked == 0, 'with source order: delivered qty < ordered qty: delivery order item not linked'); +ok(scalar @$linked == 1, 'with source order: delivered qty < ordered qty: delivery order item linked (fill up)'); +ok($linked->[0]->position == 3, 'with source order: delivered qty < ordered qty: order position ok (fill up)'); + +$entry = $entries->[4]; +$linked = $entry->{object}->linked_records(from => 'OrderItem'); +ok(scalar @$linked == 1, 'with source order: delivered qty < ordered qty: delivery order item linked (fill up) 2'); +ok($linked->[0]->position == 3, 'with source order: delivered qty < ordered qty: order position ok (fill up) 2'); + +$entry = $entries->[5]; +$linked = $entry->{object}->linked_records(from => 'OrderItem'); +ok(scalar @$linked == 1, 'with source order: delivered qty == ordered qty: found exact match after fill up'); +ok($linked->[0]->position == 4, 'with source order: delivered qty == ordered qty: order position ok after fill up'); + +ok(!$orders[0]->delivered, 'with source order: order not completely delivered'); + +$entries = undef; +clear_up; ##### +@customers = (new_customer(name => 'TestCustomer1', discount => 0)->save); +@parts = ( + new_part(description => 'TestPart1', ean => '')->save, + new_part(description => 'TestPart2', ean => '')->save, + new_part(description => 'TestPart3', ean => '')->save +); +@orders = ( + create_sales_order( + save => 1, + customer => $customers[0], + ordnumber => '1234', + orderitems => [ create_order_item(part => $parts[0], qty => 3, sellprice => 70), + create_order_item(part => $parts[1], qty => 10, sellprice => 50), + create_order_item(part => $parts[2], qty => 8, sellprice => 80), + create_order_item(part => $parts[2], qty => 11, sellprice => 80) + ] + ) +); + +$file = \<load; # reload order to get correct delivered status + +$entry = $entries->[1]; +$linked = $entry->{object}->linked_records(from => 'OrderItem'); +ok($linked->[0]->position == 1, 'with source order: mixed qtys and fill up: order position ok 1'); + +$entry = $entries->[2]; +$linked = $entry->{object}->linked_records(from => 'OrderItem'); +ok($linked->[0]->position == 2, 'with source order: mixed qtys and fill up: order position ok 2'); + +$entry = $entries->[3]; +$linked = $entry->{object}->linked_records(from => 'OrderItem'); +ok($linked->[0]->position == 1, 'with source order: mixed qtys and fill up: order position ok 3'); + +$entry = $entries->[4]; +$linked = $entry->{object}->linked_records(from => 'OrderItem'); +ok($linked->[0]->position == 3, 'with source order: mixed qtys and fill up: order position ok 4'); + +$entry = $entries->[5]; +$linked = $entry->{object}->linked_records(from => 'OrderItem'); +ok($linked->[0]->position == 4, 'with source order: mixed qtys and fill up: order position ok 5'); + +$entry = $entries->[6]; +$linked = $entry->{object}->linked_records(from => 'OrderItem'); +ok($linked->[0]->position == 3, 'with source order: mixed qtys and fill up: order position ok 6'); + +ok(!!$orders[0]->delivered, 'with source order: mixed qtys and fill up: order completely delivered'); + +##### +$entries = undef; clear_up; +##### + $::myconfig{numberformat} = $old_numberformat; $::locale = $old_locale; -- 2.20.1