can't set $p without $cgi
[freeside.git] / sql-ledger / old / sql-ledger / bin / mozilla / io.pl
1 ######################################################################
2 # SQL-Ledger, Accounting
3 # Copyright (c) 1998-2002
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 #
25 # common routines used in is, ir, oe
26 #
27 #######################################################################
28
29 # any custom scripts for this one
30 if (-f "$form->{path}/custom_io.pl") {
31   eval { require "$form->{path}/custom_io.pl"; };
32 }
33 if (-f "$form->{path}/$form->{login}_io.pl") {
34   eval { require "$form->{path}/$form->{login}_io.pl"; };
35 }
36
37
38 1;
39 # end of main
40
41
42 # this is for our long dates
43 # $locale->text('January')
44 # $locale->text('February')
45 # $locale->text('March')
46 # $locale->text('April')
47 # $locale->text('May ')
48 # $locale->text('June')
49 # $locale->text('July')
50 # $locale->text('August')
51 # $locale->text('September')
52 # $locale->text('October')
53 # $locale->text('November')
54 # $locale->text('December')
55
56 # this is for our short month
57 # $locale->text('Jan')
58 # $locale->text('Feb')
59 # $locale->text('Mar')
60 # $locale->text('Apr')
61 # $locale->text('May')
62 # $locale->text('Jun')
63 # $locale->text('Jul')
64 # $locale->text('Aug')
65 # $locale->text('Sep')
66 # $locale->text('Oct')
67 # $locale->text('Nov')
68 # $locale->text('Dec')
69
70
71 sub display_row {
72   my $numrows = shift;
73
74   @column_index = (partnumber, description, qty);
75   
76   if ($form->{type} eq "sales_order") {
77     if ($form->{id}) {
78       push @column_index, "ship";
79       $column_data{ship} = qq|<th class=listheading align=left width="auto">|.$locale->text('Ship').qq|</th>|;
80     }
81   }
82   if ($form->{type} eq "purchase_order") {
83     if ($form->{id}) {
84       push @column_index, "ship";
85       $column_data{ship} = qq|<th class=listheading align=left width="auto">|.$locale->text('Recd').qq|</th>|;
86     }
87   }
88   
89   push @column_index, qw(unit sellprice);
90   
91   if ($form->{script} eq 'is.pl' || $form->{type} eq 'sales_order') {
92     push @column_index, qw(discount);
93   }
94   
95   push @column_index, "linetotal";
96
97   my $colspan = $#column_index + 1;
98
99      
100   $form->{invsubtotal} = 0;
101   map { $form->{"${_}_base"} = 0 } (split / /, $form->{taxaccounts});
102   
103   $column_data{partnumber} = qq|<th class=listheading nowrap>|.$locale->text('Number').qq|</th>|;
104   $column_data{description} = qq|<th class=listheading nowrap>|.$locale->text('Description').qq|</th>|;
105   $column_data{qty} = qq|<th class=listheading nowrap>|.$locale->text('Qty').qq|</th>|;
106   $column_data{unit} = qq|<th class=listheading nowrap>|.$locale->text('Unit').qq|</th>|;
107   $column_data{sellprice} = qq|<th class=listheading nowrap>|.$locale->text('Price').qq|</th>|;
108   $column_data{discount} = qq|<th class=listheading>%</th>|;
109   $column_data{linetotal} = qq|<th class=listheading nowrap>|.$locale->text('Extended').qq|</th>|;
110   $column_data{bin} = qq|<th class=listheading nowrap>|.$locale->text('Bin').qq|</th>|;
111   
112   print qq|
113   <tr>
114     <td>
115       <table width=100%>
116         <tr class=listheading>|;
117
118   map { print "\n$column_data{$_}" } @column_index;
119
120   print qq|
121         </tr>
122 |;
123
124
125   $projectnumber = $locale->text('Project');
126   $runningnumber = $locale->text('No.');
127   $partsgroup = $locale->text('Group');
128   
129   if ($form->{type} =~ /_order/) {
130     $reqdate = $locale->text('Required by');
131     $delvar = "reqdate";
132   } else {
133     $deliverydate = $locale->text('Delivery Date');
134     $delvar = "deliverydate";
135   }
136   
137   
138   for $i (1 .. $numrows) {
139     # undo formatting
140     map { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } qw(qty ship discount sellprice);
141
142     ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
143     $dec = length $dec;
144     $decimalplaces = ($dec > 2) ? $dec : 2;
145     
146     $discount = $form->round_amount($form->{"sellprice_$i"} * $form->{"discount_$i"}/100, $decimalplaces);
147     $linetotal = $form->round_amount($form->{"sellprice_$i"} - $discount, $decimalplaces);
148     $linetotal = $form->round_amount($linetotal * $form->{"qty_$i"}, 2);
149
150     # convert " to &quot;
151     map { $form->{"${_}_$i"} =~ s/"/&quot;/g } qw(partnumber description unit);
152     
153     $column_data{partnumber} = qq|<td><input name="partnumber_$i" size=20 value="$form->{"partnumber_$i"}"></td>|;
154
155     if (($rows = $form->numtextrows($form->{"description_$i"}, 30, 6)) > 1) {
156       $column_data{description} = qq|<td><textarea name="description_$i" rows=$rows cols=30 wrap=soft>$form->{"description_$i"}</textarea></td>|;
157     } else {
158       $column_data{description} = qq|<td><input name="description_$i" size=30 value="$form->{"description_$i"}"></td>|;
159     }
160
161     $column_data{qty} = qq|<td align=right><input name="qty_$i" size=5 value=|.$form->format_amount(\%myconfig, $form->{"qty_$i"}).qq|></td>|;
162     $column_data{ship} = qq|<td align=right><input name="ship_$i" size=5 value=|.$form->format_amount(\%myconfig, $form->{"ship_$i"}).qq|></td>|;
163     $column_data{unit} = qq|<td><input name="unit_$i" size=5 maxsize=5 value="$form->{"unit_$i"}"></td>|;
164     $column_data{sellprice} = qq|<td align=right><input name="sellprice_$i" size=9 value=|.$form->format_amount(\%myconfig, $form->{"sellprice_$i"}, $decimalplaces).qq|></td>|;
165     $column_data{discount} = qq|<td align=right><input name="discount_$i" size=3 value=|.$form->format_amount(\%myconfig, $form->{"discount_$i"}).qq|></td>|;
166     $column_data{linetotal} = qq|<td align=right>|.$form->format_amount(\%myconfig, $linetotal, 2).qq|</td>|;
167     $column_data{bin} = qq|<td>$form->{"bin_$i"}</td>|;
168     
169     print qq|
170         <tr valign=top>|;
171
172     map { print "\n$column_data{$_}" } @column_index;
173   
174     print qq|
175         </tr>
176
177 <input type=hidden name="id_$i" value=$form->{"id_$i"}>
178 <input type=hidden name="inventory_accno_$i" value=$form->{"inventory_accno_$i"}>
179 <input type=hidden name="bin_$i" value="$form->{"bin_$i"}">
180 <input type=hidden name="income_accno_$i" value=$form->{"income_accno_$i"}>
181 <input type=hidden name="expense_accno_$i" value=$form->{"expense_accno_$i"}>
182 <input type=hidden name="listprice_$i" value="$form->{"listprice_$i"}">
183 <input type=hidden name="assembly_$i" value="$form->{"assembly_$i"}">
184 <input type=hidden name="taxaccounts_$i" value="$form->{"taxaccounts_$i"}">
185
186 |;
187
188     # print second row
189     print qq|
190         <tr>
191           <td colspan=$colspan>
192             <table>
193               <tr>
194                 <th>$runningnumber</th>
195                 <td><input name="runningnumber_$i" size=3 value=$i></td>
196                 <td width=20></td>
197                 <th>$partsgroup</th>
198                 <td><input name="partsgroup_$i" size=10 value="$form->{"partsgroup_$i"}">
199                 <th>${$delvar}</th>
200                 <td><input name="${delvar}_$i" size=11 title="$myconfig{dateformat}" value="$form->{"${delvar}_$i"}"></td>
201                 <th>$projectnumber</th>
202                 <td><input name="projectnumber_$i" size=10 value="$form->{"projectnumber_$i"}">
203                     <input type=hidden name="oldprojectnumber_$i" value="$form->{"oldprojectnumber_$i"}">
204                     <input type=hidden name="project_id_$i" value="$form->{"project_id_$i"}"></td>
205               </tr>
206             </table>
207           </td>
208         </tr>
209         <tr>
210           <td colspan=$colspan><hr size=1 noshade></td>
211         </tr>
212 |;
213   
214
215     map { $form->{"${_}_base"} += $linetotal } (split / /, $form->{"taxaccounts_$i"});
216   
217     $form->{invsubtotal} += $linetotal;
218   }
219
220   print qq|
221       </table>
222     </td>
223   </tr>
224 |;
225
226 }
227
228
229 sub select_item {
230   
231   @column_index = qw(ndx partnumber description onhand sellprice);
232
233   $column_data{ndx} = qq|<th>&nbsp;</th>|;
234   $column_data{partnumber} = qq|<th class=listheading>|.$locale->text('Number').qq|</th>|;
235   $column_data{description} = qq|<th class=listheading>|.$locale->text('Description').qq|</th>|;
236   $column_data{sellprice} = qq|<th class=listheading>|.$locale->text('Price').qq|</th>|;
237   $column_data{onhand} = qq|<th class=listheading>|.$locale->text('Qty').qq|</th>|;
238   
239   
240   # list items with radio button on a form
241   $form->header;
242
243   $title = $locale->text('Select from one of the items below');
244   $colspan = $#column_index + 1;
245
246   print qq|
247 <body>
248
249 <form method=post action=$form->{script}>
250
251 <table width=100%>
252   <tr>
253     <th class=listtop colspan=$colspan>$title</th>
254   </tr>
255   <tr height="5"></tr>
256   <tr class=listheading>|;
257
258   map { print "\n$column_data{$_}" } @column_index;
259   
260   print qq|</tr>|;
261
262   my $i = 0;
263   foreach $ref (@{ $form->{item_list} }) {
264     $checked = ($i++) ? "" : "checked";
265
266     map { $ref->{$_} =~ s/"/&quot;/g } qw(partnumber description unit);
267
268     $column_data{ndx} = qq|<td><input name=ndx class=radio type=radio value=$i $checked></td>|;
269     $column_data{partnumber} = qq|<td><input name="new_partnumber_$i" type=hidden value="$ref->{partnumber}">$ref->{partnumber}</td>|;
270     $column_data{description} = qq|<td><input name="new_description_$i" type=hidden value="$ref->{description}">$ref->{description}</td>|;
271     $column_data{sellprice} = qq|<td align=right><input name="new_sellprice_$i" type=hidden value=$ref->{sellprice}>|.$form->format_amount(\%myconfig, $ref->{sellprice}, 2, "&nbsp;").qq|</td>|;
272     $column_data{onhand} = qq|<td align=right><input name="new_onhand_$i" type=hidden value=$ref->{onhand}>|.$form->format_amount(\%myconfig, $ref->{onhand}, '', "&nbsp;").qq|</td>|;
273     
274     $j++; $j %= 2;
275     print qq|
276 <tr class=listrow$j>|;
277
278     map { print "\n$column_data{$_}" } @column_index;
279
280     print qq|
281 </tr>
282
283 <input name="new_bin_$i" type=hidden value="$ref->{bin}">
284 <input name="new_listprice_$i" type=hidden value=$ref->{listprice}>
285 <input name="new_inventory_accno_$i" type=hidden value=$ref->{inventory_accno}>
286 <input name="new_income_accno_$i" type=hidden value=$ref->{income_accno}>
287 <input name="new_expense_accno_$i" type=hidden value=$ref->{expense_accno}>
288 <input name="new_unit_$i" type=hidden value="$ref->{unit}">
289 <input name="new_weight_$i" type=hidden value="$ref->{weight}">
290 <input name="new_assembly_$i" type=hidden value="$ref->{assembly}">
291 <input name="new_taxaccounts_$i" type=hidden value="$ref->{taxaccounts}">
292 <input name="new_partsgroup_$i" type=hidden value="$ref->{partsgroup}">
293
294 <input name="new_id_$i" type=hidden value=$ref->{id}>
295
296 |;
297
298   }
299   
300   print qq|
301 <tr><td colspan=8><hr size=3 noshade></td></tr>
302 </table>
303
304 <input name=lastndx type=hidden value=$i>
305
306 |;
307
308   # delete action variable
309   delete $form->{action};
310   delete $form->{item_list};
311     
312   # save all other form variables
313   foreach $key (keys %${form}) {
314     $form->{$key} =~ s/"/&quot;/g;
315     print qq|<input name=$key type=hidden value="$form->{$key}">\n|;
316   }
317
318   print qq|
319 <input type=hidden name=nextsub value=item_selected>
320
321 <br>
322 <input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
323 </form>
324
325 </body>
326 </html>
327 |;
328
329 }
330
331
332
333 sub item_selected {
334
335   # replace the last row with the checked row
336   $i = $form->{rowcount};
337   $i = $form->{assembly_rows} if ($form->{item} eq 'assembly');
338
339   # index for new item
340   $j = $form->{ndx};
341
342   # if there was a price entered, override it
343   $sellprice = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"});
344   
345   map { $form->{"${_}_$i"} = $form->{"new_${_}_$j"} } qw(id partnumber description sellprice listprice inventory_accno income_accno expense_accno bin unit weight assembly taxaccounts partsgroup);
346
347   ($dec) = ($form->{"sellprice_$i"} =~ /\.(\d+)/);
348   $dec = length $dec;
349   $decimalplaces = ($dec > 2) ? $dec : 2;
350
351   if ($sellprice) {
352     $form->{"sellprice_$i"} = $sellprice;
353   } else {
354     # if there is an exchange rate adjust sellprice
355     if (($form->{exchangerate} * 1) != 0) {
356       $form->{"sellprice_$i"} /= $form->{exchangerate};
357       $form->{"sellprice_$i"} = $form->round_amount($form->{"sellprice_$i"}, $decimalplaces);
358     }
359   }
360
361   map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(sellprice weight);
362
363   $form->{sellprice} += ($form->{"sellprice_$i"} * $form->{"qty_$i"});
364   $form->{weight} += ($form->{"weight_$i"} * $form->{"qty_$i"});
365
366   $amount = $form->{"sellprice_$i"} * (1 - $form->{"discount_$i"} / 100) * $form->{"qty_$i"};
367   map { $form->{"${_}_base"} += $amount } (split / /, $form->{"taxaccounts_$i"});
368   map { $amount += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } split / /, $form->{"taxaccounts_$i"} if !$form->{taxincluded};
369
370   $form->{creditremaining} -= $amount;
371
372   $form->{"runningnumber_$i"} = $i;
373   
374   # delete all the new_ variables
375   for $i (1 .. $form->{lastndx}) {
376     map { delete $form->{"new_${_}_$i"} } qw(partnumber description sellprice bin listprice inventory_accno income_accno expense_accno unit assembly taxaccounts id);
377   }
378   
379   map { delete $form->{$_} } qw(ndx lastndx nextsub);
380
381   if ($form->{item} eq 'assembly') {
382     map { $form->{"qty_$_"} = $form->parse_amount(\%myconfig, $form->{"qty_$_"}) } (1 .. $i);
383   } else {
384     # format amounts for invoice / order
385     map { $form->{"${_}_$i"} = $form->format_amount(\%myconfig, $form->{"${_}_$i"}, $decimalplaces) } qw(sellprice listprice);
386   }
387
388   &display_form;
389   
390 }
391
392
393 sub new_item {
394
395   # change callback
396   $form->{old_callback} = $form->escape($form->{callback},1);
397   $form->{callback} = $form->escape("$form->{script}?action=display_form",1);
398
399   # delete action
400   delete $form->{action};
401
402   # save all other form variables in a previous_form variable
403   foreach $key (keys %$form) {
404     # escape ampersands
405     $form->{$key} =~ s/&/%26/g;
406     $previous_form .= qq|$key=$form->{$key}&|;
407   }
408   chop $previous_form;
409   $previous_form = $form->escape($previous_form, 1);
410
411   $i = $form->{rowcount};
412   map { $form->{"${_}_$i"} =~ s/"/&quot;/g } qw(partnumber description);
413
414   $form->header;
415
416   print qq|
417 <body>
418
419 <h4 class=error>|.$locale->text('Item not on file!').qq|
420
421 <p>
422 |.$locale->text('What type of item is this?').qq|</h4>
423
424 <form method=post action=ic.pl>
425
426 <p>
427
428   <input class=radio type=radio name=item value=part checked>&nbsp;|.$locale->text('Part')
429 .qq|<br>
430   <input class=radio type=radio name=item value=service>&nbsp;|.$locale->text('Service')
431
432 .qq|
433 <input type=hidden name=previous_form value="$previous_form">
434 <input type=hidden name=partnumber value="$form->{"partnumber_$i"}">
435 <input type=hidden name=description value="$form->{"description_$i"}">
436 <input type=hidden name=rowcount value=$form->{rowcount}>
437
438 <input type=hidden name=path value=$form->{path}>
439 <input type=hidden name=login value=$form->{login}>
440 <input type=hidden name=password value=$form->{password}>
441
442 <input type=hidden name=nextsub value=add>
443
444 <p>
445 <input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
446 </form>
447
448 </body>
449 </html>
450 |;
451
452 }
453
454
455
456 sub display_form {
457
458   &form_header;
459
460   $numrows = ++$form->{rowcount};
461   $subroutine = "display_row";
462
463   if ($form->{item} eq 'part') {
464     $numrows = ++$form->{makemodel_rows};
465     $subroutine = "makemodel_row";
466   }
467   if ($form->{item} eq 'assembly') {
468     $numrows = ++$form->{makemodel_rows};
469     $subroutine = "makemodel_row";
470   
471     # create makemodel rows
472     &{ $subroutine }($numrows);
473
474     $numrows = ++$form->{assembly_rows};
475     $subroutine = "assembly_row";
476   }
477   if ($form->{item} eq 'service') {
478     $numrows = 0;
479   }
480
481   # create rows
482   &{ $subroutine }($numrows) if $numrows;
483
484   &form_footer;
485
486 }
487
488
489
490 sub check_form {
491   
492   my @a = ();
493   my $count = 0;
494   my @flds = (qw(id partnumber description qty sellprice unit discount inventory_accno income_accno expense_accno listprice taxaccounts bin assembly weight projectnumber project_id oldprojectnumber runningnumber partsgroup));
495
496   # remove any makes or model rows
497   if ($form->{item} eq 'part') {
498     map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(listprice sellprice lastcost weight rop);
499     
500     @flds = (make, model);
501     for my $i (1 .. ($form->{makemodel_rows})) {
502       if (($form->{"make_$i"} ne "") || ($form->{"model_$i"} ne "")) {
503         push @a, {};
504         my $j = $#a;
505
506         map { $a[$j]->{$_} = $form->{"${_}_$i"} } @flds;
507         $count++;
508       }
509     }
510
511     $form->redo_rows(\@flds, \@a, $count, $form->{makemodel_rows});
512     $form->{makemodel_rows} = $count;
513
514   } elsif ($form->{item} eq 'assembly') {
515     
516     $form->{sellprice} = 0;
517     $form->{weight} = 0;
518     map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(listprice rop);
519
520     @flds = qw(id qty unit bom partnumber description sellprice weight runningnumber partsgroup);
521     
522     for my $i (1 .. ($form->{assembly_rows} - 1)) {
523       if ($form->{"qty_$i"}) {
524         push @a, {};
525         my $j = $#a;
526
527         $form->{"qty_$i"} = $form->parse_amount(\%myconfig, $form->{"qty_$i"});
528
529         map { $a[$j]->{$_} = $form->{"${_}_$i"} } @flds;
530
531         $form->{sellprice} += ($form->{"qty_$i"} * $form->{"sellprice_$i"});
532         $form->{weight} += ($form->{"qty_$i"} * $form->{"weight_$i"});
533         $count++;
534       }
535     }
536
537     $form->{sellprice} = $form->round_amount($form->{sellprice}, 2);
538     
539     $form->redo_rows(\@flds, \@a, $count, $form->{assembly_rows});
540     $form->{assembly_rows} = $count;
541     
542     $count = 0;
543     @flds = qw(make model);
544     @a = ();
545     
546     for my $i (1 .. ($form->{makemodel_rows})) {
547       if (($form->{"make_$i"} ne "") || ($form->{"model_$i"} ne "")) {
548         push @a, {};
549         my $j = $#a;
550
551         map { $a[$j]->{$_} = $form->{"${_}_$i"} } @flds;
552         $count++;
553       }
554     }
555
556     $form->redo_rows(\@flds, \@a, $count, $form->{makemodel_rows});
557     $form->{makemodel_rows} = $count;
558
559   } else {
560
561     # this section applies to invoices and orders
562     # remove any empty numbers
563     
564     if ($form->{rowcount}) {
565       for my $i (1 .. $form->{rowcount} - 1) {
566         if ($form->{"partnumber_$i"}) {
567           push @a, {};
568           my $j = $#a;
569
570           map { $a[$j]->{$_} = $form->{"${_}_$i"} } @flds;
571           $count++;
572         }
573       }
574       
575       $form->redo_rows(\@flds, \@a, $count, $form->{rowcount});
576       $form->{rowcount} = $count;
577
578       $form->{creditremaining} -= &invoicetotal;
579       
580     }
581   }
582
583   &display_form;
584
585 }
586
587
588 sub invoicetotal {
589
590   $form->{oldinvtotal} = 0;
591   # add all parts and deduct paid
592   map { $form->{"${_}_base"} = 0 } split / /, $form->{taxaccounts};
593
594   my ($amount, $sellprice, $discount, $qty);
595   
596   for my $i (1 .. $form->{rowcount}) {
597     $sellprice = $form->parse_amount(\%myconfig, $form->{"sellprice_$i"});
598     $discount = $form->parse_amount(\%myconfig, $form->{"discount_$i"});
599     $qty = $form->parse_amount(\%myconfig, $form->{"qty_$i"});
600
601     $amount = $sellprice * (1 - $discount / 100) * $qty;
602     map { $form->{"${_}_base"} += $amount } (split / /, $form->{"taxaccounts_$i"});
603     $form->{oldinvtotal} += $amount;
604   }
605
606   map { $form->{oldinvtotal} += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } split / /, $form->{taxaccounts} if !$form->{taxincluded};
607   
608   $form->{oldtotalpaid} = 0;
609   for $i (1 .. $form->{paidaccounts}) {
610     $form->{oldtotalpaid} += $form->{"paid_$i"};
611   }
612   
613   # return total
614   ($form->{oldinvtotal} - $form->{oldtotalpaid});
615
616 }
617
618
619 sub validate_items {
620   
621   # check if items are valid
622   if ($form->{rowcount} == 1) {
623     &update;
624     exit;
625   }
626     
627   for $i (1 .. $form->{rowcount} - 1) {
628     $form->isblank("partnumber_$i", $locale->text('Number missing in Row') . " $i");
629   }
630
631 }
632
633
634 sub order {
635
636   $form->{ordnumber} = $form->{invnumber};
637
638   $form->{id} = '';
639
640   if ($form->{script} eq 'ir.pl') {
641     $form->{title} = $locale->text('Add Purchase Order');
642     $form->{vc} = 'vendor';
643     $form->{type} = 'purchase_order';
644     $buysell = 'sell';
645   }
646   if ($form->{script} eq 'is.pl') {
647     $form->{title} = $locale->text('Add Sales Order');
648     $form->{vc} = 'customer';
649     $form->{type} = 'sales_order';
650     $buysell = 'buy';
651   }
652   $form->{script} = 'oe.pl';
653
654   $form->{shipto} = 1;
655   
656   $form->{rowcount}--;
657
658   require "$form->{path}/$form->{script}";
659
660   map { $form->{"select$_"} = "" } ($form->{vc}, currency);
661   
662   $currency = $form->{currency};
663   
664   &order_links;
665
666   $form->{currency} = $currency;
667   $form->{exchangerate} = "";
668   $form->{forex} = "";
669   $form->{exchangerate} = $exchangerate if ($form->{forex} = ($exchangerate = $form->check_exchangerate(\%myconfig, $form->{currency}, $form->{orddate}, $buysell))); 
670   
671   &prepare_order;
672   &display_form;
673
674 }
675
676
677 sub e_mail {
678
679
680   if ($myconfig{admin}) {
681     $bcc = qq|
682           <th align=right nowrap=true>|.$locale->text('Bcc').qq|</th>
683           <td><input name=bcc size=30 value="$form->{bcc}"></td>
684 |;
685   }
686
687   if ($form->{type} eq 'packing_list') {
688     $form->{email} = $form->{shiptoemail} if $form->{shiptoemail};
689   }
690
691   $name = $form->{$form->{vc}};
692   $name =~ s/--.*//g;
693   $title = $locale->text('E-mail')." $name";
694   
695   $form->{oldmedia} = $form->{media};
696   $form->{media} = "email";
697   
698   $form->header;
699
700   print qq|
701 <body>
702
703 <form method=post action=$form->{script}>
704
705 <table width=100%>
706   <tr class=listtop>
707     <th class=listtop>$title</th>
708   </tr>
709   <tr height="5"></tr>
710   <tr>
711     <td>
712       <table width=100%>
713         <tr>
714           <th align=right nowrap>|.$locale->text('To').qq|</th>
715           <td><input name=email size=30 value="$form->{email}"></td>
716           <th align=right nowrap>|.$locale->text('Cc').qq|</th>
717           <td><input name=cc size=30 value="$form->{cc}"></td>
718         </tr>
719         <tr>
720           <th align=right nowrap>|.$locale->text('Subject').qq|</th>
721           <td><input name=subject size=30 value="$form->{subject}"></td>
722           $bcc
723         </tr>
724       </table>
725     </td>
726   </tr>
727   <tr>
728     <td>
729       <table width=100%>
730         <tr>
731           <th align=left nowrap>|.$locale->text('Message').qq|</th>
732         </tr>
733         <tr>
734           <td><textarea name=message rows=15 cols=60 wrap=soft>$form->{message}</textarea></td>
735         </tr>
736       </table>
737     </td>
738   </tr>
739   <tr>
740     <td>
741 |;
742
743   &print_options;
744   
745   map { delete $form->{$_} } qw(action email cc bcc subject message type sendmode format);
746   
747   # save all other variables
748   foreach $key (keys %$form) {
749     $form->{$key} =~ s/"/&quot;/g;
750     print qq|<input type=hidden name=$key value="$form->{$key}">\n|;
751   }
752
753   print qq|
754     </td>
755   </tr>
756   <tr>
757     <td><hr size=3 noshade></td>
758   </tr>
759 </table>
760
761 <input type=hidden name=nextsub value=send_email>
762
763 <br>
764 <input name=action class=submit type=submit value="|.$locale->text('Continue').qq|">
765 </form>
766
767 </body>
768 </html>
769 |;
770
771 }
772
773
774 sub send_email {
775
776   $old_form = new Form;
777   map { $old_form->{$_} = $form->{$_} } keys %$form;
778   $old_form->{media} = $form->{oldmedia};
779   &print_form($old_form);
780   
781 }
782   
783
784  
785 sub print_options {
786
787   $form->{sendmode} = "attachment";
788   $form->{copies} = 3 unless $form->{copies};
789   
790   $form->{PD}{$form->{type}} = "checked";
791   $form->{DF}{$form->{format}} = "checked";
792   $form->{OP}{$form->{media}} = "checked";
793   $form->{SM}{$form->{sendmode}} = "checked";
794   
795   if ($form->{type} =~ /_order/) {
796     $order = qq|
797           <td align=right><input class=radio type=radio name=type value="$`_order" $form->{PD}{"$`_order"}></td><td>|.$locale->text('Order').qq|</td>
798 |;
799   } else {
800     $invoice = qq|
801           <td align=right><input class=radio type=radio name=type value=invoice $form->{PD}{invoice}></td><td>|.$locale->text('Invoice').qq|</td>
802           <td align=right><input class=radio type=radio name=type value=packing_list $form->{PD}{packing_list}></td><td>|.$locale->text('Packing List').qq|</td>
803 |;
804   }
805
806   if ($form->{media} eq 'email') {
807     $email = qq|
808         <td align=center><input class=radio type=radio name=sendmode value=attachment $form->{SM}{attachment}> |.$locale->text('Attachment')
809         .qq| <input class=radio type=radio name=sendmode value=inline $form->{SM}{inline}> |.$locale->text('In-line').qq|</td>
810 |;
811   } else {
812     $screen = qq|
813         <td align=right><input class=radio type=radio name=media value=screen $form->{OP}{screen}></td>
814         <td>|.$locale->text('Screen').qq|</td>
815 |;
816   }
817
818   print qq|
819 <table width=100%>
820   <tr valign=top>
821     $invoice
822     $order
823     <td align=right><input class=radio type=radio name=format value=html $form->{DF}{html}></td>
824     <td>html</td>
825 |;
826
827   if ($latex) {
828       print qq|
829     <td align=right><input class=radio type=radio name=format value=postscript $form->{DF}{postscript}></td>
830     <td>|.$locale->text('Postscript').qq|</td>
831     <td align=right><input class=radio type=radio name=format value=pdf $form->{DF}{pdf}></td>
832     <td>|.$locale->text('PDF').qq|</td>
833 |;
834   }
835
836   print qq|
837     $screen
838 |;
839
840   if ($screen) {
841     if ($myconfig{printer} && $latex) {
842       print qq|
843     <td align=right><input class=radio type=radio name=media value=printer $form->{OP}{printer}></td>
844     <td>|.$locale->text('Printer')
845     .qq| (|.$locale->text('Copies')
846     .qq| <input name=copies size=2 value=$form->{copies}>)</td>
847 |;
848     }
849   }
850
851   
852   $form->{groupitems} = "checked" if $form->{groupitems};
853   
854   print qq|
855     $email
856     <td align=right><input name=groupitems type=checkbox class=checkbox $form->{groupitems}></td>
857     <td>|.$locale->text('Group Items').qq|</td>
858   </tr>
859 </table>
860 |;
861
862 }
863
864
865 sub print {
866   
867   # if this goes to the printer pass through
868   if ($form->{media} eq 'printer') {
869     $form->error($locale->text('Select postscript or PDF!')) if ($form->{format} !~ /(postscript|pdf)/);
870
871     $old_form = new Form;
872     map { $old_form->{$_} = $form->{$_} } keys %$form;
873   }
874
875   &print_form($old_form);
876
877 }
878
879
880 sub print_form {
881   my $old_form = shift;
882   
883   $inv = "inv";
884   $due = "due";
885
886   if ($form->{type} eq "invoice") {
887     $form->{label} = $locale->text('Invoice');
888   }
889   if ($form->{type} eq "packing_list") {
890     $form->{label} = $locale->text('Packing List');
891   }
892   if ($form->{type} eq 'sales_order') {
893     $inv = "ord";
894     $due = "req";
895     $form->{label} = $locale->text('Sales Order');
896   }
897   if ($form->{type} eq 'purchase_order') {
898     $inv = "ord";
899     $due = "req";
900     $form->{label} = $locale->text('Purchase Order');
901   }
902
903   $form->isblank("email", $locale->text('E-mail address missing!')) if ($form->{media} eq 'email');
904   $form->isblank("${inv}number", $locale->text($form->{label} .' Number missing!'));
905   $form->isblank("${inv}date", $locale->text($form->{label} .' Date missing!'));
906
907 # $locale->text('Invoice Number missing!')
908 # $locale->text('Invoice Date missing!')
909 # $locale->text('Packing List Number missing!')
910 # $locale->text('Packing List Date missing!')
911 # $locale->text('Order Number missing!')
912 # $locale->text('Order Date missing!')
913
914   &validate_items;
915
916   &{ "$form->{vc}_details" };
917
918   @a = ();
919   map { push @a, ("partnumber_$_", "description_$_") } (1 .. $form->{rowcount});
920   map { push @a, "${_}_description" } split / /, $form->{taxaccounts};
921   $form->format_string(@a);
922
923   # format payment dates
924   map { $form->{"datepaid_$_"} = $locale->date(\%myconfig, $form->{"datepaid_$_"}) } (1 .. $form->{paidaccounts});
925   
926   # create the form variables for the invoice, packing list or order
927   if ($form->{type} =~ /order$/) {
928     OE->order_details(\%myconfig, \%$form);
929   } else {
930     IS->invoice_details(\%myconfig, \%$form);
931   }
932
933   $form->{"${inv}date"} = $locale->date(\%myconfig, $form->{"${inv}date"}, 1);
934   $form->{"${due}date"} = $locale->date(\%myconfig, $form->{"${due}date"}, 1);
935   
936   
937   @a = qw(name addr1 addr2 addr3 addr4);
938  
939   $fillshipto = 1;
940   # if there is no shipto fill it in from billto
941   foreach $item (@a) {
942     if ($form->{"shipto$item"}) {
943       $fillshipto = 0;
944       last;
945     }
946   }
947
948   if ($fillshipto) {
949     if ($form->{type} eq 'purchase_order') {
950         $form->{shiptoname} = $myconfig{company};
951         $form->{shiptoaddr1} = $myconfig{address};
952     } else {
953       map { $form->{"shipto$_"} = $form->{$_} } @a;
954     }
955   }
956
957   $form->{notes} =~ s/^\s+//g;
958
959   # some of the stuff could have umlauts so we translate them
960   push @a, qw(shiptoname shiptoaddr1 shiptoaddr2 shiptoaddr3 shiptoaddr4 shippingpoint company address signature notes);
961
962   push @a, ("${inv}date", "${due}date");
963   
964   $form->format_string(@a);
965
966
967   $form->{templates} = "$myconfig{templates}";
968   $form->{IN} = "$form->{type}.html";
969
970   if ($form->{format} eq 'postscript') {
971     $form->{postscript} = 1;
972     $form->{IN} =~ s/html$/tex/;
973   }
974   if ($form->{format} eq 'pdf') {
975     $form->{pdf} = 1;
976     $form->{IN} =~ s/html$/tex/;
977   }
978
979   $form->format_string(email, shiptoemail, cc, bcc) if $form->{format} =~ /(pdf|postscript)/;
980   
981   if ($form->{media} eq 'printer') {
982     $form->{OUT} = "| $myconfig{printer}";
983   }
984
985   if ($form->{media} eq 'email') {
986     $form->{subject} = qq|$form->{label} $form->{"${inv}number"}| unless $form->{subject};
987     
988     $form->{OUT} = "$sendmail";
989   }
990   
991
992   $form->parse_template(\%myconfig, $userspath);
993
994   $form->{callback} = "";
995   
996   # if we got back here restore the previous form
997   if ($form->{media} =~ /(printer|email)/) {
998     if ($old_form) {
999       # restore and display form
1000       map { $form->{$_} = $old_form->{$_} } keys %$old_form;
1001       $form->{rowcount}--;
1002       map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(exchangerate creditlimit creditremaining);
1003
1004       for $i (1 .. $form->{paidaccounts}) {
1005         map { $form->{"${_}_$i"} = $form->parse_amount(\%myconfig, $form->{"${_}_$i"}) } qw(paid exchangerate);
1006       }
1007       
1008       &display_form;
1009       exit;
1010     }
1011
1012     $msg = ($form->{media} eq 'printer') ? $locale->text('sent to printer') : $locale->text('emailed to')." $form->{email}";
1013     $form->redirect(qq|$form->{label} $form->{"${inv}number"} $msg|);
1014   }
1015
1016 }
1017
1018
1019 sub customer_details {
1020
1021   IS->customer_details(\%myconfig, \%$form);
1022
1023 }
1024
1025
1026 sub vendor_details {
1027
1028   IR->vendor_details(\%myconfig, \%$form);
1029
1030 }
1031
1032
1033 sub post_as_new {
1034
1035   $form->{postasnew} = 1;
1036   &post;
1037
1038 }
1039
1040
1041 sub ship_to {
1042
1043   $title = $form->{title};
1044   $form->{title} = $locale->text('Ship to');
1045   
1046   $form->{rowcount}--;
1047
1048   map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(exchangerate creditlimit creditremaining);
1049
1050   # get details for name
1051   &{ "$form->{vc}_details" };
1052
1053   $form->header;
1054
1055   print qq|
1056 <body>
1057
1058 <form method=post action=$form->{script}>
1059
1060 <table width=100%>
1061   <tr>
1062     <td>
1063       <table>
1064         <tr class=listheading>
1065           <th class=listheading colspan=2 width=50%>|.$locale->text('To').qq|</th>
1066           <th class=listheading width=50%>|.$locale->text('Ship to').qq|</th>
1067         </tr>
1068         <tr height="5"></tr>
1069         <tr>
1070           <th align=right nowrap>|.$locale->text('Number').qq|</th>
1071           <td>$form->{"$form->{vc}number"}</td>
1072         </tr>
1073         <tr>
1074           <th align=right nowrap>|.$locale->text('Name').qq|</th>
1075           <td>$form->{name}</td>
1076           <td><input name=shiptoname size=35 maxsize=35 value="$form->{shiptoname}"></td>
1077         </tr>
1078         <tr>
1079           <th align=right nowrap>|.$locale->text('Address').qq|</th>
1080           <td>$form->{addr1}</td>
1081           <td><input name=shiptoaddr1 size=35 maxsize=35 value="$form->{shiptoaddr1}"></td>
1082         </tr>
1083         <tr>
1084           <th></th>
1085           <td>$form->{addr2}</td>
1086           <td><input name=shiptoaddr2 size=35 maxsize=35 value="$form->{shiptoaddr2}"></td>
1087         </tr>
1088         <tr>
1089           <th></th>
1090           <td>$form->{addr3}</td>
1091           <td><input name=shiptoaddr3 size=35 maxsize=35 value="$form->{shiptoaddr3}"></td>
1092         </tr>
1093         <tr>
1094           <th></th>
1095           <td>$form->{addr4}</td>
1096           <td><input name=shiptoaddr4 size=35 maxsize=35 value="$form->{shiptoaddr4}"></td>
1097         </tr>
1098         <tr>
1099           <th align=right nowrap>|.$locale->text('Contact').qq|</th>
1100           <td>$form->{contact}</td>
1101           <td><input name=shiptocontact size=35 maxsize=35 value="$form->{shiptocontact}"></td>
1102         </tr>
1103         <tr>
1104           <th align=right nowrap>|.$locale->text('Phone').qq|</th>
1105           <td>$form->{"$form->{vc}phone"}</td>
1106           <td><input name=shiptophone size=20 maxsize=20 value="$form->{shiptophone}"></td>
1107         </tr>
1108         <tr>
1109           <th align=right nowrap>|.$locale->text('Fax').qq|</th>
1110           <td>$form->{"$form->{vc}fax"}</td>
1111           <td><input name=shiptofax size=20 maxsize=20 value="$form->{shiptofax}"></td>
1112         </tr>
1113         <tr>
1114           <th align=right nowrap>|.$locale->text('E-mail').qq|</th>
1115           <td>$form->{email}</td>
1116           <td><input name=shiptoemail size=35 value="$form->{shiptoemail}"></td>
1117         </tr>
1118       </table>
1119     </td>
1120   </tr>
1121 </table>
1122 |;
1123
1124   # delete shipto
1125   map { delete $form->{$_} } qw(shiptoname shiptoaddr1 shiptoaddr2 shiptoaddr3 shiptoaddr4 shiptocontact shiptophone shiptofax shiptoemail);
1126   $form->{title} = $title;
1127   
1128   foreach $key (keys %$form) {
1129     $form->{$key} =~ s/"/&quot;/g;
1130     print qq|<input type=hidden name=$key value="$form->{$key}">\n|;
1131   }
1132
1133   print qq|
1134
1135 <input type=hidden name=nextsub value=display_form>
1136
1137 <hr size=3 noshade>
1138
1139 <br>
1140 <input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
1141 </form>
1142
1143 </body>
1144 </html>
1145 |;
1146
1147 }
1148
1149