1 #====================================================================
4 # Based on SQL-Ledger Version 2.1.9
5 # Web http://www.lx-office.org
7 #=====================================================================
8 # SQL-Ledger Accounting
9 # Copyright (C) 1999-2003
11 # Author: Dieter Simader
12 # Email: dsimader@sql-ledger.org
13 # Web: http://www.sql-ledger.org
17 # This program is free software; you can redistribute it and/or modify
18 # it under the terms of the GNU General Public License as published by
19 # the Free Software Foundation; either version 2 of the License, or
20 # (at your option) any later version.
22 # This program is distributed in the hope that it will be useful,
23 # but WITHOUT ANY WARRANTY; without even the implied warranty of
24 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 # GNU General Public License for more details.
26 # You should have received a copy of the GNU General Public License
27 # along with this program; if not, write to the Free Software
28 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #======================================================================
33 #======================================================================
37 use List::Util qw(max first);
48 OE.pm - Order entry module
52 OE.pm is part of the OE module. OE is responsible for sales and purchase orders, as well as sales quotations and purchase requests. This file abstracts the database tables C<oe> and C<orderitems>.
61 $main::lxdebug->enter_sub();
63 my ($self, $myconfig, $form) = @_;
66 my $dbh = $form->dbconnect($myconfig);
69 my $ordnumber = 'ordnumber';
75 my $rate = ($form->{vc} eq 'customer') ? 'buy' : 'sell';
77 if ($form->{type} =~ /_quotation$/) {
79 $ordnumber = 'quonumber';
82 my $vc = $form->{vc} eq "customer" ? "customer" : "vendor";
85 qq|SELECT o.id, o.ordnumber, o.transdate, o.reqdate, | .
86 qq| o.amount, ct.name, o.netamount, o.${vc}_id, o.globalproject_id, | .
87 qq| o.closed, o.delivered, o.quonumber, o.shippingpoint, o.shipvia, | .
88 qq| o.transaction_description, | .
89 qq| o.marge_total, o.marge_percent, | .
90 qq| ex.$rate AS exchangerate, | .
91 qq| pr.projectnumber AS globalprojectnumber, | .
92 qq| e.name AS employee, s.name AS salesman, | .
93 qq| ct.${vc}number AS vcnumber, ct.country, ct.ustid | .
95 qq|JOIN $vc ct ON (o.${vc}_id = ct.id) | .
96 qq|LEFT JOIN employee e ON (o.employee_id = e.id) | .
97 qq|LEFT JOIN employee s ON (o.salesman_id = s.id) | .
98 qq|LEFT JOIN exchangerate ex ON (ex.curr = o.curr | .
99 qq| AND ex.transdate = o.transdate) | .
100 qq|LEFT JOIN project pr ON (o.globalproject_id = pr.id) | .
101 qq|WHERE (o.quotation = ?) |;
102 push(@values, $quotation);
104 my ($null, $split_department_id) = split /--/, $form->{department};
105 my $department_id = $form->{department_id} || $split_department_id;
106 if ($department_id) {
107 $query .= qq| AND o.department_id = ?|;
108 push(@values, $department_id);
111 if ($form->{"project_id"}) {
113 qq|AND ((globalproject_id = ?) OR EXISTS | .
114 qq| (SELECT * FROM orderitems oi | .
115 qq| WHERE oi.project_id = ? AND oi.trans_id = o.id))|;
116 push(@values, conv_i($form->{"project_id"}), conv_i($form->{"project_id"}));
119 if ($form->{"projectnumber"}) {
121 AND (pr.projectnumber ILIKE ?) OR EXISTS (
122 SELECT * FROM orderitems oi
123 LEFT JOIN project proi ON proi.id = oi.project_id
124 WHERE proi.projectnumber ILIKE ? AND oi.trans_id = o.id
127 push @values, "%" . $form->{"projectnumber"} . "%", "%" . $form->{"projectnumber"} . "%" ;
130 if ($form->{"${vc}_id"}) {
131 $query .= " AND o.${vc}_id = ?";
132 push(@values, $form->{"${vc}_id"});
134 } elsif ($form->{$vc}) {
135 $query .= " AND ct.name ILIKE ?";
136 push(@values, '%' . $form->{$vc} . '%');
139 if ($form->{employee_id}) {
140 $query .= " AND o.employee_id = ?";
141 push @values, conv_i($form->{employee_id});
144 if ($form->{salesman_id}) {
145 $query .= " AND o.salesman_id = ?";
146 push @values, conv_i($form->{salesman_id});
149 if (!$form->{open} && !$form->{closed}) {
150 $query .= " AND o.id = 0";
151 } elsif (!($form->{open} && $form->{closed})) {
152 $query .= ($form->{open}) ? " AND o.closed = '0'" : " AND o.closed = '1'";
155 if (($form->{"notdelivered"} || $form->{"delivered"}) &&
156 ($form->{"notdelivered"} ne $form->{"delivered"})) {
157 $query .= $form->{"delivered"} ?
158 " AND o.delivered " : " AND NOT o.delivered";
161 if ($form->{$ordnumber}) {
162 $query .= qq| AND o.$ordnumber ILIKE ?|;
163 push(@values, '%' . $form->{$ordnumber} . '%');
166 if($form->{transdatefrom}) {
167 $query .= qq| AND o.transdate >= ?|;
168 push(@values, conv_date($form->{transdatefrom}));
171 if($form->{transdateto}) {
172 $query .= qq| AND o.transdate <= ?|;
173 push(@values, conv_date($form->{transdateto}));
176 if($form->{reqdatefrom}) {
177 $query .= qq| AND o.reqdate >= ?|;
178 push(@values, conv_date($form->{reqdatefrom}));
181 if($form->{reqdateto}) {
182 $query .= qq| AND o.reqdate <= ?|;
183 push(@values, conv_date($form->{reqdateto}));
186 if ($form->{transaction_description}) {
187 $query .= qq| AND o.transaction_description ILIKE ?|;
188 push(@values, '%' . $form->{transaction_description} . '%');
191 my $sortdir = !defined $form->{sortdir} ? 'ASC' : $form->{sortdir} ? 'ASC' : 'DESC';
192 my $sortorder = join(', ', map { "${_} ${sortdir} " } ("o.id", $form->sort_columns("transdate", $ordnumber, "name")));
193 my %allowed_sort_columns = (
194 "transdate" => "o.transdate",
195 "reqdate" => "o.reqdate",
197 "ordnumber" => "o.ordnumber",
198 "quonumber" => "o.quonumber",
200 "employee" => "e.name",
201 "salesman" => "e.name",
202 "shipvia" => "o.shipvia",
203 "transaction_description" => "o.transaction_description"
205 if ($form->{sort} && grep($form->{sort}, keys(%allowed_sort_columns))) {
206 $sortorder = $allowed_sort_columns{$form->{sort}} . " ${sortdir}";
208 $query .= qq| ORDER by | . $sortorder;
210 my $sth = $dbh->prepare($query);
211 $sth->execute(@values) ||
212 $form->dberror($query . " (" . join(", ", @values) . ")");
216 while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
217 $ref->{exchangerate} = 1 unless $ref->{exchangerate};
218 push @{ $form->{OE} }, $ref if $ref->{id} != $id{ $ref->{id} };
219 $id{ $ref->{id} } = $ref->{id};
225 $main::lxdebug->leave_sub();
228 sub transactions_for_todo_list {
229 $main::lxdebug->enter_sub();
234 my $myconfig = \%main::myconfig;
235 my $form = $main::form;
237 my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig);
239 my $query = qq|SELECT id FROM employee WHERE login = ?|;
240 my ($e_id) = selectrow_query($form, $dbh, $query, $form->{login});
243 qq|SELECT oe.id, oe.transdate, oe.reqdate, oe.quonumber, oe.transaction_description, oe.amount,
244 CASE WHEN (COALESCE(oe.customer_id, 0) = 0) THEN 'vendor' ELSE 'customer' END AS vc,
249 LEFT JOIN customer c ON (oe.customer_id = c.id)
250 LEFT JOIN vendor v ON (oe.vendor_id = v.id)
251 LEFT JOIN employee e ON (oe.employee_id = e.id)
252 WHERE (COALESCE(quotation, FALSE) = TRUE)
253 AND (COALESCE(closed, FALSE) = FALSE)
254 AND ((oe.employee_id = ?) OR (oe.salesman_id = ?))
255 AND NOT (oe.reqdate ISNULL)
256 AND (oe.reqdate < current_date)
259 my $quotations = selectall_hashref_query($form, $dbh, $query, $e_id, $e_id);
261 $main::lxdebug->leave_sub();
267 $main::lxdebug->enter_sub();
269 my ($self, $myconfig, $form) = @_;
271 # connect to database, turn off autocommit
272 my $dbh = $form->dbconnect_noauto($myconfig);
274 my ($query, @values, $sth, $null);
275 my $exchangerate = 0;
277 my $all_units = AM->retrieve_units($myconfig, $form);
278 $form->{all_units} = $all_units;
280 my $ic_cvar_configs = CVar->get_configs(module => 'IC',
283 $form->{employee_id} = (split /--/, $form->{employee})[1] if !$form->{employee_id};
284 unless ($form->{employee_id}) {
285 $form->get_employee($dbh);
288 my $ml = ($form->{type} eq 'sales_order') ? 1 : -1;
291 $query = qq|DELETE FROM custom_variables
292 WHERE (config_id IN (SELECT id FROM custom_variable_configs WHERE module = 'IC'))
293 AND (sub_module = 'orderitems')
294 AND (trans_id IN (SELECT id FROM orderitems WHERE trans_id = ?))|;
295 do_query($form, $dbh, $query, $form->{id});
297 $query = qq|DELETE FROM orderitems WHERE trans_id = ?|;
298 do_query($form, $dbh, $query, $form->{id});
300 $query = qq|DELETE FROM shipto | .
301 qq|WHERE trans_id = ? AND module = 'OE'|;
302 do_query($form, $dbh, $query, $form->{id});
306 $query = qq|SELECT nextval('id')|;
307 ($form->{id}) = selectrow_query($form, $dbh, $query);
309 $query = qq|INSERT INTO oe (id, ordnumber, employee_id) VALUES (?, '', ?)|;
310 do_query($form, $dbh, $query, $form->{id}, $form->{employee_id});
328 $form->get_lists('price_factors' => 'ALL_PRICE_FACTORS');
329 my %price_factors = map { $_->{id} => $_->{factor} } @{ $form->{ALL_PRICE_FACTORS} };
332 for my $i (1 .. $form->{rowcount}) {
334 map({ $form->{"${_}_$i"} = $form->parse_amount($myconfig, $form->{"${_}_$i"}) } qw(qty ship));
336 if ($form->{"id_$i"}) {
339 $query = qq|SELECT unit FROM parts WHERE id = ?|;
340 my ($item_unit) = selectrow_query($form, $dbh, $query, $form->{"id_$i"});
343 if (defined($all_units->{$item_unit}->{factor}) &&
344 (($all_units->{$item_unit}->{factor} * 1) != 0)) {
345 $basefactor = $all_units->{$form->{"unit_$i"}}->{factor} / $all_units->{$item_unit}->{factor};
347 my $baseqty = $form->{"qty_$i"} * $basefactor;
349 $form->{"marge_percent_$i"} = $form->parse_amount($myconfig, $form->{"marge_percent_$i"}) * 1;
350 $form->{"marge_total_$i"} = $form->parse_amount($myconfig, $form->{"marge_total_$i"}) * 1;
351 $form->{"lastcost_$i"} = $form->{"lastcost_$i"} * 1;
353 # set values to 0 if nothing entered
354 $form->{"discount_$i"} = $form->parse_amount($myconfig, $form->{"discount_$i"}) / 100;
356 $form->{"sellprice_$i"} = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
357 $fxsellprice = $form->{"sellprice_$i"};
359 my ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
361 my $decimalplaces = ($dec > 2) ? $dec : 2;
363 $discount = $form->round_amount($form->{"sellprice_$i"} * $form->{"discount_$i"}, $decimalplaces);
364 $form->{"sellprice_$i"} = $form->round_amount($form->{"sellprice_$i"} - $discount, $decimalplaces);
366 $form->{"inventory_accno_$i"} *= 1;
367 $form->{"expense_accno_$i"} *= 1;
369 $price_factor = $price_factors{ $form->{"price_factor_id_$i"} } || 1;
370 $linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"} / $price_factor, 2);
372 @taxaccounts = split(/ /, $form->{"taxaccounts_$i"});
376 map { $taxrate += $form->{"${_}_rate"} } @taxaccounts;
378 if ($form->{taxincluded}) {
379 $taxamount = $linetotal * $taxrate / (1 + $taxrate);
380 $taxbase = $linetotal - $taxamount;
382 # we are not keeping a natural price, do not round
383 $form->{"sellprice_$i"} =
384 $form->{"sellprice_$i"} * (1 / (1 + $taxrate));
386 $taxamount = $linetotal * $taxrate;
387 $taxbase = $linetotal;
390 if ($form->round_amount($taxrate, 7) == 0) {
391 if ($form->{taxincluded}) {
392 foreach my $item (@taxaccounts) {
393 $taxamount = $form->round_amount($linetotal * $form->{"${item}_rate"} / (1 + abs($form->{"${item}_rate"})), 2);
394 $taxaccounts{$item} += $taxamount;
395 $taxdiff += $taxamount;
396 $taxbase{$item} += $taxbase;
398 $taxaccounts{ $taxaccounts[0] } += $taxdiff;
400 foreach my $item (@taxaccounts) {
401 $taxaccounts{$item} += $linetotal * $form->{"${item}_rate"};
402 $taxbase{$item} += $taxbase;
406 foreach my $item (@taxaccounts) {
407 $taxaccounts{$item} += $taxamount * $form->{"${item}_rate"} / $taxrate;
408 $taxbase{$item} += $taxbase;
412 $netamount += $form->{"sellprice_$i"} * $form->{"qty_$i"} / $price_factor;
414 $reqdate = ($form->{"reqdate_$i"}) ? $form->{"reqdate_$i"} : undef;
416 # get pricegroup_id and save ist
417 ($null, my $pricegroup_id) = split(/--/, $form->{"sellprice_pg_$i"});
420 # save detail record in orderitems table
421 my $orderitems_id = $form->{"orderitems_id_$i"};
422 ($orderitems_id) = selectfirst_array_query($form, $dbh, qq|SELECT nextval('orderitemsid')|) if (!$orderitems_id);
425 $query = qq|INSERT INTO orderitems (
426 id, trans_id, parts_id, description, longdescription, qty, base_qty,
427 sellprice, discount, unit, reqdate, project_id, serialnumber, ship,
428 pricegroup_id, ordnumber, transdate, cusordnumber, subtotal,
429 marge_percent, marge_total, lastcost, price_factor_id, price_factor, marge_price_factor)
430 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
431 (SELECT factor FROM price_factors WHERE id = ?), ?)|;
433 conv_i($orderitems_id), conv_i($form->{id}), conv_i($form->{"id_$i"}),
434 $form->{"description_$i"}, $form->{"longdescription_$i"},
435 $form->{"qty_$i"}, $baseqty,
436 $fxsellprice, $form->{"discount_$i"},
437 $form->{"unit_$i"}, conv_date($reqdate), conv_i($form->{"project_id_$i"}),
438 $form->{"serialnumber_$i"}, $form->{"ship_$i"}, conv_i($pricegroup_id),
439 $form->{"ordnumber_$i"}, conv_date($form->{"transdate_$i"}),
440 $form->{"cusordnumber_$i"}, $form->{"subtotal_$i"} ? 't' : 'f',
441 $form->{"marge_percent_$i"}, $form->{"marge_total_$i"},
442 $form->{"lastcost_$i"},
443 conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}),
444 conv_i($form->{"marge_price_factor_$i"}));
445 do_query($form, $dbh, $query, @values);
447 $form->{"sellprice_$i"} = $fxsellprice;
448 $form->{"discount_$i"} *= 100;
450 CVar->save_custom_variables(module => 'IC',
451 sub_module => 'orderitems',
452 trans_id => $orderitems_id,
453 configs => $ic_cvar_configs,
455 name_prefix => 'ic_',
456 name_postfix => "_$i",
461 $reqdate = ($form->{reqdate}) ? $form->{reqdate} : undef;
465 map { $tax += $form->round_amount($taxaccounts{$_}, 2) } keys %taxaccounts;
467 $amount = $form->round_amount($netamount + $tax, 2);
468 $netamount = $form->round_amount($netamount, 2);
470 if ($form->{currency} eq $form->{defaultcurrency}) {
471 $form->{exchangerate} = 1;
473 $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{transdate}, ($form->{vc} eq 'customer') ? 'buy' : 'sell');
476 $form->{exchangerate} = $exchangerate || $form->parse_amount($myconfig, $form->{exchangerate});
478 my $quotation = $form->{type} =~ /_order$/ ? 'f' : 't';
480 ($null, $form->{department_id}) = split(/--/, $form->{department}) if $form->{department};
485 ordnumber = ?, quonumber = ?, cusordnumber = ?, transdate = ?, vendor_id = ?,
486 customer_id = ?, amount = ?, netamount = ?, reqdate = ?, taxincluded = ?,
487 shippingpoint = ?, shipvia = ?, notes = ?, intnotes = ?, curr = ?, closed = ?,
488 delivered = ?, proforma = ?, quotation = ?, department_id = ?, language_id = ?,
489 taxzone_id = ?, shipto_id = ?, payment_id = ?, delivery_vendor_id = ?, delivery_customer_id = ?,
490 globalproject_id = ?, employee_id = ?, salesman_id = ?, cp_id = ?, transaction_description = ?, marge_total = ?, marge_percent = ?
493 @values = ($form->{ordnumber} || '', $form->{quonumber},
494 $form->{cusordnumber}, conv_date($form->{transdate}),
495 conv_i($form->{vendor_id}), conv_i($form->{customer_id}),
496 $amount, $netamount, conv_date($reqdate),
497 $form->{taxincluded} ? 't' : 'f', $form->{shippingpoint},
498 $form->{shipvia}, $form->{notes}, $form->{intnotes},
499 substr($form->{currency}, 0, 3), $form->{closed} ? 't' : 'f',
500 $form->{delivered} ? "t" : "f", $form->{proforma} ? 't' : 'f',
501 $quotation, conv_i($form->{department_id}),
502 conv_i($form->{language_id}), conv_i($form->{taxzone_id}),
503 conv_i($form->{shipto_id}), conv_i($form->{payment_id}),
504 conv_i($form->{delivery_vendor_id}),
505 conv_i($form->{delivery_customer_id}),
506 conv_i($form->{globalproject_id}), conv_i($form->{employee_id}),
507 conv_i($form->{salesman_id}), conv_i($form->{cp_id}),
508 $form->{transaction_description},
509 $form->{marge_total} * 1, $form->{marge_percent} * 1,
510 conv_i($form->{id}));
511 do_query($form, $dbh, $query, @values);
513 $form->{ordtotal} = $amount;
516 $form->{name} = $form->{ $form->{vc} };
517 $form->{name} =~ s/--\Q$form->{"$form->{vc}_id"}\E//;
519 if (!$form->{shipto_id}) {
520 $form->add_shipto($dbh, $form->{id}, "OE");
523 # save printed, emailed, queued
524 $form->save_status($dbh);
526 # Link this record to the records it was created from.
527 $form->{convert_from_oe_ids} =~ s/^\s+//;
528 $form->{convert_from_oe_ids} =~ s/\s+$//;
529 my @convert_from_oe_ids = split m/\s+/, $form->{convert_from_oe_ids};
530 delete $form->{convert_from_oe_ids};
532 if (scalar @convert_from_oe_ids) {
533 RecordLinks->create_links('dbh' => $dbh,
535 'from_table' => 'oe',
536 'from_ids' => \@convert_from_oe_ids,
538 'to_id' => $form->{id},
541 $self->_close_quotations_rfqs('dbh' => $dbh,
542 'from_id' => \@convert_from_oe_ids,
543 'to_id' => $form->{id});
546 if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
547 if ($form->{vc} eq 'customer') {
548 $form->update_exchangerate($dbh, $form->{currency}, $form->{transdate}, $form->{exchangerate}, 0);
550 if ($form->{vc} eq 'vendor') {
551 $form->update_exchangerate($dbh, $form->{currency}, $form->{transdate}, 0, $form->{exchangerate});
555 $form->{saved_xyznumber} = $form->{$form->{type} =~ /_quotation$/ ?
556 "quonumber" : "ordnumber"};
558 Common::webdav_folder($form) if ($main::webdav);
560 my $rc = $dbh->commit;
563 $main::lxdebug->leave_sub();
568 sub _close_quotations_rfqs {
569 $main::lxdebug->enter_sub();
574 Common::check_params(\%params, qw(from_id to_id));
576 my $myconfig = \%main::myconfig;
577 my $form = $main::form;
579 my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig);
581 my $query = qq|SELECT quotation FROM oe WHERE id = ?|;
582 my $sth = prepare_query($form, $dbh, $query);
584 do_statement($form, $sth, $query, conv_i($params{to_id}));
586 my ($quotation) = $sth->fetchrow_array();
589 $main::lxdebug->leave_sub();
595 foreach my $from_id (@{ $params{from_id} }) {
596 $from_id = conv_i($from_id);
597 do_statement($form, $sth, $query, $from_id);
598 ($quotation) = $sth->fetchrow_array();
599 push @close_ids, $from_id if ($quotation);
604 if (scalar @close_ids) {
605 $query = qq|UPDATE oe SET closed = TRUE WHERE id IN (| . join(', ', ('?') x scalar @close_ids) . qq|)|;
606 do_query($form, $dbh, $query, @close_ids);
608 $dbh->commit() unless ($params{dbh});
611 $main::lxdebug->leave_sub();
615 $main::lxdebug->enter_sub();
617 my ($self, $myconfig, $form, $spool) = @_;
619 # connect to database
620 my $dbh = $form->dbconnect_noauto($myconfig);
623 my $query = qq|SELECT s.spoolfile FROM status s | .
624 qq|WHERE s.trans_id = ?|;
625 my @values = (conv_i($form->{id}));
626 my $sth = $dbh->prepare($query);
627 $sth->execute(@values) || $self->dberror($query);
632 while (($spoolfile) = $sth->fetchrow_array) {
633 push @spoolfiles, $spoolfile;
638 @values = (conv_i($form->{id}));
640 # delete status entries
641 $query = qq|DELETE FROM status | .
642 qq|WHERE trans_id = ?|;
643 do_query($form, $dbh, $query, @values);
646 $query = qq|DELETE FROM oe | .
648 do_query($form, $dbh, $query, @values);
650 # delete individual entries
651 $query = qq|DELETE FROM orderitems | .
652 qq|WHERE trans_id = ?|;
653 do_query($form, $dbh, $query, @values);
655 $query = qq|DELETE FROM shipto | .
656 qq|WHERE trans_id = ? AND module = 'OE'|;
657 do_query($form, $dbh, $query, @values);
659 my $rc = $dbh->commit;
663 foreach $spoolfile (@spoolfiles) {
664 unlink "$spool/$spoolfile" if $spoolfile;
668 $main::lxdebug->leave_sub();
674 $main::lxdebug->enter_sub();
676 my ($self, $myconfig, $form) = @_;
678 # connect to database
679 my $dbh = $form->dbconnect_noauto($myconfig);
681 my ($query, $query_add, @values, @ids, $sth);
683 my $ic_cvar_configs = CVar->get_configs(module => 'IC',
686 # translate the ids (given by id_# and trans_id_#) into one array of ids, so we can join them later
688 push @ids, $form->{"trans_id_$_"}
689 if ($form->{"multi_id_$_"} and $form->{"trans_id_$_"})
690 } (1 .. $form->{"rowcount"});
692 if ($form->{rowcount} && scalar @ids) {
693 $form->{convert_from_oe_ids} = join ' ', @ids;
696 # if called in multi id mode, and still only got one id, switch back to single id
697 if ($form->{"rowcount"} and $#ids == 0) {
698 $form->{"id"} = $ids[0];
702 # and remember for the rest of the function
703 my $is_collective_order = scalar @ids;
706 my $wday = (localtime(time))[6];
707 my $next_workday = $wday == 5 ? 3 : $wday == 6 ? 2 : 1;
708 $query_add = qq|, current_date AS transdate, date(current_date + interval '${next_workday} days') AS reqdate|;
711 # get default accounts
712 $query = qq|SELECT (SELECT c.accno FROM chart c WHERE d.inventory_accno_id = c.id) AS inventory_accno,
713 (SELECT c.accno FROM chart c WHERE d.income_accno_id = c.id) AS income_accno,
714 (SELECT c.accno FROM chart c WHERE d.expense_accno_id = c.id) AS expense_accno,
715 (SELECT c.accno FROM chart c WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
716 (SELECT c.accno FROM chart c WHERE d.fxloss_accno_id = c.id) AS fxloss_accno,
720 my $ref = selectfirst_hashref_query($form, $dbh, $query);
721 map { $form->{$_} = $ref->{$_} } keys %$ref;
723 ($form->{currency}) = split(/:/, $form->{currencies}) unless ($form->{currency});
725 # set reqdate if this is an invoice->order conversion. If someone knows a better check to ensure
726 # we come from invoices, feel free.
727 $form->{reqdate} = $form->{deliverydate}
728 if ( $form->{deliverydate}
729 and $form->{callback} =~ /action=ar_transactions/);
731 my $vc = $form->{vc} eq "customer" ? "customer" : "vendor";
733 if ($form->{id} or @ids) {
735 # retrieve order for single id
736 # NOTE: this query is intended to fetch all information only ONCE.
737 # so if any of these infos is important (or even different) for any item,
738 # it will be killed out and then has to be fetched from the item scope query further down
740 qq|SELECT o.cp_id, o.ordnumber, o.transdate, o.reqdate,
741 o.taxincluded, o.shippingpoint, o.shipvia, o.notes, o.intnotes,
742 o.curr AS currency, e.name AS employee, o.employee_id, o.salesman_id,
743 o.${vc}_id, cv.name AS ${vc}, o.amount AS invtotal,
744 o.closed, o.reqdate, o.quonumber, o.department_id, o.cusordnumber,
745 d.description AS department, o.payment_id, o.language_id, o.taxzone_id,
746 o.delivery_customer_id, o.delivery_vendor_id, o.proforma, o.shipto_id,
747 o.globalproject_id, o.delivered, o.transaction_description
749 JOIN ${vc} cv ON (o.${vc}_id = cv.id)
750 LEFT JOIN employee e ON (o.employee_id = e.id)
751 LEFT JOIN department d ON (o.department_id = d.id) | .
754 : "WHERE o.id IN (" . join(', ', map("? ", @ids)) . ")"
756 @values = $form->{id} ? ($form->{id}) : @ids;
757 $sth = prepare_execute_query($form, $dbh, $query, @values);
759 $ref = $sth->fetchrow_hashref("NAME_lc");
760 map { $form->{$_} = $ref->{$_} } keys %$ref;
762 $form->{saved_xyznumber} = $form->{$form->{type} =~ /_quotation$/ ?
763 "quonumber" : "ordnumber"};
765 # set all entries for multiple ids blank that yield different information
766 while ($ref = $sth->fetchrow_hashref("NAME_lc")) {
767 map { $form->{$_} = '' if ($ref->{$_} ne $form->{$_}) } keys %$ref;
770 # if not given, fill transdate with current_date
771 $form->{transdate} = $form->current_date($myconfig)
772 unless $form->{transdate};
776 if ($form->{delivery_customer_id}) {
777 $query = qq|SELECT name FROM customer WHERE id = ?|;
778 ($form->{delivery_customer_string}) = selectrow_query($form, $dbh, $query, $form->{delivery_customer_id});
781 if ($form->{delivery_vendor_id}) {
782 $query = qq|SELECT name FROM customer WHERE id = ?|;
783 ($form->{delivery_vendor_string}) = selectrow_query($form, $dbh, $query, $form->{delivery_vendor_id});
786 # shipto and pinted/mailed/queued status makes only sense for single id retrieve
788 $query = qq|SELECT s.* FROM shipto s WHERE s.trans_id = ? AND s.module = 'OE'|;
789 $sth = prepare_execute_query($form, $dbh, $query, $form->{id});
791 $ref = $sth->fetchrow_hashref("NAME_lc");
793 map { $form->{$_} = $ref->{$_} } keys %$ref;
796 # get printed, emailed and queued
797 $query = qq|SELECT s.printed, s.emailed, s.spoolfile, s.formname FROM status s WHERE s.trans_id = ?|;
798 $sth = prepare_execute_query($form, $dbh, $query, $form->{id});
800 while ($ref = $sth->fetchrow_hashref("NAME_lc")) {
801 $form->{printed} .= "$ref->{formname} " if $ref->{printed};
802 $form->{emailed} .= "$ref->{formname} " if $ref->{emailed};
803 $form->{queued} .= "$ref->{formname} $ref->{spoolfile} " if $ref->{spoolfile};
806 map { $form->{$_} =~ s/ +$//g } qw(printed emailed queued);
809 my %oid = ('Pg' => 'oid',
810 'Oracle' => 'rowid');
812 my $transdate = $form->{transdate} ? $dbh->quote($form->{transdate}) : "current_date";
814 $form->{taxzone_id} = 0 unless ($form->{taxzone_id});
816 # retrieve individual items
817 # this query looks up all information about the items
818 # stuff different from the whole will not be overwritten, but saved with a suffix.
820 qq|SELECT o.id AS orderitems_id,
821 c1.accno AS inventory_accno, c1.new_chart_id AS inventory_new_chart, date($transdate) - c1.valid_from as inventory_valid,
822 c2.accno AS income_accno, c2.new_chart_id AS income_new_chart, date($transdate) - c2.valid_from as income_valid,
823 c3.accno AS expense_accno, c3.new_chart_id AS expense_new_chart, date($transdate) - c3.valid_from as expense_valid,
824 oe.ordnumber AS ordnumber_oe, oe.transdate AS transdate_oe, oe.cusordnumber AS cusordnumber_oe,
825 p.partnumber, p.assembly, o.description, o.qty,
826 o.sellprice, o.parts_id AS id, o.unit, o.discount, p.bin, p.notes AS partnotes, p.inventory_accno_id AS part_inventory_accno_id,
827 o.reqdate, o.project_id, o.serialnumber, o.ship, o.lastcost,
828 o.ordnumber, o.transdate, o.cusordnumber, o.subtotal, o.longdescription,
829 o.price_factor_id, o.price_factor, o.marge_price_factor,
830 pr.projectnumber, p.formel,
831 pg.partsgroup, o.pricegroup_id, (SELECT pricegroup FROM pricegroup WHERE id=o.pricegroup_id) as pricegroup
833 JOIN parts p ON (o.parts_id = p.id)
834 JOIN oe ON (o.trans_id = oe.id)
835 LEFT JOIN chart c1 ON ((SELECT inventory_accno_id FROM buchungsgruppen WHERE id=p.buchungsgruppen_id) = c1.id)
836 LEFT JOIN chart c2 ON ((SELECT income_accno_id_$form->{taxzone_id} FROM buchungsgruppen WHERE id=p.buchungsgruppen_id) = c2.id)
837 LEFT JOIN chart c3 ON ((SELECT expense_accno_id_$form->{taxzone_id} FROM buchungsgruppen WHERE id=p.buchungsgruppen_id) = c3.id)
838 LEFT JOIN project pr ON (o.project_id = pr.id)
839 LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) | .
841 ? qq|WHERE o.trans_id = ?|
842 : qq|WHERE o.trans_id IN (| . join(", ", map("?", @ids)) . qq|)|) .
843 qq|ORDER BY o.$oid{$myconfig->{dbdriver}}|;
845 @ids = $form->{id} ? ($form->{id}) : @ids;
846 $sth = prepare_execute_query($form, $dbh, $query, @values);
848 while ($ref = $sth->fetchrow_hashref("NAME_lc")) {
849 # Retrieve custom variables.
850 my $cvars = CVar->get_custom_variables(dbh => $dbh,
852 sub_module => 'orderitems',
853 trans_id => $ref->{orderitems_id},
855 map { $ref->{"ic_cvar_$_->{name}"} = $_->{value} } @{ $cvars };
858 if (!$ref->{"part_inventory_accno_id"}) {
859 map({ delete($ref->{$_}); } qw(inventory_accno inventory_new_chart inventory_valid));
861 delete($ref->{"part_inventory_accno_id"});
863 # in collective order, copy global ordnumber, transdate, cusordnumber into item scope
864 # unless already present there
865 # remove _oe entries afterwards
866 map { $ref->{$_} = $ref->{"${_}_oe"} if ($ref->{$_} eq '') }
867 qw|ordnumber transdate cusordnumber|
869 map { delete $ref->{$_} } qw|ordnumber_oe transdate_oe cusordnumber_oe|;
873 while ($ref->{inventory_new_chart} && ($ref->{inventory_valid} >= 0)) {
875 qq|SELECT accno AS inventory_accno, | .
876 qq| new_chart_id AS inventory_new_chart, | .
877 qq| date($transdate) - valid_from AS inventory_valid | .
878 qq|FROM chart WHERE id = $ref->{inventory_new_chart}|;
879 ($ref->{inventory_accno}, $ref->{inventory_new_chart},
880 $ref->{inventory_valid}) = selectrow_query($form, $dbh, $query);
883 while ($ref->{income_new_chart} && ($ref->{income_valid} >= 0)) {
885 qq|SELECT accno AS income_accno, | .
886 qq| new_chart_id AS income_new_chart, | .
887 qq| date($transdate) - valid_from AS income_valid | .
888 qq|FROM chart WHERE id = $ref->{income_new_chart}|;
889 ($ref->{income_accno}, $ref->{income_new_chart},
890 $ref->{income_valid}) = selectrow_query($form, $dbh, $query);
893 while ($ref->{expense_new_chart} && ($ref->{expense_valid} >= 0)) {
895 qq|SELECT accno AS expense_accno, | .
896 qq| new_chart_id AS expense_new_chart, | .
897 qq| date($transdate) - valid_from AS expense_valid | .
898 qq|FROM chart WHERE id = $ref->{expense_new_chart}|;
899 ($ref->{expense_accno}, $ref->{expense_new_chart},
900 $ref->{expense_valid}) = selectrow_query($form, $dbh, $query);
903 # delete orderitems_id in collective orders, so that they get cloned no matter what
904 delete $ref->{orderitems_id} if (@ids);
906 # get tax rates and description
907 my $accno_id = ($form->{vc} eq "customer") ? $ref->{income_accno} : $ref->{expense_accno};
909 qq|SELECT c.accno, t.taxdescription, t.rate, t.taxnumber | .
910 qq|FROM tax t LEFT JOIN chart c on (c.id = t.chart_id) | .
911 qq|WHERE t.id IN (SELECT tk.tax_id FROM taxkeys tk | .
912 qq| WHERE tk.chart_id = (SELECT id FROM chart WHERE accno = ?) | .
913 qq| AND startdate <= $transdate ORDER BY startdate DESC LIMIT 1) | .
914 qq|ORDER BY c.accno|;
915 my $stw = prepare_execute_query($form, $dbh, $query, $accno_id);
916 $ref->{taxaccounts} = "";
918 while (my $ptr = $stw->fetchrow_hashref("NAME_lc")) {
919 if (($ptr->{accno} eq "") && ($ptr->{rate} == 0)) {
923 $ref->{taxaccounts} .= "$ptr->{accno} ";
924 if (!($form->{taxaccounts} =~ /\Q$ptr->{accno}\E/)) {
925 $form->{"$ptr->{accno}_rate"} = $ptr->{rate};
926 $form->{"$ptr->{accno}_description"} = $ptr->{taxdescription};
927 $form->{"$ptr->{accno}_taxnumber"} = $ptr->{taxnumber};
928 $form->{taxaccounts} .= "$ptr->{accno} ";
933 chop $ref->{taxaccounts};
935 push @{ $form->{form_details} }, $ref;
943 $form->lastname_used($dbh, $myconfig, $form->{vc})
944 unless $form->{"$form->{vc}_id"};
948 $form->{exchangerate} = $form->get_exchangerate($dbh, $form->{currency}, $form->{transdate}, ($form->{vc} eq 'customer') ? "buy" : "sell");
950 Common::webdav_folder($form) if ($main::webdav);
952 my $rc = $dbh->commit;
955 $main::lxdebug->leave_sub();
960 =item retrieve_simple PARAMS
962 simple OE retrieval by id. does not look up customer, vendor, units or any other stuff. only oe and orderitems.
964 my $order = retrieve_simple(id => 2);
976 sub retrieve_simple {
977 $main::lxdebug->enter_sub();
982 Common::check_params(\%params, qw(id));
984 my $myconfig = \%main::myconfig;
985 my $form = $main::form;
987 my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig);
989 my $oe_query = qq|SELECT * FROM oe WHERE id = ?|;
990 my $oi_query = qq|SELECT * FROM orderitems WHERE trans_id = ?|;
992 my $order = selectfirst_hashref_query($form, $dbh, $oe_query, conv_i($params{id}));
993 $order->{orderitems} = selectall_hashref_query( $form, $dbh, $oi_query, conv_i($params{id}));
995 $main::lxdebug->leave_sub();
1001 $main::lxdebug->enter_sub();
1003 my ($self, $myconfig, $form) = @_;
1005 # connect to database
1006 my $dbh = $form->dbconnect($myconfig);
1012 my $nodiscount_subtotal = 0;
1013 my $discount_subtotal = 0;
1016 my @partsgroup = ();
1019 my $subtotal_header = 0;
1020 my $subposition = 0;
1027 my %oid = ('Pg' => 'oid',
1028 'Oracle' => 'rowid');
1030 my (@project_ids, %projectnumbers);
1032 push(@project_ids, $form->{"globalproject_id"}) if ($form->{"globalproject_id"});
1034 $form->get_lists('price_factors' => 'ALL_PRICE_FACTORS',
1035 'departments' => 'ALL_DEPARTMENTS');
1038 foreach my $pfac (@{ $form->{ALL_PRICE_FACTORS} }) {
1039 $price_factors{$pfac->{id}} = $pfac;
1040 $pfac->{factor} *= 1;
1041 $pfac->{formatted_factor} = $form->format_amount($myconfig, $pfac->{factor});
1045 foreach my $dept (@{ $form->{ALL_DEPARTMENTS} }) {
1046 next unless $dept->{id} eq $form->{department_id};
1047 $form->{department} = $dept->{description};
1051 # sort items by partsgroup
1052 for $i (1 .. $form->{rowcount}) {
1054 if ($form->{"partsgroup_$i"} && $form->{groupitems}) {
1055 $partsgroup = $form->{"partsgroup_$i"};
1057 push @partsgroup, [$i, $partsgroup];
1058 push(@project_ids, $form->{"project_id_$i"}) if ($form->{"project_id_$i"});
1062 $query = "SELECT id, projectnumber FROM project WHERE id IN (" .
1063 join(", ", map("?", @project_ids)) . ")";
1064 $sth = prepare_execute_query($form, $dbh, $query, @project_ids);
1065 while (my $ref = $sth->fetchrow_hashref()) {
1066 $projectnumbers{$ref->{id}} = $ref->{projectnumber};
1071 $form->{"globalprojectnumber"} = $projectnumbers{$form->{"globalproject_id"}};
1073 $form->{discount} = [];
1075 $form->{TEMPLATE_ARRAYS} = { };
1076 IC->prepare_parts_for_printing();
1078 my $ic_cvar_configs = CVar->get_configs(module => 'IC');
1081 qw(runningnumber number description longdescription qty ship unit bin
1082 partnotes serialnumber reqdate sellprice listprice netprice
1083 discount p_discount discount_sub nodiscount_sub
1084 linetotal nodiscount_linetotal tax_rate projectnumber
1085 price_factor price_factor_name partsgroup);
1087 push @arrays, map { "ic_cvar_$_->{name}" } @{ $ic_cvar_configs };
1089 my @tax_arrays = qw(taxbase tax taxdescription taxrate taxnumber);
1091 map { $form->{TEMPLATE_ARRAYS}->{$_} = [] } (@arrays, @tax_arrays);
1094 foreach $item (sort { $a->[1] cmp $b->[1] } @partsgroup) {
1097 if ($item->[1] ne $sameitem) {
1098 push(@{ $form->{TEMPLATE_ARRAYS}->{description} }, qq|$item->[1]|);
1099 $sameitem = $item->[1];
1101 map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, "") } grep({ $_ ne "description" } @arrays));
1104 $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
1106 if ($form->{"id_$i"} != 0) {
1108 # add number, description and qty to $form->{number}, ....
1110 if ($form->{"subtotal_$i"} && !$subtotal_header) {
1111 $subtotal_header = $i;
1112 $position = int($position);
1115 } elsif ($subtotal_header) {
1117 $position = int($position);
1118 $position = $position.".".$subposition;
1120 $position = int($position);
1124 my $price_factor = $price_factors{$form->{"price_factor_id_$i"}} || { 'factor' => 1 };
1126 push @{ $form->{TEMPLATE_ARRAYS}->{runningnumber} }, $position;
1127 push @{ $form->{TEMPLATE_ARRAYS}->{number} }, $form->{"partnumber_$i"};
1128 push @{ $form->{TEMPLATE_ARRAYS}->{description} }, $form->{"description_$i"};
1129 push @{ $form->{TEMPLATE_ARRAYS}->{longdescription} }, $form->{"longdescription_$i"};
1130 push @{ $form->{TEMPLATE_ARRAYS}->{qty} }, $form->format_amount($myconfig, $form->{"qty_$i"});
1131 push @{ $form->{TEMPLATE_ARRAYS}->{ship} }, $form->format_amount($myconfig, $form->{"ship_$i"});
1132 push @{ $form->{TEMPLATE_ARRAYS}->{unit} }, $form->{"unit_$i"};
1133 push @{ $form->{TEMPLATE_ARRAYS}->{bin} }, $form->{"bin_$i"};
1134 push @{ $form->{TEMPLATE_ARRAYS}->{partnotes} }, $form->{"partnotes_$i"};
1135 push @{ $form->{TEMPLATE_ARRAYS}->{serialnumber} }, $form->{"serialnumber_$i"};
1136 push @{ $form->{TEMPLATE_ARRAYS}->{reqdate} }, $form->{"reqdate_$i"};
1137 push @{ $form->{TEMPLATE_ARRAYS}->{sellprice} }, $form->{"sellprice_$i"};
1138 push @{ $form->{TEMPLATE_ARRAYS}->{listprice} }, $form->{"listprice_$i"};
1139 push @{ $form->{TEMPLATE_ARRAYS}->{price_factor} }, $price_factor->{formatted_factor};
1140 push @{ $form->{TEMPLATE_ARRAYS}->{price_factor_name} }, $price_factor->{description};
1141 push @{ $form->{TEMPLATE_ARRAYS}->{partsgroup} }, $form->{"partsgroup_$i"};
1143 my $sellprice = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
1144 my ($dec) = ($sellprice =~ /\.(\d+)/);
1145 my $decimalplaces = max 2, length($dec);
1147 my $parsed_discount = $form->parse_amount($myconfig, $form->{"discount_$i"});
1148 my $linetotal_exact = $form->{"qty_$i"} * $sellprice * (100 - $parsed_discount) / 100 / $price_factor->{factor};
1149 my $linetotal = $form->round_amount($linetotal_exact, 2);
1150 my $discount = $form->round_amount($form->{"qty_$i"} * $sellprice * $parsed_discount / 100 / $price_factor->{factor} - ($linetotal - $linetotal_exact),
1152 my $nodiscount_linetotal = $form->round_amount($form->{"qty_$i"} * $sellprice / $price_factor->{factor}, 2);
1153 $form->{"netprice_$i"} = $form->round_amount($form->{"qty_$i"} ? ($linetotal / $form->{"qty_$i"}) : 0, 2);
1155 push @{ $form->{TEMPLATE_ARRAYS}->{netprice} }, ($form->{"netprice_$i"} != 0) ? $form->format_amount($myconfig, $form->{"netprice_$i"}, $decimalplaces) : '';
1157 $linetotal = ($linetotal != 0) ? $linetotal : '';
1159 push @{ $form->{TEMPLATE_ARRAYS}->{discount} }, ($discount != 0) ? $form->format_amount($myconfig, $discount * -1, 2) : '';
1160 push @{ $form->{TEMPLATE_ARRAYS}->{p_discount} }, $form->{"discount_$i"};
1162 $form->{ordtotal} += $linetotal;
1163 $form->{nodiscount_total} += $nodiscount_linetotal;
1164 $form->{discount_total} += $discount;
1166 if ($subtotal_header) {
1167 $discount_subtotal += $linetotal;
1168 $nodiscount_subtotal += $nodiscount_linetotal;
1171 if ($form->{"subtotal_$i"} && $subtotal_header && ($subtotal_header != $i)) {
1172 push @{ $form->{TEMPLATE_ARRAYS}->{discount_sub} }, $form->format_amount($myconfig, $discount_subtotal, 2);
1173 push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_sub} }, $form->format_amount($myconfig, $nodiscount_subtotal, 2);
1175 $discount_subtotal = 0;
1176 $nodiscount_subtotal = 0;
1177 $subtotal_header = 0;
1180 push @{ $form->{TEMPLATE_ARRAYS}->{discount_sub} }, "";
1181 push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_sub} }, "";
1184 if (!$form->{"discount_$i"}) {
1185 $nodiscount += $linetotal;
1188 push @{ $form->{TEMPLATE_ARRAYS}->{linetotal} }, $form->format_amount($myconfig, $linetotal, 2);
1189 push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_linetotal} }, $form->format_amount($myconfig, $nodiscount_linetotal, 2);
1191 push(@{ $form->{TEMPLATE_ARRAYS}->{projectnumber} }, $projectnumbers{$form->{"project_id_$i"}});
1193 my ($taxamount, $taxbase);
1196 map { $taxrate += $form->{"${_}_rate"} } split(/ /, $form->{"taxaccounts_$i"});
1198 if ($form->{taxincluded}) {
1201 $taxamount = $linetotal * $taxrate / (1 + $taxrate);
1202 $taxbase = $linetotal / (1 + $taxrate);
1204 $taxamount = $linetotal * $taxrate;
1205 $taxbase = $linetotal;
1208 if ($taxamount != 0) {
1209 foreach my $accno (split / /, $form->{"taxaccounts_$i"}) {
1210 $taxaccounts{$accno} += $taxamount * $form->{"${accno}_rate"} / $taxrate;
1211 $taxbase{$accno} += $taxbase;
1215 $tax_rate = $taxrate * 100;
1216 push(@{ $form->{TEMPLATE_ARRAYS}->{tax_rate} }, qq|$tax_rate|);
1218 if ($form->{"assembly_$i"}) {
1221 # get parts and push them onto the stack
1223 if ($form->{groupitems}) {
1224 $sortorder = qq|ORDER BY pg.partsgroup, a.$oid{$myconfig->{dbdriver}}|;
1226 $sortorder = qq|ORDER BY a.$oid{$myconfig->{dbdriver}}|;
1229 $query = qq|SELECT p.partnumber, p.description, p.unit, a.qty, | .
1230 qq|pg.partsgroup | .
1231 qq|FROM assembly a | .
1232 qq| JOIN parts p ON (a.parts_id = p.id) | .
1233 qq| LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) | .
1234 qq| WHERE a.bom = '1' | .
1235 qq| AND a.id = ? | . $sortorder;
1236 @values = ($form->{"id_$i"});
1237 $sth = $dbh->prepare($query);
1238 $sth->execute(@values) || $form->dberror($query);
1240 while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
1241 if ($form->{groupitems} && $ref->{partsgroup} ne $sameitem) {
1242 map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, "") } grep({ $_ ne "description" } @arrays));
1243 $sameitem = ($ref->{partsgroup}) ? $ref->{partsgroup} : "--";
1244 push(@{ $form->{TEMPLATE_ARRAYS}->{description} }, $sameitem);
1247 push(@{ $form->{TEMPLATE_ARRAYS}->{description} }, $form->format_amount($myconfig, $ref->{qty} * $form->{"qty_$i"}) . qq|, $ref->{partnumber}, $ref->{description}|);
1248 map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, "") } grep({ $_ ne "description" } @arrays));
1253 map { push @{ $form->{TEMPLATE_ARRAYS}->{"ic_cvar_$_->{name}"} }, $form->{"ic_cvar_$_->{name}_$i"} } @{ $ic_cvar_configs };
1258 foreach $item (sort keys %taxaccounts) {
1259 $tax += $taxamount = $form->round_amount($taxaccounts{$item}, 2);
1261 push(@{ $form->{TEMPLATE_ARRAYS}->{taxbase} }, $form->format_amount($myconfig, $taxbase{$item}, 2));
1262 push(@{ $form->{TEMPLATE_ARRAYS}->{tax} }, $form->format_amount($myconfig, $taxamount, 2));
1263 push(@{ $form->{TEMPLATE_ARRAYS}->{taxrate} }, $form->format_amount($myconfig, $form->{"${item}_rate"} * 100));
1264 push(@{ $form->{TEMPLATE_ARRAYS}->{taxdescription} }, $form->{"${item}_description"} . q{ } . 100 * $form->{"${item}_rate"} . q{%});
1265 push(@{ $form->{TEMPLATE_ARRAYS}->{taxnumber} }, $form->{"${item}_taxnumber"});
1268 $form->{nodiscount_subtotal} = $form->format_amount($myconfig, $form->{nodiscount_total}, 2);
1269 $form->{discount_total} = $form->format_amount($myconfig, $form->{discount_total}, 2);
1270 $form->{nodiscount} = $form->format_amount($myconfig, $nodiscount, 2);
1271 $form->{yesdiscount} = $form->format_amount($myconfig, $form->{nodiscount_total} - $nodiscount, 2);
1273 if($form->{taxincluded}) {
1274 $form->{subtotal} = $form->format_amount($myconfig, $form->{ordtotal} - $tax, 2);
1276 $form->{subtotal} = $form->format_amount($myconfig, $form->{ordtotal}, 2);
1279 $form->{ordtotal} = ($form->{taxincluded}) ? $form->{ordtotal} : $form->{ordtotal} + $tax;
1282 $form->{quototal} = $form->{ordtotal} = $form->format_amount($myconfig, $form->{ordtotal}, 2);
1284 if ($form->{type} =~ /_quotation/) {
1285 $form->set_payment_options($myconfig, $form->{quodate});
1287 $form->set_payment_options($myconfig, $form->{orddate});
1290 $form->{username} = $myconfig->{name};
1294 $main::lxdebug->leave_sub();
1297 sub project_description {
1298 $main::lxdebug->enter_sub();
1300 my ($self, $dbh, $id) = @_;
1302 my $query = qq|SELECT description FROM project WHERE id = ?|;
1303 my ($value) = selectrow_query($main::form, $dbh, $query, $id);
1305 $main::lxdebug->leave_sub();