can't set $p without $cgi
[freeside.git] / sql-ledger / old / sql-ledger / SL / OE.pm
1 #=====================================================================
2 # SQL-Ledger Accounting
3 # Copyright (C) 2001
4 #
5 #  Author: Dieter Simader
6 #   Email: dsimader@sql-ledger.org
7 #     Web: http://www.sql-ledger.org
8 #
9 #  Contributors:
10 #
11 # This program is free software; you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; either version 2 of the License, or
14 # (at your option) any later version.
15 #
16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 # GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with this program; if not, write to the Free Software
22 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #======================================================================
24 #
25 # Order entry module
26 #
27 #======================================================================
28
29 package OE;
30
31
32 sub transactions {
33   my ($self, $myconfig, $form) = @_;
34
35   # connect to database
36   my $dbh = $form->dbconnect($myconfig);
37  
38   my $query;
39
40   my $rate = ($form->{vc} eq 'customer') ? 'buy' : 'sell';
41   
42   my $query = qq|SELECT o.id, o.ordnumber, o.transdate, o.reqdate,
43                  o.amount, ct.name, o.netamount, o.$form->{vc}_id,
44                  (SELECT $rate FROM exchangerate ex
45                   WHERE ex.curr = o.curr
46                   AND ex.transdate = o.transdate) AS exchangerate,
47                  o.closed
48                  FROM oe o, $form->{vc} ct
49                  WHERE o.$form->{vc}_id = ct.id|;
50               
51   my $ordnumber = $form->like(lc $form->{ordnumber});
52   
53   if ($form->{"$form->{vc}_id"}) {
54     $query .= qq| AND o.$form->{vc}_id = $form->{"$form->{vc}_id"}|;
55   } else {
56     if ($form->{$form->{vc}}) {
57       my $name = $form->like(lc $form->{$form->{vc}});
58       $query .= " AND lower(name) LIKE '$name'";
59     }
60   }
61   unless ($form->{open} && $form->{closed}) {
62     $query .= ($form->{open}) ? " AND o.closed = '0'" : " AND o.closed = '1'";
63   }
64
65   my $sortorder = join ', ', $form->sort_columns(qw(transdate ordnumber name));
66   $sortorder = $form->{sort} unless $sortorder;
67   
68   $query .= " AND lower(ordnumber) LIKE '$ordnumber'" if $form->{ordnumber};
69   $query .= " AND transdate >= '$form->{transdatefrom}'" if $form->{transdatefrom};
70   $query .= " AND transdate <= '$form->{transdateto}'" if $form->{transdateto};
71   $query .= " ORDER by $sortorder";
72
73   my $sth = $dbh->prepare($query);
74   $sth->execute || $form->dberror($query);
75
76   while (my $oe = $sth->fetchrow_hashref(NAME_lc)) {
77     $oe->{exchangerate} = 1 unless $oe->{exchangerate};
78     push @{ $form->{OE} }, $oe;
79   }
80
81   $sth->finish;
82   $dbh->disconnect;
83   
84 }
85
86
87 sub save_order {
88   my ($self, $myconfig, $form) = @_;
89   
90   # connect to database, turn off autocommit
91   my $dbh = $form->dbconnect_noauto($myconfig);
92
93   my ($query, $sth);
94   my $exchangerate = 0;
95
96   if ($form->{id}) {
97
98     $query = qq|DELETE FROM orderitems
99                 WHERE trans_id = $form->{id}|;
100     $dbh->do($query) || $form->dberror($query);
101
102     $query = qq|DELETE FROM shipto
103                 WHERE trans_id = $form->{id}|;
104     $dbh->do($query) || $form->dberror($query);
105
106   } else {
107     my $uid = time;
108     $uid .= $form->{login};
109     
110     $query = qq|INSERT INTO oe (ordnumber, employee_id)
111                 VALUES ('$uid', (SELECT id FROM employee
112                                  WHERE login = '$form->{login}') )|;
113     $dbh->do($query) || $form->dberror($query);
114    
115     $query = qq|SELECT id FROM oe
116                 WHERE ordnumber = '$uid'|;
117     $sth = $dbh->prepare($query);
118     $sth->execute || $form->dberror($query);
119
120     ($form->{id}) = $sth->fetchrow_array;
121     $sth->finish;
122   }
123
124   map { $form->{$_} =~ s/'/''/g } qw(ordnumber shippingpoint notes message);
125   
126   my ($amount, $linetotal, $discount, $project_id, $reqdate);
127   my ($taxrate, $taxamount, $fxsellprice);
128   my %taxbase = ();
129   my %taxaccounts = ();
130   my ($netamount, $tax) = (0, 0);
131
132   for my $i (1 .. $form->{rowcount}) {
133     
134     $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
135     
136     if ($form->{"qty_$i"} != 0) {
137       
138       map { $form->{"${_}_$i"} =~ s/'/''/g } qw(partnumber description unit);
139       
140       # set values to 0 if nothing entered
141       $form->{"discount_$i"} = $form->parse_amount($myconfig, $form->{"discount_$i"}) / 100;
142
143       $form->{"sellprice_$i"} = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
144       $fxsellprice = $form->{"sellprice_$i"};
145
146       my ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
147       $dec = length $dec;
148       my $decimalplaces = ($dec > 2) ? $dec : 2;
149       
150       $discount = $form->round_amount($form->{"sellprice_$i"} * $form->{"discount_$i"}, $decimalplaces);
151       $form->{"sellprice_$i"} = $form->round_amount($form->{"sellprice_$i"} - $discount, $decimalplaces);
152       
153       $linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2);
154       $taxrate = 0;
155       map { $taxrate += $form->{"${_}_rate"} } split / /, $form->{"taxaccounts_$i"};
156
157       if ($form->{taxincluded}) {
158         $taxamount = $linetotal * $taxrate / (1 + $taxrate);
159         $taxbase = $linetotal - $taxamount;
160         # we are not keeping a natural price, do not round
161         $form->{"sellprice_$i"} = $form->{"sellprice_$i"} * (1 / (1 + $taxrate));
162       } else {
163         $taxamount = $linetotal * $taxrate;
164         $taxbase = $linetotal;
165       }
166
167       if ($taxamount != 0) {
168         foreach my $item (split / /, $form->{"taxaccounts_$i"}) {
169           $taxaccounts{$item} += $taxamount * $form->{"${item}_rate"} / $taxrate;
170           $taxbase{$item} += $taxbase;
171         }
172       }
173       
174       $netamount += $form->{"sellprice_$i"} * $form->{"qty_$i"};
175       
176       $project_id = 'NULL';
177       if ($form->{"project_id_$i"}) {
178         $project_id = $form->{"project_id_$i"};
179       }
180       $reqdate = ($form->{"reqdate_$i"}) ? qq|'$form->{"reqdate_$i"}'| : "NULL";
181       
182       # save detail record in orderitems table
183       $query = qq|INSERT INTO orderitems
184                  (trans_id, parts_id, description, qty, sellprice, discount,
185                   unit, reqdate, project_id) VALUES (
186                   $form->{id}, $form->{"id_$i"}, '$form->{"description_$i"}',
187                   $form->{"qty_$i"}, $fxsellprice, $form->{"discount_$i"},
188                   '$form->{"unit_$i"}', $reqdate, $project_id)|;
189       $dbh->do($query) || $form->dberror($query);
190
191       $form->{"sellprice_$i"} = $fxsellprice;
192       $form->{"discount_$i"} *= 100;
193     }
194   }
195
196
197   # set values which could be empty
198   map { $form->{$_} *= 1 } qw(vendor_id customer_id taxincluded closed);
199
200   $reqdate = ($form->{reqdate}) ? qq|'$form->{reqdate}'| : "NULL";
201   
202   # add up the tax
203   foreach my $item (sort keys %taxaccounts) {
204     $taxamount = $form->round_amount($taxaccounts{$item}, 2);
205     $tax += $taxamount;
206   }
207   
208   $amount = $form->round_amount($netamount + $tax, 2);
209   $netamount = $form->round_amount($netamount, 2);
210
211   if ($form->{currency} eq $form->{defaultcurrency}) {
212     $form->{exchangerate} = 1;
213   } else {
214     $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{transdate}, ($form->{vc} eq 'customer') ? 'buy' : 'sell');
215   }
216   
217   $form->{exchangerate} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{exchangerate});
218   
219   # fill in subject if there is none
220   $form->{subject} = qq|$form->{label} $form->{ordnumber}| unless $form->{subject};
221   # if there is a message stuff it into the notes
222   my $cc = "Cc: $form->{cc}\\r\n" if $form->{cc};
223   my $bcc = "Bcc: $form->{bcc}\\r\n" if $form->{bcc};
224   $form->{notes} .= qq|\r
225 \r
226 [email]\r
227 To: $form->{email}\r
228 $cc${bcc}Subject: $form->{subject}\r
229 \r
230 Message: $form->{message}\r| if $form->{message};
231   
232   # save OE record
233   $query = qq|UPDATE oe set
234               ordnumber = '$form->{ordnumber}',
235               transdate = '$form->{orddate}',
236               vendor_id = $form->{vendor_id},
237               customer_id = $form->{customer_id},
238               amount = $amount,
239               netamount = $netamount,
240               reqdate = $reqdate,
241               taxincluded = '$form->{taxincluded}',
242               shippingpoint = '$form->{shippingpoint}',
243               notes = '$form->{notes}',
244               curr = '$form->{currency}',
245               closed = '$form->{closed}'
246               WHERE id = $form->{id}|;
247   $dbh->do($query) || $form->dberror($query);
248
249   $form->{ordtotal} = $amount;
250
251   # add shipto
252   $form->{name} = $form->{$form->{vc}};
253   $form->{name} =~ s/--$form->{"$form->{vc}_id"}//;
254   $form->add_shipto($dbh, $form->{id});
255   
256   if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
257     if ($form->{vc} eq 'customer') {
258       $form->update_exchangerate($dbh, $form->{currency}, $form->{orddate}, $form->{exchangerate}, 0);
259     }
260     if ($form->{vc} eq 'vendor') {
261       $form->update_exchangerate($dbh, $form->{currency}, $form->{orddate}, 0, $form->{exchangerate});
262     }
263   }
264   
265   my $rc = $dbh->commit;
266   $dbh->disconnect;
267
268   $rc;
269   
270 }
271
272
273
274 sub delete_order {
275   my ($self, $myconfig, $form) = @_;
276
277   # connect to database
278   my $dbh = $form->dbconnect_noauto($myconfig);
279
280   my $query;
281
282   # can't use $form->delete_exchangerate
283   if ($form->{currency} ne $form->{defaultcurrency}) {
284        $query = qq|SELECT transdate FROM acc_trans
285                    WHERE ar.id = trans_id
286                    AND ar.curr = '$form->{currency}'
287                    AND transdate = '$form->{orddate}'
288            UNION SELECT transdate FROM acc_trans
289                    WHERE ap.id = trans_id
290                    AND ap.curr = '$form->{currency}'
291                    AND transdate = '$form->{orddate}'|;
292     my $sth = $dbh->prepare($query);
293     $sth->execute || $form->dberror($query);
294     
295     my ($transdate) = $sth->fetchrow_array;
296     $sth->finish;
297
298     if (!$transdate) {
299       $query = qq|DELETE FROM exchangerate
300                   WHERE curr = '$form->{currency}'
301                   AND transdate = '$form->{orddate}'|;
302       $dbh->do($query) || $self->dberror($query);
303     }
304   }
305               
306   
307   # delete OE record
308   $query = qq|DELETE FROM oe
309               WHERE id = $form->{id}|;
310   $dbh->do($query) || $form->dberror($query);
311
312   # delete individual entries
313   $query = qq|DELETE FROM orderitems
314               WHERE trans_id = $form->{id}|;
315   $dbh->do($query) || $form->dberror($query);
316
317   $query = qq|DELETE FROM shipto
318               WHERE trans_id = $form->{id}|;
319   $dbh->do($query) || $form->dberror($query);
320   
321   my $rc = $dbh->commit;
322   $dbh->disconnect;
323
324   $rc;
325   
326 }
327
328
329
330 sub retrieve_order {
331   my ($self, $myconfig, $form) = @_;
332   
333   # connect to database
334   my $dbh = $form->dbconnect_noauto($myconfig);
335
336   my $query;
337
338   if ($form->{id}) {
339     # get default accounts and last order number
340     $query = qq|SELECT (SELECT c.accno FROM chart c
341                         WHERE d.inventory_accno_id = c.id) AS inventory_accno,
342                        (SELECT c.accno FROM chart c
343                         WHERE d.income_accno_id = c.id) AS income_accno,
344                        (SELECT c.accno FROM chart c
345                         WHERE d.expense_accno_id = c.id) AS expense_accno,
346                        (SELECT c.accno FROM chart c
347                         WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
348                        (SELECT c.accno FROM chart c
349                         WHERE d.fxloss_accno_id = c.id) AS fxloss_accno,
350                 d.curr AS currencies
351                 FROM defaults d|;
352   } else {
353     my $ordnumber = ($form->{vc} eq 'customer') ? 'sonumber' : 'ponumber';
354     $query = qq|SELECT (SELECT c.accno FROM chart c
355                         WHERE d.inventory_accno_id = c.id) AS inventory_accno,
356                        (SELECT c.accno FROM chart c
357                         WHERE d.income_accno_id = c.id) AS income_accno,
358                        (SELECT c.accno FROM chart c
359                         WHERE d.expense_accno_id = c.id) AS expense_accno,
360                        (SELECT c.accno FROM chart c
361                         WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
362                        (SELECT c.accno FROM chart c
363                         WHERE d.fxloss_accno_id = c.id) AS fxloss_accno,
364                 $ordnumber AS ordnumber, d.curr AS currencies,
365                 current_date AS orddate, current_date AS reqdate
366                 FROM defaults d|;
367   }
368   my $sth = $dbh->prepare($query);
369   $sth->execute || $form->dberror($query);
370
371   my $ref = $sth->fetchrow_hashref(NAME_lc);
372   map { $form->{$_} = $ref->{$_} } keys %$ref;
373   $sth->finish;
374
375   ($form->{currency}) = split /:/, $form->{currencies};
376   
377   if ($form->{id}) {
378     
379     # retrieve order
380     $query = qq|SELECT o.ordnumber, o.transdate AS orddate, o.reqdate,
381                 o.taxincluded, o.shippingpoint, o.notes, o.curr AS currency,
382                 (SELECT name FROM employee e
383                  WHERE e.id = o.employee_id) AS employee,
384                 o.$form->{vc}_id, cv.name AS $form->{vc}, o.amount AS invtotal,
385                 o.closed, o.reqdate
386                 FROM oe o, $form->{vc} cv
387                 WHERE o.$form->{vc}_id = cv.id
388                 AND o.id = $form->{id}|;
389     $sth = $dbh->prepare($query);
390     $sth->execute || $form->dberror($query);
391
392     $ref = $sth->fetchrow_hashref(NAME_lc);
393     map { $form->{$_} = $ref->{$_} } keys %$ref;
394     $sth->finish;
395     
396    
397     $query = qq|SELECT * FROM shipto
398                 WHERE trans_id = $form->{id}|;
399     $sth = $dbh->prepare($query);
400     $sth->execute || $form->dberror($query);
401
402     $ref = $sth->fetchrow_hashref(NAME_lc);
403     map { $form->{$_} = $ref->{$_} } keys %$ref;
404     $sth->finish;
405     
406     my %oid = ( 'Pg'            => 'oid',
407                 'Oracle'        => 'rowid',
408                 'DB2'           => '' );
409
410     # retrieve individual items
411     $query = qq|SELECT c1.accno AS inventory_accno,
412                        c2.accno AS income_accno,
413                        c3.accno AS expense_accno,
414                 p.partnumber, p.assembly, o.description, o.qty,
415                 o.sellprice, o.parts_id AS id, o.unit, o.discount, p.bin,
416                 o.reqdate, o.project_id,
417                 pr.projectnumber,
418                 pg.partsgroup
419                 FROM orderitems o
420                 JOIN parts p ON (o.parts_id = p.id)
421                 LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id)
422                 LEFT JOIN chart c2 ON (p.income_accno_id = c2.id)
423                 LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id)
424                 LEFT JOIN project pr ON (o.project_id = pr.id)
425                 LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
426                 WHERE trans_id = $form->{id}
427                 ORDER BY o.$oid{$myconfig->{dbdriver}}|;
428     $sth = $dbh->prepare($query);
429     $sth->execute || $form->dberror($query);
430
431     while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
432
433       # get tax rates for part
434       $query = qq|SELECT c.accno
435                   FROM chart c, partstax pt
436                   WHERE pt.chart_id = c.id
437                   AND pt.parts_id = $ref->{id}|;
438       my $pth = $dbh->prepare($query);
439       $pth->execute || $form->dberror($query);
440
441       $ref->{taxaccounts} = "";
442       my $taxrate = 0;
443       
444       while (my $ptref = $pth->fetchrow_hashref(NAME_lc)) {
445         $ref->{taxaccounts} .= "$ptref->{accno} ";
446         $taxrate += $form->{"$ptref->{accno}_rate"};
447       }
448       $pth->finish;
449       chop $ref->{taxaccounts};
450
451       push @{ $form->{order_details} }, $ref;
452       
453     }
454     $sth->finish;
455
456   } else {
457
458     my $ordnumber = ($form->{vc} eq 'customer') ? 'sonumber' : 'ponumber';
459     # up order number by 1
460     $form->{ordnumber}++;
461
462     # save the new number
463     $query = qq|UPDATE defaults
464                 SET $ordnumber = '$form->{ordnumber}'|;
465     $dbh->do($query) || $form->dberror($query);
466
467     $form->get_employee($dbh);
468     
469     # get last name used
470     $form->lastname_used($dbh, $myconfig, $form->{vc}) unless $form->{"$form->{vc}_id"};
471
472   }
473   
474   $form->{exchangerate} = $form->get_exchangerate($dbh, $form->{currency}, $form->{orddate}, ($form->{vc} eq 'customer') ? "buy" : "sell");
475   
476   my $rc = $dbh->commit;
477   $dbh->disconnect;
478
479   $rc;
480   
481 }
482
483
484
485 sub order_details {
486   my ($self, $myconfig, $form) = @_;
487
488   # connect to database
489   my $dbh = $form->dbconnect($myconfig);
490     
491   my $tax = 0;
492   my $item;
493   my $i;
494   my @partsgroup = ();
495   my $partsgroup;
496   my %oid = ( 'Pg' => 'oid',
497               'Oracle' => 'rowid' );
498
499   # sort items by partsgroup
500   for $i (1 .. $form->{rowcount}) {
501     $partsgroup = "";
502     if ($form->{"partsgroup_$i"} && $form->{groupitems}) {
503       $form->format_string("partsgroup_$i");
504       $partsgroup = $form->{"partsgroup_$i"};
505     }
506     push @partsgroup, [ $i, $partsgroup ];
507   }
508   
509   my $sameitem = "";
510   foreach $item (sort { $a->[1] cmp $b->[1] } @partsgroup) {
511     $i = $item->[0];
512
513     if ($item->[1] ne $sameitem) {
514       push(@{ $form->{description} }, qq|$item->[1]|);
515       $sameitem = $item->[1];
516
517       map { push(@{ $form->{$_} }, "") } qw(runningnumber number bin qty unit reqdate sellprice listprice netprice discount linetotal);
518     }
519
520     $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
521     
522     if ($form->{"qty_$i"} != 0) {
523
524       # add number, description and qty to $form->{number}, ....
525       push(@{ $form->{runningnumber} }, $i);
526       push(@{ $form->{number} }, qq|$form->{"partnumber_$i"}|);
527       push(@{ $form->{description} }, qq|$form->{"description_$i"}|);
528       push(@{ $form->{qty} }, $form->format_amount($myconfig, $form->{"qty_$i"}));
529       push(@{ $form->{unit} }, qq|$form->{"unit_$i"}|);
530       push(@{ $form->{reqdate} }, qq|$form->{"reqdate_$i"}|);
531       
532       push(@{ $form->{sellprice} }, $form->{"sellprice_$i"});
533       
534       push(@{ $form->{listprice} }, $form->{"listprice_$i"});
535       
536       my $sellprice = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
537       my ($dec) = ($sellprice =~ /\.(\d+)/);
538       $dec = length $dec;
539       my $decimalplaces = ($dec > 2) ? $dec : 2;
540
541       my $discount = $form->round_amount($sellprice * $form->parse_amount($myconfig, $form->{"discount_$i"}) / 100, $decimalplaces);
542
543       # keep a netprice as well, (sellprice - discount)
544       $form->{"netprice_$i"} = $sellprice - $discount;
545
546       my $linetotal = $form->round_amount($form->{"qty_$i"} * $form->{"netprice_$i"}, 2);
547
548       push(@{ $form->{netprice} }, ($form->{"netprice_$i"} != 0) ? $form->format_amount($myconfig, $form->{"netprice_$i"}, $decimalplaces) : " ");
549       
550       $discount = ($discount != 0) ? $form->format_amount($myconfig, $discount * -1, $decimalplaces) : " ";
551       $linetotal = ($linetotal != 0) ? $linetotal : " ";
552
553       push(@{ $form->{discount} }, $discount);
554       
555       $form->{ordtotal} += $linetotal;
556
557       push(@{ $form->{linetotal} }, $form->format_amount($myconfig, $linetotal, 2));
558       
559       my ($taxamount, $taxbase);
560       my $taxrate = 0;
561       
562       map { $taxrate += $form->{"${_}_rate"} } split / /, $form->{"taxaccounts_$i"};
563
564       if ($form->{taxincluded}) {
565         # calculate tax
566         $taxamount = $linetotal * $taxrate / (1 + $taxrate);
567         $taxbase = $linetotal / (1 + $taxrate);
568       } else {
569         $taxamount = $linetotal * $taxrate;
570         $taxbase = $linetotal;
571       }
572
573
574       if ($taxamount != 0) {
575         foreach my $item (split / /, $form->{"taxaccounts_$i"}) {
576           $taxaccounts{$item} += $taxamount * $form->{"${item}_rate"} / $taxrate;
577           $taxbase{$item} += $taxbase;
578         }
579       }
580
581       if ($form->{"assembly_$i"}) {
582         $sameitem = "";
583         
584         # get parts and push them onto the stack
585         my $sortorder = "";
586         if ($form->{groupitems}) {
587           $sortorder = qq|ORDER BY pg.partsgroup, a.$oid{$myconfig->{dbdriver}}|;
588         } else {
589           $sortorder = qq|ORDER BY a.$oid{$myconfig->{dbdriver}}|;
590         }
591         
592         $query = qq|SELECT p.partnumber, p.description, p.unit, a.qty,
593                     pg.partsgroup
594                     FROM assembly a
595                     JOIN parts p ON (a.parts_id = p.id)
596                     LEFT JOIN partsgroup pg ON (p.partsgroup_id = pg.id)
597                     WHERE a.bom = '1'
598                     AND a.id = '$form->{"id_$i"}'
599                     $sortorder|;
600         $sth = $dbh->prepare($query);
601         $sth->execute || $form->dberror($query);
602
603         while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
604           if ($form->{groupitems} && $ref->{partsgroup} ne $sameitem) {
605             map { push(@{ $form->{$_} }, "") } qw(runningnumber number unit bin qty sellprice listprice netprice discount linetotal);
606             $sameitem = ($ref->{partsgroup}) ? $ref->{partsgroup} : "--";
607             push(@{ $form->{description} }, $sameitem);
608           }
609             
610           push(@{ $form->{number} }, qq|$ref->{partnumber}|);
611           push(@{ $form->{description} }, qq|$ref->{description}|);
612           push(@{ $form->{unit} }, qq|$ref->{unit}|);
613           push(@{ $form->{qty} }, $form->format_amount($myconfig, $ref->{qty} * $form->{"qty_$i"}));
614
615           map { push(@{ $form->{$_} }, "") } qw(runningnumber bin sellprice listprice netprice discount linetotal);
616           
617         }
618         $sth->finish;
619       }
620
621     }
622   }
623
624
625   foreach $item (sort keys %taxaccounts) {
626     if ($form->round_amount($taxaccounts{$item}, 2) != 0) {
627       push(@{ $form->{taxbase} }, $form->format_amount($myconfig, $taxbase{$item}, 2));
628       
629       $taxamount = $form->round_amount($taxaccounts{$item}, 2);
630       $tax += $taxamount;
631       
632       push(@{ $form->{tax} }, $form->format_amount($myconfig, $taxamount, 2));
633       push(@{ $form->{taxdescription} }, $form->{"${item}_description"});
634       push(@{ $form->{taxrate} }, $form->format_amount($myconfig, $form->{"${item}_rate"} * 100));
635       push(@{ $form->{taxnumber} }, $form->{"${item}_taxnumber"});
636     }
637   }
638
639
640   $form->{subtotal} = $form->format_amount($myconfig, $form->{ordtotal}, 2);
641   $form->{ordtotal} = ($form->{taxincluded}) ? $form->{ordtotal} : $form->{ordtotal} + $tax;
642   
643   # format amounts
644   $form->{ordtotal} = $form->format_amount($myconfig, $form->{ordtotal}, 2);
645
646   # myconfig variables
647   map { $form->{$_} = $myconfig->{$_} } (qw(company address tel fax signature businessnumber));
648   $form->{username} = $myconfig->{name};
649
650   $dbh->disconnect;
651
652 }
653
654
655 sub project_description {
656   my ($self, $dbh, $id) = @_;
657
658   my $query = qq|SELECT description
659                  FROM project
660                  WHERE id = $id|;
661   my $sth = $dbh->prepare($query);
662   $sth->execute || $form->dberror($query);
663
664   ($_) = $sth->fetchrow_array;
665   
666   $sth->finish;
667
668   $_;
669
670 }
671
672
673 1;
674