Dokumentation und Hinweise zur check_name, nachdem ich zum x-ten Male wieder selber...
[kivitendo-erp.git] / bin / mozilla / arap.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., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #======================================================================
29 #
30 # common routines for gl, ar, ap, is, ir, oe
31 #
32
33 use SL::Projects;
34
35 use strict;
36
37 # any custom scripts for this one
38 if (-f "bin/mozilla/custom_arap.pl") {
39   eval { require "bin/mozilla/custom_arap.pl"; };
40 }
41 if (-f "bin/mozilla/$main::form->{login}_arap.pl") {
42   eval { require "bin/mozilla/$main::form->{login}_arap.pl"; };
43 }
44
45 1;
46
47 require "bin/mozilla/common.pl";
48
49 # end of main
50
51 sub check_name {
52   $main::lxdebug->enter_sub();
53
54   my $form     = $main::form;
55   my %myconfig = %main::myconfig;
56   my $locale   = $main::locale;
57
58   $main::auth->assert('general_ledger               | vendor_invoice_edit       | sales_order_edit    | invoice_edit |' .
59                 'request_quotation_edit       | sales_quotation_edit      | purchase_order_edit | cash         |' .
60                 'purchase_delivery_order_edit | sales_delivery_order_edit');
61
62   my ($name) = @_;
63
64   $name = $name eq "customer" ? "customer" : "vendor";
65
66   my ($new_name, $new_id) = split /--/, $form->{$name};
67   my $i = 0;
68   # if we use a selection
69   if ($form->{"select$name"}) {
70     if ($form->{"old$name"} ne $form->{$name}) {
71
72       # this is needed for is, ir and oe
73       $form->{update} = 0;
74       # for credit calculations
75       $form->{oldinvtotal}  = 0;
76       $form->{oldtotalpaid} = 0;
77       $form->{calctax}      = 1;
78
79       $form->{"${name}_id"} = $new_id;
80
81       IS->get_customer(\%myconfig, \%$form) if ($name eq 'customer');
82       IR->get_vendor(\%myconfig, \%$form) if ($name eq 'vendor');
83
84       $form->{$name} = $form->{"old$name"} = "$new_name--$new_id";
85
86       $i = 1;
87     }
88   } else {
89
90     # check name, combine name and id
91     if ($form->{"old$name"} ne qq|$form->{$name}--$form->{"${name}_id"}|) {
92
93       # this is needed for is, ir and oe
94       $form->{update} = 0;
95
96       # for credit calculations
97       $form->{oldinvtotal}  = 0;
98       $form->{oldtotalpaid} = 0;
99       $form->{calctax}      = 1;
100
101       # return one name or a list of names in $form->{name_list}
102       if (($i = $form->get_name(\%myconfig, $name)) > 1) {
103         &select_name($name);
104         exit;
105       }
106
107       if ($i == 1) {
108
109         # we got one name
110         $form->{"${name}_id"} = $form->{name_list}[0]->{id};
111         $form->{$name}        = $form->{name_list}[0]->{name};
112         $form->{"old$name"}   = qq|$form->{$name}--$form->{"${name}_id"}|;
113
114         IS->get_customer(\%myconfig, \%$form) if ($name eq 'customer');
115         IR->get_vendor(\%myconfig, \%$form) if ($name eq 'vendor');
116
117       } else {
118
119         # name is not on file
120         # $locale->text('Customer not on file or locked!')
121         # $locale->text('Vendor not on file or locked!')
122         my $msg = ucfirst $name . " not on file or locked!";
123         $form->error($locale->text($msg));
124       }
125     }
126   }
127   $form->language_payment(\%myconfig);
128
129   $main::lxdebug->leave_sub();
130
131   return $i;
132 }
133
134 # $locale->text('Customer not on file!')
135 # $locale->text('Vendor not on file!')
136
137 sub select_name {
138   $main::lxdebug->enter_sub();
139
140   my $form     = $main::form;
141   my $locale   = $main::locale;
142
143   $main::auth->assert('general_ledger         | vendor_invoice_edit  | sales_order_edit    | invoice_edit |' .
144                 'request_quotation_edit | sales_quotation_edit | purchase_order_edit | cash');
145
146   my ($table) = @_;
147
148   my @column_index = qw(ndx name address);
149
150   my $label             = ucfirst $table;
151   my %column_data;
152   $column_data{ndx}  = qq|<th>&nbsp;</th>|;
153   $column_data{name} =
154     qq|<th class=listheading>| . $locale->text($label) . qq|</th>|;
155   $column_data{address} =
156     qq|<th class=listheading>| . $locale->text('Address') . qq|</th>|;
157
158   # list items with radio button on a form
159   $form->header;
160
161   my $title = $locale->text('Select from one of the names below');
162
163   print qq|
164 <body>
165
166 <form method=post action=$form->{script}>
167
168 <table width=100%>
169   <tr>
170     <th class=listtop>$title</th>
171   </tr>
172   <tr space=5></tr>
173   <tr>
174     <td>
175       <table width=100%>
176         <tr class=listheading>|;
177
178   map { print "\n$column_data{$_}" } @column_index;
179
180   print qq|
181         </tr>
182 |;
183
184   my $i = 0;
185   my $j;
186   foreach my $ref (@{ $form->{name_list} }) {
187     my $checked = ($i++) ? "" : "checked";
188
189     $ref->{name} =~ s/\"/&quot;/g;
190
191     $column_data{ndx} =
192       qq|<td><input name=ndx class=radio type=radio value=$i $checked></td>|;
193     $column_data{name} =
194       qq|<td><input name="new_name_$i" type=hidden value="$ref->{name}">$ref->{name}</td>|;
195     $column_data{address} = qq|<td>$ref->{address}&nbsp;</td>|;
196
197     $j++;
198     $j %= 2;
199     print qq|
200         <tr class=listrow$j>|;
201
202     map { print "\n$column_data{$_}" } @column_index;
203
204     print qq|
205         </tr>
206
207 <input name="new_id_$i" type=hidden value=$ref->{id}>
208
209 |;
210
211   }
212
213   print qq|
214       </table>
215     </td>
216   </tr>
217   <tr>
218     <td><hr size=3 noshade></td>
219   </tr>
220 </table>
221
222 <input name=lastndx type=hidden value=$i>
223
224 |;
225
226   # delete variables
227   map { delete $form->{$_} } qw(action name_list header);
228
229   # save all other form variables
230   foreach my $key (keys %${form}) {
231     next if (($key eq 'login') || ($key eq 'password') || ('' ne ref $form->{$key}));
232     $form->{$key} =~ s/\"/&quot;/g;
233     print qq|<input name=$key type=hidden value="$form->{$key}">\n|;
234   }
235
236   print qq|
237 <input type=hidden name=nextsub value=name_selected>
238
239 <input type=hidden name=vc value=$table>
240 <br>
241 <input class=submit type=submit name=action value="|
242     . $locale->text('Continue') . qq|">
243 </form>
244
245 </body>
246 </html>
247 |;
248
249   $main::lxdebug->leave_sub();
250 }
251
252 sub name_selected {
253   $main::lxdebug->enter_sub();
254
255   my $form     = $main::form;
256   my %myconfig = %main::myconfig;
257
258   $main::auth->assert('general_ledger         | vendor_invoice_edit  | sales_order_edit    | invoice_edit |' .
259                 'request_quotation_edit | sales_quotation_edit | purchase_order_edit | cash');
260
261   # replace the variable with the one checked
262
263   # index for new item
264   my $i = $form->{ndx};
265
266   $form->{ $form->{vc} }    = $form->{"new_name_$i"};
267   $form->{"$form->{vc}_id"} = $form->{"new_id_$i"};
268   $form->{"old$form->{vc}"} =
269     qq|$form->{$form->{vc}}--$form->{"$form->{vc}_id"}|;
270
271   # delete all the new_ variables
272   for $i (1 .. $form->{lastndx}) {
273     map { delete $form->{"new_${_}_$i"} } qw(id name);
274   }
275
276   map { delete $form->{$_} } qw(ndx lastndx nextsub);
277
278   IS->get_customer(\%myconfig, \%$form) if ($form->{vc} eq 'customer');
279   IR->get_vendor(\%myconfig, \%$form) if ($form->{vc} eq 'vendor');
280
281   &update(1);
282
283   $main::lxdebug->leave_sub();
284 }
285
286 sub check_project {
287   $main::lxdebug->enter_sub();
288
289   my $form     = $main::form;
290   my $locale   = $main::locale;
291
292   $main::auth->assert('general_ledger         | vendor_invoice_edit  | sales_order_edit    | invoice_edit |' .
293                 'request_quotation_edit | sales_quotation_edit | purchase_order_edit | cash         | report');
294
295   my $nextsub = shift || 'update';
296
297   for my $i (1 .. $form->{rowcount}) {
298     my $suffix = $i ? "_$i" : "";
299     my $prefix = $i ? "" : "global";
300     $form->{"${prefix}project_id${suffix}"} = "" unless $form->{"${prefix}projectnumber$suffix"};
301     if ($form->{"${prefix}projectnumber${suffix}"} ne $form->{"old${prefix}projectnumber${suffix}"}) {
302       if ($form->{"${prefix}projectnumber${suffix}"}) {
303
304         # get new project
305         $form->{projectnumber} = $form->{"${prefix}projectnumber${suffix}"};
306         my %params             = map { $_ => $form->{$_} } qw(projectnumber description active);
307         my $rows;
308         if (($rows = Projects->search_projects(%params)) > 1) {
309
310           # check form->{project_list} how many there are
311           $form->{rownumber} = $i;
312           &select_project($i ? undef : 1, $nextsub);
313           exit;
314         }
315
316         if ($rows == 1) {
317           $form->{"${prefix}project_id${suffix}"}       = $form->{project_list}->[0]->{id};
318           $form->{"${prefix}projectnumber${suffix}"}    = $form->{project_list}->[0]->{projectnumber};
319           $form->{"old${prefix}projectnumber${suffix}"} = $form->{project_list}->[0]->{projectnumber};
320         } else {
321
322           # not on file
323           $form->error($locale->text('Project not on file!'));
324         }
325       } else {
326         $form->{"old${prefix}projectnumber${suffix}"} = "";
327       }
328     }
329   }
330
331   $main::lxdebug->leave_sub();
332 }
333
334 sub select_project {
335   $main::lxdebug->enter_sub();
336
337   my $form     = $main::form;
338   my $locale   = $main::locale;
339   my $cgi      = $main::cgi;
340
341   $main::auth->assert('general_ledger         | vendor_invoice_edit  | sales_order_edit    | invoice_edit |' .
342                 'request_quotation_edit | sales_quotation_edit | purchase_order_edit | cash         | report');
343
344   my ($is_global, $nextsub) = @_;
345
346   my @column_index = qw(ndx projectnumber description);
347
348   my %column_data;
349   $column_data{ndx}           = qq|<th>&nbsp;</th>|;
350   $column_data{projectnumber} = qq|<th>| . $locale->text('Number') . qq|</th>|;
351   $column_data{description}   =
352     qq|<th>| . $locale->text('Description') . qq|</th>|;
353
354   # list items with radio button on a form
355   $form->header;
356
357   my $title = $locale->text('Select from one of the projects below');
358
359   print qq|
360 <body>
361
362 <form method=post action=$form->{script}>
363
364 <input type=hidden name=rownumber value=$form->{rownumber}>
365
366 <table width=100%>
367   <tr>
368     <th class=listtop>$title</th>
369   </tr>
370   <tr space=5></tr>
371   <tr>
372     <td>
373       <table width=100%>
374         <tr class=listheading>|;
375
376   map { print "\n$column_data{$_}" } @column_index;
377
378   print qq|
379         </tr>
380 |;
381
382   my $i = 0;
383   my $j;
384   foreach my $ref (@{ $form->{project_list} }) {
385     my $checked = ($i++) ? "" : "checked";
386
387     $ref->{name} =~ s/\"/&quot;/g;
388
389     $column_data{ndx} =
390       qq|<td><input name=ndx class=radio type=radio value=$i $checked></td>|;
391     $column_data{projectnumber} =
392       qq|<td><input name="new_projectnumber_$i" type=hidden value="$ref->{projectnumber}">$ref->{projectnumber}</td>|;
393     $column_data{description} = qq|<td>$ref->{description}</td>|;
394
395     $j++;
396     $j %= 2;
397     print qq|
398         <tr class=listrow$j>|;
399
400     map { print "\n$column_data{$_}" } @column_index;
401
402     print qq|
403         </tr>
404
405 <input name="new_id_$i" type=hidden value=$ref->{id}>
406
407 |;
408
409   }
410
411   print qq|
412       </table>
413     </td>
414   </tr>
415   <tr>
416     <td><hr size=3 noshade></td>
417   </tr>
418 </table>
419
420 <input name=lastndx type=hidden value=$i>
421
422 |;
423
424   # delete action variable
425   map { delete $form->{$_} } qw(action project_list header update);
426
427   # save all other form variables
428   foreach my $key (keys %${form}) {
429     next if (($key eq 'login') || ($key eq 'password') || ('' ne ref $form->{$key}));
430     $form->{$key} =~ s/\"/&quot;/g;
431     print qq|<input name=$key type=hidden value="$form->{$key}">\n|;
432   }
433
434   print
435       $cgi->hidden('-name' => 'is_global',                '-default' => [$is_global])
436     . $cgi->hidden('-name' => 'project_selected_nextsub', '-default' => [$nextsub])
437     . qq|<input type=hidden name=nextsub value=project_selected>
438
439 <br>
440 <input class=submit type=submit name=action value="|
441     . $locale->text('Continue') . qq|">
442 </form>
443
444 </body>
445 </html>
446 |;
447
448   $main::lxdebug->leave_sub();
449 }
450
451 sub project_selected {
452   $main::lxdebug->enter_sub();
453
454   my $form     = $main::form;
455
456   $main::auth->assert('general_ledger         | vendor_invoice_edit  | sales_order_edit    | invoice_edit |' .
457                 'request_quotation_edit | sales_quotation_edit | purchase_order_edit | cash         | report');
458
459   # replace the variable with the one checked
460
461   # index for new item
462   my $i = $form->{ndx};
463
464   my $prefix = $form->{"is_global"} ? "global" : "";
465   my $suffix = $form->{"is_global"} ? "" : "_$form->{rownumber}";
466
467   $form->{"${prefix}projectnumber${suffix}"} =
468     $form->{"new_projectnumber_$i"};
469   $form->{"old${prefix}projectnumber${suffix}"} =
470     $form->{"new_projectnumber_$i"};
471   $form->{"${prefix}project_id${suffix}"} = $form->{"new_id_$i"};
472
473   # delete all the new_ variables
474   for $i (1 .. $form->{lastndx}) {
475     map { delete $form->{"new_${_}_$i"} } qw(id projectnumber description);
476   }
477
478   my $nextsub = $form->{project_selected_nextsub} || 'update';
479
480   map { delete $form->{$_} } qw(ndx lastndx nextsub is_global project_selected_nextsub);
481
482   call_sub($nextsub);
483
484   $main::lxdebug->leave_sub();
485 }
486
487 sub continue       { call_sub($main::form->{"nextsub"}); }
488
489
490 1;
491
492 __END__
493
494 =head1 NAME
495
496 bin/mozilla/arap.pl - helper routines for invoiceing frontend.
497
498 =head1 SYNOPSIS
499
500 nothing yet
501
502 =head1 DESCRIPTION
503
504 nothing yet
505
506 =head1 FUNCTIONS
507
508 =head2 check_name customer|vendor
509
510 check_name was originally meant to update the selected customer or vendor. The
511 way it does that has generted more hate than almost any other part of this
512 software.
513
514 What it does is:
515
516 =over 4
517
518 =item
519
520 It checks if a vendor or customer is given. No failsafe, vendor fallback if
521 $_[0] is something fancy.
522
523 =item
524
525 It assumes, that there is a field named customer or vendor in $form.
526
527 =item
528
529 It assumes, that this field is filled with name--id, and tries to split that.
530 sql ledger uses that combination to get ids into the select keys.
531
532 =item
533
534 It looks for a field selectcustomer or selectvendor in $form. sql ledger used
535 to store a copy of the html select in there. (again, don't ask)
536
537 =item
538
539 If this field exists, it looks for a field called oldcustomer or oldvendor, in
540 which the old name--id string was stored in sql ledger, and compares those.
541
542 =item
543
544 if they don't match, it will set customer_id or vendor_id in $form, load the
545 entry (which will clobber everything in $form named like a column in customer
546 oder vendor) and return.
547
548 =item
549
550 If there was no select* entry, it assumes that vclimit was lower than the
551 number of entries, and that an input field was generated. In that case the
552 splitting is omitted (since users don't generally include ids in entered names)
553
554 =item
555
556 It looks for a *_id field, and combines it with the given input into a name--id
557 entry and compares it to the old* entry. (Missing any of these will instantly
558 break check_namea.
559
560 =item
561
562 If those do not match, $form->get_name is called to get matching results.
563 get_name only matches by *number and name, not by id, don't try to get it to do
564 so.
565
566 =item
567
568 The results are stored in $form>{name_list} but a count is returned, and
569 checked.
570
571 =item
572
573 If only one result was found, *_id, * and old* are copied into $form, the entry
574 is loaded (like above, clobbering)
575
576 =item
577
578 If there is more than one, a selection dialog is rendered
579
580 =item
581
582 If none is found, an error is generated.
583
584 =back
585
586 =head3 I built a customer/vendor box somewhere and it doesn't work, what's wrong?
587
588 Make sure a select* field is given if and only if you render a select box. The
589 actual contents are ignored, but recognition fails if not present.
590
591 Make sure old* and *_id fields are set correctly (name--id form for old*). They
592 are necessary in all steps and branches.
593
594 Since get_customer and get_vendor clobber a lot of fields, make sure what
595 changes exactly.
596
597 =cut