arap.pl entfernt
[kivitendo-erp.git] / bin / mozilla / cp.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) 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., 51 Franklin Street, Fifth Floor, Boston,
28 # MA 02110-1335, USA.
29 #======================================================================
30 #
31 # Payment module
32 #
33 #======================================================================
34
35 use SL::CP;
36 use SL::IS;
37 use SL::IR;
38 use SL::AR;
39 use SL::AP;
40 use Data::Dumper;
41 use strict;
42 #use warnings;
43
44 require "bin/mozilla/common.pl";
45
46 our ($form, %myconfig, $lxdebug, $locale, $auth);
47
48 1;
49
50 # end of main
51
52 sub payment {
53   $lxdebug->enter_sub();
54
55   $auth->assert('cash');
56
57   my (@curr);
58
59   $form->{ARAP} = ($form->{type} eq 'receipt') ? "AR" : "AP";
60   $form->{arap} = lc $form->{ARAP};
61
62   CP->paymentaccounts(\%myconfig, \%$form);
63
64   # Standard Konto für Umlaufvermögen
65   my $accno_arap = IS->get_standard_accno_current_assets(\%myconfig, \%$form);
66   # Entsprechend präventiv die Auswahlliste für Kontonummer
67   # auch mit value= zusammenbauen (s.a. oben bugfix 1771)
68   # Wichtig: Auch das Template anpassen, damit hidden input korrekt die "
69   # escaped.
70   $form->{selectaccount} = "";
71   $form->{"select$form->{ARAP}"} = "";
72
73   map { $form->{selectaccount} .= "<option value=\"$_->{accno}--$_->{description}\">$_->{accno}--$_->{description}</option>\n";
74         $form->{account}        = "$_->{accno}--$_->{description}" if ($_->{accno} eq $accno_arap) } @{ $form->{PR}{"$form->{ARAP}_paid"} };
75
76   # currencies
77   # oldcurrency ist zwar noch hier als fragment enthalten, wird aber bei
78   # der aktualisierung der form auch nicht mitübernommen. das konzept
79   # old_$FOO habe ich auch noch nicht verstanden ...
80   # Ok. Wenn currency übernommen werden, dann in callback-string über-
81   # geben und hier reinparsen, oder besser multibox oder html auslagern?
82   # Antwort: form->currency wird mit oldcurrency oder curr[0] überschrieben
83   # Wofür macht das Sinn?
84   @curr = $form->get_all_currencies();
85   $form->{defaultcurrency} = $form->{currency} = $form->{oldcurrency} =
86     $form->get_default_currency(\%myconfig);
87
88   # Entsprechend präventiv die Auswahlliste für Währungen
89   # auch mit value= zusammenbauen (s.a. oben bugfix 1771)
90   $form->{selectcurrency} = "";
91   map { $form->{selectcurrency} .= "<option value=\"$_\">$_</option>\n" } @curr;
92
93
94   &form_header;
95   &form_footer;
96
97   $lxdebug->leave_sub();
98 }
99
100 sub form_header {
101   $lxdebug->enter_sub;
102
103   $auth->assert('cash');
104
105   $::request->layout->add_javascripts("autocomplete_customer.js");
106
107   my ($arap, $exchangerate);
108
109   if (!$form->{ $form->{vc} . '_id' }) {
110     map { $form->{"addr$_"} = "" } (1 .. 4);
111   }
112
113   # bugfix 1771
114   # geändert von <option>asdf--2929
115   # nach:
116   #              <option value="asdf--2929">asdf--2929</option>
117   # offen: $form->{ARAP} kann raus?
118   for my $item ("account", "currency", $form->{ARAP}) {
119     $form->{$item} = H($form->{$item});
120     $form->{"select$item"} =~ s/ selected//;
121     $form->{"select$item"} =~ s/option value="\Q$form->{$item}\E">\Q$form->{$item}\E/option selected value="$form->{$item}">$form->{$item}/;
122   }
123
124   $form->{openinvoices} = 1;
125
126   # $locale->text('AR')
127   # $locale->text('AP')
128
129   $form->header;
130
131   $arap = lc $form->{ARAP};
132
133   print $::form->parse_html_template('cp/form_header', {
134     is_customer => $form->{vc}   eq 'customer',
135     is_receipt  => $form->{type} eq 'receipt',
136     arap        => $arap,
137   });
138
139   $lxdebug->leave_sub;
140 }
141
142 sub list_invoices {
143   $::lxdebug->enter_sub;
144   $::auth->assert('cash');
145
146   my @columns = qw(amount due paid invnumber id transdate checked);
147   my (@invoices, %total);
148   for my $i (1 .. $::form->{rowcount}) {
149     push @invoices, +{ map { $_ => $::form->{"$_\_$i"} } @columns };
150     $total{$_} += $invoices[-1]{$_} = $::form->parse_amount(\%::myconfig, $invoices[-1]{$_}) for qw(amount due paid);
151   }
152
153   print $::form->parse_html_template('cp/invoices', {
154     invoices => \@invoices,
155     totals   => \%total,
156   });
157
158   $::lxdebug->leave_sub;
159 }
160
161 sub form_footer {
162   $::lxdebug->enter_sub;
163   $::auth->assert('cash');
164
165   print $::form->parse_html_template('cp/form_footer');
166
167   $::lxdebug->leave_sub;
168 }
169
170 sub update {
171   $lxdebug->enter_sub();
172
173   $auth->assert('cash');
174
175   my ($buysell, $updated, $exchangerate, $amount);
176
177   if ($form->{vc} eq 'customer') {
178     $buysell = "buy";
179   } else {
180     $buysell = "sell";
181   }
182
183   # search by invoicenumber,
184   if ($form->{invnumber}) {
185     $form->{open} ='Y'; # only open invoices
186     if ($form->{ARAP} eq 'AR'){
187       # ar_transactions automatically searches by $form->{customer_id} or else
188       # $form->{customer} if available, and these variables will always be set
189       # so we have to empty these values first
190       $form->{customer_id} = '';
191       $form->{customer} = '';
192       AR->ar_transactions(\%myconfig, \%$form);
193
194       # if you search for invoice '11' ar_transactions will also match invoices
195       # 112, 211, ... due to the LIKE
196
197       # so there is now an extra loop that tries to match the invoice number
198       # exactly among all returned results, and then passes the customer_id instead of the name
199       # because the name may not be unique
200
201       my $found_exact_invnumber_match = 0;
202       foreach my $i ( @{ $form->{AR} } ) {
203         next unless $i->{invnumber} eq $form->{invnumber};
204         # found exactly matching invnumber
205         $form->{customer_id} = $i->{customer_id};
206         $found_exact_invnumber_match = 1;
207       };
208
209       unless ( $found_exact_invnumber_match ) {
210         # use first returned entry, may not be the correct one if invnumber doesn't
211         # match uniquely
212         $form->{customer_id} = $form->{AR}[0]{customer_id};
213       };
214     } else {
215       # s.o. nur für zahlungsausgang
216       AP->ap_transactions(\%myconfig, \%$form);
217       $form->{vendor_id} = $form->{AP}[0]{vendor_id};
218     }
219   }
220
221   # determine customer/vendor
222   my $vc = $form->{vc};
223   if (($form->{"previous_${vc}_id"} || $form->{"${vc}_id"}) != $form->{"${vc}_id"}) {
224     IS->get_customer(\%myconfig, \%$form);
225   }
226
227   $form->{oldcurrency} = $form->{currency};
228
229   # get open invoices from ar/ap using a.${vc}_id, i.e. customer_id
230   CP->get_openinvoices(\%myconfig, \%$form) if $form->{"${vc}_id"};
231
232   if (!$form->{forex}) {        # read exchangerate from input field (not hidden)
233     $form->{exchangerate} = $form->parse_amount(\%myconfig, $form->{exchangerate});
234   }
235   $form->{forex}        = $form->check_exchangerate( \%myconfig, $form->{currency}, $form->{datepaid}, $buysell);
236   $form->{exchangerate} = $form->{forex} if $form->{forex};
237
238   $amount = $form->{amount} = $form->parse_amount(\%myconfig, $form->{amount});
239
240   if ($form->{"${vc}_id"}) {
241     $form->{rowcount} = 0;
242
243     $form->{queued} = "";
244
245     my $i = 0;
246     foreach my $ref (@{ $form->{PR} }) {
247       $i++;
248       $form->{"id_$i"}        = $ref->{id};
249       $form->{"invnumber_$i"} = $ref->{invnumber};
250       $form->{"transdate_$i"} = $ref->{transdate};
251       $ref->{exchangerate} = 1 unless $ref->{exchangerate};
252       $form->{"amount_$i"} = $ref->{amount} / $ref->{exchangerate};
253       $form->{"due_$i"}    =
254         ($ref->{amount} - $ref->{paid}) / $ref->{exchangerate};
255       $form->{"checked_$i"} = "";
256       $form->{"paid_$i"}    = "";
257
258       # need to format
259       map {
260         $form->{"${_}_$i"} =
261           $form->format_amount(\%myconfig, $form->{"${_}_$i"}, 2)
262       } qw(amount due);
263
264     }
265     $form->{rowcount} = $i;
266   }
267
268   # recalculate
269
270   # Modified from $amount = $form->{amount} by J.Zach to update amount to total
271   # payment amount in Zahlungsausgang
272   $amount = 0;
273   for my $i (1 .. $form->{rowcount}) {
274
275     map {
276       $form->{"${_}_$i"} =
277         $form->parse_amount(\%myconfig, $form->{"${_}_$i"})
278     } qw(amount due paid);
279
280     if ($form->{"checked_$i"}) {
281
282       # calculate paid_$i
283       if (!$form->{"paid_$i"}) {
284         $form->{"paid_$i"} = $form->{"due_$i"};
285       }
286
287       # Modified by J.Zach, see abovev
288       $amount += $form->{"paid_$i"};
289
290     } else {
291       $form->{"paid_$i"} = "";
292     }
293
294     map {
295       $form->{"${_}_$i"} =
296         $form->format_amount(\%myconfig, $form->{"${_}_$i"}, 2)
297     } qw(amount due paid);
298
299   }
300
301   # Line added by J.Zach, see above
302   $form->{amount}=$amount;
303
304   &form_header;
305   list_invoices() if $form->{"${vc}_id"};
306   &form_footer;
307
308   $lxdebug->leave_sub();
309 }
310
311 sub post {
312   $lxdebug->enter_sub();
313
314   $auth->assert('cash');
315
316   &check_form;
317
318   if ($form->{currency} ne $form->{defaultcurrency}) {
319     $form->error($locale->text('Exchangerate missing!'))
320       unless $form->{exchangerate};
321   }
322
323   # Beim Aktualisieren wird das Konto übernommen
324   # und jetzt auch Beleg und Datum
325   $form->{callback} = "cp.pl?action=payment&vc=$form->{vc}&type=$form->{type}&account=$form->{account}&$form->{currency}" .
326                       "&datepaid=$form->{datepaid}&source=$form->{source}";
327
328   my $msg1 = $::form->{type} eq 'receipt' ? $::locale->text("Receipt posted!") : $::locale->text("Payment posted!");
329   my $msg2 = $::form->{type} eq 'receipt' ? $::locale->text("Cannot post Receipt!") : $::locale->text("Cannot post Payment!");
330
331   # Die Nachrichten (Receipt posted!) werden nicht angezeigt.
332   # Entweder wieder aktivieren oder komplett rausnehmen
333   $form->redirect($msg1) if (CP->process_payment(\%::myconfig, $::form));
334   $form->error($msg2);
335
336   $lxdebug->leave_sub();
337 }
338
339 sub check_form {
340   $lxdebug->enter_sub();
341
342   $auth->assert('cash');
343
344   my ($closedto, $datepaid, $amount);
345
346   my $vc = $form->{vc};
347   if (($form->{"previous_${vc}_id"} || $form->{"${vc}_id"}) != $form->{"${vc}_id"}) {
348     IS->get_customer(\%myconfig, $form) if $vc eq 'customer';
349     IR->get_vendor(\%myconfig, $form)   if $vc eq 'vendor';
350   }
351
352   if ($form->{currency} ne $form->{oldcurrency}) {
353     &update;
354     $::dispatcher->end_request;
355   }
356   $form->error($locale->text('Date missing!')) unless $form->{datepaid};
357   my $selected_check = 1;
358   for my $i (1 .. $form->{rowcount}) {
359     next unless $form->{"checked_$i"};
360     if (abs($form->parse_amount(\%myconfig, $form->{"paid_$i"}, 2)) < 0.01) {
361       $form->error($locale->text('Row #1: amount has to be different from zero.', $i));
362     }
363     undef $selected_check;
364   }
365   $form->error($locale->text('No transaction selected!')) if $selected_check;
366
367   $closedto = $form->datetonum($form->{closedto}, \%myconfig);
368   $datepaid = $form->datetonum($form->{datepaid}, \%myconfig);
369
370   $form->error($locale->text('Cannot process payment for a closed period!'))
371     if ($form->date_closed($form->{"datepaid"}, \%myconfig));
372
373   $amount = $form->parse_amount(\%myconfig, $form->{amount});
374   $form->{amount} = $amount;
375
376   for my $i (1 .. $form->{rowcount}) {
377     if ($form->parse_amount(\%myconfig, $form->{"paid_$i"})) {
378       $amount -= $form->parse_amount(\%myconfig, $form->{"paid_$i"});
379
380       push(@{ $form->{paid}      ||= [] }, $form->{"paid_$i"});
381       push(@{ $form->{due}       ||= [] }, $form->{"due_$i"});
382       push(@{ $form->{invnumber} ||= [] }, $form->{"invnumber_$i"});
383       push(@{ $form->{invdate}   ||= [] }, $form->{"transdate_$i"});
384     }
385   }
386
387   if ($form->round_amount($amount, 2) != 0) {
388     push(@{ $form->{paid} }, $form->format_amount(\%myconfig, $amount, 2));
389     push(@{ $form->{due} }, $form->format_amount(\%myconfig, 0, "0"));
390     push(@{ $form->{invnumber} },
391          ($form->{ARAP} eq 'AR')
392          ? $locale->text('Deposit')
393          : $locale->text('Prepayment'));
394     push(@{ $form->{invdate} }, $form->{datepaid});
395   }
396
397   $lxdebug->leave_sub();
398 }