can't set $p without $cgi
[freeside.git] / sql-ledger / old / sql-ledger / bin / mozilla / ap.pl
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 #
10 # This program is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
14 #
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this program; if not, write to the Free Software
21 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #======================================================================
23 #
24 # Accounts Payables
25 #
26 #======================================================================
27
28
29 use SL::AP;
30 use SL::IR;
31 use SL::PE;
32
33 require "$form->{path}/arap.pl";
34
35 1;
36 # end of main
37
38
39 # this is for our long dates
40 # $locale->text('January')
41 # $locale->text('February')
42 # $locale->text('March')
43 # $locale->text('April')
44 # $locale->text('May ')
45 # $locale->text('June')
46 # $locale->text('July')
47 # $locale->text('August')
48 # $locale->text('September')
49 # $locale->text('October')
50 # $locale->text('November')
51 # $locale->text('December')
52
53 # this is for our short month
54 # $locale->text('Jan')
55 # $locale->text('Feb')
56 # $locale->text('Mar')
57 # $locale->text('Apr')
58 # $locale->text('May')
59 # $locale->text('Jun')
60 # $locale->text('Jul')
61 # $locale->text('Aug')
62 # $locale->text('Sep')
63 # $locale->text('Oct')
64 # $locale->text('Nov')
65 # $locale->text('Dec')
66
67
68 sub add {
69
70   $form->{title} = "Add";
71   
72   $form->{callback} = "$form->{script}?action=add&path=$form->{path}&login=$form->{login}&password=$form->{password}" unless $form->{callback};
73
74   &create_links;
75   &display_form;
76   
77 }
78
79
80 sub edit {
81   
82   $form->{title} = "Edit";
83
84   &create_links;
85   &display_form;
86
87 }
88
89
90 sub display_form {
91   
92   &form_header;
93   &form_footer;
94
95 }
96
97
98 sub create_links {
99
100   $form->create_links("AP", \%myconfig, "vendor");
101
102   $taxincluded = $form->{taxincluded};
103   $duedate = $form->{duedate};
104   
105   IR->get_vendor(\%myconfig, \%$form);
106   
107   $form->{duedate} = $duedate;
108   $form->{oldvendor} = "$form->{vendor}--$form->{vendor_id}";
109   
110   # build the popup menus
111
112   # currencies
113   @curr = split /:/, $form->{currencies};
114   chomp $curr[0];
115   $form->{defaultcurrency} = $curr[0];
116
117   map { $form->{selectcurrency} .= "<option>$_\n" } @curr;
118
119   # vendors
120   if (@{ $form->{all_vendor} }) {
121     $form->{vendor} = qq|$form->{vendor}--$form->{vendor_id}|;
122     map { $form->{selectvendor} .= "<option>$_->{name}--$_->{id}\n" } (@{ $form->{all_vendor} });
123   }
124   
125
126   # forex
127   $form->{forex} = $form->{exchangerate};
128   $exchangerate = ($form->{exchangerate}) ? $form->{exchangerate} : 1;
129   
130   foreach $key (keys %{ $form->{AP_links} }) {
131     
132     foreach $ref (@{ $form->{AP_links}{$key} }) {
133       if ($key eq "AP_tax") {
134         $form->{"selectAP_tax_$ref->{accno}"} = "<option>$ref->{accno}--$ref->{description}\n";
135         next;
136       }
137       $form->{"select$key"} .= "<option>$ref->{accno}--$ref->{description}\n";
138     }
139         
140     # if there is a value we have an old entry
141     for $i (1 .. scalar @{ $form->{acc_trans}{$key} }) {
142
143       if ($key eq "AP_paid") {
144         $form->{"AP_paid_$i"} = "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}";
145         $form->{"paid_$i"} = $form->{acc_trans}{$key}->[$i-1]->{amount};
146         $form->{"datepaid_$i"} = $form->{acc_trans}{$key}->[$i-1]->{transdate};
147         $form->{"source_$i"} = $form->{acc_trans}{$key}->[$i-1]->{source};
148         
149         $form->{"forex_$i"} = $form->{"exchangerate_$i"} = $form->{acc_trans}{$key}->[$i-1]->{exchangerate};
150         
151         $form->{paidaccounts}++;
152       } else {
153
154         $akey = $key;
155         $akey =~ s/AP_//;
156
157         if ($key eq "AP_tax") {
158           $form->{"${key}_$form->{acc_trans}{$key}->[$i-1]->{accno}"} = "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}";
159           $form->{"${akey}_$form->{acc_trans}{$key}->[$i-1]->{accno}"} = $form->round_amount($form->{acc_trans}{$key}->[$i-1]->{amount} / $exchangerate * -1, 2);
160           $totaltax += $form->{"${akey}_$form->{acc_trans}{$key}->[$i-1]->{accno}"};
161         } else {
162           $form->{"${akey}_$i"} = $form->round_amount($form->{acc_trans}{$key}->[$i-1]->{amount} / $exchangerate, 2);
163           if ($akey eq 'amount') {
164             $form->{"${akey}_$i"} *= -1;
165             $totalamount += $form->{"${akey}_$i"};
166             $form->{rowcount}++;
167
168             $form->{"oldprojectnumber_$i"} = $form->{"projectnumber_$i"} = "$form->{acc_trans}{$key}->[$i-1]->{projectnumber}";
169             $form->{"project_id_$i"} = "$form->{acc_trans}{$key}->[$i-1]->{project_id}";
170           }
171           $form->{"${key}_$i"} = "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}";
172         }
173       }
174     }
175   }
176
177   $form->{taxincluded} = $taxincluded if ($form->{id});
178   $form->{paidaccounts} = 1 if not defined $form->{paidaccounts};
179
180   if ($form->{taxincluded} && $totalamount) {
181   # add tax to amounts and invtotal
182     for $i (1 .. $form->{rowcount}) {
183       $taxamount = $totaltax * $form->{"amount_$i"} / $totalamount;
184       $tax = $form->round_amount($taxamount, 2);
185       $diff += ($taxamount - $tax);
186       $form->{"amount_$i"} += $tax;
187     }
188     $form->{amount_1} += $form->round_amount($diff, 2);
189   }
190   
191   $form->{invtotal} = $totalamount + $totaltax;
192   $form->{rowcount}++ if $form->{id};
193   
194   $form->{AP} = $form->{AP_1};
195
196   $form->{locked} = ($form->datetonum($form->{transdate}, \%myconfig) <= $form->datetonum($form->{closedto}, \%myconfig));
197
198 }
199
200
201 sub form_header {
202
203   $title = $form->{title};
204   $form->{title} = $locale->text("$title Accounts Payables Transaction");
205
206   $form->{taxincluded} = ($form->{taxincluded}) ? "checked" : "";
207   
208 # type=submit $locale->text('Add Accounts Payables Transaction')
209 # type=submit $locale->text('Edit Accounts Payables Transaction')
210
211   # set option selected
212   foreach $item (qw(AP vendor currency)) {
213     $form->{"select$item"} =~ s/ selected//;
214     $form->{"select$item"} =~ s/option>\Q$form->{$item}\E/option selected>$form->{$item}/;
215   }
216
217   
218   # format amounts
219   $form->{exchangerate} = $form->format_amount(\%myconfig, $form->{exchangerate});
220   
221   $exchangerate = qq|
222 <input type=hidden name=forex value=$form->{forex}>
223 |;
224   if ($form->{currency} ne $form->{defaultcurrency}) {
225     if ($form->{forex}) {
226       $exchangerate .= qq|
227               <th align=right>|.$locale->text('Exchangerate').qq|</th>
228               <td><input type=hidden name=exchangerate value=$form->{exchangerate}>$form->{exchangerate}</td>
229 |;
230     } else {
231       $exchangerate .= qq|
232              <th align=right>|.$locale->text('Exchangerate').qq|</th>
233              <td><input name=exchangerate size=10 value=$form->{exchangerate}></td>
234 |;
235     }
236   }
237   
238   $taxincluded = "";
239   if ($form->{taxaccounts}) {
240     $taxincluded = qq|
241             <tr>
242               <td align=right><input name=taxincluded class=checkbox type=checkbox value=1 $form->{taxincluded}></td>
243               <th align=left nowrap>|.$locale->text('Tax Included').qq|</th>
244             </tr>
245 |;
246   }
247
248
249   if (($rows = $form->numtextrows($form->{notes}, 50)) < 2) {
250     $rows = 2;
251   }
252   $notes = qq|<textarea name=notes rows=$rows cols=50 wrap=soft>$form->{notes}</textarea>|;
253   
254   
255   $form->header;
256
257   $vendor = ($form->{selectvendor}) ? qq|<select name=vendor>$form->{selectvendor}</select>| : qq|<input name=vendor value="$form->{vendor}" size=35>|; 
258   
259   print qq|
260 <body>
261
262 <form method=post action=$form->{script}>
263
264 <input type=hidden name=id value=$form->{id}>
265 <input type=hidden name=sort value=$form->{sort}>
266 <input type=hidden name=closedto value=$form->{closedto}>
267 <input type=hidden name=locked value=$form->{locked}>
268 <input type=hidden name=title value="$title">
269
270 <table width=100%>
271   <tr class=listtop>
272     <th class=listtop>$form->{title}</th>
273   </tr>
274   <tr height="5"></tr>
275   <tr valign=top>
276     <td>
277       <table width=100%>
278         <tr valign=top>
279           <td>
280             <table>
281               <tr>
282                 <th align=right nowrap>|.$locale->text('Vendor').qq|</th>
283                 <td colspan=3>$vendor</td>
284                 <input type=hidden name=selectvendor value="$form->{selectvendor}">
285                 <input type=hidden name=oldvendor value="$form->{oldvendor}">
286                 <input type=hidden name=vendor_id value="$form->{vendor_id}">
287                 <input type=hidden name=terms value=$form->{terms}>
288               </tr>
289               $taxincluded
290               </tr>
291               <tr>
292                 <th align=right nowrap>|.$locale->text('Currency').qq|</th>
293                 <td><select name=currency>$form->{selectcurrency}</select></td>
294                 <input type=hidden name=selectcurrency value="$form->{selectcurrency}">
295                 <input type=hidden name=defaultcurrency value=$form->{defaultcurrency}>
296                 <input type=hidden name=fxgain_accno value=$form->{fxgain_accno}>
297                 <input type=hidden name=fxloss_accno value=$form->{fxloss_accno}>
298                 $exchangerate
299               </tr>
300             </table>
301           </td>
302           <td align=right>
303             <table>
304               <tr>
305                 <th align=right nowrap>|.$locale->text('Invoice Number').qq|</th>
306                 <td><input name=invnumber size=11 value="$form->{invnumber}"></td>
307               </tr>
308               <tr>
309                 <th align=right nowrap>|.$locale->text('Order Number').qq|</th>
310                 <td><input name=ordnumber size=11 value="$form->{ordnumber}"></td>
311               </tr>
312               <tr>
313                 <th align=right nowrap>|.$locale->text('Invoice Date').qq|</th>
314                 <td><input name=transdate size=11 title="$myconfig{'dateformat'}" value=$form->{transdate}></td>
315               </tr>
316               <tr>
317                 <th align=right nowrap>|.$locale->text('Due Date').qq|</th>
318                 <td><input name=duedate size=11 title="$myconfig{'dateformat'}" value=$form->{duedate}></td>
319               </tr>
320             </table>
321           </td>
322         </tr>
323       </table>
324     </td>
325   </tr>
326   <input type=hidden name=selectAP_amount value="$form->{selectAP_amount}">
327   <input type=hidden name=rowcount value=$form->{rowcount}>
328   <tr>
329     <td>
330       <table width=100%>
331 |;
332
333   $amount = $locale->text('Amount');
334   $project = $locale->text('Project');
335   
336   for $i (1 .. $form->{rowcount}) {
337
338     $form->{"selectAP_amount"} =~ s/ selected//;
339     $form->{"selectAP_amount"} =~ s/option>\Q$form->{"AP_amount_$i"}\E/option selected>$form->{"AP_amount_$i"}/;
340
341     # format amounts
342     $form->{"amount_$i"} = $form->format_amount(\%myconfig, $form->{"amount_$i"}, 2);
343
344     print qq|
345         <tr>
346           <th align=right nowrap>$amount</th>
347           <td><input name="amount_$i" size=10 value=$form->{"amount_$i"}></td>
348           <th>$project</th>
349           <td><input name="projectnumber_$i" size=20 value="$form->{"projectnumber_$i"}">
350               <input type=hidden name="project_id_$i" value=$form->{"project_id_$i"}>
351               <input type=hidden name="oldprojectnumber_$i" value="$form->{"oldprojectnumber_$i"}"></td>
352           <td width=50%><select name="AP_amount_$i">$form->{selectAP_amount}</select></td>
353         </tr>
354 |;
355     $amount = "";
356     $project = "";
357   }
358
359   $taxlabel = ($form->{taxincluded}) ? $locale->text('Tax Included') : $locale->text('Tax');
360   
361   foreach $item (split / /, $form->{taxaccounts}) {
362
363     # format and reverse tax
364     $form->{"tax_$item"} = $form->format_amount(\%myconfig, $form->{"tax_$item"}, 2); 
365
366     print qq|
367         <tr>
368           <th align=right nowrap>${taxlabel}</th>
369           <td><input name="tax_$item" size=10 value=$form->{"tax_$item"}></td>
370           <td colspan=2></td>
371           <td><select name=AP_tax_$item>$form->{"selectAP_tax_$item"}</select></td>
372         </tr>
373         <input type=hidden name="${item}_rate" value="$form->{"${item}_rate"}">
374         <input type=hidden name="${item}_description" value="$form->{"${item}_description"}">
375         <input type=hidden name="selectAP_tax_$item" value="$form->{"selectAP_tax_$item"}">
376 |;
377   }
378    
379   $form->{invtotal} = $form->format_amount(\%myconfig, $form->{invtotal}, 2);
380
381   print qq|
382         <tr>
383           <th align=right nowrap>|.$locale->text('Total').qq|</th>
384           <td>$form->{invtotal}</td>
385           <td colspan=2></td>
386           <td><select name=AP>$form->{selectAP}</select></td>
387           <input type=hidden name=selectAP value="$form->{selectAP}">
388           <input type=hidden name=taxaccounts value="$form->{taxaccounts}">
389         </tr>
390         <tr>
391           <th align=right nowrap>|.$locale->text('Notes').qq|</th>
392           <td colspan=5>$notes</td>
393         </tr>
394       </table>
395     </td>
396   </tr>
397   <tr>
398     <td>
399       <table width=100%>
400         <tr class=listheading>
401           <th class=listheading colspan=5>|.$locale->text('Payments').qq|</th>
402         </tr>
403 |;
404
405
406   if ($form->{currency} eq $form->{defaultcurrency}) {
407     @column_index = qw(datepaid source paid AP_paid);
408   } else {
409     @column_index = qw(datepaid source paid exchangerate AP_paid);
410   }
411
412   $column_data{datepaid} = "<th>".$locale->text('Date')."</th>";
413   $column_data{paid} = "<th>".$locale->text('Amount')."</th>";
414   $column_data{exchangerate} = "<th>".$locale->text('Exch')."</th>";
415   $column_data{AP_paid} = "<th>".$locale->text('Account')."</th>";
416   $column_data{source} = "<th>".$locale->text('Source')."</th>";
417
418   print "
419         <tr>
420 ";
421   map { print "$column_data{$_}\n" } @column_index;
422   print "
423         </tr>
424 ";
425
426   $form->{paidaccounts}++ if ($form->{"paid_$form->{paidaccounts}"});
427   for $i (1 .. $form->{paidaccounts}) {
428     print "
429         <tr>
430 ";
431
432     $form->{"selectAP_paid_$i"} = $form->{selectAP_paid};
433     $form->{"selectAP_paid_$i"} =~ s/option>\Q$form->{"AP_paid_$i"}\E/option selected>$form->{"AP_paid_$i"}/;
434
435     # format amounts
436     $form->{"paid_$i"} = $form->format_amount(\%myconfig, $form->{"paid_$i"}, 2);
437     $form->{"exchangerate_$i"} = $form->format_amount(\%myconfig, $form->{"exchangerate_$i"});
438     
439     $exchangerate = qq|&nbsp;|;
440     if ($form->{currency} ne $form->{defaultcurrency}) {
441       if ($form->{"forex_$i"}) {
442         $exchangerate = qq|<input type=hidden name="exchangerate_$i" value=$form->{"exchangerate_$i"}>$form->{"exchangerate_$i"}|;
443       } else {
444         $exchangerate = qq|<input name="exchangerate_$i" size=10 value=$form->{"exchangerate_$i"}>|;
445       }
446     }
447
448     $exchangerate .= qq|
449 <input type=hidden name="forex_$i" value=$form->{"forex_$i"}>
450 |;
451
452     $column_data{"paid_$i"} = qq|<td align=center><input name="paid_$i" size=10 value=$form->{"paid_$i"}></td>|;
453     $column_data{"AP_paid_$i"} = qq|<td align=center><select name="AP_paid_$i">$form->{"selectAP_paid_$i"}</select></td>|;
454     $column_data{"exchangerate_$i"} = qq|<td align=center>$exchangerate</td>|;
455     $column_data{"datepaid_$i"} = qq|<td align=center><input name="datepaid_$i" size=11 title="($myconfig{'dateformat'})" value=$form->{"datepaid_$i"}></td>|;
456     $column_data{"source_$i"} = qq|<td align=center><input name="source_$i" size=10 value="$form->{"source_$i"}"></td>|;
457
458     map { print qq|$column_data{"${_}_$i"}\n| } @column_index;
459
460     print "
461         </tr>
462 ";
463   }
464
465   print qq|
466     <input type=hidden name=paidaccounts value=$form->{paidaccounts}>
467     <input type=hidden name=selectAP_paid value="$form->{selectAP_paid}">
468     
469       </table>
470     </td>
471   </tr>
472   <tr>
473     <td><hr size=3 noshade></td>
474   </tr>
475 </table>
476 |;
477
478 }
479
480
481 sub form_footer {
482
483   print qq|
484
485 <input name=callback type=hidden value="$form->{callback}">
486
487 <input type=hidden name=path value=$form->{path}>
488 <input type=hidden name=login value=$form->{login}>
489 <input type=hidden name=password value=$form->{password}>
490
491 <br>
492 |;
493
494   $transdate = $form->datetonum($form->{transdate}, \%myconfig);
495   $closedto = $form->datetonum($form->{closedto}, \%myconfig);
496   
497   if ($form->{id}) {
498     print qq|<input class=submit type=submit name=action value="|.$locale->text('Update').qq|">
499 |;
500
501     if (!$form->{revtrans}) {
502       if (!$form->{locked}) {
503         print qq|
504         <input class=submit type=submit name=action value="|.$locale->text('Post').qq|">
505         <input class=submit type=submit name=action value="|.$locale->text('Delete').qq|">
506 |;
507       }
508     }
509
510     if ($transdate > $closedto) {
511       print qq|
512 <input class=submit type=submit name=action value="|.$locale->text('Post as new').qq|">
513 |;
514     }
515
516   } else {
517     if ($transdate > $closedto) {
518       print qq|<input class=submit type=submit name=action value="|.$locale->text('Update').qq|">
519       <input class=submit type=submit name=action value="|.$locale->text('Post').qq|">|;
520     }
521   }
522
523   print "
524 </form>
525
526 </body>
527 </html>
528 ";
529
530 }
531
532
533 sub update {
534   my $display = shift;
535
536   if ($display) {
537     goto TAXCALC;
538   }
539
540   $form->{invtotal} = 0;
541   
542   $form->{exchangerate} = $form->parse_amount(\%myconfig, $form->{exchangerate});
543
544   @flds = qw(amount AP_amount projectnumber oldprojectnumber project_id);
545   $count = 0;
546   for $i (1 .. $form->{rowcount}) {
547     $form->{"amount_$i"} = $form->parse_amount(\%myconfig, $form->{"amount_$i"});
548     if ($form->{"amount_$i"}) {
549       push @a, {};
550       my $j = $#a;
551       map { $a[$j]->{$_} = $form->{"${_}_$i"} } @flds;
552       $count++;
553     }
554   }
555   $form->redo_rows(\@flds, \@a, $count, $form->{rowcount});
556   $form->{rowcount} = $count + 1;
557   
558   map { $form->{invtotal} += $form->{"amount_$_"} } (1 .. $form->{rowcount});
559   
560   $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{transdate}, 'sell')));
561
562   $form->{invdate} = $form->{transdate};
563   &check_name(vendor);
564
565   &check_project;
566
567
568 TAXCALC:
569   # recalculate taxes
570   if ($form->{taxincluded}) {
571     $taxrate = 0;
572
573     map { $taxrate += $form->{"${_}_rate"} } split / /, $form->{taxaccounts};
574
575     foreach $item (split / /, $form->{taxaccounts}) {
576       $amount = ($form->{invtotal} * (1 - 1 / (1 + $taxrate)) * $form->{"${item}_rate"} / $taxrate) if $taxrate;
577       $form->{"tax_$item"} = $form->round_amount($amount, 2);
578       $taxdiff += ($amount - $form->{"tax_$item"});
579       if (abs $taxdiff >= 0.005) {
580         $form->{"tax_$item"} += $form->round_amount($taxdiff, 2);
581         $taxdiff = 0;
582       }
583       $form->{"selectAP_tax_$item"} = qq|<option>$item--$form->{"${item}_description"}|;
584       $totaltax += $form->{"tax_$item"};
585     }
586   } else {
587     foreach $item (split / /, $form->{taxaccounts}) {
588       $form->{"tax_$item"} = $form->round_amount($form->{invtotal} * $form->{"${item}_rate"}, 2);
589       $form->{"selectAP_tax_$item"} = qq|<option>$item--$form->{"${item}_description"}|;
590       $totaltax += $form->{"tax_$item"};
591     }
592   }
593
594   $form->{invtotal} = ($form->{taxincluded}) ? $form->{invtotal} : $form->{invtotal} + $totaltax;
595   
596   for $i (1 .. $form->{paidaccounts}) {
597     if ($form->{"paid_$i"}) {
598       map { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } qw(paid exchangerate);
599       
600       $form->{"exchangerate_$i"} = $exchangerate if ($form->{"forex_$i"} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{"datepaid_$i"}, 'sell')));
601     }
602   }
603
604   &display_form;
605
606 }
607
608  
609 sub post {
610
611   # check if there is an invoice number, invoice and due date
612   $form->isblank("invnumber", $locale->text("Invoice Number missing!"));
613   $form->isblank("transdate", $locale->text("Invoice Date missing!"));
614   $form->isblank("duedate", $locale->text("Due Date missing!"));
615   $form->isblank("vendor", $locale->text('Vendor missing!'));
616   
617   
618   $closedto = $form->datetonum($form->{closedto}, \%myconfig);
619   $transdate = $form->datetonum($form->{transdate}, \%myconfig);
620
621   $form->error($locale->text('Cannot post transaction for a closed period!')) if ($transdate <= $closedto);
622
623   $form->isblank("exchangerate", $locale->text('Exchangerate missing!')) if ($form->{currency} ne $form->{defaultcurrency});
624
625   for $i (1 .. $form->{paidaccounts}) {
626     if ($form->{"paid_$i"}) {
627       $datepaid = $form->datetonum($form->{"datepaid_$i"}, \%myconfig);
628
629       $form->isblank("datepaid_$i", $locale->text('Payment date missing!'));
630
631       $form->error($locale->text('Cannot post payment for a closed period!')) if ($datepaid <= $closedto);
632
633       if ($form->{currency} ne $form->{defaultcurrency}) {
634         $form->{"exchangerate_$i"} = $form->{exchangerate} if ($transdate == $datepaid);
635         $form->isblank("exchangerate_$i", $locale->text('Exchangerate for payment missing!'));
636       }
637       
638     }
639   }
640       
641
642   # if old vendor ne vendor redo form
643   ($vendor) = split /--/, $form->{vendor};
644   if ($form->{oldvendor} ne "$vendor--$form->{vendor_id}") {
645     &update;
646     exit;
647   }
648
649   $form->{id} = 0 if $form->{postasnew};
650
651   $form->redirect($locale->text('Transaction posted!')) if (AP->post_transaction(\%myconfig, \%$form));
652   $form->error($locale->text('Cannot post transaction!'));
653   
654 }
655
656
657 sub post_as_new {
658
659   $form->{postasnew} = 1;
660   &post;
661
662 }
663
664
665 sub delete {
666
667   $form->{title} = $locale->text('Confirm!');
668   
669   $form->header;
670
671   print qq|
672 <body>
673
674 <form method=post action=$form->{script}>
675 |;
676
677   foreach $key (keys %$form) {
678     print qq|<input type=hidden name=$key value="$form->{$key}">\n|;
679   }
680
681   print qq|
682 <h2 class=confirm>$form->{title}</h2>
683
684 <h4>|.$locale->text('Are you sure you want to delete Transaction').qq| $form->{invnumber}</h4>
685
686 <input name=action class=submit type=submit value="|.$locale->text('Yes').qq|">
687 </form>
688
689 </body>
690 </html>
691 |;
692
693 }
694
695
696
697 sub yes {
698
699   $form->redirect($locale->text('Transaction deleted!')) if (AP->delete_transaction(\%myconfig, \%$form));
700   $form->error($locale->text('Cannot delete transaction!'));
701
702 }
703
704
705 sub search {
706   
707   # setup vendor selection
708   $form->all_vc(\%myconfig, "vendor");
709
710   if (@{ $form->{all_vendor} }) {
711     map { $vendor .= "<option>$_->{name}--$_->{id}\n" } @{ $form->{all_vendor} };
712     $vendor = qq|<select name=vendor><option>\n$vendor\n</select>|;
713   } else {
714     $vendor = qq|<input name=vendor size=35>|;
715   }
716     
717     $form->{title} = $locale->text('AP Transactions');
718
719   $form->header;
720
721   print qq|
722 <body>
723
724 <form method=post action=$form->{script}>
725
726 <table width=100%>
727   <tr>
728     <th class=listtop>$form->{title}</th>
729   </tr>
730   <tr height="5"></tr>
731   <tr>
732     <td>
733       <table>
734         <tr>
735           <th align=right>|.$locale->text('Vendor').qq|</th>
736           <td colspan=3>$vendor</td>
737         </tr>
738         <tr>
739           <th align=right nowrap>|.$locale->text('Invoice Number').qq|</th>
740           <td colspan=3><input name=invnumber size=20></td>
741         </tr>
742         <tr>
743           <th align=right nowrap>|.$locale->text('Order Number').qq|</th>
744           <td colspan=3><input name=ordnumber size=20></td>
745         </tr>
746         <tr>
747           <th align=right nowrap>|.$locale->text('Notes').qq|</th>
748           <td colspan=3><input name=notes size=40></td>
749         </tr>
750         <tr>
751           <th align=right nowrap>|.$locale->text('From').qq|</th>
752           <td><input name=transdatefrom size=11 title="$myconfig{dateformat}"></td>
753           <th align=right>|.$locale->text('to').qq|</th>
754           <td><input name=transdateto size=11 title="$myconfig{dateformat}"></td>
755         </tr>
756         <input type=hidden name=sort value=transdate>
757       </table>
758     </td>
759   </tr>
760   <tr>
761     <td>
762       <table>
763         <tr>
764           <th align=right nowrap>|.$locale->text('Include in Report').qq|</th>
765           <td>
766             <table width=100%>
767               <tr>
768                 <td align=right><input name=open class=checkbox type=checkbox value=Y checked></td>
769                 <td nowrap>|.$locale->text('Open').qq|</td>
770                 <td align=right><input name=closed class=checkbox type=checkbox value=Y></td>
771                 <td nowrap>|.$locale->text('Closed').qq|</td>
772               </tr>
773               <tr>
774                 <td align=right><input name="l_id" class=checkbox type=checkbox value=Y></td>
775                 <td nowrap>|.$locale->text('ID').qq|</td>
776                 <td align=right><input name="l_invnumber" class=checkbox type=checkbox value=Y checked></td>
777                 <td nowrap>|.$locale->text('Invoice Number').qq|</td>
778                 <td align=right><input name="l_ordnumber" class=checkbox type=checkbox value=Y></td>
779                 <td nowrap>|.$locale->text('Order Number').qq|</td>
780               </tr>
781               <tr>
782                 <td align=right><input name="l_name" class=checkbox type=checkbox value=Y checked></td>
783                 <td nowrap>|.$locale->text('Vendor').qq|</td>
784                 <td align=right><input name="l_transdate" class=checkbox type=checkbox value=Y checked></td>
785                 <td nowrap>|.$locale->text('Invoice Date').qq|</td>
786                 <td align=right><input name="l_netamount" class=checkbox type=checkbox value=Y></td>
787                 <td nowrap>|.$locale->text('Amount').qq|</td>
788               </tr>
789               <tr>
790                 <td align=right><input name="l_tax" class=checkbox type=checkbox value=Y></td>
791                 <td nowrap>|.$locale->text('Tax').qq|</td>
792                 <td align=right><input name="l_amount" class=checkbox type=checkbox value=Y checked></td>
793                 <td nowrap>|.$locale->text('Total').qq|</td>
794                 <td align=right><input name="l_datepaid" class=checkbox type=checkbox value=Y></td>
795                 <td nowrap>|.$locale->text('Date Paid').qq|</td>
796               </tr>
797               <tr>
798                 <td align=right><input name="l_paid" class=checkbox type=checkbox value=Y checked></td>
799                 <td nowrap>|.$locale->text('Paid').qq|</td>
800                 <td align=right><input name="l_duedate" class=checkbox type=checkbox value=Y></td>
801                 <td nowrap>|.$locale->text('Due Date').qq|</td>
802                 <td align=right><input name="l_due" class=checkbox type=checkbox value=Y></td>
803                 <td nowrap>|.$locale->text('Amount Due').qq|</td>
804               </tr>
805               <tr>
806                 <td align=right><input name="l_notes" class=checkbox type=checkbox value=Y></td>
807                 <td nowrap>|.$locale->text('Notes').qq|</td>
808                 <td align=right><input name="l_employee" class=checkbox type=checkbox value=Y></td>
809                 <td nowrap>|.$locale->text('Employee').qq|</td>
810               </tr>
811               <tr>
812                 <td align=right><input name="l_subtotal" class=checkbox type=checkbox value=Y></td>
813                 <td nowrap>|.$locale->text('Subtotal').qq|</td>
814               </tr>
815             </table>
816           </td>
817         </tr>
818       </table>
819     </td>
820   </tr>
821   <tr>
822     <td><hr size=3 noshade></td>
823   </tr>
824 </table>
825
826 <br>
827 <input type=hidden name=nextsub value=$form->{nextsub}>
828 <input type=hidden name=path value=$form->{path}>
829 <input type=hidden name=login value=$form->{login}>
830 <input type=hidden name=password value=$form->{password}>
831
832 <input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
833 </form>
834
835 </body>
836 </html>
837 |;
838
839 }
840
841
842 sub ap_transactions {
843
844   $form->{vendor} = $form->unescape($form->{vendor});
845   ($form->{vendor}, $form->{vendor_id}) = split(/--/, $form->{vendor});
846
847   AP->ap_transactions(\%myconfig, \%$form);
848
849   $callback = "$form->{script}?action=ap_transactions&path=$form->{path}&login=$form->{login}&password=$form->{password}";
850   $href = $callback;
851     
852
853   if ($form->{vendor}) {
854     $callback .= "&vendor=".$form->escape($form->{vendor});
855     $href .= "&vendor=".$form->escape($form->{vendor});
856     $option .= $locale->text('Vendor')." : $form->{vendor}";
857   }
858   if ($form->{invnumber}) {
859     $callback .= "&invnumber=$form->{invnumber}";
860     $href .= "&invnumber=".$form->escape($form->{invnumber});
861     $option .= "\n<br>" if ($option);
862     $option .= $locale->text('Invoice Number')." : $form->{invnumber}";
863   }
864   if ($form->{ordnumber}) {
865     $callback .= "&ordnumber=$form->{ordnumber}";
866     $href .= "&ordnumber=".$form->escape($form->{ordnumber});
867     $option .= "\n<br>" if ($option);
868     $option .= $locale->text('Order Number')." : $form->{ordnumber}";
869   }
870   if ($form->{notes}) {
871     $callback .= "&notes=$form->{notes}";
872     $href .= "&notes=".$form->escape($form->{notes});
873     $option .= "\n<br>" if $option;
874     $option .= $locale->text('Notes')." : $form->{notes}";
875   }
876   
877   if ($form->{transdatefrom}) {
878     $callback .= "&transdatefrom=$form->{transdatefrom}";
879     $href .= "&transdatefrom=$form->{transdatefrom}";
880     $option .= "\n<br>" if ($option);
881     $option .= $locale->text('From')." ".$locale->date(\%myconfig, $form->{transdatefrom}, 1);
882   }
883   if ($form->{transdateto}) {
884     $callback .= "&transdateto=$form->{transdateto}";
885     $href .= "&transdateto=$form->{transdateto}";
886     $option .= "\n<br>" if ($option);
887     $option .= $locale->text('to')." ".$locale->date(\%myconfig, $form->{transdateto}, 1);
888   }
889   if ($form->{open}) {
890     $callback .= "&open=$form->{open}";
891     $href .= "&open=$form->{open}";
892     $option .= "\n<br>" if ($option);
893     $option .= $locale->text('Open');
894   }
895   if ($form->{closed}) {
896     $callback .= "&closed=$form->{closed}";
897     $href .= "&closed=$form->{closed}";
898     $option .= "\n<br>" if ($option);
899     $option .= $locale->text('Closed');
900   }
901
902   @columns = $form->sort_columns(qw(transdate id invnumber ordnumber name netamount tax amount paid datepaid due duedate notes employee));
903
904   foreach $item (@columns) {
905     if ($form->{"l_$item"} eq "Y") {
906       push @column_index, $item;
907       
908       # add column to href and callback
909       $callback .= "&l_$item=Y";
910       $href .= "&l_$item=Y";
911     }
912   }
913   
914   if ($form->{l_subtotal} eq 'Y') {
915     $callback .= "&l_subtotal=Y";
916     $href .= "&l_subtotal=Y";
917   }
918   
919     
920   $column_header{id} = qq|<th><a class=listheading href=$href&sort=id>|.$locale->text('ID').qq|</a></th>|;
921   $column_header{transdate} = qq|<th><a class=listheading href=$href&sort=transdate>|.$locale->text('Date').qq|</a></th>|;
922   $column_header{duedate} = qq|<th><a class=listheading href=$href&sort=duedate>|.$locale->text('Due Date').qq|</a></th>|;
923   $column_header{due} = qq|<th class=listheading>|.$locale->text('Amount Due').qq|</th>|;
924   $column_header{invnumber} = qq|<th><a class=listheading href=$href&sort=invnumber>|.$locale->text('Invoice').qq|</a></th>|;
925   $column_header{ordnumber} = qq|<th><a class=listheading href=$href&sort=ordnumber>|.$locale->text('Order').qq|</a></th>|;
926   $column_header{name} = qq|<th><a class=listheading href=$href&sort=name>|.$locale->text('Vendor').qq|</a></th>|;
927   $column_header{netamount} = qq|<th class=listheading>|.$locale->text('Amount').qq|</th>|;
928   $column_header{tax} = qq|<th class=listheading>|.$locale->text('Tax').qq|</th>|;
929   $column_header{amount} = qq|<th class=listheading>|.$locale->text('Total').qq|</th>|;
930   $column_header{paid} = qq|<th class=listheading>|.$locale->text('Paid').qq|</th>|;
931   $column_header{datepaid} = qq|<th><a class=listheading href=$href&sort=datepaid>|.$locale->text('Date Paid').qq|</a></th>|;
932   $column_header{notes} = qq|<th><a class=listheading>|.$locale->text('Notes').qq|</th>|;
933   $column_header{employee} = "<th><a class=listheading href=$href&sort=employee>".$locale->text('Employee')."</th>";
934
935   
936   $form->{title} = $locale->text('AP Transactions');
937
938   $form->header;
939   
940   print qq|
941 <body>
942
943 <table width=100%>
944   <tr>
945     <th class=listtop>$form->{title}</th>
946   </tr>
947   <tr height="5"></tr>
948   <tr>
949     <td>$option</td>
950   </tr>
951   <tr>
952     <td>
953       <table width=100%>
954         <tr class=listheading>
955 |;
956
957   map { print "\n$column_header{$_}" } @column_index;
958
959   print qq|
960         </tr>
961 |;
962
963   # add sort and escape callback
964   $form->{callback} = "$callback&sort=$form->{sort}";
965   $callback = $form->escape($form->{callback});
966
967   if (@{ $form->{AP} }) {
968     $sameitem = $form->{AP}->[0]->{$form->{sort}};
969   }
970   
971   # sums and tax on reports by Antonio Gallardo
972   #
973   foreach $ap (@{ $form->{AP} }) {
974
975     if ($form->{l_subtotal} eq 'Y') {
976       if ($sameitem ne $ap->{$form->{sort}}) {
977         &ap_subtotal;
978         $sameitem = $ap->{$form->{sort}};
979       }
980     }
981     
982     $column_data{netamount} = "<td align=right>".$form->format_amount(\%myconfig, $ap->{netamount}, 2, "&nbsp;")."</td>";
983     $column_data{tax} = "<td align=right>".$form->format_amount(\%myconfig, $ap->{amount} - $ap->{netamount}, 2, "&nbsp;") . "</td>";
984     $column_data{amount} = "<td align=right>".$form->format_amount(\%myconfig, $ap->{amount}, 2, "&nbsp;") . "</td>";
985     $column_data{paid} = "<td align=right>".$form->format_amount(\%myconfig, $ap->{paid}, 2, "&nbsp;")."</td>";
986     $column_data{due} = "<td align=right>".$form->format_amount(\%myconfig, $ap->{amount} - $ap->{paid}, 2, "&nbsp;")."</td>";
987
988     $totalnetamount += $ap->{netamount};
989     $totalamount += $ap->{amount};
990     $totalpaid += $ap->{paid};
991     $totaldue += ($ap->{amount} - $ap->{paid});
992
993     $subtotalnetamount += $ap->{netamount};
994     $subtotalamount += $ap->{amount};
995     $subtotalpaid += $ap->{paid};
996     $subtotaldue += ($ap->{amount} - $ap->{paid});
997
998     $column_data{transdate} = "<td>$ap->{transdate}&nbsp;</td>";
999     $column_data{duedate} = "<td>$ap->{duedate}&nbsp;</td>";
1000     $column_data{datepaid} = "<td>$ap->{datepaid}&nbsp;</td>";
1001
1002     $module = ($ap->{invoice}) ? "ir.pl" : $form->{script};
1003
1004     $column_data{invnumber} = qq|<td><a href="$module?action=edit&path=$form->{path}&id=$ap->{id}&login=$form->{login}&password=$form->{password}&callback=$callback">$ap->{invnumber}</a></td>|;
1005     $column_data{id} = "<td>$ap->{id}</td>";
1006     $column_data{ordnumber} = "<td>$ap->{ordnumber}&nbsp;</td>";
1007     $column_data{name} = "<td>$ap->{name}</td>";
1008     $ap->{notes} =~ s/\r\n/<br>/g;
1009     $column_data{notes} = "<td>$ap->{notes}&nbsp;</td>";
1010     $column_data{employee} = "<td>$ap->{employee}&nbsp;</td>";
1011     
1012     $i++;
1013     $i %= 2;
1014     print "
1015         <tr class=listrow$i >
1016 ";
1017     
1018     map { print "\n$column_data{$_}" } @column_index;
1019
1020     print qq|
1021         </tr>
1022 |;
1023
1024   }
1025   
1026   if ($form->{l_subtotal} eq 'Y') {
1027     &ap_subtotal;
1028   }
1029   
1030   # print totals
1031   print qq|
1032         <tr class=listtotal>
1033 |;
1034   
1035   map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
1036   
1037   $column_data{netamount} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalnetamount, 2, "&nbsp;")."</th>";
1038   $column_data{tax} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalamount - $totalnetamount, 2, "&nbsp;")."</th>";
1039   $column_data{amount} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalamount, 2, "&nbsp;")."</th>";
1040   $column_data{paid} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalpaid, 2, "&nbsp;")."</th>";
1041   $column_data{due} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totaldue, 2, "&nbsp;")."</th>";
1042
1043   map { print "$column_data{$_}\n" } @column_index;
1044
1045   print qq|
1046         </tr>
1047       </table>
1048     </td>
1049   </tr>
1050   <tr>
1051     <td><hr size=3 noshade></td>
1052   </tr>  
1053 </table>
1054
1055 <br>
1056 <form method=post action=$form->{script}>
1057  
1058 <input name=callback type=hidden value="$form->{callback}">
1059   
1060 <input type=hidden name=path value=$form->{path}>
1061 <input type=hidden name=login value=$form->{login}>
1062 <input type=hidden name=password value=$form->{password}>
1063    
1064 <input class=submit type=submit name=action value="|.$locale->text('AP Transaction').qq|">
1065
1066 <input class=submit type=submit name=action value="|.$locale->text('Vendor Invoice').qq|">
1067
1068 </form>
1069
1070 </body>
1071 </html>
1072 |;
1073
1074 }
1075
1076
1077 sub ap_subtotal {
1078
1079   map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
1080   
1081   $column_data{netamount} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalnetamount, 2, "&nbsp;")."</th>";
1082   $column_data{tax} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalamount - $subtotalnetamount, 2, "&nbsp;")."</th>";
1083   $column_data{amount} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalamount, 2, "&nbsp;")."</th>";
1084   $column_data{paid} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalpaid, 2, "&nbsp;")."</th>";
1085   $column_data{due} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotaldue, 2, "&nbsp;")."</th>";
1086
1087   $subtotalnetamount = 0;
1088   $subtotalamount = 0;
1089   $subtotalpaid = 0;
1090   $subtotaldue = 0;
1091
1092   print "<tr class=listsubtotal>";
1093   
1094   map { print "\n$column_data{$_}" } @column_index;
1095
1096   print qq|
1097   </tr>
1098 |;
1099
1100 }
1101
1102
1103