From: Sven Schöling Date: Fri, 21 May 2021 13:02:42 +0000 (+0200) Subject: WH: fix: duplizierte Lagerjournalmengen bei produzierten Erzeugnissen X-Git-Tag: kivitendo-mebil_0.1-0~9^2~206 X-Git-Url: http://wagnertech.de/git?a=commitdiff_plain;h=6daa0ecafc7bf211b7ba8e9d479b8782301eabf1;p=kivitendo-erp.git WH: fix: duplizierte Lagerjournalmengen bei produzierten Erzeugnissen Analog zu odyn e7850d3d61 und b829d12400 Das Lagerjournal wurde ursprünglich in der Annahme gebaut dass eine Transaktion maximal 2 Einträge hat. Eine Einlagerung und eine Auslagerung. Beim Produzieren von Erzeugnissen werden aber mittlerweile in einer trans_id mehrere Lagerbewegungen zusammengefasst. Der Self-join auf inventory für eine rechte und eine linke Seite funktioniert damit nicht mehr. Eigentlich müsste man das komplett umbauen, dieser Fix sorgt aber erstmal dafür dass die Mengen stimmen, in dem der selfjoin exakt auf die gleiche Zeile passiert. Rückbuchungen und Stornos sind damit auch korrekt verbucht. --- diff --git a/SL/WH.pm b/SL/WH.pm index 3efe8c0fa..2899aaf30 100644 --- a/SL/WH.pm +++ b/SL/WH.pm @@ -548,26 +548,10 @@ sub get_warehouse_journal { $where_clause = defined($where_clause) ? $where_clause : ''; my $query = - qq|SELECT * FROM (SELECT DISTINCT $select{trans} - FROM inventory i1 - LEFT JOIN inventory i2 ON i1.trans_id = i2.trans_id - LEFT JOIN parts p ON i1.parts_id = p.id - LEFT JOIN bin b1 ON i1.bin_id = b1.id - LEFT JOIN bin b2 ON i2.bin_id = b2.id - LEFT JOIN warehouse w1 ON i1.warehouse_id = w1.id - LEFT JOIN warehouse w2 ON i2.warehouse_id = w2.id - LEFT JOIN transfer_type tt ON i1.trans_type_id = tt.id - LEFT JOIN project pr ON i1.project_id = pr.id - LEFT JOIN employee e ON i1.employee_id = e.id - WHERE $where_clause i2.qty = -i1.qty AND i2.qty > 0 AND - i1.trans_id IN ( SELECT i.trans_id FROM inventory i GROUP BY i.trans_id HAVING COUNT(i.trans_id) = 2 ) - GROUP BY $group_clause - - UNION - + qq|SELECT * FROM ( SELECT DISTINCT $select{out} FROM inventory i1 - LEFT JOIN inventory i2 ON i1.trans_id = i2.trans_id + LEFT JOIN inventory i2 ON i1.trans_id = i2.trans_id AND i1.id = i2.id LEFT JOIN parts p ON i1.parts_id = p.id LEFT JOIN bin b1 ON i1.bin_id = b1.id LEFT JOIN bin b2 ON i2.bin_id = b2.id @@ -576,7 +560,7 @@ sub get_warehouse_journal { LEFT JOIN transfer_type tt ON i1.trans_type_id = tt.id LEFT JOIN project pr ON i1.project_id = pr.id LEFT JOIN employee e ON i1.employee_id = e.id - WHERE $where_clause i1.qty < 0 AND + WHERE $where_clause i1.qty != 0 AND tt.direction = 'out' AND i1.trans_id IN ( SELECT i.trans_id FROM inventory i GROUP BY i.trans_id HAVING COUNT(i.trans_id) >= 1 ) GROUP BY $group_clause @@ -584,7 +568,7 @@ sub get_warehouse_journal { SELECT DISTINCT $select{in} FROM inventory i1 - LEFT JOIN inventory i2 ON i1.trans_id = i2.trans_id + LEFT JOIN inventory i2 ON i1.trans_id = i2.trans_id AND i1.id = i2.id LEFT JOIN parts p ON i1.parts_id = p.id LEFT JOIN bin b1 ON i1.bin_id = b1.id LEFT JOIN bin b2 ON i2.bin_id = b2.id @@ -593,12 +577,12 @@ sub get_warehouse_journal { LEFT JOIN transfer_type tt ON i1.trans_type_id = tt.id LEFT JOIN project pr ON i1.project_id = pr.id LEFT JOIN employee e ON i1.employee_id = e.id - WHERE $where_clause i1.qty > 0 AND + WHERE $where_clause i1.qty != 0 AND tt.direction = 'in' AND i1.trans_id IN ( SELECT i.trans_id FROM inventory i GROUP BY i.trans_id HAVING COUNT(i.trans_id) >= 1 ) GROUP BY $group_clause - ORDER BY r_${sort_spec}) AS lines WHERE r_qty>0|; + ORDER BY r_${sort_spec}) AS lines WHERE r_qty != 0|; - my @all_vars = (@filter_vars,@filter_vars,@filter_vars); + my @all_vars = (@filter_vars,@filter_vars); if ($filter{limit}) { $query .= " LIMIT ?"; diff --git a/t/wh/journal.t b/t/wh/journal.t new file mode 100644 index 000000000..e91bdb7dd --- /dev/null +++ b/t/wh/journal.t @@ -0,0 +1,75 @@ +use strict; +use Test::More tests => 4; + +use lib 't'; + +use SL::Dev::Part qw(new_part); +use SL::Dev::Inventory qw(create_warehouse_and_bins); +use SL::DB::Inventory; +use Support::TestSetup; + +Support::TestSetup::login(); + +use_ok("SL::WH"); + +my ($wh, $bin, $part); + +sub init { + ($wh, $bin) = create_warehouse_and_bins( + warehouse_description => 'Test warehouse', + bin_description => 'Test bin', + number_of_bins => 1, + ); + + $part = new_part()->save->load; + + my $tt_used = SL::DB::Manager::TransferType->find_by(direction => 'out', description => 'used') or die; + my $tt_assembled = SL::DB::Manager::TransferType->find_by(direction => 'in', description => 'assembled') or die; + + my %args = ( + trans_id => 1, + bin => $bin, + warehouse => $wh, + part => $part, + qty => 1, + employee => SL::DB::Manager::Employee->current, + shippingdate => DateTime->now, + ); + + SL::DB::Inventory->new(%args, trans_type => $tt_used, qty => -1)->save; + SL::DB::Inventory->new(%args, trans_type => $tt_used, qty => -1)->save; + SL::DB::Inventory->new(%args, trans_type => $tt_assembled, qty => 1)->save; + + qty => { type => 'numeric', precision => 25, scale => 5 }, + shippingdate => { type => 'date', not_null => 1 }, +} + +sub reset_inventory { + SL::DB::Manager::Inventory->delete_all(all => 1); +} + +reset_inventory(); +init(); + +# l_date = Y +# l_warehouse_from = Y +# l_bin_from = Y +# l_warehouse_to = Y +# l_bin_to = Y +# l_partnumber = Y +# l_partdescription = Y +# l_chargenumber = Y +# l_trans_type = Y +# l_qty = Y +# l_oe_id = Y +# l_projectnumber = Y +# qty_op = dontcare + + +my @contents = WH->get_warehouse_journal(sort => 'date'); + +is $contents[0]{qty}, '1.00000', "produce assembly does not multiply qty (1)"; +is $contents[1]{qty}, '1.00000', "produce assembly does not multiply qty (2)"; +is $contents[2]{qty}, '1.00000', "produce assembly does not multiply qty (3)"; + +1;