generic translations strict
[kivitendo-erp.git] / bin / mozilla / ir.pl
1 #=====================================================================
2 # LX-Office ERP
3 # Copyright (C) 2004
4 # Based on SQL-Ledger Version 2.1.9
5 # Web http://www.lx-office.org
6 #
7 #=====================================================================
8 # SQL-Ledger, Accounting
9 # Copyright (c) 1998-2002
10 #
11 #  Author: Dieter Simader
12 #   Email: dsimader@sql-ledger.org
13 #     Web: http://www.sql-ledger.org
14 #
15 #
16 # This program is free software; you can redistribute it and/or modify
17 # it under the terms of the GNU General Public License as published by
18 # the Free Software Foundation; either version 2 of the License, or
19 # (at your option) any later version.
20 #
21 # This program is distributed in the hope that it will be useful,
22 # but WITHOUT ANY WARRANTY; without even the implied warranty of
23 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 # GNU General Public License for more details.
25 # You should have received a copy of the GNU General Public License
26 # along with this program; if not, write to the Free Software
27 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #======================================================================
29 #
30 # Inventory received module
31 #
32 #======================================================================
33
34 use SL::FU;
35 use SL::IR;
36 use SL::IS;
37 use SL::PE;
38 use List::Util qw(max sum);
39
40 require "bin/mozilla/io.pl";
41 require "bin/mozilla/invoice_io.pl";
42 require "bin/mozilla/arap.pl";
43 require "bin/mozilla/common.pl";
44 require "bin/mozilla/drafts.pl";
45
46 1;
47
48 # end of main
49
50 sub add {
51   $lxdebug->enter_sub();
52
53   $auth->assert('vendor_invoice_edit');
54
55   return $lxdebug->leave_sub() if (load_draft_maybe());
56
57   $form->{title} = $locale->text('Add Vendor Invoice');
58
59   &invoice_links;
60   &prepare_invoice;
61   &display_form;
62
63   $lxdebug->leave_sub();
64 }
65
66 sub edit {
67   $lxdebug->enter_sub();
68
69   $auth->assert('vendor_invoice_edit');
70
71   # show history button
72   $form->{javascript} = qq|<script type=text/javascript src=js/show_history.js></script>|;
73   #/show hhistory button
74
75   $form->{title} = $locale->text('Edit Vendor Invoice');
76
77   &invoice_links;
78   &prepare_invoice;
79   &display_form;
80
81   $lxdebug->leave_sub();
82 }
83
84 sub invoice_links {
85   $lxdebug->enter_sub();
86
87   $auth->assert('vendor_invoice_edit');
88
89   # create links
90   $form->{webdav}   = $webdav;
91   $form->{jsscript} = 1;
92
93   $form->create_links("AP", \%myconfig, "vendor");
94
95   #quote all_vendor Bug 133
96   foreach $ref (@{ $form->{all_vendor} }) {
97     $ref->{name} = $form->quote($ref->{name});
98   }
99
100   if ($form->{all_vendor}) {
101     unless ($form->{vendor_id}) {
102       $form->{vendor_id} = $form->{all_vendor}->[0]->{id};
103     }
104   }
105   if ($form->{payment_id}) {
106     $payment_id = $form->{payment_id};
107   }
108   if ($form->{language_id}) {
109     $language_id = $form->{language_id};
110   }
111   if ($form->{taxzone_id}) {
112     $taxzone_id = $form->{taxzone_id};
113   }
114
115   $cp_id = $form->{cp_id};
116   IR->get_vendor(\%myconfig, \%$form);
117   IR->retrieve_invoice(\%myconfig, \%$form);
118   $form->{cp_id} = $cp_id;
119
120   if ($payment_id) {
121     $form->{payment_id} = $payment_id;
122   }
123   if ($language_id) {
124     $form->{language_id} = $language_id;
125   }
126   if ($taxzone_id) {
127     $form->{taxzone_id} = $taxzone_id;
128   }
129
130   map { $form->{selectcurrency} .= "<option>$_\n" } @curr;
131
132   $form->{oldvendor} = "$form->{vendor}--$form->{vendor_id}";
133
134   # departments
135   if ($form->{all_departments}) {
136     $form->{selectdepartment} = "<option>\n";
137     $form->{department}       = "$form->{department}--$form->{department_id}";
138
139     map {
140       $form->{selectdepartment} .=
141         "<option>$_->{description}--$_->{id}\n"
142     } (@{ $form->{all_departments} });
143   }
144
145   # forex
146   $form->{forex} = $form->{exchangerate};
147   $exchangerate = ($form->{exchangerate}) ? $form->{exchangerate} : 1;
148
149   foreach $key (keys %{ $form->{AP_links} }) {
150
151     foreach $ref (@{ $form->{AP_links}{$key} }) {
152       $form->{"select$key"} .= "<option>$ref->{accno}--$ref->{description}\n";
153     }
154
155     if ($key eq "AP_paid") {
156       for $i (1 .. scalar @{ $form->{acc_trans}{$key} }) {
157         $form->{"AP_paid_$i"} =
158           "$form->{acc_trans}{$key}->[$i-1]->{accno}--$form->{acc_trans}{$key}->[$i-1]->{description}";
159
160         # reverse paid
161         $form->{"paid_$i"}     = $form->{acc_trans}{$key}->[$i - 1]->{amount};
162         $form->{"datepaid_$i"} =
163           $form->{acc_trans}{$key}->[$i - 1]->{transdate};
164         $form->{"forex_$i"} = $form->{"exchangerate_$i"} =
165           $form->{acc_trans}{$key}->[$i - 1]->{exchangerate};
166         $form->{"source_$i"} = $form->{acc_trans}{$key}->[$i - 1]->{source};
167         $form->{"memo_$i"}   = $form->{acc_trans}{$key}->[$i - 1]->{memo};
168
169         $form->{paidaccounts} = $i;
170       }
171     } else {
172       $form->{$key} =
173         "$form->{acc_trans}{$key}->[0]->{accno}--$form->{acc_trans}{$key}->[0]->{description}";
174     }
175
176   }
177
178   $form->{paidaccounts} = 1 unless (exists $form->{paidaccounts});
179
180   $form->{AP} = $form->{AP_1} unless $form->{id};
181
182   $form->{locked} =
183     ($form->datetonum($form->{invdate}, \%myconfig) <=
184      $form->datetonum($form->{closedto}, \%myconfig));
185
186   $lxdebug->leave_sub();
187 }
188
189 sub prepare_invoice {
190   $lxdebug->enter_sub();
191
192   $auth->assert('vendor_invoice_edit');
193
194   if ($form->{id}) {
195
196     map { $form->{$_} =~ s/\"/&quot;/g } qw(invnumber ordnumber quonumber);
197
198     my $i = 0;
199     foreach $ref (@{ $form->{invoice_details} }) {
200       $i++;
201       map { $form->{"${_}_$i"} = $ref->{$_} } keys %{$ref};
202
203       ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
204       $dec           = length $dec;
205       $decimalplaces = ($dec > 2) ? $dec : 2;
206
207       $form->{"sellprice_$i"} =
208         $form->format_amount(\%myconfig, $form->{"sellprice_$i"},
209                              $decimalplaces);
210
211       (my $dec_qty) = ($form->{"qty_$i"} =~ /\.(\d+)/);
212       $dec_qty = length $dec_qty;
213
214       $form->{"qty_$i"} =
215         $form->format_amount(\%myconfig, ($form->{"qty_$i"} * -1), $dec_qty);
216
217       $form->{rowcount} = $i;
218     }
219   }
220
221   $lxdebug->leave_sub();
222 }
223
224 sub form_header {
225   $lxdebug->enter_sub();
226
227   $auth->assert('vendor_invoice_edit');
228
229   push @{ $form->{AJAX} }, CGI::Ajax->new('set_duedate_vendor' => "$form->{script}?action=set_duedate_vendor");
230
231   # set option selected
232   foreach $item (qw(AP vendor currency department)) {
233     $form->{"select$item"} =~ s/ selected//;
234     $form->{"select$item"} =~ s/option>\Q$form->{$item}\E/option selected>$form->{$item}/;
235   }
236
237   $form->{employee_id}     = $form->{old_employee_id} if $form->{old_employee_id};
238   $form->{salesman_id}     = $form->{old_salesman_id} if $form->{old_salesman_id};
239   $form->{defaultcurrency} = $form->get_default_currency(\%myconfig);
240   $form->{radier}          = ($form->current_date(\%myconfig) eq $form->{gldate}) ? 1 : 0;
241   $form->{exchangerate}    = $form->format_amount(\%myconfig, $form->{exchangerate});
242   $form->{creditlimit}     = $form->format_amount(\%myconfig, $form->{creditlimit}, 0, "0");
243   $form->{creditremaining} = $form->format_amount(\%myconfig, $form->{creditremaining}, 0, "0");
244
245   $exchangerate = "";
246   if ($form->{currency} ne $form->{defaultcurrency}) {
247     if ($form->{forex}) {
248       $exchangerate .= qq| <th align=right nowrap>| . $locale->text('Exchangerate') . qq|</th>
249                            <td>$form->{exchangerate}<input type=hidden name=exchangerate value=$form->{exchangerate}></td>\n|;
250     } else {
251       $exchangerate .= qq| <th align=right nowrap>| . $locale->text('Exchangerate') . qq|</th>
252                            <td><input name=exchangerate size=10 value=$form->{exchangerate}></td>\n|;
253     }
254   }
255   $exchangerate .= qq| <input type=hidden name=forex value=$form->{forex}>\n|;
256
257   my @old_project_ids = ($form->{"globalproject_id"});
258   map { push @old_project_ids, $form->{"project_id_$_"} if $form->{"project_id_$_"}; } 1..$form->{"rowcount"};
259
260   $form->get_lists("contacts"      => "ALL_CONTACTS",
261                    "projects"      => { "key"  => "ALL_PROJECTS",
262                                       "all"    => 0,
263                                       "old_id" => \@old_project_ids },
264                    "taxzones"      => "ALL_TAXZONES",
265                    "employees"     => "ALL_SALESMEN",
266                    "currencies"    => "ALL_CURRENCIES",
267                    "vendors"       => "ALL_VENDORS",
268                    "price_factors" => "ALL_PRICE_FACTORS");
269
270   my %labels;
271   my @values = (undef);
272   foreach my $item (@{ $form->{"ALL_CONTACTS"} }) {
273     push(@values, $item->{"cp_id"});
274     $labels{$item->{"cp_id"}} = $item->{"cp_name"} . ($item->{"cp_abteilung"} ? " ($item->{cp_abteilung})" : "");
275   }
276
277   my $contact;
278   if (scalar @values > 1) {
279     $contact = qq|
280     <tr>
281       <th align="right">| . $locale->text('Contact Person') . qq|</th>
282       <td>| .  NTI($cgi->popup_menu('-name' => 'cp_id', '-values' => \@values, '-style' => 'width: 250px',
283                                     '-labels' => \%labels, '-default' => $form->{"cp_id"})) . qq|
284       </td>
285     </tr>|;
286   }
287
288   %labels = ();
289   @values = ("");
290   foreach my $item (@{ $form->{"ALL_PROJECTS"} }) {
291     push(@values, $item->{"id"});
292     $labels{$item->{"id"}} = $item->{"projectnumber"};
293   }
294   my $globalprojectnumber = NTI($cgi->popup_menu('-name' => 'globalproject_id', '-values' => \@values, '-labels' => \%labels,
295                                                  '-default' => $form->{"globalproject_id"}));
296
297   %labels = ();
298   @values = ();
299   my $i = 0;
300   foreach my $item (@{ $form->{"ALL_CURRENCIES"} }) {
301     push(@values, $item);
302     $labels{$item} = $item;
303   }
304
305   $form->{currency} = $form->{defaultcurrency} unless $form->{currency};
306   my $currencies;
307   if (scalar @values) {
308     $currencies = qq|
309     <tr>
310       <th align="right">| . $locale->text('Currency') . qq|</th>
311       <td>| .  NTI($cgi->popup_menu('-name' => 'currency', '-default' => $form->{"currency"},
312                                     '-values' => \@values, '-labels' => \%labels)) . qq|
313       </td>
314     </tr>|;
315   }
316
317   %labels = ();
318   @values = ();
319   my $i = 0;
320   foreach my $item (@{ $form->{"ALL_SALESMEN"} }) {
321     push(@values, $item->{"id"});
322     $labels{$item->{"id"}} = $item->{"name"};
323   }
324   my $employees = qq|
325     <tr>
326       <th align="right">| . $locale->text('Employee') . qq|</th>
327       <td>| .  NTI($cgi->popup_menu('-name' => 'employee_id', '-default' => $form->{"employee_id"},
328                                     '-values' => \@values, '-labels' => \%labels)) . qq|
329       </td>
330     </tr>|;
331
332   %labels = ();
333   @values = ();
334   my $i = 0;
335   foreach my $item (@{ $form->{"ALL_VENDORS"} }) {
336     push(@values, $item->{name}.qq|--|.$item->{"id"});
337     $labels{$item->{name}.qq|--|.$item->{"id"}} = $item->{"name"};
338   }
339
340   $form->{selectvendor} = ($myconfig{vclimit} > scalar(@values));
341
342   my $vendors = qq|
343       <th align="right">| . $locale->text('Vendor') . qq|</th>
344       <td>| .
345         (($myconfig{vclimit} <=  scalar(@values))
346               ? qq|<input type="text" value="| . H($form->{vendor}) . qq|" name="vendor">|
347               : (NTI($cgi->popup_menu('-name' => 'vendor', '-default' => $form->{oldvendor},
348                                       '-onChange' => 'document.getElementById(\'update_button\').click();',
349                                       '-values' => \@values, '-labels' => \%labels, '-style' => 'width: 250px')))) . qq|
350         <input type="button" value="| . $locale->text('Details (one letter abbreviation)') . qq|" onclick="show_vc_details('vendor')">
351       </td>|;
352
353   %labels = ();
354   @values = ();
355   foreach my $item (@{ $form->{"ALL_TAXZONES"} }) {
356     push(@values, $item->{"id"});
357     $labels{$item->{"id"}} = $item->{"description"};
358   }
359
360   if (!$form->{"id"}) {
361     $taxzone = qq|
362     <tr>
363       <th align="right">| . $locale->text('Steuersatz') . qq|</th>
364       <td>| .  NTI($cgi->popup_menu('-name' => 'taxzone_id', '-default' => $form->{"taxzone_id"},
365                                     '-values' => \@values, '-labels' => \%labels, '-style' => 'width: 250px')) . qq|
366       </td>
367     </tr>|;
368   } else {
369     $taxzone = qq|
370     <tr>
371       <th align="right">| . $locale->text('Steuersatz') . qq|</th>
372       <td>
373         <input type="hidden" name="taxzone_id" value="| . H($form->{"taxzone_id"}) . qq|">
374         | . H($labels{$form->{"taxzone_id"}}) . qq|
375       </td>
376     </tr>|;
377   }
378
379   $department = qq|
380            <tr>
381               <th align="right" nowrap>| . $locale->text('Department') . qq|</th>
382               <td colspan="3"><select name="department" style="width: 250px">$form->{selectdepartment}</select>
383               <input type="hidden" name="selectdepartment" value="$form->{selectdepartment}">
384               </td>
385             </tr>\n| if $form->{selectdepartment};
386
387   $n = ($form->{creditremaining} =~ /-/) ? "0" : "1";
388
389   # use JavaScript Calendar or not
390   $form->{jsscript} = 1;
391   $jsscript = "";
392
393   $button1 = qq|
394      <td nowrap>
395          <input name=invdate id=invdate size=11 title="$myconfig{dateformat}" value="$form->{invdate}" onBlur=\"check_right_date_format(this)\"
396                 onChange="if (this.value) set_duedate_vendor(['invdate__' + this.value, 'old_duedate__' + document.getElementsByName('duedate')[0].value, 'vendor_id__' + document.getElementsByName('vendor_id')[0].value],['duedate'])">
397          <input type=button name=invdate id="trigger1" value="?">
398      </td>\n|;
399
400 #, 'old_duedate__'' + document.getElementsByName('duedate')[0].value, 'vendor_id__' + document.getElementsByName('vendor_id')[0].value],['duedate'])">
401   $button2 = qq|
402      <td width="13" nowrap>
403           <input name=duedate id=duedate size=11 title="$myconfig{dateformat}" value="$form->{duedate}"  onBlur=\"check_right_date_format(this)\">
404           <input type=button name=duedate id="trigger2" value=| . $locale->text('button') . qq|>
405      </td>\n|;
406
407   #write Trigger
408   $jsscript =
409     Form->write_trigger(\%myconfig, "2",
410                         "invdate", "BL", "trigger1",
411                         "duedate", "BL", "trigger2");
412
413   my $follow_up_vc         =  $form->{vendor};
414   $follow_up_vc            =~ s/--\d*\s*$//;
415   my $follow_up_trans_info =  "$form->{invnumber} ($follow_up_vc)";
416
417   $form->{javascript} .= qq|<script type="text/javascript" src="js/show_form_details.js"></script>|;
418   $form->{javascript} .= qq|<script type="text/javascript" src="js/common.js"></script>|;
419   $form->{javascript} .= qq|<script type="text/javascript" src="js/show_vc_details.js"></script>|;
420   $form->{javascript} .= qq|<script type="text/javascript" src="js/follow_up.js"></script>|;
421
422   $jsscript .= $form->write_trigger(\%myconfig, 2, "orddate", "BL", "trigger_orddate", "quodate", "BL", "trigger_quodate");
423
424   $form->header;
425   $onload  = qq|focus()|;
426   $onload .= qq|;setupDateFormat('|. $myconfig{dateformat} .qq|', '|. $locale->text("Falsches Datumsformat!") .qq|')|;
427   $onload .= qq|;setupPoints('|. $myconfig{numberformat} .qq|', '|. $locale->text("wrongformat") .qq|')|;
428   print qq|
429 <body onLoad="$onload">
430 <script type="text/javascript" src="js/common.js"></script>
431 <form method="post" action="ir.pl" name="Form">
432 |;
433
434   $form->hide_form(qw(id title vc type level creditlimit creditremaining closedto locked shippted storno storno_id
435                       max_dunning_level dunning_amount vendor_id oldvendor selectvendor taxaccounts
436                       fxgain_accno fxloss_accno taxpart taxservice cursor_fokus
437                       convert_from_oe_ids convert_from_do_ids),
438                       map { $_.'_rate', $_.'_description' } split / /, $form->{taxaccounts} );
439
440   print qq|<p>$form->{saved_message}</p>| if $form->{saved_message};
441
442   print qq|
443
444 <div class="listtop" width="100%">$form->{title}</div>
445
446 <table width=100%>
447   <tr>
448     <td valign="top">
449             <table>
450         $vendors
451         $contact
452         <tr>
453           <td align="right">| . $locale->text('Credit Limit') . qq|</td>
454           <td>$form->{creditlimit}; | . $locale->text('Remaining') . qq| <span class="plus$n">$form->{creditremaining}</span></td>
455         </tr>
456               <tr>
457                 <th align="right">| . $locale->text('Record in') . qq|</th>
458                 <td colspan="3"><select name="AP" style="width: 250px">$form->{selectAP}</select></td>
459                 <input type="hidden" name="selectAP" value="$form->{selectAP}">
460               </tr>
461               $taxzone
462               $department
463               <tr>
464     $currencies
465                 $exchangerate
466               </tr>
467             </table>
468           </td>
469           <td align=right>
470             <table>
471      $employees
472               <tr>
473                 <th align=right nowrap>| . $locale->text('Invoice Number') . qq|</th>
474                 <td><input name=invnumber size=11 value="$form->{invnumber}"></td>
475               </tr>
476               <tr>
477                 <th align=right nowrap>| . $locale->text('Invoice Date') . qq|</th>
478                 $button1
479               </tr>
480               <tr>
481                 <th align=right nowrap>| . $locale->text('Due Date') . qq|</th>
482                 $button2
483               </tr>
484               <tr>
485                 <th align=right nowrap>| . $locale->text('Order Number') . qq|</th>
486                 <td><input name=ordnumber size=11 value="$form->{ordnumber}"></td>
487 <input type=hidden name=quonumber value="$form->{quonumber}">
488               </tr>
489         <tr>
490           <th align="right" nowrap>| . $locale->text('Order Date') . qq|</th>
491           <td><input name="orddate" id="orddate" size="11" title="$myconfig{dateformat}" value="| . Q($form->{orddate}) . qq|" onBlur=\"check_right_date_format(this)\">
492            <input type="button" name="b_orddate" id="trigger_orddate" value="?"></td>
493         </tr>
494         <tr>
495           <th align="right" nowrap>| . $locale->text('Quotation Date') . qq|</th>
496           <td><input name="quodate" id="quodate" size="11" title="$myconfig{dateformat}" value="| . Q($form->{quodate}) . qq|" onBlur=\"check_right_date_format(this)\">
497            <input type="button" name="b_quodate" id="trigger_quodate" value="?"></td>
498         </tr>
499               <tr>
500           <th align="right" nowrap>| . $locale->text('Project Number') . qq|</th>
501           <td>$globalprojectnumber</td>
502               </tr>
503      </table>
504           </td>
505         </tr>
506       </table>
507     </td>
508   </tr>
509
510 $jsscript
511
512 <input type=hidden name=webdav value=$webdav>
513 |;
514
515   foreach $item (split / /, $form->{taxaccounts}) {
516     print qq|
517 <input type=hidden name="${item}_rate" value=$form->{"${item}_rate"}>
518 <input type=hidden name="${item}_description" value="$form->{"${item}_description"}">
519 |;
520   }
521
522   $lxdebug->leave_sub();
523 }
524
525 sub form_footer {
526   $lxdebug->enter_sub();
527
528   $auth->assert('vendor_invoice_edit');
529
530   $form->{invtotal} = $form->{invsubtotal};
531
532   if (($rows = $form->numtextrows($form->{notes}, 25, 8)) < 2) {
533     $rows = 2;
534   }
535   if (($introws = $form->numtextrows($form->{intnotes}, 35, 8)) < 2) {
536     $introws = 2;
537   }
538   $rows = ($rows > $introws) ? $rows : $introws;
539   $notes =
540     qq|<textarea name=notes rows=$rows cols=25 wrap=soft>$form->{notes}</textarea>|;
541   $intnotes =
542     qq|<textarea name=intnotes rows=$rows cols=35 wrap=soft>$form->{intnotes}</textarea>|;
543
544   $form->{taxincluded} = ($form->{taxincluded}) ? "checked" : "";
545
546   $taxincluded = "";
547   if ($form->{taxaccounts}) {
548     $taxincluded = qq|
549                 <input name=taxincluded class=checkbox type=checkbox value=1 $form->{taxincluded}> <b>|
550       . $locale->text('Tax Included') . qq|</b>
551 |;
552   }
553
554   if (!$form->{taxincluded}) {
555
556     foreach $item (split / /, $form->{taxaccounts}) {
557       if ($form->{"${item}_base"}) {
558         $form->{invtotal} += $form->{"${item}_total"} =
559           $form->round_amount(
560                              $form->{"${item}_base"} * $form->{"${item}_rate"},
561                              2);
562         $form->{"${item}_total"} =
563           $form->format_amount(\%myconfig, $form->{"${item}_total"}, 2);
564
565         $tax .= qq|
566                 <tr>
567                   <th align=right>$form->{"${item}_description"}&nbsp;|
568                     . $form->{"${item}_rate"} * 100 .qq|%</th>
569                   <td align=right>$form->{"${item}_total"}</td>
570                 </tr>
571 |;
572       }
573     }
574
575     $form->{invsubtotal} =
576       $form->format_amount(\%myconfig, $form->{invsubtotal}, 2, 0);
577
578     $subtotal = qq|
579               <tr>
580                 <th align=right>| . $locale->text('Subtotal') . qq|</th>
581                 <td align=right>$form->{invsubtotal}</td>
582               </tr>
583 |;
584
585   }
586
587   if ($form->{taxincluded}) {
588     foreach $item (split / /, $form->{taxaccounts}) {
589       if ($form->{"${item}_base"}) {
590         $form->{"${item}_total"} =
591           $form->round_amount(
592                            ($form->{"${item}_base"} * $form->{"${item}_rate"} /
593                               (1 + $form->{"${item}_rate"})
594                            ),
595                            2);
596         $form->{"${item}_base"} =
597           $form->round_amount($form->{"${item}_base"}, 2);
598         $form->{"${item}_netto"} =
599           $form->round_amount(
600                           ($form->{"${item}_base"} - $form->{"${item}_total"}),
601                           2);
602         $form->{"${item}_netto"} =
603           $form->format_amount(\%myconfig, $form->{"${item}_netto"}, 2);
604         $form->{"${item}_total"} =
605           $form->format_amount(\%myconfig, $form->{"${item}_total"}, 2);
606
607         $tax .= qq|
608               <tr>
609                 <th align=right>Enthaltene $form->{"${item}_description"}&nbsp;|
610                                     . $form->{"${item}_rate"} * 100 .qq|%</th>
611                 <td align=right>$form->{"${item}_total"}</td>
612               </tr>
613               <tr>
614                 <th align=right>Nettobetrag</th>
615                 <td align=right>$form->{"${item}_netto"}</td>
616               </tr>
617 |;
618       }
619     }
620
621   }
622
623   $form->{oldinvtotal} = $form->{invtotal};
624   $form->{invtotal}    =
625     $form->format_amount(\%myconfig, $form->{invtotal}, 2, 0);
626
627   my $follow_ups_block;
628   if ($form->{id}) {
629     my $follow_ups = FU->follow_ups('trans_id' => $form->{id});
630
631     if (@{ $follow_ups} ) {
632       my $num_due       = sum map { $_->{due} * 1 } @{ $follow_ups };
633       $follow_ups_block = qq|
634       <tr>
635         <td colspan="2">| . $locale->text("There are #1 unfinished follow-ups of which #2 are due.", scalar @{ $follow_ups }, $num_due) . qq|</td>
636       </tr>
637 |;
638     }
639   }
640
641   print qq|
642   <tr>
643     <td colspan=$colspan>
644       <table cellspacing="0">
645         <tr valign=bottom>
646           <td>
647             <table>
648               <tr>
649                 <th align=left>| . $locale->text('Notes') . qq|</th>
650                 <th align=left>| . $locale->text('Internal Notes') . qq|</th>
651               </tr>
652               <tr valign=top>
653                 <td>$notes</td>
654                 <td>$intnotes</td>
655               </tr>
656         $follow_ups_block
657             </table>
658           </td>
659           <td colspan=2 align=right width=100%>
660             $taxincluded
661             <br>
662             <table width=100%>
663               $subtotal
664               $tax
665               <tr>
666                 <th align=right>| . $locale->text('Total') . qq|</th>
667                 <td align=right>$form->{invtotal}</td>
668               </tr>
669             </table>
670           </td>
671         </tr>
672       </table>
673     </td>
674   </tr>
675 |;
676   if ($webdav) {
677     $webdav_list = qq|
678   <tr>
679     <td><hr size=3 noshade></td>
680   </tr>
681   <tr>
682     <th class=listtop align=left>Dokumente im Webdav-Repository</th>
683   </tr>
684     <table width=100%>
685       <td align=left width=30%><b>Dateiname</b></td>
686       <td align=left width=70%><b>Webdavlink</b></td>
687 |;
688     foreach $file (@{ $form->{WEBDAV} }) {
689       $webdav_list .= qq|
690       <tr>
691         <td align="left">$file->{name}</td>
692         <td align="left"><a href="$file->{link}">$file->{type}</a></td>
693       </tr>
694 |;
695     }
696     $webdav_list .= qq|
697     </table>
698   </tr>
699 |;
700
701     print $webdav_list;
702   }
703   print qq|
704   <tr>
705     <td colspan=$colspan>
706       <table width=100%>
707         <tr>
708           <th colspan=6 class=listheading>| . $locale->text('Payments') . qq|</th>
709         </tr>
710 |;
711
712   if ($form->{currency} eq $form->{defaultcurrency}) {
713     @column_index = qw(datepaid source memo paid AP_paid);
714   } else {
715     @column_index = qw(datepaid source memo paid exchangerate AP_paid);
716   }
717
718   $column_data{datepaid}     = "<th>" . $locale->text('Date') . "</th>";
719   $column_data{paid}         = "<th>" . $locale->text('Amount') . "</th>";
720   $column_data{exchangerate} = "<th>" . $locale->text('Exch') . "</th>";
721   $column_data{AP_paid}      = "<th>" . $locale->text('Account') . "</th>";
722   $column_data{source}       = "<th>" . $locale->text('Source') . "</th>";
723   $column_data{memo}         = "<th>" . $locale->text('Memo') . "</th>";
724
725   print qq|
726         <tr>
727 |;
728   map { print "$column_data{$_}\n" } @column_index;
729   print qq|
730         </tr>
731 |;
732
733   my @triggers  = ();
734   my $totalpaid = 0;
735
736   $form->{paidaccounts}++ if ($form->{"paid_$form->{paidaccounts}"});
737   for $i (1 .. $form->{paidaccounts}) {
738
739     print qq|
740         <tr>
741 |;
742
743     $form->{"selectAP_paid_$i"} = $form->{selectAP_paid};
744     $form->{"selectAP_paid_$i"} =~
745       s/option>\Q$form->{"AP_paid_$i"}\E/option selected>$form->{"AP_paid_$i"}/;
746
747     $totalpaid += $form->{"paid_$i"};
748
749     # format amounts
750     if ($form->{"paid_$i"}) {
751       $form->{"paid_$i"} =
752         $form->format_amount(\%myconfig, $form->{"paid_$i"}, 2);
753     }
754     $form->{"exchangerate_$i"} =
755       $form->format_amount(\%myconfig, $form->{"exchangerate_$i"});
756
757     $exchangerate = qq|&nbsp;|;
758     if ($form->{currency} ne $form->{defaultcurrency}) {
759       if ($form->{"forex_$i"}) {
760         $exchangerate =
761           qq|<input type=hidden name="exchangerate_$i" value=$form->{"exchangerate_$i"}>$form->{"exchangerate_$i"}|;
762       } else {
763         $exchangerate =
764           qq|<input name="exchangerate_$i" size=10 value=$form->{"exchangerate_$i"}>|;
765       }
766     }
767     $exchangerate .= qq|
768 <input type=hidden name="forex_$i" value=$form->{"forex_$i"}>
769 |;
770
771     $column_data{"paid_$i"} =
772       qq|<td align=center><input name="paid_$i" size=11 value="$form->{"paid_$i"}" onBlur=\"check_right_number_format(this)\"></td>|;
773     $column_data{"exchangerate_$i"} = qq|<td align=center>$exchangerate</td>|;
774     $column_data{"AP_paid_$i"}      =
775       qq|<td align=center><select name="AP_paid_$i">$form->{"selectAP_paid_$i"}</select></td>|;
776     $column_data{"datepaid_$i"} =
777       qq|<td align=center><input name="datepaid_$i" id="datepaid_$i" size=11 title="$myconfig{dateformat}" value="$form->{"datepaid_$i"}" onBlur=\"check_right_date_format(this)\">
778          <input type="button" name="datepaid_$i" id="trigger_datepaid_$i" value="?"></td>|;
779     $column_data{"source_$i"} =
780       qq|<td align=center><input name="source_$i" size=11 value="$form->{"source_$i"}"></td>|;
781     $column_data{"memo_$i"} =
782       qq|<td align=center><input name="memo_$i" size=11 value="$form->{"memo_$i"}"></td>|;
783
784     map { print qq|$column_data{"${_}_$i"}\n| } @column_index;
785
786     print qq|
787         </tr>
788 |;
789     push(@triggers, "datepaid_$i", "BL", "trigger_datepaid_$i");
790   }
791
792   my $paid_missing = $form->{oldinvtotal} - $totalpaid;
793
794   print qq|
795         <tr>
796           <td></td>
797           <td></td>
798           <td align="center">| . $locale->text('Total') . qq|</td>
799           <td align="center">| . H($form->format_amount(\%myconfig, $totalpaid, 2)) . qq|</td>
800         </tr>
801         <tr>
802           <td></td>
803           <td></td>
804           <td align="center">| . $locale->text('Missing amount') . qq|</td>
805           <td align="center">| . H($form->format_amount(\%myconfig, $paid_missing, 2)) . qq|</td>
806         </tr>
807
808             <input type=hidden name=oldinvtotal value=$form->{oldinvtotal}>
809             <input type=hidden name=paidaccounts value=$form->{paidaccounts}>
810             <input type=hidden name=selectAP_paid value="$form->{selectAP_paid}">
811       </table>
812     </td>
813   </tr>
814   <tr>
815     <td><hr size=3 noshade></td>
816   </tr>
817 </table>
818 <br>
819 |;
820
821   $invdate  = $form->datetonum($form->{invdate},  \%myconfig);
822   $closedto = $form->datetonum($form->{closedto}, \%myconfig);
823
824   print qq|<input class=submit type=submit name=action id=update_button value="|
825     . $locale->text('Update') . qq|">
826 |;
827
828   if ($form->{id}) {
829     my $show_storno = !$form->{storno} && !IS->has_storno(\%myconfig, $form, "ap") && (($totalpaid == 0) || ($totalpaid eq ""));
830
831     print qq|<input class=submit type=submit name=action value="|
832       . $locale->text('Post Payment') . qq|">
833 |;
834     print qq|<input class=submit type=submit name=action value="|
835       . $locale->text('Storno') . qq|">
836 | if ($show_storno);
837     if ($form->{radier}) {
838     print qq|
839     <input class=submit type=submit name=action value="|
840       . $locale->text('Delete') . qq|">
841 |;
842   }
843     print qq|<input class=submit type=submit name=action value="|
844       . $locale->text('Use As Template') . qq|">
845         <input type="button" class="submit" onclick="follow_up_window()" value="|
846       . $locale->text('Follow-Up')
847       . qq|">
848 |;
849
850   }
851
852   if (!$form->{id} && ($invdate > $closedto)) {
853     print qq| <input class=submit type=submit name=action value="|
854       . $locale->text('Post') . qq|"> | .
855       NTI($cgi->submit('-name' => 'action', '-value' => $locale->text('Save draft'),
856                        '-class' => 'submit'));
857   }
858
859   print $form->write_trigger(\%myconfig, scalar(@triggers) / 3, @triggers);
860   $form->hide_form(qw(rowcount callback draft_id draft_description vendor_discount));
861
862   # button for saving history
863   if($form->{id} ne "") {
864     print qq|
865           <input type="button" class="submit" onclick="set_history_window(|
866           . Q($form->{id})
867           . qq|);" name="history" id="history" value="|
868           . $locale->text('history')
869           . qq|">|;
870   }
871   # /button for saving history
872   # mark_as_paid button
873   if($form->{id} ne "") {
874     print qq| <input type="submit" class="submit" name="action" value="|
875           . $locale->text('mark as paid') . qq|">|;
876   }
877   # /mark_as_paid button
878 print qq|</form>
879 </body>
880 </html>
881 |;
882
883   $lxdebug->leave_sub();
884 }
885
886 sub mark_as_paid {
887   $lxdebug->enter_sub();
888
889   $auth->assert('vendor_invoice_edit');
890
891   &mark_as_paid_common(\%myconfig,"ap");
892
893   $lxdebug->leave_sub();
894 }
895
896 sub update {
897   $lxdebug->enter_sub();
898
899   $auth->assert('vendor_invoice_edit');
900
901   map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(exchangerate creditlimit creditremaining);
902
903   &check_name(vendor);
904
905   $form->{forex}        = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{invdate}, 'sell');
906   $form->{exchangerate} = $form->{forex} if $form->{forex};
907
908   for $i (1 .. $form->{paidaccounts}) {
909     next unless $form->{"paid_$i"};
910     map { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } qw(paid exchangerate);
911     $form->{"forex_$i"}        = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{"datepaid_$i"}, 'sell');
912     $form->{"exchangerate_$i"} = $form->{"forex_$i"} if $form->{"forex_$i"};
913   }
914
915   $i            = $form->{rowcount};
916   $exchangerate = ($form->{exchangerate} * 1) || 1;
917
918   if (   ($form->{"partnumber_$i"} eq "")
919       && ($form->{"description_$i"} eq "")
920       && ($form->{"partsgroup_$i"} eq "")) {
921     $form->{creditremaining} += ($form->{oldinvtotal} - $form->{oldtotalpaid});
922     &check_form;
923
924   } else {
925
926     IR->retrieve_item(\%myconfig, \%$form);
927
928     my $rows = scalar @{ $form->{item_list} };
929
930     if ($rows) {
931       $form->{"qty_$i"} = 1 unless ($form->{"qty_$i"});
932
933       if ($rows > 1) {
934
935         &select_item;
936         exit;
937
938       } else {
939
940         # override sellprice if there is one entered
941         $sellprice = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"});
942
943         # ergaenzung fuer bug 736 Lieferanten-Rabatt auch in Einkaufsrechnungen vorbelegen jb
944         $form->{"discount_$i"} = $form->format_amount(\%myconfig, 
945                                                       $form->{vendor_discount} * 100 );
946         map { $form->{item_list}[$i]{$_} =~ s/\"/&quot;/g } qw(partnumber description unit);
947         map { $form->{"${_}_$i"} = $form->{item_list}[0]{$_} } keys %{ $form->{item_list}[0] };
948
949         $form->{"marge_price_factor_$i"} = $form->{item_list}->[0]->{price_factor};
950
951         ($sellprice || $form->{"sellprice_$i"}) =~ /\.(\d+)/;
952         $decimalplaces = max 2, length $1;
953
954         if ($sellprice) {
955           $form->{"sellprice_$i"} = $sellprice;
956         } else {
957           # if there is an exchange rate adjust sellprice
958           $form->{"sellprice_$i"} /= $exchangerate;
959         }
960
961         $amount                   = $form->{"sellprice_$i"} * $form->{"qty_$i"} * (1 - $form->{"discount_$i"} / 100);
962         $form->{creditremaining} -= $amount;
963         $form->{"sellprice_$i"}   = $form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces);
964         $form->{"qty_$i"}         = $form->format_amount(\%myconfig, $form->{"qty_$i"},       $dec_qty);
965       }
966
967       &display_form;
968
969     } else {
970
971       # ok, so this is a new part
972       # ask if it is a part or service item
973
974       if (   $form->{"partsgroup_$i"}
975           && ($form->{"partsnumber_$i"} eq "")
976           && ($form->{"description_$i"} eq "")) {
977         $form->{rowcount}--;
978         $form->{"discount_$i"} = "";
979         display_form();
980
981       } else {
982         $form->{"id_$i"}   = 0;
983         new_item();
984       }
985     }
986   }
987   $lxdebug->leave_sub();
988 }
989
990 sub storno {
991   $lxdebug->enter_sub();
992
993   $auth->assert('vendor_invoice_edit');
994
995   if ($form->{storno}) {
996     $form->error($locale->text('Cannot storno storno invoice!'));
997   }
998
999   if (IS->has_storno(\%myconfig, $form, "ap")) {
1000     $form->error($locale->text("Invoice has already been storno'd!"));
1001   }
1002
1003   my $employee_id = $form->{employee_id};
1004   invoice_links();
1005   prepare_invoice();
1006   relink_accounts();
1007
1008   # Payments must not be recorded for the new storno invoice.
1009   $form->{paidaccounts} = 0;
1010   map { my $key = $_; delete $form->{$key} if grep { $key =~ /^$_/ } qw(datepaid_ source_ memo_ paid_ exchangerate_ AR_paid_) } keys %{ $form };
1011
1012   # saving the history
1013   if(!exists $form->{addition} && $form->{id} ne "") {
1014     $form->{snumbers} = qq|invnumber_| . $form->{invnumber};
1015     $form->{addition} = "CANCELED";
1016     $form->save_history($form->dbconnect(\%myconfig));
1017   }
1018   # /saving the history
1019
1020   $form->{storno_id} = $form->{id};
1021   $form->{storno} = 1;
1022   $form->{id} = "";
1023   $form->{invnumber} = "Storno zu " . $form->{invnumber};
1024   $form->{rowcount}++;
1025   $form->{employee_id} = $employee_id;
1026   post();
1027   $lxdebug->leave_sub();
1028
1029 }
1030
1031 sub use_as_template {
1032   $lxdebug->enter_sub();
1033
1034   $auth->assert('vendor_invoice_edit');
1035
1036   map { delete $form->{$_} } qw(printed emailed queued invnumber invdate deliverydate id datepaid_1 source_1 memo_1 paid_1 exchangerate_1 AP_paid_1 storno);
1037   $form->{paidaccounts} = 1;
1038   $form->{rowcount}--;
1039   $form->{invdate} = $form->current_date(\%myconfig);
1040   &display_form;
1041
1042   $lxdebug->leave_sub();
1043 }
1044
1045 sub post_payment {
1046   $lxdebug->enter_sub();
1047
1048   $auth->assert('vendor_invoice_edit');
1049
1050   $form->{defaultcurrency} = $form->get_default_currency(\%myconfig);
1051   for $i (1 .. $form->{paidaccounts}) {
1052     if ($form->{"paid_$i"}) {
1053       $datepaid = $form->datetonum($form->{"datepaid_$i"}, \%myconfig);
1054
1055       $form->isblank("datepaid_$i", $locale->text('Payment date missing!'));
1056
1057       $form->error($locale->text('Cannot post payment for a closed period!'))
1058         if ($form->date_closed($form->{"datepaid_$i"}, \%myconfig));
1059
1060       if ($form->{currency} ne $form->{defaultcurrency}) {
1061         $form->{"exchangerate_$i"} = $form->{exchangerate}
1062           if ($invdate == $datepaid);
1063         $form->isblank("exchangerate_$i",
1064                        $locale->text('Exchangerate for payment missing!'));
1065       }
1066     }
1067   }
1068
1069   ($form->{AP})      = split /--/, $form->{AP};
1070   ($form->{AP_paid}) = split /--/, $form->{AP_paid};
1071   if (IR->post_payment(\%myconfig, \%$form)){
1072         if (!exists $form->{addition} && $form->{id} ne "") {
1073                 # saving the history
1074       $form->{snumbers} = qq|invnumber_| . $form->{invnumber};
1075                 $form->{addition} = "PAYMENT POSTED";
1076       $form->{what_done} = $form->{currency} . qq| | . $form->{paid} . qq| | . $locale->text("POSTED");
1077                 $form->save_history($form->dbconnect(\%myconfig));
1078                 # /saving the history
1079         }
1080
1081     $form->redirect($locale->text('Payment posted!'));
1082   }
1083
1084   $form->error($locale->text('Cannot post payment!'));
1085
1086   $lxdebug->leave_sub();
1087 }
1088
1089 sub post {
1090   $lxdebug->enter_sub();
1091
1092   $auth->assert('vendor_invoice_edit');
1093
1094   $form->{defaultcurrency} = $form->get_default_currency(\%myconfig);
1095
1096   $form->isblank("invdate",   $locale->text('Invoice Date missing!'));
1097   $form->isblank("vendor",    $locale->text('Vendor missing!'));
1098   $form->isblank("invnumber", $locale->text('Invnumber missing!'));
1099
1100   $form->{invnumber} =~ s/^\s*//g;
1101   $form->{invnumber} =~ s/\s*$//g;
1102
1103   # if the vendor changed get new values
1104   if (&check_name(vendor)) {
1105     &update;
1106     exit;
1107   }
1108
1109   &validate_items;
1110
1111   $closedto = $form->datetonum($form->{closedto}, \%myconfig);
1112   $invdate  = $form->datetonum($form->{invdate},  \%myconfig);
1113
1114   $form->error($locale->text('Cannot post invoice for a closed period!'))
1115     if ($form->date_closed($form->{"datepaid_$i"}, \%myconfig));
1116
1117   $form->isblank("exchangerate", $locale->text('Exchangerate missing!'))
1118     if ($form->{currency} ne $form->{defaultcurrency});
1119
1120   for $i (1 .. $form->{paidaccounts}) {
1121     if ($form->parse_amount(\%myconfig, $form->{"paid_$i"})) {
1122       $datepaid = $form->datetonum($form->{"datepaid_$i"}, \%myconfig);
1123
1124       $form->isblank("datepaid_$i", $locale->text('Payment date missing!'));
1125
1126       $form->error($locale->text('Cannot post payment for a closed period!'))
1127         if ($form->date_closed($form->{"datepaid_$i"}, \%myconfig));
1128
1129       if ($form->{currency} ne $form->{defaultcurrency}) {
1130         $form->{"exchangerate_$i"} = $form->{exchangerate}
1131           if ($invdate == $datepaid);
1132         $form->isblank("exchangerate_$i",
1133                        $locale->text('Exchangerate for payment missing!'));
1134       }
1135     }
1136   }
1137
1138   ($form->{AP})      = split /--/, $form->{AP};
1139   ($form->{AP_paid}) = split /--/, $form->{AP_paid};
1140   $form->{storno}  ||= 0;
1141
1142   $form->{id} = 0 if $form->{postasnew};
1143
1144
1145   relink_accounts();
1146   if (IR->post_invoice(\%myconfig, \%$form)){
1147         # saving the history
1148         if(!exists $form->{addition} && $form->{id} ne "") {
1149       $form->{snumbers} = qq|invnumber_| . $form->{invnumber};
1150       $form->{addition} = "POSTED";
1151                 #$form->{what_done} = $locale->text("Rechnungsnummer") . qq| | . $form->{invnumber};
1152                 $form->save_history($form->dbconnect(\%myconfig));
1153         }
1154         # /saving the history
1155     remove_draft() if $form->{remove_draft};
1156         $form->redirect(  $locale->text('Invoice')
1157                   . " $form->{invnumber} "
1158                   . $locale->text('posted!'));
1159   }
1160   $form->error($locale->text('Cannot post invoice!'));
1161
1162   $lxdebug->leave_sub();
1163 }
1164
1165 sub delete {
1166   $lxdebug->enter_sub();
1167
1168   $auth->assert('vendor_invoice_edit');
1169
1170   $form->header;
1171   print qq|
1172 <body>
1173
1174 <form method=post action=$form->{script}>
1175 |;
1176
1177   # delete action variable
1178   map { delete $form->{$_} } qw(action header);
1179
1180   foreach $key (keys %$form) {
1181     next if (($key eq 'login') || ($key eq 'password') || ('' ne ref $form->{$key}));
1182     $form->{$key} =~ s/\"/&quot;/g;
1183     print qq|<input type=hidden name=$key value="$form->{$key}">\n|;
1184   }
1185
1186   print qq|
1187 <h2 class=confirm>| . $locale->text('Confirm!') . qq|</h2>
1188
1189 <h4>|
1190     . $locale->text('Are you sure you want to delete Invoice Number')
1191     . qq| $form->{invnumber}</h4>
1192 <p>
1193 <input name=action class=submit type=submit value="|
1194     . $locale->text('Yes') . qq|">
1195 </form>
1196 |;
1197
1198   $lxdebug->leave_sub();
1199 }
1200
1201 sub yes {
1202   $lxdebug->enter_sub();
1203
1204   $auth->assert('vendor_invoice_edit');
1205
1206   if (IR->delete_invoice(\%myconfig, \%$form)) {
1207     # saving the history
1208     if(!exists $form->{addition}) {
1209       $form->{snumbers} = qq|invnumber_| . $form->{invnumber};
1210           $form->{addition} = "DELETED";
1211           $form->save_history($form->dbconnect(\%myconfig));
1212     }
1213     # /saving the history
1214     $form->redirect($locale->text('Invoice deleted!'));
1215   }
1216   $form->error($locale->text('Cannot delete invoice!'));
1217
1218   $lxdebug->leave_sub();
1219 }
1220
1221 sub set_duedate_vendor {
1222   $lxdebug->enter_sub();
1223
1224   print $form->ajax_response_header(), IR->get_duedate('vendor_id' => $form->{vendor_id},
1225                                                        'invdate'   => $form->{invdate},
1226                                                        'default'   => $form->{old_duedate});
1227
1228   $lxdebug->leave_sub();
1229 }