This commit was generated by cvs2svn to compensate for changes in r3880,
[freeside.git] / sql-ledger / old / sql-ledger / bin / mozilla / ic.pl
1 #=====================================================================
2 # SQL-Ledger, Accounting
3 # Copyright (c) 2001
4 #
5 #  Author: Dieter Simader
6 #   Email: dsimader@sql-ledger.org
7 #     Web: http://www.sql-ledger.org
8 #
9 #
10 # This program is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
14 #
15 # This program is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this program; if not, write to the Free Software
21 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #======================================================================
23 #
24 # Inventory Control module
25 #
26 #======================================================================
27
28
29 use SL::IC;
30
31 require "$form->{path}/io.pl";
32
33 1;
34 # end of main
35
36
37
38 sub add {
39
40   $form->{title} = $locale->text('Add ' . ucfirst $form->{item});
41
42   $form->{callback} = "$form->{script}?action=add&item=$form->{item}&path=$form->{path}&login=$form->{login}&password=$form->{password}" unless $form->{callback};
43
44   $form->{unit} = ($form->{item} eq 'service') ? $locale->text('hr') : $locale->text('ea');
45
46   &link_part;
47   
48   &display_form;
49   
50 }
51
52
53 sub search {
54
55   $form->{title} = (ucfirst $form->{searchitems})."s";
56   $form->{title} = $locale->text($form->{title});
57   
58 # $locale->text('Parts')
59 # $locale->text('Services')
60
61   unless ($form->{searchitems} eq 'service') {
62     
63     $onhand = qq|
64             <input name=itemstatus class=radio type=radio value=onhand>&nbsp;|.$locale->text('On Hand').qq|
65             <input name=itemstatus class=radio type=radio value=short>&nbsp;|.$locale->text('Short').qq|
66 |;
67
68     $makemodel = qq|
69         <tr>
70           <th width="1%" align=right nowrap>|.$locale->text('Make').qq|</th>
71           <td><input name=make size=20></td>
72           <th width="1%" align=right nowrap>|.$locale->text('Model').qq|</th>
73           <td><input name=model size=20></td>
74         </tr>
75 |;
76   }
77
78   if ($form->{searchitems} eq 'assembly') {
79
80     $form->{title} = $locale->text('Assemblies');
81     
82     $toplevel = qq|
83         <tr>
84           <td></td>
85           <td colspan=3>
86           <input name=none class=radio type=radio value=1 checked>&nbsp;|.$locale->text('Top Level').qq|
87           <input name=bom class=checkbox type=checkbox value=1>&nbsp;|.$locale->text('Individual Items').qq|
88           </td>
89         </tr>
90 |;
91     
92     $bought = qq|
93         <tr>
94           <td></td>
95           <td colspan=3>
96             <table>
97               <tr>
98                 <td>
99                   <table>
100                     <tr>
101                       <td><input name=sold class=checkbox type=checkbox value=1></td>
102                       <td nowrap>|.$locale->text('Sold').qq|</td>
103                     </tr>
104                     <tr>
105                       <td colspan=2><hr size=1 noshade></td>
106                     </tr>
107                     <tr>
108                       <td><input name=ordered class=checkbox type=checkbox value=1></td>
109                       <td nowrap>|.$locale->text('Ordered').qq|</td>
110                     </tr>
111                   </table>
112                 </td>
113                 <td width=5%>&nbsp;</td>
114                 <th>|.$locale->text('From').qq|</th>
115                 <td><input name=transdatefrom size=11 title="$myconfig{dateformat}"></td>
116                 <th>|.$locale->text('to').qq|</th>
117                 <td><input name=transdateto size=11 title="$myconfig{dateformat}"></td>
118
119                 <td><input name=closed class=checkbox type=checkbox value=1>&nbsp;|.$locale->text('Closed').qq|</td>
120               </tr>
121             </table>
122           </td>
123         </tr>
124 |;
125
126   } else {
127        
128      $bought = qq|
129         <tr>
130           <td></td>
131           <td colspan=3>
132             <table>
133               <tr>
134                 <td>
135                   <table>
136                     <tr>
137                       <td><input name=bought class=checkbox type=checkbox value=1></td>
138                       <td nowrap>|.$locale->text('Bought').qq|</td>
139                       <td><input name=sold class=checkbox type=checkbox value=1></td>
140                       <td nowrap>|.$locale->text('Sold').qq|</td>
141                     </tr>
142                     <tr>
143                       <td colspan=4><hr size=1 noshade></td>
144                     </tr>
145                     <tr>
146                       <td><input name=onorder class=checkbox type=checkbox value=1></td>
147                       <td nowrap>|.$locale->text('On Order').qq|</td>
148                       <td><input name=ordered class=checkbox type=checkbox value=1></td>
149                       <td nowrap>|.$locale->text('Ordered').qq|</td>
150                     </tr>
151                   </table>
152                 </td>
153                 <td width=5%>&nbsp;</td>
154                 <td>
155                   <table>
156                     <tr>
157                       <th>|.$locale->text('From').qq|</th>
158                       <td><input name=transdatefrom size=11 title="$myconfig{dateformat}"></td>
159                       <th>|.$locale->text('to').qq|</th>
160                       <td><input name=transdateto size=11 title="$myconfig{dateformat}"></td>
161
162                       <td><input name=closed class=checkbox type=checkbox value=1>&nbsp;|.$locale->text('Closed').qq|</td>
163                     </tr>
164                   </table>
165                 </td>
166               </tr>
167             </table>
168           </td>
169         </tr>
170 |;
171   }
172
173
174   $form->header;
175   
176   print qq|
177 <body>
178
179 <form method=post action=$form->{script}>
180
181 <input type=hidden name=searchitems value=$form->{searchitems}>
182 <input type=hidden name=title value="$form->{title}">
183
184 <table width="100%">
185   <tr><th class=listtop>$form->{title}</th></tr>
186   <tr height="5"></tr>
187   <tr valign=top>
188     <td>
189       <table>
190         <tr>
191           <th width=1% align=right nowrap>|.$locale->text('Number').qq|</th>
192           <td><input name=partnumber size=20></td>
193           <th align=right nowrap>|.$locale->text('Description').qq|</th>
194           <td><input name=description size=40></td>
195         </tr>
196         <tr>
197           <th align=right nowrap>|.$locale->text('Group').qq|</th>
198           <td><input name=partsgroup size=20></td>
199         </tr>
200         $makemodel
201         <tr>
202           <th align=right nowrap>|.$locale->text('Drawing').qq|</th>
203           <td><input name=drawing size=20></td>
204           <th align=right nowrap>|.$locale->text('Microfiche').qq|</th>
205           <td><input name=microfiche size=20></td>
206         </tr>
207         $toplevel
208         <tr>
209           <td></td>
210           <td colspan=3>
211             <input name=itemstatus class=radio type=radio value=active checked>&nbsp;|.$locale->text('Active').qq|
212             $onhand
213             <input name=itemstatus class=radio type=radio value=obsolete>&nbsp;|.$locale->text('Obsolete').qq|
214             <input name=itemstatus class=radio type=radio value=orphaned>&nbsp;|.$locale->text('Orphaned').qq|
215           </td>
216         </tr>
217         $bought
218         <tr>
219           <td></td>
220           <td colspan=3>
221             <hr size=1 noshade>
222           </td>
223         </tr>
224         <tr>
225           <th align=right nowrap>|.$locale->text('Include in Report').qq|</th>
226           <td colspan=3>
227             <table>
228               <tr>
229                 <td><input name=l_partnumber class=checkbox type=checkbox value=Y checked>&nbsp;|.$locale->text('Number').qq|</td>
230                 <td><input name=l_description class=checkbox type=checkbox value=Y checked>&nbsp;|.$locale->text('Description').qq|</td>
231                 <td><input name=l_unit class=checkbox type=checkbox value=Y checked>&nbsp;|.$locale->text('Unit of measure').qq|</td>
232               </tr>
233               <tr>
234                 <td><input name=l_listprice class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('List Price').qq|</td>
235                 <td><input name=l_sellprice class=checkbox type=checkbox value=Y checked>&nbsp;|.$locale->text('Sell Price').qq|</td>
236                 <td><input name=l_lastcost class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Last Cost').qq|</td>
237                 <td><input name=l_linetotal class=checkbox type=checkbox value=Y checked>&nbsp;|.$locale->text('Line Total').qq|</td>
238               </tr>
239               <tr>
240                 <td><input name=l_priceupdate class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Updated').qq|</td>
241                 <td><input name=l_bin class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Bin').qq|</td>
242                 <td><input name=l_rop class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('ROP').qq|</td>
243                 <td><input name=l_weight class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Weight').qq|</td>
244               </tr>
245               <tr>
246                 <td><input name=l_image class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Image').qq|</td>
247                 <td><input name=l_drawing class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Drawing').qq|</td>
248                 <td><input name=l_microfiche class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Microfiche').qq|</td>
249                 <td><input name=l_partsgroup class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Group').qq|</td>
250               </tr>
251               <tr>
252                 <td><input name=l_subtotal class=checkbox type=checkbox value=Y>&nbsp;|.$locale->text('Subtotal').qq|</td>
253               </tr>
254             </table>
255           </td>
256         </tr>
257       </table>
258     </td>
259   </tr>
260   <tr><td colspan=4><hr size=3 noshade></td></tr>
261 </table>
262
263 <input type=hidden name=nextsub value=generate_report>
264
265 <input type=hidden name=path value=$form->{path}>
266 <input type=hidden name=login value=$form->{login}>
267 <input type=hidden name=password value=$form->{password}>
268
269 <br>
270 <input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
271 </form>
272
273 </body>
274 </html>
275 |;
276
277 }
278
279
280
281 sub generate_report {
282
283   # setup $form->{sort}
284   unless ($form->{sort}) {
285     if ($form->{description} && !($form->{partnumber})) {
286       $form->{sort} = "description";
287     } else {
288       $form->{sort} = "partnumber";
289     }
290   }
291
292   $callback = "$form->{script}?action=generate_report&path=$form->{path}&login=$form->{login}&password=$form->{password}&searchitems=$form->{searchitems}&itemstatus=$form->{itemstatus}&bom=$form->{bom}&l_linetotal=$form->{l_linetotal}&title=".$form->escape($form->{title},1);
293
294   IC->all_parts(\%myconfig, \%$form);
295
296
297   if ($form->{itemstatus} eq 'active') {
298     $option .= $locale->text('Active')." : ";
299   }
300   if ($form->{itemstatus} eq 'obsolete') {
301     $option .= $locale->text('Obsolete')." : ";
302   }
303   if ($form->{itemstatus} eq 'orphaned') {
304     $option .= $locale->text('Orphaned')." : ";
305   }
306   if ($form->{itemstatus} eq 'onhand') {
307     $option .= $locale->text('On Hand')." : ";
308     $form->{l_onhand} = "Y";
309   }
310   if ($form->{itemstatus} eq 'short') {
311     $option .= $locale->text('Short')." : ";
312     $form->{l_onhand} = "Y";
313   }
314   if ($form->{onorder}) {
315     $form->{l_ordnumber} = "Y";
316     $callback .= "&onorder=$form->{onorder}";
317     $option .= $locale->text('On Order')." : ";
318   }
319   if ($form->{ordered}) {
320     $form->{l_ordnumber} = "Y";
321     $callback .= "&ordered=$form->{ordered}";
322     $option .= $locale->text('Ordered')." : ";
323   }
324   if ($form->{closed}) {
325     $callback .= "&closed=$form->{closed}";
326     $option .= $locale->text('Closed')." : ";
327   }
328   if ($form->{bought}) {
329     $form->{l_invnumber} = "Y";
330     $callback .= "&bought=$form->{bought}";
331     $option .= $locale->text('Bought')." : ";
332   }
333   if ($form->{sold}) {
334     $form->{l_invnumber} = "Y";
335     $callback .= "&sold=$form->{sold}";
336     $option .= $locale->text('Sold')." : ";
337   }
338   if ($form->{bought} || $form->{sold} || $form->{onorder} || $form->{ordered}) {
339     
340     $form->{l_lastcost} = "";
341     if ($form->{transdatefrom}) {
342       $callback .= "&transdatefrom=$form->{transdatefrom}";
343       $option .= "\n<br>".$locale->text('From')."&nbsp;".$locale->date(\%myconfig, $form->{transdatefrom}, 1);
344     }
345     if ($form->{transdateto}) {
346       $callback .= "&transdateto=$form->{transdateto}";
347       $option .= "\n<br>".$locale->text('to')."&nbsp;".$locale->date(\%myconfig, $form->{transdateto}, 1);
348     }
349   }
350   
351   $option .= "<br>";
352   
353   if ($form->{partnumber}) {
354     $callback .= "&partnumber=$form->{partnumber}";
355     $option .= $locale->text('Number').qq| : $form->{partnumber}<br>|;
356   }
357   if ($form->{description}) {
358     $callback .= "&description=$form->{description}";
359     $option .= $locale->text('Description').qq| : $form->{description}<br>|;
360   }
361   if ($form->{make}) {
362     $callback .= "&make=$form->{make}";
363     $option .= $locale->text('Make').qq| : $form->{make}<br>|;
364   }
365   if ($form->{model}) {
366     $callback .= "&model=$form->{model}";
367     $option .= $locale->text('Model').qq| : $form->{model}<br>|;
368   }
369   if ($form->{drawing}) {
370     $callback .= "&drawing=$form->{drawing}";
371     $option .= $locale->text('Drawing').qq| : $form->{drawing}<br>|;
372   }
373   if ($form->{microfiche}) {
374     $callback .= "&microfiche=$form->{microfiche}";
375     $option .= $locale->text('Microfiche').qq| : $form->{microfiche}<br>|;
376   }
377   if ($form->{partsgroup}) {
378     $callback .= "&partsgroup=$form->{partsgroup}";
379     $option .= $locale->text('Group').qq| : $form->{partsgroup}<br>|;
380   }
381
382
383   @columns = $form->sort_columns(qw(partnumber description partsgroup bin onhand rop unit listprice linetotallistprice sellprice linetotalsellprice lastcost linetotallastcost priceupdate weight image drawing microfiche invnumber ordnumber));
384
385   if ($form->{l_linetotal}) {
386     $form->{l_onhand} = "Y";
387     $form->{l_linetotalsellprice} = "Y" if $form->{l_sellprice};
388     if ($form->{l_lastcost}) {
389       $form->{l_linetotallastcost} = "Y";
390       if (($form->{searchitems} eq 'assembly') && !$form->{bom}) {
391         $form->{l_linetotallastcost} = "";
392       }
393     }
394     $form->{l_linetotallistprice} = "Y" if $form->{l_listprice};
395   }
396
397   if ($form->{searchitems} eq 'service') {
398     # remove bin, weight and rop from list
399     map { $form->{"l_$_"} = "" } qw(bin weight rop);
400
401     $form->{l_onhand} = "";
402     # qty is irrelevant unless bought or sold
403     if ($form->{bought} || $form->{sold} || $form->{onorder} || $form->{ordered}) {
404       $form->{l_onhand} = "Y";
405     } else {
406       $form->{l_linetotalsellprice} = "";
407       $form->{l_linetotallastcost} = "";
408     }
409   }
410
411   $form->{l_lastcost} = "" if ($form->{searchitems} eq 'assembly' && !$form->{bom});
412   
413   foreach $item (@columns) {
414     if ($form->{"l_$item"} eq "Y") {
415       push @column_index, $item;
416
417       # add column to callback
418       $callback .= "&l_$item=Y";
419     }
420   }
421
422   if ($form->{l_subtotal} eq 'Y') {
423     $callback .= "&l_subtotal=Y";
424   }
425   
426   $column_header{partnumber} = qq|<th nowrap><a class=listheading href=$callback&sort=partnumber>|.$locale->text('Number').qq|</a></th>|;
427   $column_header{description} = qq|<th nowrap><a class=listheading href=$callback&sort=description>|.$locale->text('Description').qq|</a></th>|;
428   $column_header{partsgroup} = qq|<th nowrap><a class=listheading href=$callback&sort=partsgroup>|.$locale->text('Group').qq|</a></th>|;
429   $column_header{bin} = qq|<th><a class=listheading href=$callback&sort=bin>|.$locale->text('Bin').qq|</a></th>|;
430   $column_header{priceupdate} = qq|<th nowrap><a class=listheading href=$callback&sort=priceupdate>|.$locale->text('Updated').qq|</a></th>|;
431   $column_header{onhand} = qq|<th class=listheading nowrap>|.$locale->text('Qty').qq|</th>|;
432   $column_header{unit} = qq|<th class=listheading nowrap>|.$locale->text('Unit').qq|</th>|;
433   $column_header{listprice} = qq|<th class=listheading nowrap>|.$locale->text('List Price').qq|</th>|;
434   $column_header{lastcost} = qq|<th class=listheading nowrap>|.$locale->text('Last Cost').qq|</th>|;
435   $column_header{rop} = qq|<th class=listheading nowrap>|.$locale->text('ROP').qq|</th>|;
436   $column_header{weight} = qq|<th class=listheading nowrap>|.$locale->text('Weight').qq|</th>|;
437   
438   $column_header{invnumber} = qq|<th nowrap><a class=listheading href=$callback&sort=invnumber>|.$locale->text('Invoice Number').qq|</a></th>|;
439   $column_header{ordnumber} = qq|<th nowrap><a class=listheading href=$callback&sort=ordnumber>|.$locale->text('Order Number').qq|</a></th>|;
440   
441   $column_header{sellprice} = qq|<th class=listheading nowrap>|.$locale->text('Sell Price').qq|</th>|;
442   $column_header{linetotalsellprice} = qq|<th class=listheading nowrap>|.$locale->text('Extended').qq|</th>|;
443   $column_header{linetotallastcost} = qq|<th class=listheading nowrap>|.$locale->text('Extended').qq|</th>|;
444   $column_header{linetotallistprice} = qq|<th class=listheading nowrap>|.$locale->text('Extended').qq|</th>|;
445   
446   $column_header{image} = qq|<th class=listheading nowrap>|.$locale->text('Image').qq|</a></th>|;
447   $column_header{drawing} = qq|<th nowrap><a class=listheading href=$callback&sort=drawing>|.$locale->text('Drawing').qq|</a></th>|;
448   $column_header{microfiche} = qq|<th nowrap><a class=listheading href=$callback&sort=microfiche>|.$locale->text('Microfiche').qq|</a></th>|;
449   
450   $form->header;
451   $colspan = $#column_index + 1;
452
453   print qq|
454 <body>
455
456 <table width=100%>
457 <tr><th class=listtop colspan=$colspan>$form->{title}</th></tr>
458 <tr height="5"></tr>
459
460 <tr><td colspan=$colspan>$option</td></tr>
461
462   <tr class=listheading>
463 |;
464
465   map { print "\n$column_header{$_}" } @column_index;
466   
467   print qq|
468   </tr>
469   |;
470
471
472   # add order to callback
473   $form->{callback} = $callback .= "&sort=$form->{sort}";
474
475   # escape callback for href
476   $callback = $form->escape($callback);
477
478   if (@{ $form->{parts} }) {
479     $sameitem = $form->{parts}->[0]->{$form->{sort}};
480   }
481
482   foreach $ref (@{ $form->{parts} }) {
483   
484     if ($form->{l_subtotal} eq 'Y' && !$ref->{assemblyitem}) {
485       if ($sameitem ne $ref->{$form->{sort}}) {
486         &parts_subtotal;
487         $sameitem = $ref->{$form->{sort}};
488       }
489     }
490
491     $ref->{exchangerate} = 1 unless $ref->{exchangerate};
492     $ref->{sellprice} *= $ref->{exchangerate};
493     $ref->{listprice} *= $ref->{exchangerate};
494     $ref->{lastcost} *= $ref->{exchangerate};
495     
496     $align = "left";
497     $onhand = $ref->{onhand};
498     
499     if ($ref->{assemblyitem}) {
500       $align = "right";
501       $onhand = 0 if ($form->{sold});
502     }
503
504     $column_data{partnumber} = "<td align=$align><a href=$form->{script}?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{partnumber}&nbsp;</a></td>";
505     $column_data{description} = "<td>$ref->{description}&nbsp;</td>";
506     $column_data{partsgroup} = "<td>$ref->{partsgroup}&nbsp;</td>";
507    
508     $column_data{onhand} = "<td align=right>".$form->format_amount(\%myconfig, $onhand, '', "&nbsp;")."</td>";
509     $column_data{sellprice} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{sellprice}, 2, "&nbsp;") . "</td>";
510     $column_data{listprice} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{listprice}, 2, "&nbsp;") . "</td>";
511     $column_data{lastcost} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{lastcost}, 2, "&nbsp;") . "</td>";
512     
513     $column_data{linetotalsellprice} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{onhand} * $ref->{sellprice}, 2, "&nbsp;")."</td>";
514     $column_data{linetotallastcost} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{onhand} * $ref->{lastcost}, 2, "&nbsp;")."</td>";
515     $column_data{linetotallistprice} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{onhand} * $ref->{listprice}, 2, "&nbsp;")."</td>";
516     
517     if (!$ref->{assemblyitem}) {
518       $totalsellprice += $onhand * $ref->{sellprice};
519       $totallastcost += $onhand * $ref->{lastcost};
520       $totallistprice += $onhand * $ref->{listprice};
521
522       $subtotalonhand += $onhand;
523       $subtotalsellprice += $onhand * $ref->{sellprice};
524       $subtotallastcost += $onhand * $ref->{lastcost};
525       $subtotallistprice += $onhand * $ref->{listprice};
526     }
527
528     $column_data{rop} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{rop}, '', "&nbsp;")."</td>";
529     $column_data{weight} = "<td align=right>".$form->format_amount(\%myconfig, $ref->{weight}, '', "&nbsp;")."</td>";
530     $column_data{unit} = "<td>$ref->{unit}&nbsp;</td>";
531     $column_data{bin} = "<td>$ref->{bin}&nbsp;</td>";
532     $column_data{priceupdate} = "<td>$ref->{priceupdate}&nbsp;</td>";
533     
534     $column_data{invnumber} = ($ref->{module} ne 'oe') ? "<td><a href=$ref->{module}.pl?action=edit&type=invoice&id=$ref->{trans_id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{invnumber}&nbsp;</a></td>" : "<td>$ref->{invnumber}&nbsp;</td>";
535     $column_data{ordnumber} = ($ref->{module} eq 'oe') ? "<td><a href=$ref->{module}.pl?action=edit&type=$ref->{type}&id=$ref->{trans_id}&path=$form->{path}&login=$form->{login}&password=$form->{password}&callback=$callback>$ref->{ordnumber}&nbsp;</a></td>" : "<td>$ref->{ordnumber}&nbsp;</td>";
536    
537     $column_data{image} = ($ref->{image}) ? "<td><a href=$ref->{image}><img src=$ref->{image} height=32 border=0></a></td>" : "<td>&nbsp;</td>";
538     $column_data{drawing} = ($ref->{drawing}) ? "<td><a href=$ref->{drawing}>$ref->{drawing}</a></td>" : "<td>&nbsp;</td>";
539     $column_data{microfiche} = ($ref->{microfiche}) ? "<td><a href=$ref->{microfiche}>$ref->{microfiche}</a></td>" : "<td>&nbsp;</td>";
540     
541     $i++; $i %= 2;
542     print "<tr class=listrow$i>";
543
544     map { print "\n$column_data{$_}" } @column_index;
545
546     print qq|
547     </tr>
548 |;
549
550   }
551   
552   
553   if ($form->{l_subtotal} eq 'Y') {
554     &parts_subtotal;
555   }
556
557   if ($form->{"l_linetotal"}) {
558     map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
559     $column_data{linetotalsellprice} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totalsellprice, 2, "&nbsp;")."</th>";
560     $column_data{linetotallastcost} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totallastcost, 2, "&nbsp;")."</th>";
561     $column_data{linetotallistprice} = "<th class=listtotal align=right>".$form->format_amount(\%myconfig, $totallistprice, 2, "&nbsp;")."</th>";
562
563     print "<tr class=listtotal>";
564
565     map { print "\n$column_data{$_}" } @column_index;
566
567     print qq|</tr>
568     |;
569   }
570
571   print qq|
572   <tr><td colspan=$colspan><hr size=3 noshade></td></tr>
573 </table>
574
575 |;
576
577
578   print qq|
579
580 <br>
581
582 <form method=post action=$form->{script}>
583
584 <input name=callback type=hidden value="$form->{callback}">
585
586 <input type=hidden name=item value=$form->{searchitems}>
587
588 <input type=hidden name=path value=$form->{path}>
589 <input type=hidden name=login value=$form->{login}>
590 <input type=hidden name=password value=$form->{password}>
591
592 <input class=submit type=submit name=action value="|.$locale->text('Add').qq|">
593
594 </form>
595
596 </body>
597 </html>
598 |;
599
600 }
601
602
603
604 sub parts_subtotal {
605
606   map { $column_data{$_} = "<td>&nbsp;</td>" } @column_index;
607   $subtotalonhand = 0 if ($form->{searchitems} eq 'assembly' && $form->{bom});
608
609   $column_data{onhand} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalonhand, '', "&nbsp;")."</th>";
610   $column_data{sellprice} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotalsellprice, 2, "&nbsp;")."</th>";
611   $column_data{listprice} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotallistprice, 2, "&nbsp;")."</th>";
612   $column_data{lastcost} = "<th class=listsubtotal align=right>".$form->format_amount(\%myconfig, $subtotallastcost, 2, "&nbsp;")."</th>";
613   
614   $subtotalonhand = 0;
615   $subtotalsellprice = 0;
616   $subtotallistprice = 0;
617   $subtotallastcost = 0;
618
619   print "<tr class=listsubtotal>";
620
621   map { print "\n$column_data{$_}" } @column_index;
622
623   print qq|
624   </tr>
625 |;
626
627 }
628
629
630
631 sub edit {
632
633   IC->get_part(\%myconfig, \%$form);
634
635   $form->{title} = $locale->text('Edit '.ucfirst $form->{item});
636
637   &link_part;
638   &display_form;
639   
640 }
641
642
643
644 sub link_part {
645
646   IC->create_links("IC", \%myconfig, \%$form);
647   
648   # parts and assemblies have the same links
649   $item = $form->{item};
650   if ($form->{item} eq 'assembly') {
651     $item = 'part';
652   }
653
654   # build the popup menus
655   $form->{taxaccounts} = "";
656   foreach $key (keys %{ $form->{IC_links} }) {
657     foreach $ref (@{ $form->{IC_links}{$key} }) {
658       # if this is a tax field
659       if ($key =~ /IC_tax/) {
660         if ($key =~ /$item/) {
661           $form->{taxaccounts} .= "$ref->{accno} ";
662           $form->{"IC_tax_$ref->{accno}_description"} = "$ref->{accno}--$ref->{description}";
663           
664           if ($form->{id}) {
665             if ($form->{amount}{$ref->{accno}}) {
666               $form->{"IC_tax_$ref->{accno}"} = "checked";
667             }
668           } else {
669             $form->{"IC_tax_$ref->{accno}"} = "checked";
670           }
671         }
672       } else {
673
674         $form->{"select$key"} .= "<option>$ref->{accno}--$ref->{description}\n";
675         if ($form->{amount}{$key} eq $ref->{accno}) {
676           $form->{$key} = "$ref->{accno}--$ref->{description}";
677         }
678         
679       }
680     }
681   }
682   chop $form->{taxaccounts};
683
684   if (($form->{item} eq "part") || ($form->{item} eq "assembly")) {
685     $form->{selectIC_income} = $form->{selectIC_sale};
686     $form->{selectIC_expense} = $form->{selectIC_cogs};
687     $form->{IC_income} = $form->{IC_sale};
688     $form->{IC_expense} = $form->{IC_cogs};
689   }
690   
691   delete $form->{IC_links};
692   delete $form->{amount};
693
694 }
695
696
697
698 sub form_header {
699
700   ($dec) = ($form->{sellprice} =~ /\.(\d+)/);
701   $dec = length $dec;
702   my $decimalplaces = ($dec > 2) ? $dec : 2;
703
704   map { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}, $decimalplaces)} qw(listprice sellprice);
705
706   ($dec) = ($form->{lastcost} =~ /\.(\d+)/);
707   $dec = length $dec;
708   my $decimalplaces = ($dec > 2) ? $dec : 2;
709
710   $form->{lastcost} = $form->format_amount(\%myconfig, $form->{lastcost}, $decimalplaces);
711
712   map { $form->{$_} = $form->format_amount(\%myconfig, $form->{$_}) } qw(weight rop stock);
713
714   foreach $item (qw(partnumber description unit notes)) {
715     $form->{$item} =~ s/"/&quot;/g;
716   }
717
718   
719   if (($rows = $form->numtextrows($form->{notes}, 40)) < 2) {
720     $rows = 2;
721   }
722   
723   $notes = qq|<textarea name=notes rows=$rows cols=40 wrap=soft>$form->{notes}</textarea>|;
724
725   if (($rows = $form->numtextrows($form->{description}, 40)) > 1) {
726     $description = qq|<textarea name="description" rows=$rows cols=40 wrap=soft>$form->{description}</textarea>|;
727   } else {
728     $description = qq|<input name=description size=40 value="$form->{description}">|;
729   }
730   
731   foreach $item (split / /, $form->{taxaccounts}) {
732     $form->{"IC_tax_$item"} = ($form->{"IC_tax_$item"}) ? "checked" : "";
733   }
734
735
736   # set option
737   foreach $item (qw(IC IC_income IC_expense)) {
738     if ($form->{$item}) {
739       if ($form->{id} && $form->{orphaned}) {
740         $form->{"select$item"} =~ s/ selected//;
741         $form->{"select$item"} =~ s/option>\Q$form->{$item}\E/option selected>$form->{$item}/;
742
743       } else {
744         $form->{"select$item"} = qq|<option selected>$form->{$item}|;
745       }
746     }
747   }
748
749   # tax fields
750   foreach $item (split / /, $form->{taxaccounts}) {
751     $tax .= qq|
752       <input class=checkbox type=checkbox name="IC_tax_$item" value=1 $form->{"IC_tax_$item"}>&nbsp;<b>$form->{"IC_tax_${item}_description"}</b>
753       <br><input type=hidden name=IC_tax_${item}_description value="$form->{"IC_tax_${item}_description"}">
754 |;
755   }
756
757   $form->{obsolete} = "checked" if $form->{obsolete};
758
759   $lastcost = qq|
760               <tr>
761                 <th align="right" nowrap="true">|.$locale->text('Last Cost').qq|</th>
762                 <td><input name=lastcost size=11 value=$form->{lastcost}></td>
763               </tr>
764 |;
765  
766   if ($form->{item} eq "part") {
767
768     $linkaccounts = qq|
769               <tr>
770                 <th width="1%" align=right>|.$locale->text('Inventory').qq|</th>
771                 <td><select name=IC>$form->{selectIC}</select></td>
772                 <input name=selectIC type=hidden value="$form->{selectIC}">
773               </tr>
774               <tr>
775                 <th align=right>|.$locale->text('Sales').qq|</th>
776                 <td><select name=IC_income>$form->{selectIC_income}</select></td>
777                 <input name=selectIC_income type=hidden value="$form->{selectIC_income}">
778               </tr>
779               <tr>
780                 <th align=right>|.$locale->text('COGS').qq|</th>
781                 <td><select name=IC_expense>$form->{selectIC_expense}</select></td>
782                 <input name=selectIC_expense type=hidden value="$form->{selectIC_expense}">
783               </tr>
784 |;
785   
786     if ($tax) {
787       $linkaccounts .= qq|
788               <tr>
789                 <th align=right>|.$locale->text('Tax').qq|</th>
790                 <td>$tax</td>
791               </tr>
792 |;
793     }
794   
795     $weight = qq|
796               <tr>
797                 <th align="right" nowrap="true">|.$locale->text('Weight').qq|</th>
798                 <td>
799                   <table>
800                     <tr>
801                       <td>
802                         <input name=weight size=10 value=$form->{weight}>
803                       </td>
804                       <th>
805                         &nbsp;
806                         $form->{weightunit}
807                         <input type=hidden name=weightunit value=$form->{weightunit}>
808                       </th>
809                     </tr>
810                   </table>
811                 </td>
812               </tr>
813 |;
814     
815   }
816
817
818   if ($form->{item} eq "assembly") {
819     
820     $lastcost = "";
821     
822     $linkaccounts = qq|
823               <tr>
824                 <th width="1%" align=right>|.$locale->text('Sales').qq|</th>
825                 <td><select name=IC_income>$form->{selectIC_income}</select></td>
826                 <input name=selectIC_income type=hidden value="$form->{selectIC_income}">
827               </tr>
828 |;
829   
830     if ($tax) {
831       $linkaccounts .= qq|
832               <tr>
833                 <th align=right>|.$locale->text('Tax').qq|</th>
834                 <td>$tax</td>
835               </tr>
836 |;
837     }
838   
839     $weight = qq|
840               <tr>
841                 <th align="right" nowrap="true">|.$locale->text('Weight').qq|</th>
842                 <td>
843                   <table>
844                     <tr>
845                       <td>
846                         &nbsp;$form->{weight}
847                         <input type=hidden name=weight value=$form->{weight}>
848                       </td>
849                       <th>
850                         &nbsp;
851                         $form->{weightunit}
852                         <input type=hidden name=weightunit value=$form->{weightunit}>
853                       </th>
854                     </tr>
855                   </table>
856                 </td>
857               </tr>
858 |;
859
860    
861   }
862
863  
864   if ($form->{item} eq "service") {
865     
866     $linkaccounts = qq|
867               <tr>
868                 <th width="1%" align=right>|.$locale->text('Income').qq|</th>
869                 <td><select name=IC_income>$form->{selectIC_income}</select></td>
870                 <input name=selectIC_income type=hidden value="$form->{selectIC_income}">
871               </tr>
872               <tr>
873                 <th align=right>|.$locale->text('Expense').qq|</th>
874                 <td><select name=IC_expense>$form->{selectIC_expense}</select></td>
875                 <input name=selectIC_expense type=hidden value="$form->{selectIC_expense}">
876               </tr>
877 |;
878   
879     if ($tax) {
880       $linkaccounts .= qq|
881               <tr>
882                 <th align=right>|.$locale->text('Tax').qq|</th>
883                 <td>$tax</td>
884               </tr>
885 |;
886     }
887
888   }
889
890
891   if ($form->{item} ne 'service') {
892     $color = ($form->{onhand} > 0) ? "green" : "red";
893     $rop = qq|
894               <tr>
895                 <th align="right" nowrap>|.$locale->text('On Hand').qq|</th>
896                 <th align=left nowrap>&nbsp;|.$form->format_amount(\%myconfig, $form->{onhand}).qq|</th>
897               </tr>
898 |;
899
900     if ($form->{item} eq 'assembly') {
901       $rop .= qq|
902               <tr>
903                 <th align="right" nowrap>|.$locale->text('Stock').qq|</th>
904                 <td><input name=stock size=10 value=$form->{stock}></td>
905               </tr>
906 |;
907     }
908   
909     $rop .= qq|
910               <tr>
911                 <th align="right" nowrap="true">|.$locale->text('ROP').qq|</th>
912                 <td><input name=rop size=10 value=$form->{rop}></td>
913               </tr>
914 |;
915     
916     $bin = qq|
917               <tr>
918                 <th align="right" nowrap="true">|.$locale->text('Bin').qq|</th>
919                 <td><input name=bin size=10 value=$form->{bin}></td>
920               </tr>
921 |;
922     
923     $imagelinks = qq|
924   <tr>
925     <td>
926       <table>
927         <tr>
928           <th width=1% align=right nowrap>|.$locale->text('Image').qq|</th>
929           <td width=70%><input name=image size=40 value="$form->{image}"></td>
930
931         </tr>
932         <tr>
933           <th width=1% align=right nowrap>|.$locale->text('Drawing').qq|</th>
934           <td width=70%><input name=drawing size=40 value="$form->{drawing}"></td>
935           <th width=1% align=right nowrap>|.$locale->text('Microfiche').qq|</th>
936           <td width=30%><input name=microfiche size=20 value="$form->{microfiche}"></td>
937         </tr>
938       </table>
939     </td>
940   </tr>
941 |;
942
943   }
944
945   if ($form->{id}) {
946     $obsolete = qq|
947               <tr>
948                 <th align="right" nowrap="true">|.$locale->text('Obsolete').qq|</th>
949                 <td><input name=obsolete type=checkbox class=checkbox value=1 $form->{obsolete}></td>
950               </tr>
951 |;
952   }
953
954
955
956 # type=submit $locale->text('Add Part')
957 # type=submit $locale->text('Add Service')
958 # type=submit $locale->text('Add Assembly')
959
960 # type=submit $locale->text('Edit Part')
961 # type=submit $locale->text('Edit Service')
962 # type=submit $locale->text('Edit Assembly')
963
964
965   $form->header;
966
967   print qq|
968 <body>
969
970 <form method=post action=$form->{script}>
971
972 <input name=id type=hidden value=$form->{id}>
973 <input name=item type=hidden value=$form->{item}>
974 <input name=title type=hidden value="$form->{title}">
975 <input name=makemodel type=hidden value="$form->{makemodel}">
976 <input name=alternate type=hidden value="$form->{alternate}">
977 <input name=onhand type=hidden value=$form->{onhand}>
978 <input name=orphaned type=hidden value=$form->{orphaned}>
979 <input name=taxaccounts type=hidden value="$form->{taxaccounts}">
980 <input name=rowcount type=hidden value=$form->{rowcount}>
981
982 <table width="100%">
983   <tr><th class=listtop>$form->{title}</th></tr>
984   <tr height="5"></tr>
985   <tr>
986     <td>
987       <table width="100%">
988         <tr valign=top>
989           <th align=left>|.$locale->text('Number').qq|</th>
990           <th align=left>|.$locale->text('Description').qq|</th>
991           <th align=left>|.$locale->text('Group').qq|</th>
992         </tr>
993         <tr valign=top>
994           <td><input name=partnumber value="$form->{partnumber}" size=20></td>
995           <td>$description</td>
996           <td><input name=partsgroup size=20 value="$form->{partsgroup}"></td>
997           <input type=hidden name=oldpartsgroup value="$form->{oldpartsgroup}">
998         </tr>
999       </table>
1000     </td>
1001   </tr>
1002   <tr>
1003     <td>
1004       <table width="100%" height="100%">
1005         <tr valign=top>
1006           <td width=70%>
1007             <table width="100%" height="100%">
1008               <tr class="listheading">
1009                 <th class="listheading" align="center" colspan=2>|.$locale->text('Link Accounts').qq|</th>
1010               </tr>
1011               $linkaccounts
1012               <tr>
1013                 <th align="left">|.$locale->text('Notes').qq|</th>
1014               </tr>
1015               <tr>
1016                 <td colspan=2>
1017                   $notes
1018                 </td>
1019               </tr>
1020             </table>
1021           </td>
1022           <td width="30%">
1023             <table width="100%">
1024               <tr>
1025                 <th align="right" nowrap="true">|.$locale->text('Updated').qq|</th>
1026                 <td><input name=priceupdate size=11 title="$myconfig{dateformat}" value=$form->{priceupdate}></td>    
1027               </tr>
1028               <tr>
1029                 <th align="right" nowrap="true">|.$locale->text('List Price').qq|</th>
1030                 <td><input name=listprice size=11 value=$form->{listprice}></td>
1031               </tr>
1032               <tr>
1033                 <th align="right" nowrap="true">|.$locale->text('Sell Price').qq|</th>
1034                 <td><input name=sellprice size=11 value=$form->{sellprice}></td>
1035               </tr>
1036               $lastcost
1037               <tr>
1038                 <th align="right" nowrap="true">|.$locale->text('Unit').qq|</th>
1039                 <td><input name=unit size=5 maxsize=5 value="$form->{unit}"></td>
1040               </tr>
1041               $weight
1042               $rop
1043               $bin
1044               $obsolete
1045             </table>
1046           </td>
1047         </tr>
1048       </table>
1049     </td>
1050   </tr>
1051   $imagelinks
1052 |;
1053 }
1054
1055
1056 sub form_footer {
1057
1058   if ($form->{item} eq "assembly") {
1059
1060     print qq|
1061         <tr>
1062           <td>
1063             <table width="100%">
1064               <tr>
1065                 <th colspan=2 align=right>|.$locale->text('Total').qq|&nbsp;</th>
1066                 <th width="1%" align=right>|.$form->format_amount(\%myconfig, $form->{assemblytotal}, 2).qq|</th>
1067               </tr>
1068             </table>
1069           </td>
1070         </tr>
1071         <input type=hidden name=assembly_rows value=$form->{assembly_rows}>
1072 |;
1073   }
1074
1075   print qq|
1076       <input type=hidden name=path value=$form->{path}>
1077       <input type=hidden name=login value=$form->{login}>
1078       <input type=hidden name=password value=$form->{password}>
1079       <input type=hidden name=callback value="$form->{callback}">
1080       <input type=hidden name=previous_form value="$form->{previous_form}">
1081   <tr>
1082     <td><hr size=3 noshade></td>
1083   </tr>
1084 </table>
1085
1086 <br>
1087 <input class=submit type=submit name=action value="|.$locale->text('Update').qq|">
1088 |;
1089
1090   if ($form->{item} ne "service") {
1091     print qq|
1092       <input type=hidden name=makemodel_rows value=$form->{makemodel_rows}>
1093     |;
1094   }
1095
1096   print qq|
1097       <input class=submit type=submit name=action value="|.$locale->text('Save').qq|">|;
1098
1099   if ($form->{id}) {
1100
1101     if (! $form->{previous_form}) {
1102       print qq|
1103       <input class=submit type=submit name=action value="|.$locale->text('Save as new').qq|">|;
1104     }
1105     
1106     if ($form->{orphaned}) {
1107       if (! $form->{previous_form}) {
1108         print qq|
1109       <input class=submit type=submit name=action value="|.$locale->text('Delete').qq|">|;
1110       }
1111     }
1112
1113   }
1114
1115   print qq|
1116
1117 </form>
1118
1119 </body>
1120 </html>
1121 |;
1122
1123 }
1124
1125
1126
1127 sub makemodel_row {
1128   my ($numrows) = @_;
1129
1130   $form->{"make_$i"} =~ s/"/&quot;/g;
1131   $form->{"model_$i"} =~ s/"/&quot;/g;
1132
1133   print qq|
1134   <tr>
1135     <td>
1136       <table width=100%>
1137         <tr>
1138           <th class="listheading">|.$locale->text('Make').qq|</th>
1139           <th class="listheading">|.$locale->text('Model').qq|</th>
1140         </tr>
1141 |;
1142
1143   for $i (1 .. $numrows) {
1144     print qq|
1145         <tr>
1146           <td width=50%><input name="make_$i" size=30 value="$form->{"make_$i"}"></td>
1147           <td width=50%><input name="model_$i" size=30 value="$form->{"model_$i"}"></td>
1148         </tr>
1149 |;
1150   }
1151
1152   print qq|
1153       </table>
1154     </td>
1155   </tr>
1156 |;
1157
1158 }
1159
1160
1161 sub assembly_row {
1162   my ($numrows) = @_;
1163
1164   @column_index = qw(runningnumber qty unit bom partnumber description partsgroup total);
1165   
1166   if ($form->{previous_form}) {
1167     $nochange = 1;
1168     @column_index = qw(qty unit bom partnumber description partsgroup total);
1169   } else {
1170     # change callback
1171     $form->{old_callback} = $form->{callback};
1172     $callback = $form->{callback};
1173     $form->{callback} = "$form->{script}?action=display_form";
1174
1175     # delete action
1176     delete $form->{action};
1177
1178     $previous_form = "";
1179     # save form variables in a previous_form variable
1180     foreach $key (sort keys %$form) {
1181       # escape ampersands
1182       $form->{$key} =~ s/&/%26/g;
1183       $previous_form .= qq|$key=$form->{$key}&|;
1184     }
1185     chop $previous_form;
1186     $previous_form = $form->escape($form->escape($previous_form, 1));
1187     $form->{callback} = $callback;
1188     
1189     $form->{assemblytotal} = 0;
1190     $form->{weight} = 0;
1191
1192   }
1193
1194   $column_header{runningnumber} = qq|<th nowrap width=5%>|.$locale->text('No.').qq|</th>|;
1195   $column_header{qty} = qq|<th align=left nowrap width=10%>|.$locale->text('Qty').qq|</th>|;
1196   $column_header{unit} = qq|<th align=left nowrap width=5%>|.$locale->text('Unit').qq|</th>|;
1197   $column_header{partnumber} = qq|<th align=left nowrap width=20%>|.$locale->text('Number').qq|</th>|;
1198   $column_header{description} = qq|<th nowrap width=50%>|.$locale->text('Description').qq|</th>|;
1199   $column_header{total} = qq|<th align=right nowrap>|.$locale->text('Extended').qq|</th>|;
1200   $column_header{bom} = qq|<th>|.$locale->text('BOM').qq|</th>|;
1201   $column_header{partsgroup} = qq|<th>|.$locale->text('Group').qq|</th>|;
1202   
1203   print qq|
1204   <tr class=listheading>
1205     <th class=listheading>|.$locale->text('Individual Items').qq|</th>
1206   </tr>
1207   <tr>
1208     <td>
1209       <table width=100%>
1210         <tr>
1211 |;
1212
1213   map { print "\n$column_header{$_}" } @column_index;
1214   
1215   print qq|
1216         </tr>
1217 |;
1218
1219   for $i (1 .. $numrows) {
1220     $form->{"partnumber_$i"} =~ s/"/&quot;/g;
1221
1222     $linetotal = $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2);
1223     $form->{assemblytotal} += $linetotal;
1224     
1225     $form->{"qty_$i"} = $form->format_amount(\%myconfig, $form->{"qty_$i"});
1226
1227     $linetotal = $form->format_amount(\%myconfig, $linetotal, 2);
1228
1229     if (($i >= 1) && ($i == $numrows)) {
1230
1231       if ($nochange) {
1232         map { $column_data{$_} = qq|<td></td>| } qw(qty unit partnumber description bom partsgroup);
1233       } else {
1234         
1235         map { $column_data{$_} = qq|<td></td>| } qw(runningnumber unit bom);
1236         
1237         $column_data{qty} = qq|<td><input name="qty_$i" size=5 value="$form->{"qty_$i"}"></td>|;
1238         $column_data{partnumber} = qq|<td><input name="partnumber_$i" size=15 value="$form->{"partnumber_$i"}"></td>|;
1239         $column_data{description} = qq|<td><input name="description_$i" size=40 value="$form->{"description_$i"}"></td>|;
1240         $column_data{partsgroup} = qq|<td><input name="partsgroup_$i" size=10 value="$form->{"partsgroup_$i"}"></td>|;
1241         
1242       }
1243
1244     } else {
1245       
1246       if ($form->{previous_form}) {
1247         $column_data{partnumber} = qq|<td><input type=hidden name="partnumber_$i" value="$form->{"partnumber_$i"}">$form->{"partnumber_$i"}</td>|;
1248         $column_data{qty} = qq|<td align=right><input type=hidden name="qty_$i" value="$form->{"qty_$i"}">$form->{"qty_$i"}</td>|;
1249
1250         $column_data{bom} = qq|<td align=center><input type=hidden name="bom_$i" value=$form->{"bom_$i"}>|;
1251         $column_data{bom} .= ($form->{"bom_$i"}) ? "x" : "&nbsp;";
1252         $column_data{bom} .= qq|</td>|;
1253
1254         $column_data{partsgroup} = qq|<td><input type=hidden name="partsgroup_$i" value="$form->{"partsgroup_$i"}">$form->{"partsgroup_$i"}</td>|;
1255         
1256       } else {
1257         $href = qq|$form->{script}?action=edit&id=$form->{"id_$i"}&path=$form->{path}&login=$form->{login}&password=$form->{password}&rowcount=$i&previous_form=$previous_form|;
1258         $column_data{partnumber} = qq|<td><input type=hidden name="partnumber_$i" value="$form->{"partnumber_$i"}"><a href=$href>$form->{"partnumber_$i"}</a></td>|;
1259         $column_data{runningnumber} = qq|<td><input name="runningnumber_$i" size=3 value="$i"}"></td>|;
1260         $column_data{qty} = qq|<td><input name="qty_$i" size=5 value="$form->{"qty_$i"}"></td>|;
1261
1262         $form->{"bom_$i"} = ($form->{"bom_$i"}) ? "checked" : "";
1263         $column_data{bom} = qq|<td align=center><input name="bom_$i" type=checkbox class=checkbox value=1 $form->{"bom_$i"}></td>|;
1264
1265         $column_data{partsgroup} = qq|<td><input type=hidden name="partsgroup_$i" value="$form->{"partsgroup_$i"}">$form->{"partsgroup_$i"}</td>|;
1266
1267       }
1268
1269       $column_data{unit} = qq|<td><input type=hidden name="unit_$i" value="$form->{"unit_$i"}">$form->{"unit_$i"}</td>|;
1270       $column_data{description} = qq|<td><input type=hidden name="description_$i" value="$form->{"description_$i"}">$form->{"description_$i"}</td>|;
1271     }
1272     
1273     $column_data{total} = qq|<td align=right>$linetotal</td>|;
1274     
1275     print qq|
1276         <tr>|;
1277
1278     map { print "\n$column_data{$_}" } @column_index;
1279     
1280     print qq|
1281         </tr>
1282   <input type=hidden name="id_$i" value=$form->{"id_$i"}>
1283   <input type=hidden name="sellprice_$i" value=$form->{"sellprice_$i"}>
1284   <input type=hidden name="weight_$i" value=$form->{"weight_$i"}>
1285 |;
1286   }
1287
1288   print qq|
1289       </table>
1290     </td>
1291   </tr>
1292 |;
1293  
1294 }
1295
1296
1297 sub update {
1298
1299  
1300   if ($form->{item} eq "assembly") {
1301
1302     $i = $form->{assembly_rows};
1303     
1304     # if last row is empty check the form otherwise retrieve item
1305     if (($form->{"partnumber_$i"} eq "") && ($form->{"description_$i"} eq "") && ($form->{"partsgroup_$i"} eq "")) {
1306       
1307       &check_form;
1308       
1309     } else {
1310
1311       IC->assembly_item(\%myconfig, \%$form);
1312
1313       $rows = scalar @{ $form->{item_list} };
1314       
1315       if ($rows) {
1316         $form->{"qty_$i"} = 1 unless ($form->{"qty_$i"});
1317         
1318         if ($rows > 1) {
1319           $form->{makemodel_rows}--;
1320           &select_item;
1321           exit;
1322         } else {
1323           map { $form->{item_list}[$i]{$_} =~ s/"/&quot;/g } qw(partnumber description unit partsgroup);
1324           map { $form->{"${_}_$i"} = $form->{item_list}[0]{$_} } keys %{ $form->{item_list}[0] };
1325           $form->{"runningnumber_$i"} = $form->{assembly_rows};
1326           $form->{assembly_rows}++;
1327
1328           &check_form;
1329
1330         }
1331
1332       } else {
1333
1334         $form->{rowcount} = $i;
1335         $form->{assembly_rows}++;
1336         
1337         &new_item;
1338
1339       }
1340     }
1341   }
1342   
1343   if ($form->{item} eq "part") {
1344     &check_form;
1345   }
1346
1347   if ($form->{item} eq 'service') {
1348     map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(sellprice listprice);
1349     
1350     &form_header;
1351     &form_footer;
1352   }
1353
1354 }
1355
1356
1357 sub save {
1358
1359   # check if there is a part number
1360   $form->isblank("partnumber", $locale->text(ucfirst $form->{item}." Number missing!"));
1361
1362   if ($form->{obsolete}) {
1363     $form->error($locale->text("Inventory quantity must be zero before you can set this $form->{item} obsolete!")) if ($form->{onhand});
1364   }
1365
1366 # expand dynamic strings
1367 # $locale->text('Inventory quantity must be zero before you can set this part obsolete!')
1368 # $locale->text('Inventory quantity must be zero before you can set this assembly obsolete!')
1369 # $locale->text('Part Number missing!')
1370 # $locale->text('Service Number missing!')
1371 # $locale->text('Assembly Number missing!')
1372
1373   # save part
1374   $rc = IC->save(\%myconfig, \%$form);
1375
1376   $parts_id = $form->{id};
1377   
1378   # load previous variables
1379   if ($form->{previous_form}) {
1380     # save the new form variables before splitting previous_form
1381     map { $newform{$_} = $form->{$_} } keys %$form;
1382
1383     $previous_form = $form->unescape($form->{previous_form});
1384
1385     # don't trample on previous variables
1386     map { delete $form->{$_} } keys %newform;
1387
1388     # now take it apart and restore original values
1389     foreach $item (split /&/, $previous_form) {
1390       ($key, $value) = split /=/, $item, 2;
1391       $value =~ s/%26/&/g;
1392       $form->{$key} = $value;
1393     }
1394
1395     if ($form->{item} eq 'assembly') {
1396       # undo formatting
1397       map { $form->{$_} = $form->parse_amount(\%myconfig, $form->{$_}) } qw(listprice sellprice weight);
1398
1399       $form->{assembly_rows}--;
1400       $i = $newform{rowcount};
1401       $form->{"qty_$i"} = 1 unless ($form->{"qty_$i"});
1402
1403       $form->{sellprice} -= $form->{"sellprice_$i"} * $form->{"qty_$i"};
1404       $form->{weight} -= $form->{"weight_$i"} * $form->{"qty_$i"};
1405       
1406       # change/add values for assembly item
1407       map { $form->{"${_}_$i"} = $newform{$_} } qw(partnumber description bin unit weight listprice sellprice inventory_accno income_accno expense_accno partsgroup);
1408
1409       # undo string formatting
1410       map { $form->{"${_}_$i"} =~ s/''/'/g } qw(partnumber description unit bin);
1411       
1412       $form->{sellprice} += $form->round_amount($form->{"sellprice_$i"} * $form->{"qty_$i"}, 2);
1413       $form->{weight} += $form->{"weight_$i"} * $form->{"qty_$i"};
1414
1415     } else {
1416       # set values for last invoice/order item
1417       $i = $form->{rowcount};
1418       $form->{"qty_$i"} = 1 unless ($form->{"qty_$i"});
1419
1420       map { $form->{"${_}_$i"} = $newform{$_} } qw(partnumber description bin unit listprice inventory_accno income_accno expense_accno sellprice);
1421       $form->{"sellprice_$i"} = $newform{lastcost} if ($form->{vendor_id});
1422
1423       if ($form->{exchangerate} != 0) {
1424         $form->{"sellprice_$i"} /= $form->{exchangerate};
1425       }
1426       
1427       map { $form->{"taxaccounts_$i"} .= "$_ " if ($newform{"IC_tax_$_"}) } split / /, $newform{taxaccounts};
1428       chop $form->{"taxaccounts_$i"};
1429
1430       # credit remaining calculation
1431       $amount = $form->{"sellprice_$i"} * (1 - $form->{"discount_$i"} / 100) * $form->{"qty_$i"};
1432       map { $form->{"${_}_base"} += $amount } (split / /, $form->{"taxaccounts_$i"});
1433       map { $amount += ($form->{"${_}_base"} * $form->{"${_}_rate"}) } split / /, $form->{"taxaccounts_$i"} if !$form->{taxincluded};
1434       
1435       $form->{creditremaining} -= $amount;
1436       
1437     }
1438     
1439     $form->{"id_$i"} = $parts_id;
1440     delete $form->{action};
1441
1442     # restore original callback
1443     $callback = $form->unescape($form->{callback});
1444     $form->{callback} = $form->unescape($form->{old_callback});
1445     delete $form->{old_callback};
1446
1447     $form->{makemodel_rows}--;
1448
1449     # put callback together
1450     foreach $key (keys %$form) {
1451       # do single escape for Apache 2.0
1452       $value = $form->escape($form->{$key}, 1);
1453       $callback .= qq|&$key=$value|;
1454     }
1455     $form->{callback} = $callback;
1456   }
1457
1458   # redirect
1459   $form->redirect;
1460
1461 }
1462
1463
1464 sub save_as_new {
1465
1466   $form->{id} = 0;
1467   &save;
1468
1469 }
1470
1471
1472 sub delete {
1473
1474   $rc = IC->delete(\%myconfig, \%$form);
1475   
1476   # redirect
1477   $form->redirect($locale->text('Item deleted!')) if ($rc > 0);
1478   $form->error($locale->text('Cannot delete item!'));
1479
1480 }
1481
1482
1483
1484 sub stock_assembly {
1485
1486   $form->{title} = $locale->text('Stock Assembly');
1487   
1488   $form->header;
1489   
1490   print qq|
1491 <body>
1492
1493 <form method=post action=$form->{script}>
1494
1495 <table width="100%">
1496   <tr><th class=listtop>$form->{title}</th></tr>
1497   <tr height="5"></tr>
1498   <tr valign=top>
1499     <td>
1500       <table width="100%">
1501         <tr>
1502           <th width="1%" align="right" nowrap="true">|.$locale->text('Number').qq|</th>
1503           <td width="40%"><input name=partnumber size=20></td>
1504           <td>&nbsp;</td>
1505         </tr>
1506         <tr>
1507           <th align="right" nowrap="true">|.$locale->text('Description').qq|</th>
1508           <td colspan="2"><input name=description size=40></td>
1509         </tr>
1510       </table>
1511     </td>
1512   </tr>
1513   <tr><td><hr size=3 noshade></td></tr>
1514 </table>
1515
1516 <input type=hidden name=path value=$form->{path}>
1517 <input type=hidden name=login value=$form->{login}>
1518 <input type=hidden name=password value=$form->{password}>
1519
1520 <input type=hidden name=nextsub value=list_assemblies>
1521
1522 <br>
1523 <input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
1524 </form>
1525
1526 </body>
1527 </html>
1528 |;
1529
1530 }
1531
1532
1533
1534
1535 sub list_assemblies {
1536
1537   IC->retrieve_assemblies(\%myconfig, \%$form);
1538
1539   $column_header{partnumber} = qq|<th class=listheading>|.$locale->text('Number').qq|</th>|;
1540   $column_header{description} = qq|<th class=listheading>|.$locale->text('Description').qq|</th>|;
1541   $column_header{bin} = qq|<th class=listheading>|.$locale->text('Bin').qq|</th>|;
1542   $column_header{onhand} = qq|<th class=listheading>|.$locale->text('Qty').qq|</th>|;
1543   $column_header{rop} = qq|<th class=listheading>|.$locale->text('ROP').qq|</th>|;
1544   $column_header{stock} = qq|<th class=listheading>|.$locale->text('Add').qq|</th>|;
1545
1546   @column_index = (qw(partnumber description bin onhand rop stock));
1547   
1548   $form->{title} = $locale->text('Stock Assembly');
1549
1550   $form->{callback} = "$form->{script}?action=stock_assembly&path=$form->{path}&login=$form->{login}&password=$form->{password}";
1551   
1552   $form->header;
1553   
1554   $colspan = $#column_index + 1;
1555
1556   print qq|
1557 <body>
1558
1559 <form method=post action=$form->{script}>
1560
1561 <table width=100%>
1562   <tr><th class=listtop colspan=$colspan>$form->{title}</th></tr>
1563   <tr size=5></tr>
1564   <tr class=listheading>|;
1565
1566   map { print "\n$column_header{$_}" } @column_index;
1567
1568   print qq|
1569   </tr>
1570 |;
1571
1572   $i = 1;
1573   foreach $ref (@{ $form->{assembly_items} }) {
1574
1575     map { $ref->{$_} =~ s/"/&quot;/g } qw(partnumber description);
1576    
1577     # figure out how many to stock
1578     $form->{"qty_$i"} = $form->format_amount(\%myconfig, $ref->{rop} - $ref->{onhand});
1579
1580     $column_data{partnumber} = qq|<td width=20%>$ref->{partnumber}</td>|;
1581     $column_data{description} = qq|<td width=50%>$ref->{description}&nbsp;</td>|;
1582     $column_data{bin} = qq|<td>$ref->{bin}&nbsp;</td>|;
1583     $column_data{onhand} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{onhand}, '', "&nbsp;").qq|</td>|;
1584     $column_data{rop} = qq|<td align=right>|.$form->format_amount(\%myconfig, $ref->{rop}, '', "&nbsp;").qq|</td>|;
1585     $column_data{stock} = qq|<td width=10%><input name="qty_$i" size=10 value=$form->{"qty_$i"}></td>|;
1586
1587     $j++; $j %= 2;
1588     print qq|<tr class=listrow$j><input name="id_$i" type=hidden value=$ref->{id}>\n|;
1589     
1590     map { print "\n$column_data{$_}" } @column_index;
1591     
1592     print qq|
1593     </tr>
1594 |;
1595
1596     $i++;
1597
1598   }
1599   
1600   $i--;
1601   print qq|
1602   <tr>
1603     <td colspan=6><hr size=3 noshade>
1604   </tr>
1605 </table>
1606 <input name=rowcount type=hidden value="$i">
1607
1608 <input type=hidden name=path value=$form->{path}>
1609 <input type=hidden name=login value=$form->{login}>
1610 <input type=hidden name=password value=$form->{password}>
1611
1612 <input name=callback type=hidden value="$form->{callback}">
1613
1614 <input type=hidden name=nextsub value=restock_assemblies>
1615
1616 <br>
1617 <input class=submit type=submit name=action value="|.$locale->text('Continue').qq|">
1618
1619 </form>
1620
1621 </body>
1622 </html>
1623 |;
1624  
1625 }
1626
1627
1628 sub restock_assemblies {
1629
1630   $form->redirect($locale->text('Assemblies restocked!')) if (IC->restock_assemblies(\%myconfig, \%$form));
1631   $form->error($locale->text('Cannot stock assemblies!'));
1632   
1633 }
1634
1635
1636 sub continue { &{ $form->{nextsub} } };
1637
1638