From 247a26dc4b5b0d73c03fc6f05fb17daace0835d9 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Tue, 8 Jul 2008 10:48:30 +0000 Subject: [PATCH] =?utf8?q?Beim=20Umwandeln=20von=20Auftr=C3=A4gen=20in=20R?= =?utf8?q?echnungen=20nicht=20sofort=20den=20Auftrag=20schlie=C3=9Fen.=20B?= =?utf8?q?eim=20Buchen=20von=20Rechnungen=20die=20Auftr=C3=A4ge=20schlie?= =?utf8?q?=C3=9Fen,=20aus=20denen=20die=20Rechnung=20erzeugt=20wurde=20(au?= =?utf8?q?ch=20mit=20Umweg=20=C3=BCber=20Lieferscheine),=20sofern=20der=20?= =?utf8?q?Auftrag=20damit=20vollst=C3=A4ndig=20abgerechnet=20wurde.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- SL/ARAP.pm | 168 ++++++++++++++++++++++++++++++++++++++++++++++ SL/IR.pm | 6 ++ SL/IS.pm | 6 ++ bin/mozilla/oe.pl | 12 ---- 4 files changed, 180 insertions(+), 12 deletions(-) create mode 100644 SL/ARAP.pm diff --git a/SL/ARAP.pm b/SL/ARAP.pm new file mode 100644 index 000000000..299c32f16 --- /dev/null +++ b/SL/ARAP.pm @@ -0,0 +1,168 @@ +package ARAP; + +use SL::AM; +use SL::Common; +use SL::DBUtils; +use SL::MoreCommon; +use Data::Dumper; + +sub close_orders_if_billed { + $main::lxdebug->enter_sub(); + + my $self = shift; + my %params = @_; + + Common::check_params(\%params, qw(arap_id table)); + + my $myconfig = \%main::myconfig; + my $form = $main::form; + + my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig); + + # First, find all order IDs from which this invoice has been + # created. Either directly by a conversion from an order to this invoice + # or indirectly from an order to one or more delivery orders and + # from those to this invoice. + + # Direct conversion "order -> invoice": + my @links = RecordLinks->get_links('dbh' => $dbh, + 'from_table' => 'oe', + 'to_table' => $params{table}, + 'to_id' => $params{arap_id}); + + my %oe_id_map = map { $_->{from_id} => 1 } @links; + + # Indirect conversion "order -> delivery orders -> invoice": + my @do_links = RecordLinks->get_links('dbh' => $dbh, + 'from_table' => 'delivery_orders', + 'to_table' => $params{table}, + 'to_id' => $params{arap_id}); + + foreach my $do_link (@do_links) { + @links = RecordLinks->get_links('dbh' => $dbh, + 'from_table' => 'oe', + 'to_table' => 'delivery_orders', + 'to_id' => $do_link->{from_id}); + + map { $oe_id_map{$_->{from_id}} = 1 } @links; + } + + my @oe_ids = keys %oe_id_map; + +# $main::lxdebug->dump(0, "oe_ids", \@oe_ids); + + # No orders found? Nothing to do then, so let's return. + return $main::lxdebug->leave_sub() if (!scalar @oe_ids); + + my $all_units = AM->retrieve_all_units(); + + my $qtyfactor = $params{table} eq 'ap' ? '* -1' : ''; + my $q_billed = qq|SELECT i.parts_id, i.qty ${qtyfactor} AS qty, i.unit, p.unit AS partunit + FROM invoice i + LEFT JOIN parts p ON (i.parts_id = p.id) + WHERE i.trans_id = ?|; + my $h_billed = prepare_query($form, $dbh, $q_billed); + + my $q_ordered = qq|SELECT oi.parts_id, oi.qty, oi.unit, p.unit AS partunit + FROM orderitems oi + LEFT JOIN parts p ON (oi.parts_id = p.id) + WHERE oi.trans_id = ?|; + my $h_ordered = prepare_query($form, $dbh, $q_ordered); + + my @close_oe_ids; + + # Interate over each order and look up all invoices created for + # said order. Again consider both direct conversions and indirect + # conversions via delivery orders. + foreach my $oe_id (@oe_ids) { + # Direct conversions "order -> invoice": + @links = RecordLinks->get_links('dbh' => $dbh, + 'from_table' => 'oe', + 'from_id' => $oe_id, + 'to_table' => $params{table},); + + my %arap_id_map = map { $_->{to_id} => 1 } @links; + + # Indirect conversions "order -> delivery orders -> invoice": + @do_links = RecordLinks->get_links('dbh' => $dbh, + 'from_table' => 'oe', + 'from_id' => $oe_id, + 'to_table' => 'delivery_orders',); + foreach my $do_link (@do_links) { + @links = RecordLinks->get_links('dbh' => $dbh, + 'from_table' => 'delivery_orders', + 'from_id' => $do_link->{to_id}, + 'to_table' => $params{table},); + + map { $arap_id_map{$_->{to_id}} = 1 } @links; + } + + my @arap_ids = keys %arap_id_map; + +# $main::lxdebug->dump(0, "for $oe_id arap_ids", \@arap_ids); + + next if (!scalar @arap_ids); + + # Retrieve all positions for this order. Calculate the ordered quantity for each position. + my %ordered = (); + + do_statement($form, $h_ordered, $q_ordered, $oe_id); + + while (my $ref = $h_ordered->fetchrow_hashref()) { + $ref->{baseqty} = $ref->{qty} * $all_units->{$ref->{unit}}->{factor} / $all_units->{$ref->{partunit}}->{factor}; + + if ($ordered{$ref->{parts_id}}) { + $ordered{$ref->{parts_id}}->{baseqty} += $ref->{baseqty}; + } else { + $ordered{$ref->{parts_id}} = $ref; + } + } + + # Retrieve all positions for all invoices that have been created from this order. + my %billed = (); + + foreach my $arap_id (@arap_ids) { + do_statement($form, $h_billed, $q_billed, $arap_id); + + while (my $ref = $h_billed->fetchrow_hashref()) { + $ref->{baseqty} = $ref->{qty} * $all_units->{$ref->{unit}}->{factor} / $all_units->{$ref->{partunit}}->{factor}; + + if ($billed{$ref->{parts_id}}) { + $billed{$ref->{parts_id}}->{baseqty} += $ref->{baseqty}; + } else { + $billed{$ref->{parts_id}} = $ref; + } + } + } + + # Check all ordered positions. If all positions have been billed completely then this order can be closed. + my $all_billed = 1; + foreach my $part (values %ordered) { + if (!$billed{$part->{parts_id}} || ($billed{$part->{parts_id}}->{baseqty} < $part->{baseqty})) { + $all_billed = 0; + last; + } + } + +# $main::lxdebug->message(0, "all_billed $all_billed"); +# $main::lxdebug->dump(0, "ordered", \%ordered); +# $main::lxdebug->dump(0, "billed", \%billed); + + push @close_oe_ids, $oe_id if ($all_billed); + } + + $h_billed->finish(); + $h_ordered->finish(); + + # Close orders that have been billed fully. + if (scalar @close_oe_ids) { + my $query = qq|UPDATE oe SET closed = TRUE WHERE id IN (| . join(', ', ('?') x scalar @close_oe_ids) . qq|)|; + do_query($form, $dbh, $query, @close_oe_ids); + + $dbh->commit() unless ($params{dbh}); + } + + $main::lxdebug->leave_sub(); +} + +1; diff --git a/SL/IR.pm b/SL/IR.pm index f1c9197ee..936cc98fe 100644 --- a/SL/IR.pm +++ b/SL/IR.pm @@ -35,6 +35,7 @@ package IR; use SL::AM; +use SL::ARAP; use SL::Common; use SL::DBUtils; use SL::DO; @@ -562,6 +563,11 @@ sub post_invoice { 'to_id' => $form->{id}, ); } + delete $form->{convert_from_do_ids}; + + ARAP->close_orders_if_billed('dbh' => $dbh, + 'arap_id' => $form->{id}, + 'table' => 'ap',); my $rc = 1; if (!$provided_dbh) { diff --git a/SL/IS.pm b/SL/IS.pm index c4e2a7fbd..bf52d5223 100644 --- a/SL/IS.pm +++ b/SL/IS.pm @@ -37,6 +37,7 @@ package IS; use List::Util qw(max); use SL::AM; +use SL::ARAP; use SL::CVar; use SL::Common; use SL::DBUtils; @@ -994,6 +995,11 @@ sub post_invoice { 'to_id' => $form->{id}, ); } + delete $form->{convert_from_do_ids}; + + ARAP->close_orders_if_billed('dbh' => $dbh, + 'arap_id' => $form->{id}, + 'table' => 'ar',); my $rc = 1; if (!$provided_dbh) { diff --git a/bin/mozilla/oe.pl b/bin/mozilla/oe.pl index 322706ac1..44690ddb6 100644 --- a/bin/mozilla/oe.pl +++ b/bin/mozilla/oe.pl @@ -1446,18 +1446,6 @@ sub invoice { } } - # close orders/quotations - $form->{closed} = 1; - - # save order if one ordnumber has been given - # if not it's most likely a collective order, which can't be saved back - # so they just have to be closed - if (($form->{ordnumber} ne '') || ($form->{quonumber} ne '')) { - OE->close_order(\%myconfig, \%$form) if ($form->{id}); - } else { - OE->close_orders(\%myconfig, \%$form); - } - $form->{convert_from_oe_ids} = $form->{id}; $form->{transdate} = $form->{invdate} = $form->current_date(\%myconfig); $form->{duedate} = $form->current_date(\%myconfig, $form->{invdate}, $form->{terms} * 1); -- 2.20.1