1 #=====================================================================
4 # Based on SQL-Ledger Version 2.1.9
5 # Web http://www.lx-office.org
7 #=====================================================================
8 # SQL-Ledger Accounting
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 #======================================================================
31 # Inventory received module
33 #======================================================================
39 $main::lxdebug->enter_sub();
41 my ($self, $myconfig, $form) = @_;
43 # connect to database, turn off autocommit
44 my $dbh = $form->dbconnect_noauto($myconfig);
46 my ($query, $sth, $null, $project_id);
56 &reverse_invoice($dbh, $form);
59 my $uid = rand().time;
61 $uid .= $form->{login};
63 $uid = substr($uid,2,75);
65 $query = qq|INSERT INTO ap (invnumber, employee_id)
66 VALUES ('$uid', (SELECT e.id FROM employee e
67 WHERE e.login = '$form->{login}'))|;
68 $dbh->do($query) || $form->dberror($query);
70 $query = qq|SELECT a.id FROM ap a
71 WHERE a.invnumber = '$uid'|;
72 $sth = $dbh->prepare($query);
73 $sth->execute || $form->dberror($query);
75 ($form->{id}) = $sth->fetchrow_array;
79 ($null, $form->{contact_id}) = split /--/, $form->{contact};
80 $form->{contact_id} *= 1;
82 map { $form->{$_} =~ s/\'/\'\'/g } qw(invnumber ordnumber quonumber);
84 my ($amount, $linetotal, $lastinventoryaccno, $lastexpenseaccno);
85 my ($netamount, $invoicediff, $expensediff) = (0, 0, 0);
87 if ($form->{currency} eq $form->{defaultcurrency}) {
88 $form->{exchangerate} = 1;
90 $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{transdate}, 'sell');
93 $form->{exchangerate} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{exchangerate});
96 for my $i (1 .. $form->{rowcount}) {
97 $form->{"qty_$i"} = $form->parse_amount($myconfig, $form->{"qty_$i"});
99 if ($form->{"qty_$i"} != 0) {
101 map { $form->{"${_}_$i"} =~ s/\'/\'\'/g } qw(partnumber description unit);
103 @taxaccounts = split / /, $form->{"taxaccounts_$i"};
108 $form->{"sellprice_$i"} = $form->parse_amount($myconfig, $form->{"sellprice_$i"});
109 my $fxsellprice = $form->{"sellprice_$i"};
111 my ($dec) = ($fxsellprice =~ /\.(\d+)/);
113 my $decimalplaces = ($dec > 2) ? $dec : 2;
116 map { $taxrate += $form->{"${_}_rate"} } @taxaccounts;
118 if ($form->{"inventory_accno_$i"}) {
120 $linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2);
122 if ($form->{taxincluded}) {
123 $taxamount = $linetotal * ($taxrate / (1 + $taxrate));
124 $form->{"sellprice_$i"} = $form->{"sellprice_$i"} * (1 / (1 + $taxrate));
126 $taxamount = $linetotal * $taxrate;
129 $netamount += $linetotal;
131 if ($form->round_amount($taxrate, 7) == 0) {
132 if ($form->{taxincluded}) {
133 foreach $item (@taxaccounts) {
134 $taxamount = $form->round_amount($linetotal * $form->{"${item}_rate"} / (1 + abs($form->{"${item}_rate"})), 2);
135 $taxdiff += $taxamount;
136 $form->{amount}{$form->{id}}{$item} -= $taxamount;
138 $form->{amount}{$form->{id}}{$taxaccounts[0]} += $taxdiff;
140 map { $form->{amount}{$form->{id}}{$_} -= $linetotal * $form->{"${_}_rate"} } @taxaccounts;
143 map { $form->{amount}{$form->{id}}{$_} -= $taxamount * $form->{"${_}_rate"} / $taxrate } @taxaccounts;
147 # add purchase to inventory, this one is without the tax!
148 $amount = $form->{"sellprice_$i"} * $form->{"qty_$i"} * $form->{exchangerate};
149 $linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2) * $form->{exchangerate};
150 $linetotal = $form->round_amount($linetotal, 2);
152 # this is the difference for the inventory
153 $invoicediff += ($amount - $linetotal);
155 $form->{amount}{$form->{id}}{$form->{"inventory_accno_$i"}} -= $linetotal;
157 # adjust and round sellprice
158 $form->{"sellprice_$i"} = $form->round_amount($form->{"sellprice_$i"} * $form->{exchangerate}, $decimalplaces);
162 $query = qq|UPDATE parts SET
163 lastcost = $form->{"sellprice_$i"}
164 WHERE id = $form->{"id_$i"}|;
166 $dbh->do($query) || $form->dberror($query);
168 $form->update_balance($dbh,
171 qq|id = $form->{"id_$i"}|,
172 $form->{"qty_$i"}) unless $form->{shipped};
175 # check if we sold the item already and
176 # make an entry for the expense and inventory
177 $query = qq|SELECT i.id, i.qty, i.allocated, i.trans_id,
178 p.inventory_accno_id, p.expense_accno_id, a.transdate
179 FROM invoice i, ar a, parts p
180 WHERE i.parts_id = p.id
181 AND i.parts_id = $form->{"id_$i"}
182 AND (i.qty + i.allocated) > 0
183 AND i.trans_id = a.id
185 $sth = $dbh->prepare($query);
186 $sth->execute || $form->dberror($query);
189 my $totalqty = $form->{"qty_$i"};
191 while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
193 my $qty = $ref->{qty} + $ref->{allocated};
195 if (($qty - $totalqty) > 0) {
200 $linetotal = $form->round_amount($form->{"sellprice_$i"} * $qty, 2);
202 if ($ref->{allocated} < 0) {
203 # we have an entry for it already, adjust amount
204 $form->update_balance($dbh,
207 qq|trans_id = $ref->{trans_id} AND chart_id = $ref->{inventory_accno_id} AND transdate = '$ref->{transdate}'|,
210 $form->update_balance($dbh,
213 qq|trans_id = $ref->{trans_id} AND chart_id = $ref->{expense_accno_id} AND transdate = '$ref->{transdate}'|,
217 # add entry for inventory, this one is for the sold item
218 if ($linetotal != 0) {
219 $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
221 VALUES ($ref->{trans_id}, $ref->{inventory_accno_id},
222 $linetotal, '$ref->{transdate}')|;
223 $dbh->do($query) || $form->dberror($query);
226 $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
228 VALUES ($ref->{trans_id}, $ref->{expense_accno_id},
229 |. ($linetotal * -1) .qq|, '$ref->{transdate}',
230 (SELECT taxkey from tax WHERE chart_id = $ref->{expense_accno_id}))|;
231 $dbh->do($query) || $form->dberror($query);
235 # update allocated for sold item
236 $form->update_balance($dbh,
244 last if (($totalqty -= $qty) <= 0);
249 $lastinventoryaccno = $form->{"inventory_accno_$i"};
253 $linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2);
255 if ($form->{taxincluded}) {
256 $taxamount = $linetotal * ($taxrate / (1 + $taxrate));
258 $form->{"sellprice_$i"} = $form->{"sellprice_$i"} * (1 / (1 + $taxrate));
260 $taxamount = $linetotal * $taxrate;
263 $netamount += $linetotal;
265 if ($form->round_amount($taxrate, 7) == 0) {
266 if ($form->{taxincluded}) {
267 foreach $item (@taxaccounts) {
268 $taxamount = $linetotal * $form->{"${item}_rate"} / (1 + abs($form->{"${item}_rate"}));
269 $totaltax += $taxamount;
270 $form->{amount}{$form->{id}}{$item} -= $taxamount;
273 map { $form->{amount}{$form->{id}}{$_} -= $linetotal * $form->{"${_}_rate"} } @taxaccounts;
276 map { $form->{amount}{$form->{id}}{$_} -= $taxamount * $form->{"${_}_rate"} / $taxrate } @taxaccounts;
280 $amount = $form->{"sellprice_$i"} * $form->{"qty_$i"} * $form->{exchangerate};
281 $linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2) * $form->{exchangerate};
282 $linetotal = $form->round_amount($linetotal, 2);
284 # this is the difference for expense
285 $expensediff += ($amount - $linetotal);
287 # add amount to expense
288 $form->{amount}{$form->{id}}{$form->{"expense_accno_$i"}} -= $linetotal;
290 $lastexpenseaccno = $form->{"expense_accno_$i"};
292 # adjust and round sellprice
293 $form->{"sellprice_$i"} = $form->round_amount($form->{"sellprice_$i"} * $form->{exchangerate}, $decimalplaces);
296 $query = qq|UPDATE parts SET
297 lastcost = $form->{"sellprice_$i"}
298 WHERE id = $form->{"id_$i"}|;
300 $dbh->do($query) || $form->dberror($query);
304 $project_id = 'NULL';
305 if ($form->{"projectnumber_$i"}) {
306 $project_id = $form->{"projectnumber_$i"};
308 print (STDERR $project_id, " Project_id\n");
309 $deliverydate = ($form->{"deliverydate_$i"}) ? qq|'$form->{"deliverydate_$i"}'| : "NULL";
311 # save detail record in invoice table
312 $query = qq|INSERT INTO invoice (trans_id, parts_id, description, qty,
313 sellprice, fxsellprice, allocated, unit, deliverydate,
314 project_id, serialnumber)
315 VALUES ($form->{id}, $form->{"id_$i"},
316 '$form->{"description_$i"}', |. ($form->{"qty_$i"} * -1) .qq|,
317 $form->{"sellprice_$i"}, $fxsellprice, $allocated,
318 '$form->{"unit_$i"}', $deliverydate, (SELECT id FROM project WHERE projectnumber = '$project_id'),
319 '$form->{"serialnumber_$i"}')|;
320 $dbh->do($query) || $form->dberror($query);
321 print (STDERR $query,"\n\n");
326 $form->{datepaid} = $form->{invdate};
328 # all amounts are in natural state, netamount includes the taxes
329 # if tax is included, netamount is rounded to 2 decimal places,
333 for my $i (1 .. $form->{paidaccounts}) {
334 $form->{"paid_$i"} = $form->parse_amount($myconfig, $form->{"paid_$i"});
335 $form->{paid} += $form->{"paid_$i"};
336 $form->{datepaid} = $form->{"datepaid_$i"} if ($form->{"datepaid_$i"});
339 my ($tax, $paiddiff) = (0, 0);
341 $netamount = $form->round_amount($netamount, 2);
343 # figure out rounding errors for amount paid and total amount
344 if ($form->{taxincluded}) {
346 $amount = $form->round_amount($netamount * $form->{exchangerate}, 2);
347 $paiddiff = $amount - $netamount * $form->{exchangerate};
348 $netamount = $amount;
350 foreach $item (split / /, $form->{taxaccounts}) {
351 $amount = $form->{amount}{$form->{id}}{$item} * $form->{exchangerate};
352 $form->{amount}{$form->{id}}{$item} = $form->round_amount($amount, 2);
353 $amount = $form->{amount}{$form->{id}}{$item} * -1;
355 $netamount -= $amount;
358 $invoicediff += $paiddiff;
359 $expensediff += $paiddiff;
361 ######## this only applies to tax included
362 if ($lastinventoryaccno) {
363 $form->{amount}{$form->{id}}{$lastinventoryaccno} -= $invoicediff;
365 if ($lastexpenseaccno) {
366 $form->{amount}{$form->{id}}{$lastexpenseaccno} -= $expensediff;
370 $amount = $form->round_amount($netamount * $form->{exchangerate}, 2);
371 $paiddiff = $amount - $netamount * $form->{exchangerate};
372 $netamount = $amount;
373 foreach my $item (split / /, $form->{taxaccounts}) {
374 $form->{amount}{$form->{id}}{$item} = $form->round_amount($form->{amount}{$form->{id}}{$item}, 2);
375 $amount = $form->round_amount($form->{amount}{$form->{id}}{$item} * $form->{exchangerate} * -1, 2);
376 $paiddiff += $amount - $form->{amount}{$form->{id}}{$item} * $form->{exchangerate} * -1;
377 $form->{amount}{$form->{id}}{$item} = $form->round_amount($amount * -1, 2);
378 $amount = $form->{amount}{$form->{id}}{$item} * -1;
384 $form->{amount}{$form->{id}}{$form->{AP}} = $netamount + $tax;
386 if ($form->{paid} != 0) {
387 $form->{paid} = $form->round_amount($form->{paid} * $form->{exchangerate} + $paiddiff, 2);
391 # update exchangerate
392 if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
393 $form->update_exchangerate($dbh, $form->{currency}, $form->{invdate}, 0, $form->{exchangerate});
396 # record acc_trans transactions
397 foreach my $trans_id (keys %{$form->{amount}}) {
398 foreach my $accno (keys %{ $form->{amount}{$trans_id} }) {
399 if (($form->{amount}{$trans_id}{$accno} = $form->round_amount($form->{amount}{$trans_id}{$accno}, 2)) != 0) {
400 $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
402 VALUES ($trans_id, (SELECT c.id FROM chart c
403 WHERE c.accno = '$accno'),
404 $form->{amount}{$trans_id}{$accno}, '$form->{invdate}',
405 (SELECT taxkey_id FROM chart WHERE accno = '$accno'))|;
406 $dbh->do($query) || $form->dberror($query);
411 # deduct payment differences from paiddiff
412 for my $i (1 .. $form->{paidaccounts}) {
413 if ($form->{"paid_$i"} != 0) {
414 $amount = $form->round_amount($form->{"paid_$i"} * $form->{exchangerate}, 2);
415 $paiddiff -= $amount - $form->{"paid_$i"} * $form->{exchangerate};
419 # force AP entry if 0
420 $form->{amount}{$form->{id}}{$form->{AP}} = $form->{paid} if ($form->{amount}{$form->{id}}{$form->{AP}} == 0);
422 # record payments and offsetting AP
423 for my $i (1 .. $form->{paidaccounts}) {
425 if ($form->{"paid_$i"} != 0) {
426 my ($accno) = split /--/, $form->{"AP_paid_$i"};
427 $form->{"datepaid_$i"} = $form->{invdate} unless ($form->{"datepaid_$i"});
428 $form->{datepaid} = $form->{"datepaid_$i"};
430 $amount = ($form->round_amount($form->{"paid_$i"} * $form->{exchangerate} + $paiddiff, 2)) * -1;
434 if ($form->{amount}{$form->{id}}{$form->{AP}} != 0) {
435 $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
437 VALUES ($form->{id}, (SELECT c.id FROM chart c
438 WHERE c.accno = '$form->{AP}'),
439 $amount, '$form->{"datepaid_$i"}')|;
440 $dbh->do($query) || $form->dberror($query);
445 $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount, transdate,
447 VALUES ($form->{id}, (SELECT c.id FROM chart c
448 WHERE c.accno = '$accno'),
449 $form->{"paid_$i"}, '$form->{"datepaid_$i"}',
450 '$form->{"source_$i"}', '$form->{"memo_$i"}')|;
451 $dbh->do($query) || $form->dberror($query);
456 if ($form->{currency} eq $form->{defaultcurrency}) {
457 $form->{"exchangerate_$i"} = 1;
459 $exchangerate = $form->check_exchangerate($myconfig, $form->{currency}, $form->{"datepaid_$i"}, 'sell');
461 $form->{"exchangerate_$i"} = ($exchangerate) ? $exchangerate : $form->parse_amount($myconfig, $form->{"exchangerate_$i"});
465 # exchangerate difference
466 $form->{fx}{$accno}{$form->{"datepaid_$i"}} += $form->{"paid_$i"} * ($form->{"exchangerate_$i"} - 1) + $paiddiff;
470 $amount = ($form->{"paid_$i"} * $form->{exchangerate}) - ($form->{"paid_$i"} * $form->{"exchangerate_$i"});
472 $form->{fx}{$form->{fxgain_accno}}{$form->{"datepaid_$i"}} += $amount;
474 $form->{fx}{$form->{fxloss_accno}}{$form->{"datepaid_$i"}} += $amount;
479 # update exchange rate
480 if (($form->{currency} ne $form->{defaultcurrency}) && !$exchangerate) {
481 $form->update_exchangerate($dbh, $form->{currency}, $form->{"datepaid_$i"}, 0, $form->{"exchangerate_$i"});
486 # record exchange rate differences and gains/losses
487 foreach my $accno (keys %{$form->{fx}}) {
488 foreach my $transdate (keys %{ $form->{fx}{$accno} }) {
489 if (($form->{fx}{$accno}{$transdate} = $form->round_amount($form->{fx}{$accno}{$transdate}, 2)) != 0) {
491 $query = qq|INSERT INTO acc_trans (trans_id, chart_id, amount,
492 transdate, cleared, fx_transaction)
493 VALUES ($form->{id}, (SELECT c.id FROM chart c
494 WHERE c.accno = '$accno'),
495 $form->{fx}{$accno}{$transdate}, '$transdate', '0', '1')|;
496 $dbh->do($query) || $form->dberror($query);
502 $amount = $netamount + $tax;
504 # set values which could be empty
505 $form->{taxincluded} *= 1;
506 my $datepaid = ($form->{paid}) ? qq|'$form->{datepaid}'| : "NULL";
507 my $duedate = ($form->{duedate}) ? qq|'$form->{duedate}'| : "NULL";
509 ($null, $form->{department_id}) = split(/--/, $form->{department});
510 $form->{department_id} *= 1;
512 $form->{invnumber} = $form->{id} unless $form->{invnumber};
515 $query = qq|UPDATE ap set
516 invnumber = '$form->{invnumber}',
517 ordnumber = '$form->{ordnumber}',
518 quonumber = '$form->{quonumber}',
519 transdate = '$form->{invdate}',
520 vendor_id = $form->{vendor_id},
522 netamount = $netamount,
523 paid = $form->{paid},
524 datepaid = $datepaid,
527 taxincluded = '$form->{taxincluded}',
528 notes = '$form->{notes}',
529 intnotes = '$form->{intnotes}',
530 curr = '$form->{currency}',
531 department_id = $form->{department_id},
532 cp_id = $form->{contact_id}
533 WHERE id = $form->{id}|;
534 $dbh->do($query) || $form->dberror($query);
537 $form->{name} = $form->{vendor};
538 $form->{name} =~ s/--$form->{vendor_id}//;
539 $form->add_shipto($dbh, $form->{id});
541 # delete zero entries
542 $query = qq|DELETE FROM acc_trans
544 $dbh->do($query) || $form->dberror($query);
546 if ($form->{webdav}) {
547 &webdav_folder($myconfig, $form);
550 my $rc = $dbh->commit;
553 $main::lxdebug->leave_sub();
560 sub reverse_invoice {
561 $main::lxdebug->enter_sub();
563 my ($dbh, $form) = @_;
565 # reverse inventory items
566 my $query = qq|SELECT i.parts_id, p.inventory_accno_id, p.expense_accno_id,
567 i.qty, i.allocated, i.sellprice
568 FROM invoice i, parts p
569 WHERE i.parts_id = p.id
570 AND i.trans_id = $form->{id}|;
571 my $sth = $dbh->prepare($query);
572 $sth->execute || $form->dberror($query);
576 while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
577 $netamount += $form->round_amount($ref->{sellprice} * $ref->{qty} * -1, 2);
579 if ($ref->{inventory_accno_id}) {
581 $form->update_balance($dbh,
584 qq|id = $ref->{parts_id}|,
587 # if $ref->{allocated} > 0 than we sold that many items
588 if ($ref->{allocated} > 0) {
590 # get references for sold items
591 $query = qq|SELECT i.id, i.trans_id, i.allocated, a.transdate
593 WHERE i.parts_id = $ref->{parts_id}
595 AND i.trans_id = a.id
596 ORDER BY transdate DESC|;
597 my $sth = $dbh->prepare($query);
598 $sth->execute || $form->dberror($query);
600 while (my $pthref = $sth->fetchrow_hashref(NAME_lc)) {
601 my $qty = $ref->{allocated};
602 if (($ref->{allocated} + $pthref->{allocated}) > 0) {
603 $qty = $pthref->{allocated} * -1;
606 my $amount = $form->round_amount($ref->{sellprice} * $qty, 2);
609 $form->update_balance($dbh,
612 qq|id = $pthref->{id}|,
615 $form->update_balance($dbh,
618 qq|trans_id = $pthref->{trans_id} AND chart_id = $ref->{expense_accno_id} AND transdate = '$pthref->{transdate}'|,
621 $form->update_balance($dbh,
624 qq|trans_id = $pthref->{trans_id} AND chart_id = $ref->{inventory_accno_id} AND transdate = '$pthref->{transdate}'|,
627 last if (($ref->{allocated} -= $qty) <= 0);
636 $query = qq|DELETE FROM acc_trans
637 WHERE trans_id = $form->{id}|;
638 $dbh->do($query) || $form->dberror($query);
640 # delete invoice entries
641 $query = qq|DELETE FROM invoice
642 WHERE trans_id = $form->{id}|;
643 $dbh->do($query) || $form->dberror($query);
645 $query = qq|DELETE FROM shipto
646 WHERE trans_id = $form->{id}|;
647 $dbh->do($query) || $form->dberror($query);
649 $main::lxdebug->leave_sub();
655 $main::lxdebug->enter_sub();
657 my ($self, $myconfig, $form) = @_;
659 # connect to database
660 my $dbh = $form->dbconnect_noauto($myconfig);
662 &reverse_invoice($dbh, $form);
664 # delete zero entries
665 my $query = qq|DELETE FROM acc_trans
667 $dbh->do($query) || $form->dberror($query);
670 my $query = qq|DELETE FROM ap
671 WHERE id = $form->{id}|;
672 $dbh->do($query) || $form->dberror($query);
674 my $rc = $dbh->commit;
677 $main::lxdebug->leave_sub();
684 sub retrieve_invoice {
685 $main::lxdebug->enter_sub();
687 my ($self, $myconfig, $form) = @_;
689 # connect to database
690 my $dbh = $form->dbconnect_noauto($myconfig);
695 # get default accounts and last invoice number
696 $query = qq|SELECT (SELECT c.accno FROM chart c
697 WHERE d.inventory_accno_id = c.id) AS inventory_accno,
698 (SELECT c.accno FROM chart c
699 WHERE d.income_accno_id = c.id) AS income_accno,
700 (SELECT c.accno FROM chart c
701 WHERE d.expense_accno_id = c.id) AS expense_accno,
702 (SELECT c.accno FROM chart c
703 WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
704 (SELECT c.accno FROM chart c
705 WHERE d.fxloss_accno_id = c.id) AS fxloss_accno,
709 $query = qq|SELECT (SELECT c.accno FROM chart c
710 WHERE d.inventory_accno_id = c.id) AS inventory_accno,
711 (SELECT c.accno FROM chart c
712 WHERE d.income_accno_id = c.id) AS income_accno,
713 (SELECT c.accno FROM chart c
714 WHERE d.expense_accno_id = c.id) AS expense_accno,
715 (SELECT c.accno FROM chart c
716 WHERE d.fxgain_accno_id = c.id) AS fxgain_accno,
717 (SELECT c.accno FROM chart c
718 WHERE d.fxloss_accno_id = c.id) AS fxloss_accno,
719 d.curr AS currencies,
720 current_date AS invdate
723 my $sth = $dbh->prepare($query);
724 $sth->execute || $form->dberror($query);
726 my $ref = $sth->fetchrow_hashref(NAME_lc);
727 map { $form->{$_} = $ref->{$_} } keys %$ref;
734 $query = qq|SELECT a.cp_id, a.invnumber, a.transdate AS invdate, a.duedate,
735 a.ordnumber, a.quonumber, a.paid, a.taxincluded, a.notes,
736 a.intnotes, a.curr AS currency
738 WHERE a.id = $form->{id}|;
739 $sth = $dbh->prepare($query);
740 $sth->execute || $form->dberror($query);
742 $ref = $sth->fetchrow_hashref(NAME_lc);
743 map { $form->{$_} = $ref->{$_} } keys %$ref;
746 $form->{exchangerate} = $form->get_exchangerate($dbh, $form->{currency}, $form->{invdate}, "sell");
749 $query = qq|SELECT s.* FROM shipto s
750 WHERE s.trans_id = $form->{id}|;
751 $sth = $dbh->prepare($query);
752 $sth->execute || $form->dberror($query);
754 $ref = $sth->fetchrow_hashref(NAME_lc);
755 map { $form->{$_} = $ref->{$_} } keys %$ref;
758 # retrieve individual items
759 $query = qq|SELECT c1.accno AS inventory_accno,
760 c2.accno AS income_accno,
761 c3.accno AS expense_accno,
762 p.partnumber, i.description, i.qty, i.fxsellprice AS sellprice,
763 i.parts_id AS id, i.unit, p.bin, i.deliverydate,
765 i.project_id, i.serialnumber,
768 JOIN parts p ON (i.parts_id = p.id)
769 LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id)
770 LEFT JOIN chart c2 ON (p.income_accno_id = c2.id)
771 LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id)
772 LEFT JOIN project pr ON (i.project_id = pr.id)
773 LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id)
774 WHERE i.trans_id = $form->{id}
776 $sth = $dbh->prepare($query);
777 $sth->execute || $form->dberror($query);
779 while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
781 #set expense_accno=inventory_accno if they are different => bilanz
782 $vendor_accno = ($ref->{expense_accno}!=$ref->{inventory_accno}) ? $ref->{inventory_accno} :$ref->{expense_accno};
783 $vendor_accno = ($ref->{inventory_accno}) ? $ref->{inventory_accno} :$ref->{expense_accno};
785 # get tax rates and description
786 $accno_id = ($form->{vc} eq "customer") ? $ref->{income_accno} : $vendor_accno;
787 $query = qq|SELECT c.accno, c.description, t.rate, t.taxnumber
789 WHERE c.id=t.chart_id AND t.taxkey in (SELECT taxkey_id from chart where accno = '$accno_id')
791 $stw = $dbh->prepare($query);
792 $stw->execute || $form->dberror($query);
793 $ref->{taxaccounts} = "";
794 while ($ptr = $stw->fetchrow_hashref(NAME_lc)) {
795 # if ($customertax{$ref->{accno}}) {
796 $ref->{taxaccounts} .= "$ptr->{accno} ";
797 if (!($form->{taxaccounts}=~/$ptr->{accno}/)) {
798 $form->{"$ptr->{accno}_rate"} = $ptr->{rate};
799 $form->{"$ptr->{accno}_description"} = $ptr->{description};
800 $form->{"$ptr->{accno}_taxnumber"} = $ptr->{taxnumber};
801 $form->{taxaccounts} .= "$ptr->{accno} ";
806 chop $ref->{taxaccounts};
807 push @{ $form->{invoice_details} }, $ref;
812 if ($form->{webdav}) {
813 &webdav_folder($myconfig, $form);
820 my $rc = $dbh->commit;
824 $main::lxdebug->leave_sub();
832 $main::lxdebug->enter_sub();
834 my ($self, $myconfig, $form) = @_;
836 # connect to database
837 my $dbh = $form->dbconnect($myconfig);
839 my $dateformat = $myconfig->{dateformat};
840 $dateformat .= "yy" if $myconfig->{dateformat} !~ /^y/;
842 my $duedate = ($form->{invdate}) ? "to_date('$form->{invdate}', '$dateformat')" : "current_date";
844 $form->{vendor_id} *= 1;
846 my $query = qq|SELECT v.name AS vendor, v.creditlimit, v.terms,
847 v.email, v.cc, v.bcc, v.language,
848 v.street, v.zipcode, v.city, v.country,
849 $duedate + v.terms AS duedate, v.notes AS intnotes
851 WHERE v.id = $form->{vendor_id}|;
852 my $sth = $dbh->prepare($query);
853 $sth->execute || $form->dberror($query);
855 $ref = $sth->fetchrow_hashref(NAME_lc);
856 map { $form->{$_} = $ref->{$_} } keys %$ref;
859 $form->{creditremaining} = $form->{creditlimit};
860 $query = qq|SELECT SUM(a.amount - a.paid)
862 WHERE a.vendor_id = $form->{vendor_id}|;
863 $sth = $dbh->prepare($query);
864 $sth->execute || $form->dberror($query);
866 ($form->{creditremaining}) -= $sth->fetchrow_array;
870 $query = qq|SELECT o.amount,
871 (SELECT e.sell FROM exchangerate e
872 WHERE e.curr = o.curr
873 AND e.transdate = o.transdate)
875 WHERE o.vendor_id = $form->{vendor_id}
876 AND o.quotation = '0'
878 $sth = $dbh->prepare($query);
879 $sth->execute || $form->dberror($query);
881 while (my ($amount, $exch) = $sth->fetchrow_array) {
882 $exch = 1 unless $exch;
883 $form->{creditremaining} -= $amount * $exch;
887 $form->get_contacts($dbh,$form->{vendor_id});
889 ($null, $form->{cp_id}) = split /--/, $form->{contact};
891 # get contact if selected
892 if ($form->{contact} ne "--" && $form->{contact} ne "")
894 $form->get_contact($dbh,$form->{cp_id});
897 # get shipto if we do not convert an order or invoice
898 if (!$form->{shipto}) {
899 map { delete $form->{$_} } qw(shiptoname shiptostreet shiptozipcode shiptocity shiptocountry shiptocontact shiptophone shiptofax shiptoemail);
901 $query = qq|SELECT s.* FROM shipto s
902 WHERE s.trans_id = $form->{vendor_id}|;
903 $sth = $dbh->prepare($query);
904 $sth->execute || $form->dberror($query);
906 $ref = $sth->fetchrow_hashref(NAME_lc);
907 map { $form->{$_} = $ref->{$_} } keys %$ref;
911 # get taxes for vendor
912 $query = qq|SELECT c.accno
914 JOIN vendortax v ON (v.chart_id = c.id)
915 WHERE v.vendor_id = $form->{vendor_id}|;
916 $sth = $dbh->prepare($query);
917 $sth->execute || $form->dberror($query);
920 while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
921 $vendortax{$ref->{accno}} = 1;
929 if (!$form->{id} && $form->{type} !~ /_(order|quotation)/) {
930 # setup last accounts used
931 $query = qq|SELECT c.accno, c.description, c.link, c.category
933 JOIN acc_trans ac ON (ac.chart_id = c.id)
934 JOIN ap a ON (a.id = ac.trans_id)
935 WHERE a.vendor_id = $form->{vendor_id}
936 AND NOT (c.link LIKE '%_tax%' OR c.link LIKE '%_paid%')
937 AND a.id IN (SELECT max(a2.id) FROM ap a2
938 WHERE a2.vendor_id = $form->{vendor_id})|;
939 $sth = $dbh->prepare($query);
940 $sth->execute || $form->dberror($query);
943 while ($ref = $sth->fetchrow_hashref(NAME_lc)) {
944 if ($ref->{category} eq 'E') {
946 $form->{"AP_amount_$i"} = "$ref->{accno}--$ref->{description}";
948 if ($ref->{category} eq 'L') {
949 $form->{APselected} = $form->{AP_1} = "$ref->{accno}--$ref->{description}";
953 $form->{rowcount} = $i if ($i && !$form->{type});
958 $main::lxdebug->leave_sub();
963 $main::lxdebug->enter_sub();
965 my ($self, $myconfig, $form) = @_;
967 my $i = $form->{rowcount};
969 # don't include assemblies or obsolete parts
970 my $where = "NOT p.assembly = '1' AND NOT p.obsolete = '1'";
972 if ($form->{"partnumber_$i"}) {
973 my $partnumber = $form->like(lc $form->{"partnumber_$i"});
974 $where .= " AND lower(p.partnumber) LIKE '$partnumber'";
977 if ($form->{"description_$i"}) {
978 my $description = $form->like(lc $form->{"description_$i"});
979 $where .= " AND lower(p.description) LIKE '$description'";
982 if ($form->{"partsgroup_$i"}) {
983 my $partsgroup = $form->like(lc $form->{"partsgroup_$i"});
984 $where .= " AND lower(pg.partsgroup) LIKE '$partsgroup'";
987 if ($form->{"description_$i"}) {
988 $where .= " ORDER BY p.description";
990 $where .= " ORDER BY p.partnumber";
993 # connect to database
994 my $dbh = $form->dbconnect($myconfig);
996 my $query = qq|SELECT p.id, p.partnumber, p.description,
997 c1.accno AS inventory_accno,
998 c2.accno AS income_accno,
999 c3.accno AS expense_accno,
1001 p.lastcost AS sellprice, p.unit, p.bin, p.onhand, p.notes AS partnotes
1003 LEFT JOIN chart c1 ON (p.inventory_accno_id = c1.id)
1004 LEFT JOIN chart c2 ON (p.income_accno_id = c2.id)
1005 LEFT JOIN chart c3 ON (p.expense_accno_id = c3.id)
1006 LEFT JOIN partsgroup pg ON (pg.id = p.partsgroup_id)
1008 my $sth = $dbh->prepare($query);
1009 $sth->execute || $form->dberror($query);
1011 while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
1013 #set expense_accno=inventory_accno if they are different => bilanz
1014 $vendor_accno = ($ref->{expense_accno}!=$ref->{inventory_accno}) ? $ref->{inventory_accno} :$ref->{expense_accno};
1015 $vendor_accno = ($ref->{inventory_accno}) ? $ref->{inventory_accno} :$ref->{expense_accno};
1017 # get tax rates and description
1018 $accno_id = ($form->{vc} eq "customer") ? $ref->{income_accno} : $vendor_accno;
1019 $query = qq|SELECT c.accno, c.description, t.rate, t.taxnumber
1021 WHERE c.id=t.chart_id AND t.taxkey in (SELECT taxkey_id from chart where accno = '$accno_id')
1023 $stw = $dbh->prepare($query);
1024 $stw->execute || $form->dberror($query);
1026 $ref->{taxaccounts} = "";
1027 while ($ptr = $stw->fetchrow_hashref(NAME_lc)) {
1028 # if ($customertax{$ref->{accno}}) {
1029 $ref->{taxaccounts} .= "$ptr->{accno} ";
1030 if (!($form->{taxaccounts}=~/$ptr->{accno}/)) {
1031 $form->{"$ptr->{accno}_rate"} = $ptr->{rate};
1032 $form->{"$ptr->{accno}_description"} = $ptr->{description};
1033 $form->{"$ptr->{accno}_taxnumber"} = $ptr->{taxnumber};
1034 $form->{taxaccounts} .= "$ptr->{accno} ";
1040 chop $ref->{taxaccounts};
1042 push @{ $form->{item_list} }, $ref;
1049 $main::lxdebug->leave_sub();
1054 sub vendor_details {
1055 $main::lxdebug->enter_sub();
1057 my ($self, $myconfig, $form) = @_;
1059 # connect to database
1060 my $dbh = $form->dbconnect($myconfig);
1062 # get contact id, set it if nessessary
1063 ($null, $form->{cp_id}) = split /--/, $form->{contact};
1066 if ($form->{cp_id}) {
1067 $contact = "and cp.cp_id = $form->{cp_id}";
1070 $taxincluded = $form->{taxincluded};
1072 # get rest for the vendor
1073 # fax and phone and email as vendor*
1074 my $query = qq|SELECT ct.*, cp.*, ct.notes as vendornotes, phone as vendorphone, fax as vendorfax, email as vendoremail
1076 LEFT JOIN contacts cp on ct.id = cp.cp_cv_id
1077 WHERE ct.id = $form->{vendor_id} $contact order by cp.cp_id limit 1|;
1078 my $sth = $dbh->prepare($query);
1079 $sth->execute || $form->dberror($query);
1081 $ref = $sth->fetchrow_hashref(NAME_lc);
1082 map { $form->{$_} = $ref->{$_} } keys %$ref;
1084 $form->{taxincluded} = $taxincluded;
1089 $main::lxdebug->leave_sub();
1094 $main::lxdebug->enter_sub();
1096 my ($self, $myconfig, $form) = @_;
1098 # connect to database
1099 my $dbh = $form->dbconnect($myconfig);
1101 my $query = qq|SELECT c.accno, c.description, c.link
1103 WHERE c.link LIKE '%IC%'
1105 my $sth = $dbh->prepare($query);
1106 $sth->execute || $form->dberror($query);
1108 while (my $ref = $sth->fetchrow_hashref(NAME_lc)) {
1109 foreach my $key (split(/:/, $ref->{link})) {
1111 push @{ $form->{IC_links}{$key} }, { accno => $ref->{accno},
1112 description => $ref->{description} };
1118 $main::lxdebug->leave_sub();
1123 $main::lxdebug->enter_sub();
1125 my ($myconfig, $form) = @_;
1129 $path = "webdav/rechnungen/".$form->{invnumber}, last SWITCH if ($form->{vc} eq "customer");
1130 $path = "webdav/einkaufsrechnungen/".$form->{invnumber}, last SWITCH if ($form->{vc} eq "vendor");
1135 mkdir ($path, 0770) or die "can't make directory $!\n";
1139 foreach $file (@files) {
1141 $file =~ /\/([^\/]*)$/;
1143 $ENV{'SCRIPT_NAME'} =~ /\/([^\/]*)\//;
1145 $link = "http://".$ENV{'SERVER_NAME'}."/".$lxerp."/".$file;
1146 $form->{WEBDAV}{$fname} = $link;
1152 $main::lxdebug->leave_sub();