11 sub close_orders_if_billed {
12 $main::lxdebug->enter_sub();
17 Common::check_params(\%params, qw(arap_id table));
19 my $myconfig = \%main::myconfig;
20 my $form = $main::form;
22 my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig);
24 # First, find all order IDs from which this invoice has been
25 # created. Either directly by a conversion from an order to this invoice
26 # or indirectly from an order to one or more delivery orders and
27 # from those to this invoice.
29 # Direct conversion "order -> invoice":
30 my @links = RecordLinks->get_links('dbh' => $dbh,
32 'to_table' => $params{table},
33 'to_id' => $params{arap_id});
35 my %oe_id_map = map { $_->{from_id} => 1 } @links;
37 # Indirect conversion "order -> delivery orders -> invoice":
38 my @do_links = RecordLinks->get_links('dbh' => $dbh,
39 'from_table' => 'delivery_orders',
40 'to_table' => $params{table},
41 'to_id' => $params{arap_id});
43 foreach my $do_link (@do_links) {
44 @links = RecordLinks->get_links('dbh' => $dbh,
46 'to_table' => 'delivery_orders',
47 'to_id' => $do_link->{from_id});
49 map { $oe_id_map{$_->{from_id}} = 1 } @links;
52 my @oe_ids = keys %oe_id_map;
54 # No orders found? Nothing to do then, so let's return.
55 return $main::lxdebug->leave_sub unless @oe_ids;
57 my $all_units = AM->retrieve_all_units;
59 my $qtyfactor = $params{table} eq 'ap' ? '* -1' : '';
60 my $q_billed = qq|SELECT i.parts_id, i.qty ${qtyfactor} AS qty, i.unit, p.unit AS partunit
62 LEFT JOIN parts p ON (i.parts_id = p.id)
63 WHERE i.trans_id = ?|;
64 my $h_billed = prepare_query($form, $dbh, $q_billed);
66 my $q_ordered = qq|SELECT oi.parts_id, oi.qty, oi.unit, p.unit AS partunit
68 LEFT JOIN parts p ON (oi.parts_id = p.id)
69 WHERE oi.trans_id = ?|;
70 my $h_ordered = prepare_query($form, $dbh, $q_ordered);
74 # Interate over each order and look up all invoices created for
75 # said order. Again consider both direct conversions and indirect
76 # conversions via delivery orders.
77 foreach my $oe_id (@oe_ids) {
78 # Direct conversions "order -> invoice":
79 @links = RecordLinks->get_links('dbh' => $dbh,
82 'to_table' => $params{table},);
84 my %arap_id_map = map { $_->{to_id} => 1 } @links;
86 # Indirect conversions "order -> delivery orders -> invoice":
87 @do_links = RecordLinks->get_links('dbh' => $dbh,
90 'to_table' => 'delivery_orders',);
91 foreach my $do_link (@do_links) {
92 @links = RecordLinks->get_links('dbh' => $dbh,
93 'from_table' => 'delivery_orders',
94 'from_id' => $do_link->{to_id},
95 'to_table' => $params{table},);
97 map { $arap_id_map{$_->{to_id}} = 1 } @links;
100 my @arap_ids = keys %arap_id_map;
102 next if (!scalar @arap_ids);
104 # Retrieve all positions for this order. Calculate the ordered quantity for each position.
107 do_statement($form, $h_ordered, $q_ordered, $oe_id);
109 while (my $ref = $h_ordered->fetchrow_hashref()) {
110 $ref->{baseqty} = $ref->{qty} * AM->convert_unit($ref->{unit}, $ref->{partunit}, $all_units);
112 if ($ordered{$ref->{parts_id}}) {
113 $ordered{$ref->{parts_id}}->{baseqty} += $ref->{baseqty};
115 $ordered{$ref->{parts_id}} = $ref;
119 # Retrieve all positions for all invoices that have been created from this order.
122 foreach my $arap_id (@arap_ids) {
123 do_statement($form, $h_billed, $q_billed, $arap_id);
125 while (my $ref = $h_billed->fetchrow_hashref()) {
126 $ref->{baseqty} = $ref->{qty} * AM->convert_unit($ref->{unit}, $ref->{partunit}, $all_units);
128 if ($billed{$ref->{parts_id}}) {
129 $billed{$ref->{parts_id}}->{baseqty} += $ref->{baseqty};
131 $billed{$ref->{parts_id}} = $ref;
136 # Check all ordered positions. If all positions have been billed completely then this order can be closed.
138 foreach my $part (values %ordered) {
139 if (!$billed{$part->{parts_id}} || ($billed{$part->{parts_id}}->{baseqty} < $part->{baseqty})) {
145 push @close_oe_ids, $oe_id if ($all_billed);
151 # Close orders that have been billed fully.
152 if (scalar @close_oe_ids) {
153 my $query = qq|UPDATE oe SET closed = TRUE WHERE id IN (| . join(', ', ('?') x scalar @close_oe_ids) . qq|)|;
154 do_query($form, $dbh, $query, @close_oe_ids);
156 $dbh->commit unless $params{dbh};
159 $main::lxdebug->leave_sub();