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);
47 $main::lxdebug->enter_sub();
49 my ($self, $myconfig, $form) = @_;
52 my $dbh = $form->dbconnect($myconfig);
55 my $ordnumber = 'ordnumber';
61 my $rate = ($form->{vc} eq 'customer') ? 'buy' : 'sell';
63 if ($form->{type} =~ /_quotation$/) {
65 $ordnumber = 'quonumber';
68 my $vc = $form->{vc} eq "customer" ? "customer" : "vendor";
71 qq|SELECT o.id, o.ordnumber, o.transdate, o.reqdate, | .
72 qq| o.amount, ct.name, o.netamount, o.${vc}_id, o.globalproject_id, | .
73 qq| o.closed, o.delivered, o.quonumber, o.shippingpoint, o.shipvia, | .
74 qq| o.transaction_description, | .
75 qq| o.marge_total, o.marge_percent, | .
76 qq| ex.$rate AS exchangerate, | .
77 qq| pr.projectnumber AS globalprojectnumber, | .
78 qq| e.name AS employee, s.name AS salesman, | .
79 qq| ct.${vc}number AS vcnumber, ct.country, ct.ustid | .
81 qq|JOIN $vc ct ON (o.${vc}_id = ct.id) | .
82 qq|LEFT JOIN employee e ON (o.employee_id = e.id) | .
83 qq|LEFT JOIN employee s ON (o.salesman_id = s.id) | .
84 qq|LEFT JOIN exchangerate ex ON (ex.curr = o.curr | .
85 qq| AND ex.transdate = o.transdate) | .
86 qq|LEFT JOIN project pr ON (o.globalproject_id = pr.id) | .
87 qq|WHERE (o.quotation = ?) |;
88 push(@values, $quotation);
90 my ($null, $split_department_id) = split /--/, $form->{department};
91 my $department_id = $form->{department_id} || $split_department_id;
93 $query .= qq| AND o.department_id = ?|;
94 push(@values, $department_id);
97 if ($form->{"project_id"}) {
99 qq|AND ((globalproject_id = ?) OR EXISTS | .
100 qq| (SELECT * FROM orderitems oi | .
101 qq| WHERE oi.project_id = ? AND oi.trans_id = o.id))|;
102 push(@values, conv_i($form->{"project_id"}), conv_i($form->{"project_id"}));
105 if ($form->{"projectnumber"}) {
107 AND (pr.projectnumber ILIKE ?) OR EXISTS (
108 SELECT * FROM orderitems oi
109 LEFT JOIN project proi ON proi.id = oi.project_id
110 WHERE proi.projectnumber ILIKE ? AND oi.trans_id = o.id
113 push @values, "%" . $form->{"projectnumber"} . "%", "%" . $form->{"projectnumber"} . "%" ;
116 if ($form->{"${vc}_id"}) {
117 $query .= " AND o.${vc}_id = ?";
118 push(@values, $form->{"${vc}_id"});
120 } elsif ($form->{$vc}) {
121 $query .= " AND ct.name ILIKE ?";
122 push(@values, '%' . $form->{$vc} . '%');
125 if ($form->{employee_id}) {
126 $query .= " AND o.employee_id = ?";
127 push @values, conv_i($form->{employee_id});
130 if ($form->{salesman_id}) {
131 $query .= " AND o.salesman_id = ?";
132 push @values, conv_i($form->{salesman_id});
135 if (!$form->{open} && !$form->{closed}) {
136 $query .= " AND o.id = 0";
137 } elsif (!($form->{open} && $form->{closed})) {
138 $query .= ($form->{open}) ? " AND o.closed = '0'" : " AND o.closed = '1'";
141 if (($form->{"notdelivered"} || $form->{"delivered"}) &&
142 ($form->{"notdelivered"} ne $form->{"delivered"})) {
143 $query .= $form->{"delivered"} ?
144 " AND o.delivered " : " AND NOT o.delivered";
147 if ($form->{$ordnumber}) {
148 $query .= qq| AND o.$ordnumber ILIKE ?|;
149 push(@values, '%' . $form->{$ordnumber} . '%');
152 if($form->{transdatefrom}) {
153 $query .= qq| AND o.transdate >= ?|;
154 push(@values, conv_date($form->{transdatefrom}));
157 if($form->{transdateto}) {
158 $query .= qq| AND o.transdate <= ?|;
159 push(@values, conv_date($form->{transdateto}));
162 if($form->{reqdatefrom}) {
163 $query .= qq| AND o.reqdate >= ?|;
164 push(@values, conv_date($form->{reqdatefrom}));
167 if($form->{reqdateto}) {
168 $query .= qq| AND o.reqdate <= ?|;
169 push(@values, conv_date($form->{reqdateto}));
172 if ($form->{transaction_description}) {
173 $query .= qq| AND o.transaction_description ILIKE ?|;
174 push(@values, '%' . $form->{transaction_description} . '%');
177 my $sortdir = !defined $form->{sortdir} ? 'ASC' : $form->{sortdir} ? 'ASC' : 'DESC';
178 my $sortorder = join(', ', map { "${_} ${sortdir} " } ("o.id", $form->sort_columns("transdate", $ordnumber, "name")));
179 my %allowed_sort_columns = (
180 "transdate" => "o.transdate",
181 "reqdate" => "o.reqdate",
183 "ordnumber" => "o.ordnumber",
184 "quonumber" => "o.quonumber",
186 "employee" => "e.name",
187 "salesman" => "e.name",
188 "shipvia" => "o.shipvia",
189 "transaction_description" => "o.transaction_description"
191 if ($form->{sort} && grep($form->{sort}, keys(%allowed_sort_columns))) {
192 $sortorder = $allowed_sort_columns{$form->{sort}} . " ${sortdir}";
194 $query .= qq| ORDER by | . $sortorder;
196 my $sth = $dbh->prepare($query);
197 $sth->execute(@values) ||
198 $form->dberror($query . " (" . join(", ", @values) . ")");
202 while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
203 $ref->{exchangerate} = 1 unless $ref->{exchangerate};
204 push @{ $form->{OE} }, $ref if $ref->{id} != $id{ $ref->{id} };
205 $id{ $ref->{id} } = $ref->{id};
211 $main::lxdebug->leave_sub();
214 sub transactions_for_todo_list {
215 $main::lxdebug->enter_sub();
220 my $myconfig = \%main::myconfig;
221 my $form = $main::form;
223 my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig);
225 my $query = qq|SELECT id FROM employee WHERE login = ?|;
226 my ($e_id) = selectrow_query($form, $dbh, $query, $form->{login});
229 qq|SELECT oe.id, oe.transdate, oe.reqdate, oe.quonumber, oe.transaction_description, oe.amount,
230 CASE WHEN (COALESCE(oe.customer_id, 0) = 0) THEN 'vendor' ELSE 'customer' END AS vc,
235 LEFT JOIN customer c ON (oe.customer_id = c.id)
236 LEFT JOIN vendor v ON (oe.vendor_id = v.id)
237 LEFT JOIN employee e ON (oe.employee_id = e.id)
238 WHERE (COALESCE(quotation, FALSE) = TRUE)
239 AND (COALESCE(closed, FALSE) = FALSE)
240 AND ((oe.employee_id = ?) OR (oe.salesman_id = ?))
241 AND NOT (oe.reqdate ISNULL)
242 AND (oe.reqdate < current_date)
245 my $quotations = selectall_hashref_query($form, $dbh, $query, $e_id, $e_id);
247 $main::lxdebug->leave_sub();
253 $main::lxdebug->enter_sub();
255 my ($self, $myconfig, $form) = @_;
257 # connect to database, turn off autocommit
258 my $dbh = $form->dbconnect_noauto($myconfig);
260 my ($query, @values, $sth, $null);
261 my $exchangerate = 0;
263 my $all_units = AM->retrieve_units($myconfig, $form);
264 $form->{all_units} = $all_units;
266 my $ic_cvar_configs = CVar->get_configs(module => 'IC',
269 $form->{employee_id} = (split /--/, $form->{employee})[1] if !$form->{employee_id};
270 unless ($form->{employee_id}) {
271 $form->get_employee($dbh);
274 my $ml = ($form->{type} eq 'sales_order') ? 1 : -1;
277 $query = qq|DELETE FROM custom_variables
278 WHERE (config_id IN (SELECT id FROM custom_variable_configs WHERE module = 'IC'))
279 AND (sub_module = 'orderitems')
280 AND (trans_id IN (SELECT id FROM orderitems WHERE trans_id = ?))|;
281 do_query($form, $dbh, $query, $form->{id});
283 $query = qq|DELETE FROM orderitems WHERE trans_id = ?|;
284 do_query($form, $dbh, $query, $form->{id});
286 $query = qq|DELETE FROM shipto | .
287 qq|WHERE trans_id = ? AND module = 'OE'|;
288 do_query($form, $dbh, $query, $form->{id});
292 $query = qq|SELECT nextval('id')|;
293 ($form->{id}) = selectrow_query($form, $dbh, $query);
295 $query = qq|INSERT INTO oe (id, ordnumber, employee_id) VALUES (?, '', ?)|;
296 do_query($form, $dbh, $query, $form->{id}, $form->{employee_id});
314 $form->get_lists('price_factors' => 'ALL_PRICE_FACTORS');
315 my %price_factors = map { $_->{id} => $_->{factor} } @{ $form->{ALL_PRICE_FACTORS} };
318 for my $i (1 .. $form->{rowcount}) {
320 map({ $form->{"${_}_$i"} = $form->parse_amount($myconfig, $form->{"${_}_$i"}) } qw(qty ship));
322 if ($form->{"id_$i"}) {
325 $query = qq|SELECT unit FROM parts WHERE id = ?|;
326 my ($item_unit) = selectrow_query($form, $dbh, $query, $form->{"id_$i"});
329 if (defined($all_units->{$item_unit}->{factor}) &&
330 (($all_units->{$item_unit}->{factor} * 1) != 0)) {
331 $basefactor = $all_units->{$form->{"unit_$i"}}->{factor} / $all_units->{$item_unit}->{factor};
333 my $baseqty = $form->{"qty_$i"} * $basefactor;
335 $form->{"marge_percent_$i"} = $form->parse_amount($myconfig, $form->{"marge_percent_$i"}) * 1;
336 $form->{"marge_total_$i"} = $form->parse_amount($myconfig, $form->{"marge_total_$i"}) * 1;
337 $form->{"lastcost_$i"} = $form->{"lastcost_$i"} * 1;
339 # set values to 0 if nothing entered
340 $form->{"discount_$i"} = $form->parse_amount($myconfig, $form->{"discount_$i"}) / 100;
342 $form->{"sellprice_$i"} = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
343 $fxsellprice = $form->{"sellprice_$i"};
345 my ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
347 my $decimalplaces = ($dec > 2) ? $dec : 2;
349 $discount = $form->round_amount($form->{"sellprice_$i"} * $form->{"discount_$i"}, $decimalplaces);
350 $form->{"sellprice_$i"} = $form->round_amount($form->{"sellprice_$i"} - $discount, $decimalplaces);
352 $form->{"inventory_accno_$i"} *= 1;
353 $form->{"expense_accno_$i"} *= 1;
355 $price_factor = $price_factors{ $form->{"price_factor_id_$i"} } || 1;
356 $linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"} / $price_factor, 2);
358 @taxaccounts = split(/ /, $form->{"taxaccounts_$i"});
362 map { $taxrate += $form->{"${_}_rate"} } @taxaccounts;
364 if ($form->{taxincluded}) {
365 $taxamount = $linetotal * $taxrate / (1 + $taxrate);
366 $taxbase = $linetotal - $taxamount;
368 # we are not keeping a natural price, do not round
369 $form->{"sellprice_$i"} =
370 $form->{"sellprice_$i"} * (1 / (1 + $taxrate));
372 $taxamount = $linetotal * $taxrate;
373 $taxbase = $linetotal;
376 if ($form->round_amount($taxrate, 7) == 0) {
377 if ($form->{taxincluded}) {
378 foreach my $item (@taxaccounts) {
379 $taxamount = $form->round_amount($linetotal * $form->{"${item}_rate"} / (1 + abs($form->{"${item}_rate"})), 2);
380 $taxaccounts{$item} += $taxamount;
381 $taxdiff += $taxamount;
382 $taxbase{$item} += $taxbase;
384 $taxaccounts{ $taxaccounts[0] } += $taxdiff;
386 foreach my $item (@taxaccounts) {
387 $taxaccounts{$item} += $linetotal * $form->{"${item}_rate"};
388 $taxbase{$item} += $taxbase;
392 foreach my $item (@taxaccounts) {
393 $taxaccounts{$item} += $taxamount * $form->{"${item}_rate"} / $taxrate;
394 $taxbase{$item} += $taxbase;
398 $netamount += $form->{"sellprice_$i"} * $form->{"qty_$i"} / $price_factor;
400 $reqdate = ($form->{"reqdate_$i"}) ? $form->{"reqdate_$i"} : undef;
402 # get pricegroup_id and save ist
403 ($null, my $pricegroup_id) = split(/--/, $form->{"sellprice_pg_$i"});
406 # save detail record in orderitems table
407 my $orderitems_id = $form->{"orderitems_id_$i"};
408 ($orderitems_id) = selectfirst_array_query($form, $dbh, qq|SELECT nextval('orderitemsid')|) if (!$orderitems_id);
411 $query = qq|INSERT INTO orderitems (
412 id, trans_id, parts_id, description, longdescription, qty, base_qty,
413 sellprice, discount, unit, reqdate, project_id, serialnumber, ship,
414 pricegroup_id, ordnumber, transdate, cusordnumber, subtotal,
415 marge_percent, marge_total, lastcost, price_factor_id, price_factor, marge_price_factor)
416 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
417 (SELECT factor FROM price_factors WHERE id = ?), ?)|;
419 conv_i($orderitems_id), conv_i($form->{id}), conv_i($form->{"id_$i"}),
420 $form->{"description_$i"}, $form->{"longdescription_$i"},
421 $form->{"qty_$i"}, $baseqty,
422 $fxsellprice, $form->{"discount_$i"},
423 $form->{"unit_$i"}, conv_date($reqdate), conv_i($form->{"project_id_$i"}),
424 $form->{"serialnumber_$i"}, $form->{"ship_$i"}, conv_i($pricegroup_id),
425 $form->{"ordnumber_$i"}, conv_date($form->{"transdate_$i"}),
426 $form->{"cusordnumber_$i"}, $form->{"subtotal_$i"} ? 't' : 'f',
427 $form->{"marge_percent_$i"}, $form->{"marge_total_$i"},
428 $form->{"lastcost_$i"},
429 conv_i($form->{"price_factor_id_$i"}), conv_i($form->{"price_factor_id_$i"}),
430 conv_i($form->{"marge_price_factor_$i"}));
431 do_query($form, $dbh, $query, @values);
433 $form->{"sellprice_$i"} = $fxsellprice;
434 $form->{"discount_$i"} *= 100;
436 CVar->save_custom_variables(module => 'IC',
437 sub_module => 'orderitems',
438 trans_id => $orderitems_id,
439 configs => $ic_cvar_configs,
441 name_prefix => 'ic_',
442 name_postfix => "_$i",
447 $reqdate = ($form->{reqdate}) ? $form->{reqdate} : undef;
451 map { $tax += $form->round_amount($taxaccounts{$_}, 2) } keys %taxaccounts;
453 $amount = $form->round_amount($netamount + $tax, 2);
454 $netamount = $form->round_amount($netamount, 2);
456 if ($form->{currency} eq $form->{defaultcurrency}) {
457 $form->{exchangerate} = 1;
459 $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{transdate}, ($form->{vc} eq 'customer') ? 'buy' : 'sell');
462 $form->{exchangerate} = $exchangerate || $form->parse_amount($myconfig, $form->{exchangerate});
464 my $quotation = $form->{type} =~ /_order$/ ? 'f' : 't';
466 ($null, $form->{department_id}) = split(/--/, $form->{department}) if $form->{department};
471 ordnumber = ?, quonumber = ?, cusordnumber = ?, transdate = ?, vendor_id = ?,
472 customer_id = ?, amount = ?, netamount = ?, reqdate = ?, taxincluded = ?,
473 shippingpoint = ?, shipvia = ?, notes = ?, intnotes = ?, curr = ?, closed = ?,
474 delivered = ?, proforma = ?, quotation = ?, department_id = ?, language_id = ?,
475 taxzone_id = ?, shipto_id = ?, payment_id = ?, delivery_vendor_id = ?, delivery_customer_id = ?,
476 globalproject_id = ?, employee_id = ?, salesman_id = ?, cp_id = ?, transaction_description = ?, marge_total = ?, marge_percent = ?
479 @values = ($form->{ordnumber} || '', $form->{quonumber},
480 $form->{cusordnumber}, conv_date($form->{transdate}),
481 conv_i($form->{vendor_id}), conv_i($form->{customer_id}),
482 $amount, $netamount, conv_date($reqdate),
483 $form->{taxincluded} ? 't' : 'f', $form->{shippingpoint},
484 $form->{shipvia}, $form->{notes}, $form->{intnotes},
485 substr($form->{currency}, 0, 3), $form->{closed} ? 't' : 'f',
486 $form->{delivered} ? "t" : "f", $form->{proforma} ? 't' : 'f',
487 $quotation, conv_i($form->{department_id}),
488 conv_i($form->{language_id}), conv_i($form->{taxzone_id}),
489 conv_i($form->{shipto_id}), conv_i($form->{payment_id}),
490 conv_i($form->{delivery_vendor_id}),
491 conv_i($form->{delivery_customer_id}),
492 conv_i($form->{globalproject_id}), conv_i($form->{employee_id}),
493 conv_i($form->{salesman_id}), conv_i($form->{cp_id}),
494 $form->{transaction_description},
495 $form->{marge_total} * 1, $form->{marge_percent} * 1,
496 conv_i($form->{id}));
497 do_query($form, $dbh, $query, @values);
499 $form->{ordtotal} = $amount;
502 $form->{name} = $form->{ $form->{vc} };
503 $form->{name} =~ s/--\Q$form->{"$form->{vc}_id"}\E//;
505 if (!$form->{shipto_id}) {
506 $form->add_shipto($dbh, $form->{id}, "OE");
509 # save printed, emailed, queued
510 $form->save_status($dbh);
512 # Link this record to the records it was created from.
513 $form->{convert_from_oe_ids} =~ s/^\s+//;
514 $form->{convert_from_oe_ids} =~ s/\s+$//;
515 my @convert_from_oe_ids = split m/\s+/, $form->{convert_from_oe_ids};
516 delete $form->{convert_from_oe_ids};
518 if (scalar @convert_from_oe_ids) {
519 RecordLinks->create_links('dbh' => $dbh,
521 'from_table' => 'oe',
522 'from_ids' => \@convert_from_oe_ids,
524 'to_id' => $form->{id},
527 $self->_close_quotations_rfqs('dbh' => $dbh,
528 'from_id' => \@convert_from_oe_ids,
529 'to_id' => $form->{id});
532 if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
533 if ($form->{vc} eq 'customer') {
534 $form->update_exchangerate($dbh, $form->{currency}, $form->{transdate}, $form->{exchangerate}, 0);
536 if ($form->{vc} eq 'vendor') {
537 $form->update_exchangerate($dbh, $form->{currency}, $form->{transdate}, 0, $form->{exchangerate});
541 $form->{saved_xyznumber} = $form->{$form->{type} =~ /_quotation$/ ?
542 "quonumber" : "ordnumber"};
544 Common::webdav_folder($form) if ($main::webdav);
546 my $rc = $dbh->commit;
549 $main::lxdebug->leave_sub();
554 sub _close_quotations_rfqs {
555 $main::lxdebug->enter_sub();
560 Common::check_params(\%params, qw(from_id to_id));
562 my $myconfig = \%main::myconfig;
563 my $form = $main::form;
565 my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig);
567 my $query = qq|SELECT quotation FROM oe WHERE id = ?|;
568 my $sth = prepare_query($form, $dbh, $query);
570 do_statement($form, $sth, $query, conv_i($params{to_id}));
572 my ($quotation) = $sth->fetchrow_array();
575 $main::lxdebug->leave_sub();
581 foreach my $from_id (@{ $params{from_id} }) {
582 $from_id = conv_i($from_id);
583 do_statement($form, $sth, $query, $from_id);
584 ($quotation) = $sth->fetchrow_array();
585 push @close_ids, $from_id if ($quotation);
590 if (scalar @close_ids) {
591 $query = qq|UPDATE oe SET closed = TRUE WHERE id IN (| . join(', ', ('?') x scalar @close_ids) . qq|)|;
592 do_query($form, $dbh, $query, @close_ids);
594 $dbh->commit() unless ($params{dbh});
597 $main::lxdebug->leave_sub();
601 $main::lxdebug->enter_sub();
603 my ($self, $myconfig, $form, $spool) = @_;
605 # connect to database
606 my $dbh = $form->dbconnect_noauto($myconfig);
609 my $query = qq|SELECT s.spoolfile FROM status s | .
610 qq|WHERE s.trans_id = ?|;
611 my @values = (conv_i($form->{id}));
612 my $sth = $dbh->prepare($query);
613 $sth->execute(@values) || $self->dberror($query);
618 while (($spoolfile) = $sth->fetchrow_array) {
619 push @spoolfiles, $spoolfile;
624 @values = (conv_i($form->{id}));
626 # delete status entries
627 $query = qq|DELETE FROM status | .
628 qq|WHERE trans_id = ?|;
629 do_query($form, $dbh, $query, @values);
632 $query = qq|DELETE FROM oe | .
634 do_query($form, $dbh, $query, @values);
636 # delete individual entries
637 $query = qq|DELETE FROM orderitems | .
638 qq|WHERE trans_id = ?|;
639 do_query($form, $dbh, $query, @values);
641 $query = qq|DELETE FROM shipto | .
642 qq|WHERE trans_id = ? AND module = 'OE'|;
643 do_query($form, $dbh, $query, @values);
645 my $rc = $dbh->commit;
649 foreach $spoolfile (@spoolfiles) {
650 unlink "$spool/$spoolfile" if $spoolfile;
654 $main::lxdebug->leave_sub();
660 $main::lxdebug->enter_sub();
662 my ($self, $myconfig, $form) = @_;
664 # connect to database
665 my $dbh = $form->dbconnect_noauto($myconfig);
667 my ($query, $query_add, @values, @ids, $sth);
669 my $ic_cvar_configs = CVar->get_configs(module => 'IC',
672 # translate the ids (given by id_# and trans_id_#) into one array of ids, so we can join them later
674 push @ids, $form->{"trans_id_$_"}
675 if ($form->{"multi_id_$_"} and $form->{"trans_id_$_"})
676 } (1 .. $form->{"rowcount"});
678 if ($form->{rowcount} && scalar @ids) {
679 $form->{convert_from_oe_ids} = join ' ', @ids;
682 # if called in multi id mode, and still only got one id, switch back to single id
683 if ($form->{"rowcount"} and $#ids == 0) {
684 $form->{"id"} = $ids[0];
688 # and remember for the rest of the function
689 my $is_collective_order = scalar @ids;
692 my $wday = (localtime(time))[6];
693 my $next_workday = $wday == 5 ? 3 : $wday == 6 ? 2 : 1;
694 $query_add = qq|, current_date AS transdate, date(current_date + interval '${next_workday} days') AS reqdate|;
697 # get default accounts
698 $query = qq|SELECT (SELECT c.accno FROM chart c WHERE d.inventory_accno_id = c.id) AS inventory_accno,
699 (SELECT c.accno FROM chart c WHERE d.income_accno_id = c.id) AS income_accno,
700 (SELECT c.accno FROM chart c WHERE d.expense_accno_id = c.id) AS expense_accno,
701 (SELECT c.accno FROM chart c WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
702 (SELECT c.accno FROM chart c WHERE d.fxloss_accno_id = c.id) AS fxloss_accno,
706 my $ref = selectfirst_hashref_query($form, $dbh, $query);
707 map { $form->{$_} = $ref->{$_} } keys %$ref;
709 ($form->{currency}) = split(/:/, $form->{currencies}) unless ($form->{currency});
711 # set reqdate if this is an invoice->order conversion. If someone knows a better check to ensure
712 # we come from invoices, feel free.
713 $form->{reqdate} = $form->{deliverydate}
714 if ( $form->{deliverydate}
715 and $form->{callback} =~ /action=ar_transactions/);
717 my $vc = $form->{vc} eq "customer" ? "customer" : "vendor";
719 if ($form->{id} or @ids) {
721 # retrieve order for single id
722 # NOTE: this query is intended to fetch all information only ONCE.
723 # so if any of these infos is important (or even different) for any item,
724 # it will be killed out and then has to be fetched from the item scope query further down
726 qq|SELECT o.cp_id, o.ordnumber, o.transdate, o.reqdate,
727 o.taxincluded, o.shippingpoint, o.shipvia, o.notes, o.intnotes,
728 o.curr AS currency, e.name AS employee, o.employee_id, o.salesman_id,
729 o.${vc}_id, cv.name AS ${vc}, o.amount AS invtotal,
730 o.closed, o.reqdate, o.quonumber, o.department_id, o.cusordnumber,
731 d.description AS department, o.payment_id, o.language_id, o.taxzone_id,
732 o.delivery_customer_id, o.delivery_vendor_id, o.proforma, o.shipto_id,
733 o.globalproject_id, o.delivered, o.transaction_description
735 JOIN ${vc} cv ON (o.${vc}_id = cv.id)
736 LEFT JOIN employee e ON (o.employee_id = e.id)
737 LEFT JOIN department d ON (o.department_id = d.id) | .
740 : "WHERE o.id IN (" . join(', ', map("? ", @ids)) . ")"
742 @values = $form->{id} ? ($form->{id}) : @ids;
743 $sth = prepare_execute_query($form, $dbh, $query, @values);
745 $ref = $sth->fetchrow_hashref("NAME_lc");
746 map { $form->{$_} = $ref->{$_} } keys %$ref;
748 $form->{saved_xyznumber} = $form->{$form->{type} =~ /_quotation$/ ?
749 "quonumber" : "ordnumber"};
751 # set all entries for multiple ids blank that yield different information
752 while ($ref = $sth->fetchrow_hashref("NAME_lc")) {
753 map { $form->{$_} = '' if ($ref->{$_} ne $form->{$_}) } keys %$ref;
756 # if not given, fill transdate with current_date
757 $form->{transdate} = $form->current_date($myconfig)
758 unless $form->{transdate};
762 if ($form->{delivery_customer_id}) {
763 $query = qq|SELECT name FROM customer WHERE id = ?|;
764 ($form->{delivery_customer_string}) = selectrow_query($form, $dbh, $query, $form->{delivery_customer_id});
767 if ($form->{delivery_vendor_id}) {
768 $query = qq|SELECT name FROM customer WHERE id = ?|;
769 ($form->{delivery_vendor_string}) = selectrow_query($form, $dbh, $query, $form->{delivery_vendor_id});
772 # shipto and pinted/mailed/queued status makes only sense for single id retrieve
774 $query = qq|SELECT s.* FROM shipto s WHERE s.trans_id = ? AND s.module = 'OE'|;
775 $sth = prepare_execute_query($form, $dbh, $query, $form->{id});
777 $ref = $sth->fetchrow_hashref("NAME_lc");
779 map { $form->{$_} = $ref->{$_} } keys %$ref;
782 # get printed, emailed and queued
783 $query = qq|SELECT s.printed, s.emailed, s.spoolfile, s.formname FROM status s WHERE s.trans_id = ?|;
784 $sth = prepare_execute_query($form, $dbh, $query, $form->{id});
786 while ($ref = $sth->fetchrow_hashref("NAME_lc")) {
787 $form->{printed} .= "$ref->{formname} " if $ref->{printed};
788 $form->{emailed} .= "$ref->{formname} " if $ref->{emailed};
789 $form->{queued} .= "$ref->{formname} $ref->{spoolfile} " if $ref->{spoolfile};
792 map { $form->{$_} =~ s/ +$//g } qw(printed emailed queued);
795 my %oid = ('Pg' => 'oid',
796 'Oracle' => 'rowid');
798 my $transdate = $form->{transdate} ? $dbh->quote($form->{transdate}) : "current_date";
800 $form->{taxzone_id} = 0 unless ($form->{taxzone_id});
802 # retrieve individual items
803 # this query looks up all information about the items
804 # stuff different from the whole will not be overwritten, but saved with a suffix.
806 qq|SELECT o.id AS orderitems_id,
807 c1.accno AS inventory_accno, c1.new_chart_id AS inventory_new_chart, date($transdate) - c1.valid_from as inventory_valid,
808 c2.accno AS income_accno, c2.new_chart_id AS income_new_chart, date($transdate) - c2.valid_from as income_valid,
809 c3.accno AS expense_accno, c3.new_chart_id AS expense_new_chart, date($transdate) - c3.valid_from as expense_valid,
810 oe.ordnumber AS ordnumber_oe, oe.transdate AS transdate_oe, oe.cusordnumber AS cusordnumber_oe,
811 p.partnumber, p.assembly, o.description, o.qty,
812 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,
813 o.reqdate, o.project_id, o.serialnumber, o.ship, o.lastcost,
814 o.ordnumber, o.transdate, o.cusordnumber, o.subtotal, o.longdescription,
815 o.price_factor_id, o.price_factor, o.marge_price_factor,
816 pr.projectnumber, p.formel,
817 pg.partsgroup, o.pricegroup_id, (SELECT pricegroup FROM pricegroup WHERE id=o.pricegroup_id) as pricegroup
819 JOIN parts p ON (o.parts_id = p.id)
820 JOIN oe ON (o.trans_id = oe.id)
821 LEFT JOIN chart c1 ON ((SELECT inventory_accno_id FROM buchungsgruppen WHERE id=p.buchungsgruppen_id) = c1.id)
822 LEFT JOIN chart c2 ON ((SELECT income_accno_id_$form->{taxzone_id} FROM buchungsgruppen WHERE id=p.buchungsgruppen_id) = c2.id)
823 LEFT JOIN chart c3 ON ((SELECT expense_accno_id_$form->{taxzone_id} FROM buchungsgruppen WHERE id=p.buchungsgruppen_id) = c3.id)
824 LEFT JOIN project pr ON (o.project_id = pr.id)
825 LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) | .
827 ? qq|WHERE o.trans_id = ?|
828 : qq|WHERE o.trans_id IN (| . join(", ", map("?", @ids)) . qq|)|) .
829 qq|ORDER BY o.$oid{$myconfig->{dbdriver}}|;
831 @ids = $form->{id} ? ($form->{id}) : @ids;
832 $sth = prepare_execute_query($form, $dbh, $query, @values);
834 while ($ref = $sth->fetchrow_hashref("NAME_lc")) {
835 # Retrieve custom variables.
836 my $cvars = CVar->get_custom_variables(dbh => $dbh,
838 sub_module => 'orderitems',
839 trans_id => $ref->{orderitems_id},
841 map { $ref->{"ic_cvar_$_->{name}"} = $_->{value} } @{ $cvars };
844 if (!$ref->{"part_inventory_accno_id"}) {
845 map({ delete($ref->{$_}); } qw(inventory_accno inventory_new_chart inventory_valid));
847 delete($ref->{"part_inventory_accno_id"});
849 # in collective order, copy global ordnumber, transdate, cusordnumber into item scope
850 # unless already present there
851 # remove _oe entries afterwards
852 map { $ref->{$_} = $ref->{"${_}_oe"} if ($ref->{$_} eq '') }
853 qw|ordnumber transdate cusordnumber|
855 map { delete $ref->{$_} } qw|ordnumber_oe transdate_oe cusordnumber_oe|;
859 while ($ref->{inventory_new_chart} && ($ref->{inventory_valid} >= 0)) {
861 qq|SELECT accno AS inventory_accno, | .
862 qq| new_chart_id AS inventory_new_chart, | .
863 qq| date($transdate) - valid_from AS inventory_valid | .
864 qq|FROM chart WHERE id = $ref->{inventory_new_chart}|;
865 ($ref->{inventory_accno}, $ref->{inventory_new_chart},
866 $ref->{inventory_valid}) = selectrow_query($form, $dbh, $query);
869 while ($ref->{income_new_chart} && ($ref->{income_valid} >= 0)) {
871 qq|SELECT accno AS income_accno, | .
872 qq| new_chart_id AS income_new_chart, | .
873 qq| date($transdate) - valid_from AS income_valid | .
874 qq|FROM chart WHERE id = $ref->{income_new_chart}|;
875 ($ref->{income_accno}, $ref->{income_new_chart},
876 $ref->{income_valid}) = selectrow_query($form, $dbh, $query);
879 while ($ref->{expense_new_chart} && ($ref->{expense_valid} >= 0)) {
881 qq|SELECT accno AS expense_accno, | .
882 qq| new_chart_id AS expense_new_chart, | .
883 qq| date($transdate) - valid_from AS expense_valid | .
884 qq|FROM chart WHERE id = $ref->{expense_new_chart}|;
885 ($ref->{expense_accno}, $ref->{expense_new_chart},
886 $ref->{expense_valid}) = selectrow_query($form, $dbh, $query);
889 # delete orderitems_id in collective orders, so that they get cloned no matter what
890 delete $ref->{orderitems_id} if (@ids);
892 # get tax rates and description
893 my $accno_id = ($form->{vc} eq "customer") ? $ref->{income_accno} : $ref->{expense_accno};
895 qq|SELECT c.accno, t.taxdescription, t.rate, t.taxnumber | .
896 qq|FROM tax t LEFT JOIN chart c on (c.id = t.chart_id) | .
897 qq|WHERE t.id IN (SELECT tk.tax_id FROM taxkeys tk | .
898 qq| WHERE tk.chart_id = (SELECT id FROM chart WHERE accno = ?) | .
899 qq| AND startdate <= $transdate ORDER BY startdate DESC LIMIT 1) | .
900 qq|ORDER BY c.accno|;
901 my $stw = prepare_execute_query($form, $dbh, $query, $accno_id);
902 $ref->{taxaccounts} = "";
904 while (my $ptr = $stw->fetchrow_hashref("NAME_lc")) {
905 if (($ptr->{accno} eq "") && ($ptr->{rate} == 0)) {
909 $ref->{taxaccounts} .= "$ptr->{accno} ";
910 if (!($form->{taxaccounts} =~ /\Q$ptr->{accno}\E/)) {
911 $form->{"$ptr->{accno}_rate"} = $ptr->{rate};
912 $form->{"$ptr->{accno}_description"} = $ptr->{taxdescription};
913 $form->{"$ptr->{accno}_taxnumber"} = $ptr->{taxnumber};
914 $form->{taxaccounts} .= "$ptr->{accno} ";
919 chop $ref->{taxaccounts};
921 push @{ $form->{form_details} }, $ref;
929 $form->lastname_used($dbh, $myconfig, $form->{vc})
930 unless $form->{"$form->{vc}_id"};
934 $form->{exchangerate} = $form->get_exchangerate($dbh, $form->{currency}, $form->{transdate}, ($form->{vc} eq 'customer') ? "buy" : "sell");
936 Common::webdav_folder($form) if ($main::webdav);
938 my $rc = $dbh->commit;
941 $main::lxdebug->leave_sub();
946 sub retrieve_simple {
947 $main::lxdebug->enter_sub();
952 Common::check_params(\%params, qw(id));
954 my $myconfig = \%main::myconfig;
955 my $form = $main::form;
957 my $dbh = $params{dbh} || $form->get_standard_dbh($myconfig);
959 my $oe_query = qq|SELECT * FROM oe WHERE id = ?|;
960 my $oi_query = qq|SELECT * FROM orderitems WHERE trans_id = ?|;
962 my $order = selectfirst_hashref_query($form, $dbh, $oe_query, conv_i($params{id}));
963 $order->{orderitems} = selectall_hashref_query( $form, $dbh, $oi_query, conv_i($params{id}));
965 $main::lxdebug->leave_sub();
971 $main::lxdebug->enter_sub();
973 my ($self, $myconfig, $form) = @_;
975 # connect to database
976 my $dbh = $form->dbconnect($myconfig);
982 my $nodiscount_subtotal = 0;
983 my $discount_subtotal = 0;
989 my $subtotal_header = 0;
997 my %oid = ('Pg' => 'oid',
998 'Oracle' => 'rowid');
1000 my (@project_ids, %projectnumbers);
1002 push(@project_ids, $form->{"globalproject_id"}) if ($form->{"globalproject_id"});
1004 $form->get_lists('price_factors' => 'ALL_PRICE_FACTORS',
1005 'departments' => 'ALL_DEPARTMENTS');
1008 foreach my $pfac (@{ $form->{ALL_PRICE_FACTORS} }) {
1009 $price_factors{$pfac->{id}} = $pfac;
1010 $pfac->{factor} *= 1;
1011 $pfac->{formatted_factor} = $form->format_amount($myconfig, $pfac->{factor});
1015 foreach my $dept (@{ $form->{ALL_DEPARTMENTS} }) {
1016 next unless $dept->{id} eq $form->{department_id};
1017 $form->{department} = $dept->{description};
1021 # sort items by partsgroup
1022 for $i (1 .. $form->{rowcount}) {
1024 if ($form->{"partsgroup_$i"} && $form->{groupitems}) {
1025 $partsgroup = $form->{"partsgroup_$i"};
1027 push @partsgroup, [$i, $partsgroup];
1028 push(@project_ids, $form->{"project_id_$i"}) if ($form->{"project_id_$i"});
1032 $query = "SELECT id, projectnumber FROM project WHERE id IN (" .
1033 join(", ", map("?", @project_ids)) . ")";
1034 $sth = prepare_execute_query($form, $dbh, $query, @project_ids);
1035 while (my $ref = $sth->fetchrow_hashref()) {
1036 $projectnumbers{$ref->{id}} = $ref->{projectnumber};
1041 $form->{"globalprojectnumber"} = $projectnumbers{$form->{"globalproject_id"}};
1043 $form->{discount} = [];
1045 $form->{TEMPLATE_ARRAYS} = { };
1046 IC->prepare_parts_for_printing();
1048 my $ic_cvar_configs = CVar->get_configs(module => 'IC');
1051 qw(runningnumber number description longdescription qty ship unit bin
1052 partnotes serialnumber reqdate sellprice listprice netprice
1053 discount p_discount discount_sub nodiscount_sub
1054 linetotal nodiscount_linetotal tax_rate projectnumber
1055 price_factor price_factor_name partsgroup);
1057 push @arrays, map { "ic_cvar_$_->{name}" } @{ $ic_cvar_configs };
1059 my @tax_arrays = qw(taxbase tax taxdescription taxrate taxnumber);
1061 map { $form->{TEMPLATE_ARRAYS}->{$_} = [] } (@arrays, @tax_arrays);
1064 foreach $item (sort { $a->[1] cmp $b->[1] } @partsgroup) {
1067 if ($item->[1] ne $sameitem) {
1068 push(@{ $form->{TEMPLATE_ARRAYS}->{description} }, qq|$item->[1]|);
1069 $sameitem = $item->[1];
1071 map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, "") } grep({ $_ ne "description" } @arrays));
1074 $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
1076 if ($form->{"id_$i"} != 0) {
1078 # add number, description and qty to $form->{number}, ....
1080 if ($form->{"subtotal_$i"} && !$subtotal_header) {
1081 $subtotal_header = $i;
1082 $position = int($position);
1085 } elsif ($subtotal_header) {
1087 $position = int($position);
1088 $position = $position.".".$subposition;
1090 $position = int($position);
1094 my $price_factor = $price_factors{$form->{"price_factor_id_$i"}} || { 'factor' => 1 };
1096 push @{ $form->{TEMPLATE_ARRAYS}->{runningnumber} }, $position;
1097 push @{ $form->{TEMPLATE_ARRAYS}->{number} }, $form->{"partnumber_$i"};
1098 push @{ $form->{TEMPLATE_ARRAYS}->{description} }, $form->{"description_$i"};
1099 push @{ $form->{TEMPLATE_ARRAYS}->{longdescription} }, $form->{"longdescription_$i"};
1100 push @{ $form->{TEMPLATE_ARRAYS}->{qty} }, $form->format_amount($myconfig, $form->{"qty_$i"});
1101 push @{ $form->{TEMPLATE_ARRAYS}->{ship} }, $form->format_amount($myconfig, $form->{"ship_$i"});
1102 push @{ $form->{TEMPLATE_ARRAYS}->{unit} }, $form->{"unit_$i"};
1103 push @{ $form->{TEMPLATE_ARRAYS}->{bin} }, $form->{"bin_$i"};
1104 push @{ $form->{TEMPLATE_ARRAYS}->{partnotes} }, $form->{"partnotes_$i"};
1105 push @{ $form->{TEMPLATE_ARRAYS}->{serialnumber} }, $form->{"serialnumber_$i"};
1106 push @{ $form->{TEMPLATE_ARRAYS}->{reqdate} }, $form->{"reqdate_$i"};
1107 push @{ $form->{TEMPLATE_ARRAYS}->{sellprice} }, $form->{"sellprice_$i"};
1108 push @{ $form->{TEMPLATE_ARRAYS}->{listprice} }, $form->{"listprice_$i"};
1109 push @{ $form->{TEMPLATE_ARRAYS}->{price_factor} }, $price_factor->{formatted_factor};
1110 push @{ $form->{TEMPLATE_ARRAYS}->{price_factor_name} }, $price_factor->{description};
1111 push @{ $form->{TEMPLATE_ARRAYS}->{partsgroup} }, $form->{"partsgroup_$i"};
1113 my $sellprice = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
1114 my ($dec) = ($sellprice =~ /\.(\d+)/);
1115 my $decimalplaces = max 2, length($dec);
1117 my $parsed_discount = $form->parse_amount($myconfig, $form->{"discount_$i"});
1118 my $linetotal_exact = $form->{"qty_$i"} * $sellprice * (100 - $parsed_discount) / 100 / $price_factor->{factor};
1119 my $linetotal = $form->round_amount($linetotal_exact, 2);
1120 my $discount = $form->round_amount($form->{"qty_$i"} * $sellprice * $parsed_discount / 100 / $price_factor->{factor} - ($linetotal - $linetotal_exact),
1122 my $nodiscount_linetotal = $form->round_amount($form->{"qty_$i"} * $sellprice / $price_factor->{factor}, 2);
1123 $form->{"netprice_$i"} = $form->round_amount($form->{"qty_$i"} ? ($linetotal / $form->{"qty_$i"}) : 0, 2);
1125 push @{ $form->{TEMPLATE_ARRAYS}->{netprice} }, ($form->{"netprice_$i"} != 0) ? $form->format_amount($myconfig, $form->{"netprice_$i"}, $decimalplaces) : '';
1127 $linetotal = ($linetotal != 0) ? $linetotal : '';
1129 push @{ $form->{TEMPLATE_ARRAYS}->{discount} }, ($discount != 0) ? $form->format_amount($myconfig, $discount * -1, 2) : '';
1130 push @{ $form->{TEMPLATE_ARRAYS}->{p_discount} }, $form->{"discount_$i"};
1132 $form->{ordtotal} += $linetotal;
1133 $form->{nodiscount_total} += $nodiscount_linetotal;
1134 $form->{discount_total} += $discount;
1136 if ($subtotal_header) {
1137 $discount_subtotal += $linetotal;
1138 $nodiscount_subtotal += $nodiscount_linetotal;
1141 if ($form->{"subtotal_$i"} && $subtotal_header && ($subtotal_header != $i)) {
1142 push @{ $form->{TEMPLATE_ARRAYS}->{discount_sub} }, $form->format_amount($myconfig, $discount_subtotal, 2);
1143 push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_sub} }, $form->format_amount($myconfig, $nodiscount_subtotal, 2);
1145 $discount_subtotal = 0;
1146 $nodiscount_subtotal = 0;
1147 $subtotal_header = 0;
1150 push @{ $form->{TEMPLATE_ARRAYS}->{discount_sub} }, "";
1151 push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_sub} }, "";
1154 if (!$form->{"discount_$i"}) {
1155 $nodiscount += $linetotal;
1158 push @{ $form->{TEMPLATE_ARRAYS}->{linetotal} }, $form->format_amount($myconfig, $linetotal, 2);
1159 push @{ $form->{TEMPLATE_ARRAYS}->{nodiscount_linetotal} }, $form->format_amount($myconfig, $nodiscount_linetotal, 2);
1161 push(@{ $form->{TEMPLATE_ARRAYS}->{projectnumber} }, $projectnumbers{$form->{"project_id_$i"}});
1163 my ($taxamount, $taxbase);
1166 map { $taxrate += $form->{"${_}_rate"} } split(/ /, $form->{"taxaccounts_$i"});
1168 if ($form->{taxincluded}) {
1171 $taxamount = $linetotal * $taxrate / (1 + $taxrate);
1172 $taxbase = $linetotal / (1 + $taxrate);
1174 $taxamount = $linetotal * $taxrate;
1175 $taxbase = $linetotal;
1178 if ($taxamount != 0) {
1179 foreach my $accno (split / /, $form->{"taxaccounts_$i"}) {
1180 $taxaccounts{$accno} += $taxamount * $form->{"${accno}_rate"} / $taxrate;
1181 $taxbase{$accno} += $taxbase;
1185 $tax_rate = $taxrate * 100;
1186 push(@{ $form->{TEMPLATE_ARRAYS}->{tax_rate} }, qq|$tax_rate|);
1188 if ($form->{"assembly_$i"}) {
1191 # get parts and push them onto the stack
1193 if ($form->{groupitems}) {
1194 $sortorder = qq|ORDER BY pg.partsgroup, a.$oid{$myconfig->{dbdriver}}|;
1196 $sortorder = qq|ORDER BY a.$oid{$myconfig->{dbdriver}}|;
1199 $query = qq|SELECT p.partnumber, p.description, p.unit, a.qty, | .
1200 qq|pg.partsgroup | .
1201 qq|FROM assembly a | .
1202 qq| JOIN parts p ON (a.parts_id = p.id) | .
1203 qq| LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id) | .
1204 qq| WHERE a.bom = '1' | .
1205 qq| AND a.id = ? | . $sortorder;
1206 @values = ($form->{"id_$i"});
1207 $sth = $dbh->prepare($query);
1208 $sth->execute(@values) || $form->dberror($query);
1210 while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
1211 if ($form->{groupitems} && $ref->{partsgroup} ne $sameitem) {
1212 map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, "") } grep({ $_ ne "description" } @arrays));
1213 $sameitem = ($ref->{partsgroup}) ? $ref->{partsgroup} : "--";
1214 push(@{ $form->{TEMPLATE_ARRAYS}->{description} }, $sameitem);
1217 push(@{ $form->{TEMPLATE_ARRAYS}->{description} }, $form->format_amount($myconfig, $ref->{qty} * $form->{"qty_$i"}) . qq|, $ref->{partnumber}, $ref->{description}|);
1218 map({ push(@{ $form->{TEMPLATE_ARRAYS}->{$_} }, "") } grep({ $_ ne "description" } @arrays));
1223 map { push @{ $form->{TEMPLATE_ARRAYS}->{"ic_cvar_$_->{name}"} }, $form->{"ic_cvar_$_->{name}_$i"} } @{ $ic_cvar_configs };
1228 foreach $item (sort keys %taxaccounts) {
1229 $tax += $taxamount = $form->round_amount($taxaccounts{$item}, 2);
1231 push(@{ $form->{TEMPLATE_ARRAYS}->{taxbase} }, $form->format_amount($myconfig, $taxbase{$item}, 2));
1232 push(@{ $form->{TEMPLATE_ARRAYS}->{tax} }, $form->format_amount($myconfig, $taxamount, 2));
1233 push(@{ $form->{TEMPLATE_ARRAYS}->{taxrate} }, $form->format_amount($myconfig, $form->{"${item}_rate"} * 100));
1234 push(@{ $form->{TEMPLATE_ARRAYS}->{taxdescription} }, $form->{"${item}_description"} . q{ } . 100 * $form->{"${item}_rate"} . q{%});
1235 push(@{ $form->{TEMPLATE_ARRAYS}->{taxnumber} }, $form->{"${item}_taxnumber"});
1238 $form->{nodiscount_subtotal} = $form->format_amount($myconfig, $form->{nodiscount_total}, 2);
1239 $form->{discount_total} = $form->format_amount($myconfig, $form->{discount_total}, 2);
1240 $form->{nodiscount} = $form->format_amount($myconfig, $nodiscount, 2);
1241 $form->{yesdiscount} = $form->format_amount($myconfig, $form->{nodiscount_total} - $nodiscount, 2);
1243 if($form->{taxincluded}) {
1244 $form->{subtotal} = $form->format_amount($myconfig, $form->{ordtotal} - $tax, 2);
1246 $form->{subtotal} = $form->format_amount($myconfig, $form->{ordtotal}, 2);
1249 $form->{ordtotal} = ($form->{taxincluded}) ? $form->{ordtotal} : $form->{ordtotal} + $tax;
1252 $form->{quototal} = $form->{ordtotal} = $form->format_amount($myconfig, $form->{ordtotal}, 2);
1254 if ($form->{type} =~ /_quotation/) {
1255 $form->set_payment_options($myconfig, $form->{quodate});
1257 $form->set_payment_options($myconfig, $form->{orddate});
1260 $form->{username} = $myconfig->{name};
1264 $main::lxdebug->leave_sub();
1267 sub project_description {
1268 $main::lxdebug->enter_sub();
1270 my ($self, $dbh, $id) = @_;
1272 my $query = qq|SELECT description FROM project WHERE id = ?|;
1273 my ($value) = selectrow_query($main::form, $dbh, $query, $id);
1275 $main::lxdebug->leave_sub();
1286 OE.pm - Order entry module
1290 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>.
1296 =item retrieve_simple PARAMS
1298 simple OE retrieval by id. does not look up customer, vendor, units or any other stuff. only oe and orderitems.
1300 my $order = retrieve_simple(id => 2);