1#=====================================================================
2# LedgerSMB Small Medium Business Accounting
3# http://www.ledgersmb.org/
4#
5
6# Copyright (C) 2006
7# This work contains copyrighted information from a number of sources all used
8# with permission.
9#
10# This file contains source code included with or based on SQL-Ledger which
11# is Copyright Dieter Simader and DWS Systems Inc. 2000-2005 and licensed
12# under the GNU General Public License version 2 or, at your option, any later
13# version.  For a full list including contact information of contributors,
14# maintainers, and copyright holders, see the CONTRIBUTORS file.
15#
16# Original Copyright Notice from SQL-Ledger 2.6.17 (before the fork):
17# Copyright (c) 2001
18#
19#  Author: DWS Systems Inc.
20#     Web: http://www.sql-ledger.org
21#
22# Contributors:
23#
24#
25# This program is free software; you can redistribute it and/or modify
26# it under the terms of the GNU General Public License as published by
27# the Free Software Foundation; either version 2 of the License, or
28# (at your option) any later version.
29#
30# This program is distributed in the hope that it will be useful,
31# but WITHOUT ANY WARRANTY; without even the implied warranty of
32# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33# GNU General Public License for more details.
34# You should have received a copy of the GNU General Public License
35# along with this program; if not, write to the Free Software
36# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37#======================================================================
38#
39# Inventory Control module
40#
41#======================================================================
42
43use LedgerSMB::IC;
44use LedgerSMB::Tax;
45
46require "bin/io.pl";
47
481;
49
50# end of main
51
52sub add {
53
54    %label = (
55        part     => 'Part',
56        service  => 'Service',
57        assembly => 'Assembly',
58        labor    => 'Labor/Overhead',
59    );
60
61    # $locale->text('Add Part')
62    # $locale->text('Add Service')
63    # $locale->text('Add Assembly')
64    # $locale->text('Add Labor/Overhead')
65
66    $label = "Add $label{$form->{item}}";
67    $form->{title} = $locale->text($label);
68
69    $form->{callback} =
70"$form->{script}?action=add&item=$form->{item}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}"
71      unless $form->{callback};
72
73    $form->{orphaned} = 1;
74
75    if ( $form->{previousform} ) {
76        $form->{callback} = "";
77    }
78
79    &link_part;
80
81    &display_form;
82
83}
84
85sub edit {
86
87    %label = (
88        part     => 'Part',
89        service  => 'Service',
90        assembly => 'Assembly',
91        labor    => 'Labor/Overhead',
92    );
93
94    # $locale->text('Edit Part')
95    # $locale->text('Edit Service')
96    # $locale->text('Edit Assembly')
97    # $locale->text('Edit Labor/Overhead')
98
99    IC->get_part( \%myconfig, \%$form );
100
101    $label = "Edit $label{$form->{item}}";
102    $form->{title} = $locale->text($label);
103
104    $form->{previousform} = $form->escape( $form->{previousform}, 1 )
105      if $form->{previousform};
106
107    &link_part;
108
109    &display_form;
110
111}
112
113sub link_part {
114
115    IC->create_links( "IC", \%myconfig, \%$form );
116
117    # currencies
118    $form->{selectcurrency} = "";
119    for ( split /:/, $form->{currencies} ) {
120        $form->{selectcurrency} .= "<option>$_\n";
121    }
122
123    # readonly
124    if ( $form->{item} eq 'part' ) {
125        $form->{readonly} = 1
126          if $myconfig{acs} =~ /Goods \& Services--Add Part/;
127        $form->error(
128            $locale->text(
129                'Cannot create Part; Inventory account does not exist!')
130        ) if !@{ $form->{IC_links}{IC} };
131        $form->error(
132            $locale->text('Cannot create Part; Income account does not exist!')
133        ) if !@{ $form->{IC_links}{IC_sale} };
134        $form->error(
135            $locale->text('Cannot create Part; COGS account does not exist!') )
136          if !@{ $form->{IC_links}{IC_cogs} };
137    }
138
139    if ( $form->{item} eq 'service' ) {
140        $form->{readonly} = 1
141          if $myconfig{acs} =~ /Goods \& Services--Add Service/;
142        $form->error(
143            $locale->text(
144                'Cannot create Service; Income account does not exist!')
145        ) if !@{ $form->{IC_links}{IC_income} };
146        $form->error(
147            $locale->text(
148                'Cannot create Service; Expense account does not exist!')
149        ) if !@{ $form->{IC_links}{IC_expense} };
150    }
151
152    if ( $form->{item} eq 'assembly' ) {
153        $form->{readonly} = 1
154          if $myconfig{acs} =~ /Goods \& Services--Add Assembly/;
155        $form->error(
156            $locale->text(
157                'Cannot create Assembly; Income account does not exist!')
158        ) if !@{ $form->{IC_links}{IC_income} };
159    }
160    if ( $form->{item} eq 'labor' ) {
161        $form->{readonly} = 1
162          if $myconfig{acs} =~ /Goods \& Services--Add Labor\/Overhead/;
163        $form->error(
164            $locale->text(
165                'Cannot create Labor; Inventory account does not exist!')
166        ) if !@{ $form->{IC_links}{IC} };
167        $form->error(
168            $locale->text('Cannot create Labor; COGS account does not exist!') )
169          if !@{ $form->{IC_links}{IC_cogs} };
170    }
171
172    # parts, assemblies , labor and overhead have the same links
173    $taxpart = ( $form->{item} eq 'service' ) ? "service" : "part";
174
175    # build the popup menus
176    $form->{taxaccounts} = "";
177    foreach $key ( keys %{ $form->{IC_links} } ) {
178
179        $form->{"select$key"} = "";
180        foreach $ref ( @{ $form->{IC_links}{$key} } ) {
181
182            # if this is a tax field
183            if ( $key =~ /IC_tax/ ) {
184                if ( $key =~ /$taxpart/ ) {
185
186                    $form->{taxaccounts} .= "$ref->{accno} ";
187                    $form->{"IC_tax_$ref->{accno}_description"} =
188                      "$ref->{accno}--$ref->{description}";
189
190                    if ( $form->{id} ) {
191                        if ( $form->{amount}{ $ref->{accno} } ) {
192                            $form->{"IC_tax_$ref->{accno}"} = "checked";
193                        }
194                    }
195                    else {
196                        $form->{"IC_tax_$ref->{accno}"} = "checked";
197                    }
198
199                }
200            }
201            else {
202
203                $form->{"select$key"} .=
204                  "<option>$ref->{accno}--$ref->{description}\n";
205
206            }
207        }
208    }
209    chop $form->{taxaccounts};
210
211    if ( $form->{item} !~ /service/ ) {
212        $form->{selectIC_inventory} = $form->{selectIC};
213        $form->{selectIC_income}    = $form->{selectIC_sale};
214        $form->{selectIC_expense}   = $form->{selectIC_cogs};
215        $form->{IC_income}          = $form->{IC_sale};
216        $form->{IC_expense}         = $form->{IC_cogs};
217    }
218
219    # set option
220    for (qw(IC_inventory IC_income IC_expense)) {
221        $form->{$_} =
222          "$form->{amount}{$_}{accno}--$form->{amount}{$_}{description}"
223          if $form->{amount}{$_}{accno};
224    }
225
226    delete $form->{IC_links};
227    delete $form->{amount};
228
229    $form->get_partsgroup( \%myconfig, { all => 1 } );
230    if ( $form->{partsgroup} ) {
231        $form->{partsgroup} =
232          $form->quote( $form->{partsgroup} ) . "--$form->{partsgroup_id}";
233    }
234
235    if ( @{ $form->{all_partsgroup} } ) {
236        $form->{selectpartsgroup} = qq|<option>\n|;
237
238        for ( @{ $form->{all_partsgroup} } ) {
239            $form->{selectpartsgroup} .=
240                qq|<option value="|
241              . $form->quote( $_->{partsgroup} )
242              . qq|--$_->{id}">$_->{partsgroup}\n|;
243        }
244        delete $form->{all_partsgroup};
245    }
246
247    if ( $form->{item} eq 'assembly' ) {
248
249        for ( 1 .. $form->{assembly_rows} ) {
250            if ( $form->{"partsgroup_id_$_"} ) {
251                $form->{"partsgroup_$_"} =
252                  qq|$form->{"partsgroup_$_"}--$form->{"partsgroup_id_$_"}|;
253            }
254        }
255
256        $form->get_partsgroup( \%myconfig );
257
258        if ( @{ $form->{all_partsgroup} } ) {
259            $form->{selectassemblypartsgroup} = qq|<option>\n|;
260
261            for ( @{ $form->{all_partsgroup} } ) {
262                $form->{selectassemblypartsgroup} .=
263qq|<option value="$_->{partsgroup}--$_->{id}">$_->{partsgroup}\n|;
264            }
265            delete $form->{all_partsgroup};
266        }
267    }
268
269    # setup make and models
270    $i = 1;
271    foreach $ref ( @{ $form->{makemodels} } ) {
272        for (qw(make model)) { $form->{"${_}_$i"} = $ref->{$_} }
273        $i++;
274    }
275    $form->{makemodel_rows} = $i - 1;
276    delete $form->{makemodels};
277
278    # setup vendors
279    if ( @{ $form->{all_vendor} } ) {
280        $form->{selectvendor} = "<option>\n";
281        for ( @{ $form->{all_vendor} } ) {
282            $form->{selectvendor} .=
283              qq|<option value="$_->{name}--$_->{id}">$_->{name}\n|;
284        }
285        delete $form->{all_vendor};
286    }
287
288    # vendor matrix
289    $i = 1;
290    foreach $ref ( @{ $form->{vendormatrix} } ) {
291        $form->{"vendor_$i"} = qq|$ref->{name}--$ref->{id}|;
292
293        for (qw(partnumber lastcost leadtime vendorcurr)) {
294            $form->{"${_}_$i"} = $ref->{$_};
295        }
296        $i++;
297    }
298    $form->{vendor_rows} = $i - 1;
299    delete $form->{vendormatrix};
300
301    # setup customers and groups
302    if ( @{ $form->{all_customer} } ) {
303        $form->{selectcustomer} = "<option>\n";
304        for ( @{ $form->{all_customer} } ) {
305            $form->{selectcustomer} .=
306              qq|<option value="$_->{name}--$_->{id}">$_->{name}\n|;
307        }
308        delete $form->{all_customer};
309    }
310
311    if ( @{ $form->{all_pricegroup} } ) {
312        $form->{selectpricegroup} = "<option>\n";
313        for ( @{ $form->{all_pricegroup} } ) {
314            $form->{selectpricegroup} .=
315              qq|<option value="$_->{pricegroup}--$_->{id}">$_->{pricegroup}\n|;
316        }
317        delete $form->{all_pricegroup};
318    }
319
320    $i = 1;
321
322    # customer matrix
323    foreach $ref ( @{ $form->{customermatrix} } ) {
324
325        $form->{"customer_$i"} = "$ref->{name}--$ref->{cid}" if $ref->{cid};
326        $form->{"pricegroup_$i"} = "$ref->{pricegroup}--$ref->{gid}"
327          if $ref->{gid};
328
329        for (qw(validfrom validto pricebreak customerprice customercurr)) {
330            $form->{"${_}_$i"} = $ref->{$_};
331        }
332
333        $i++;
334
335    }
336    $form->{customer_rows} = $i - 1;
337    delete $form->{customermatrix};
338
339}
340
341sub form_header {
342
343    if ( $form->{lastcost} > 0 ) {
344        $markup =
345          $form->round_amount(
346            ( ( $form->{sellprice} / $form->{lastcost} - 1 ) * 100 ), 1 );
347        $form->{markup} = $form->format_amount( \%myconfig, $markup, 1 );
348    }
349
350    ($dec) = ( $form->{sellprice} =~ /\.(\d+)/ );
351    $dec = length $dec;
352    $decimalplaces = ( $dec > 2 ) ? $dec : 2;
353
354    for (qw(listprice sellprice)) {
355        $form->{$_} =
356          $form->format_amount( \%myconfig, $form->{$_}, $decimalplaces );
357    }
358
359    ($dec) = ( $form->{lastcost} =~ /\.(\d+)/ );
360    $dec = length $dec;
361    $decimalplaces = ( $dec > 2 ) ? $dec : 2;
362
363    for (qw(lastcost avgcost)) {
364        $form->{$_} =
365          $form->format_amount( \%myconfig, $form->{$_}, $decimalplaces );
366    }
367
368    for (qw(weight rop stock)) {
369        $form->{$_} = $form->format_amount( \%myconfig, $form->{$_} );
370    }
371
372    for (qw(partnumber description unit notes)) {
373        $form->{$_} = $form->quote( $form->{$_} );
374    }
375
376    if ( ( $rows = $form->numtextrows( $form->{notes}, 40 ) ) < 2 ) {
377        $rows = 2;
378    }
379
380    $notes =
381qq|<textarea name=notes rows=$rows cols=40 wrap=soft>$form->{notes}</textarea>|;
382
383    if ( ( $rows = $form->numtextrows( $form->{description}, 40 ) ) > 1 ) {
384        $description =
385qq|<textarea name="description" rows=$rows cols=40 wrap=soft>$form->{description}</textarea>|;
386    }
387    else {
388        $description =
389          qq|<input name="description" size="40" value="$form->{description}">|;
390    }
391
392    for ( split / /, $form->{taxaccounts} ) {
393        $form->{"IC_tax_$_"} = ( $form->{"IC_tax_$_"} ) ? "checked" : "";
394    }
395
396    $form->{selectIC_inventory} = $form->{selectIC};
397
398    # set option
399    for (qw(IC_inventory IC_income IC_expense)) {
400        if ( $form->{$_} ) {
401            if ( $form->{orphaned} ) {
402                $form->{"select$_"} =~ s/ selected//;
403                $form->{"select$_"} =~
404                  s/option>\Q$form->{$_}\E/option selected>$form->{$_}/;
405            }
406            else {
407                $form->{"select$_"} = qq|<option selected>$form->{$_}|;
408            }
409        }
410    }
411
412    if ( $form->{selectpartsgroup} ) {
413        $form->{selectpartsgroup} =
414          $form->unescape( $form->{selectpartsgroup} );
415
416        $partsgroup =
417          qq|<input type="hidden" name="selectpartsgroup" value="|
418          . $form->escape( $form->{selectpartsgroup}, 1 ) . qq|">|;
419
420        $form->{partsgroup} = $form->quote( $form->{partsgroup} );
421        $form->{selectpartsgroup} =~
422          s/(<option value="\Q$form->{partsgroup}\E")/$1 selected/;
423
424        $partsgroup .=
425          qq|\n<select name="partsgroup">$form->{selectpartsgroup}</select>|;
426        $group = $locale->text('Group');
427    }
428
429    # tax fields
430    foreach $item ( split / /, $form->{taxaccounts} ) {
431        $tax .= qq|
432      <input class="checkbox" type="checkbox" name="IC_tax_$item" value="1" $form->{"IC_tax_$item"}>&nbsp;<b>$form->{"IC_tax_${item}_description"}</b>
433      <br><input type="hidden" name="IC_tax_${item}_description" value="$form->{"IC_tax_${item}_description"}">
434|;
435    }
436
437    $sellprice = qq|
438	      <tr>
439		<th align="right" nowrap="true">| . $locale->text('Sell Price') . qq|</th>
440		<td><input name="sellprice" size="11" value="$form->{sellprice}"></td>
441	      </tr>
442	      <tr>
443		<th align="right" nowrap="true">| . $locale->text('List Price') . qq|</th>
444		<td><input name="listprice" size="11" value="$form->{listprice}"></td>
445	      </tr>
446|;
447
448    $avgcost = qq|
449 	      <tr>
450                <th align="right" nowrap="true">|
451      . $locale->text('Average Cost')
452      . qq|</th>
453                <td><input type="hidden" name="avgcost" value="$form->{avgcost}">$form->{avgcost}</td>
454              </tr>
455|;
456
457    $lastcost = qq|
458 	      <tr>
459                <th align="right" nowrap="true">|
460      . $locale->text('Last Cost')
461      . qq|</th>
462                <td><input name="lastcost" size="11" value="$form->{lastcost}"></td>
463              </tr>
464	      <tr>
465	        <th align="right" nowrap="true">|
466      . $locale->text('Markup')
467      . qq| %</th>
468		<td><input name="markup" size="5" value="$form->{markup}"></td>
469		<input type="hidden" name="oldmarkup" value="$markup">
470	      </tr>
471|;
472
473    if ( $form->{item} =~ /(part|assembly)/ ) {
474        $n = ( $form->{onhand} > 0 ) ? "1" : "0";
475        $onhand = qq|
476	      <tr>
477		<th align="right" nowrap>| . $locale->text('On Hand') . qq|</th>
478		<th align="left" nowrap class="plus$n">&nbsp;|
479          . $form->format_amount( \%myconfig, $form->{onhand} )
480          . qq|</th>
481	      </tr>
482|;
483
484        $rop = qq|
485	      <tr>
486		<th align="right" nowrap="true">| . $locale->text('ROP') . qq|</th>
487		<td><input name="rop" size="10" value="$form->{rop}"></td>
488	      </tr>
489|;
490
491        $bin = qq|
492	      <tr>
493		<th align="right" nowrap="true">| . $locale->text('Bin') . qq|</th>
494		<td><input name=bin size=10 value="$form->{bin}"></td>
495	      </tr>
496|;
497
498        $imagelinks = qq|
499  <tr>
500    <td>
501      <table width=100%>
502        <tr>
503	  <th align=right nowrap>| . $locale->text('Image') . qq|</th>
504	  <td><input name=image size=40 value="$form->{image}"></td>
505	  <th align=right nowrap>| . $locale->text('Microfiche') . qq|</th>
506	  <td><input name=microfiche size=20 value="$form->{microfiche}"></td>
507	</tr>
508	<tr>
509	  <th align=right nowrap>| . $locale->text('Drawing') . qq|</th>
510	  <td><input name=drawing size=40 value="$form->{drawing}"></td>
511	</tr>
512      </table>
513    </td>
514  </tr>
515|;
516    }
517
518    if ( $form->{item} eq "part" ) {
519
520        $linkaccounts = qq|
521	      <tr>
522		<th align=right>| . $locale->text('Inventory') . qq|</th>
523		<td><select name=IC_inventory>$form->{selectIC_inventory}</select></td>
524		<input name=selectIC type=hidden value="$form->{selectIC}">
525	      </tr>
526	      <tr>
527		<th align=right>| . $locale->text('Income') . qq|</th>
528		<td><select name=IC_income>$form->{selectIC_income}</select></td>
529		<input name=selectIC_income type=hidden value="$form->{selectIC_income}">
530	      </tr>
531	      <tr>
532		<th align=right>| . $locale->text('COGS') . qq|</th>
533		<td><select name=IC_expense>$form->{selectIC_expense}</select></td>
534		<input name=selectIC_expense type=hidden value="$form->{selectIC_expense}">
535	      </tr>
536|;
537
538        if ($tax) {
539            $linkaccounts .= qq|
540	      <tr>
541		<th align=right>| . $locale->text('Tax') . qq|</th>
542		<td>$tax</td>
543	      </tr>
544|;
545        }
546
547        $weight = qq|
548	      <tr>
549		<th align="right" nowrap="true">| . $locale->text('Weight') . qq|</th>
550		<td>
551		  <table>
552		    <tr>
553		      <td>
554			<input name="weight" size="10" value="$form->{weight}">
555		      </td>
556		      <th>
557			&nbsp;
558			$form->{weightunit}
559			<input type="hidden" name="weightunit" value="$form->{weightunit}">
560		      </th>
561		    </tr>
562		  </table>
563		</td>
564	      </tr>
565|;
566
567    }
568
569    if ( $form->{item} eq "assembly" ) {
570
571        $avgcost = "";
572
573        if ( $form->{project_id} ) {
574            $weight = qq|
575	      <tr>
576		<th align="right" nowrap="true">| . $locale->text('Weight') . qq|</th>
577		<td>
578		  <table>
579		    <tr>
580		      <td>
581			<input name="weight" size="10" value="$form->{weight}">
582		      </td>
583		      <th>
584			&nbsp;
585			$form->{weightunit}
586			<input type="hidden" name="weightunit" value="$form->{weightunit}">
587		      </th>
588		    </tr>
589		  </table>
590		</td>
591	      </tr>
592|;
593        }
594        else {
595
596            $weight = qq|
597	      <tr>
598		<th align="right" nowrap="true">| . $locale->text('Weight') . qq|</th>
599		<td>
600		  <table>
601		    <tr>
602		      <td>
603			&nbsp;$form->{weight}
604			<input type="hidden" name="weight" value="$form->{weight}">
605		      </td>
606		      <th>
607			&nbsp;
608			$form->{weightunit}
609			<input type="hidden" name="weightunit" value="$form->{weightunit}">
610		      </th>
611		    </tr>
612		  </table>
613		</td>
614	      </tr>
615|;
616        }
617
618        if ( $form->{project_id} ) {
619            $lastcost               = "";
620            $avgcost                = "";
621            $onhand                 = "";
622            $rop                    = "";
623            $form->{isassemblyitem} = 1;
624
625        }
626        else {
627            $stock = qq|
628              <tr>
629	        <th align="right" nowrap>| . $locale->text('Stock') . qq|</th>
630		<td><input name="stock" size="10" value="$form->{stock}"></td>
631	      </tr>
632|;
633
634            $lastcost = qq|
635              <tr>
636	        <th align="right" nowrap="true">|
637              . $locale->text('Last Cost')
638              . qq|</th>
639		<td><input type="hidden" name="lastcost" value="$form->{lastcost}">$form->{lastcost}</td>
640	      </tr>
641	      <tr>
642	        <th align="right" nowrap="true">|
643              . $locale->text('Markup')
644              . qq| %</th>
645		<td><input name="markup" size="5" value="$form->{markup}"></td>
646		<input type="hidden" name="oldmarkup" value="$markup">
647	      </tr>
648|;
649
650        }
651
652        $linkaccounts = qq|
653	      <tr>
654		<th align=right>| . $locale->text('Income') . qq|</th>
655		<td><select name=IC_income>$form->{selectIC_income}</select></td>
656		<input name=selectIC_income type=hidden value="$form->{selectIC_income}">
657	      </tr>
658|;
659
660        if ($tax) {
661            $linkaccounts .= qq|
662	      <tr>
663		<th align=right>| . $locale->text('Tax') . qq|</th>
664		<td>$tax</td>
665	      </tr>
666|;
667        }
668
669    }
670
671    if ( $form->{item} eq "service" ) {
672        $avgcost      = "";
673        $linkaccounts = qq|
674	      <tr>
675		<th align=right>| . $locale->text('Income') . qq|</th>
676		<td><select name=IC_income>$form->{selectIC_income}</select></td>
677		<input name=selectIC_income type=hidden value="$form->{selectIC_income}">
678	      </tr>
679	      <tr>
680		<th align=right>| . $locale->text('Expense') . qq|</th>
681		<td><select name=IC_expense>$form->{selectIC_expense}</select></td>
682		<input name=selectIC_expense type=hidden value="$form->{selectIC_expense}">
683	      </tr>
684|;
685
686        if ($tax) {
687            $linkaccounts .= qq|
688	      <tr>
689		<th align=right>| . $locale->text('Tax') . qq|</th>
690		<td>$tax</td>
691	      </tr>
692|;
693        }
694
695    }
696
697    if ( $form->{item} eq 'labor' ) {
698        $avgcost = "";
699
700        $n = ( $form->{onhand} > 0 ) ? "1" : "0";
701        $onhand = qq|
702              <tr>
703	        <th align="right" nowrap>| . $locale->text('On Hand') . qq|</th>
704		<th align=left nowrap class="plus$n">&nbsp;|
705          . $form->format_amount( \%myconfig, $form->{onhand} )
706          . qq|</th>
707              </tr>
708|;
709
710        $linkaccounts = qq|
711	      <tr>
712		<th align=right>| . $locale->text('Labor/Overhead') . qq|</th>
713		<td><select name=IC_inventory>$form->{selectIC_inventory}</select></td>
714		<input name=selectIC type=hidden value="$form->{selectIC}">
715	      </tr>
716
717	      <tr>
718		<th align=right>| . $locale->text('COGS') . qq|</th>
719		<td><select name=IC_expense>$form->{selectIC_expense}</select></td>
720		<input name=selectIC_expense type=hidden value="$form->{selectIC_expense}">
721	      </tr>
722|;
723
724    }
725
726    if ( $form->{id} ) {
727        $checked = ( $form->{obsolete} ) ? "checked" : "";
728        $obsolete = qq|
729	      <tr>
730		<th align="right" nowrap="true">| . $locale->text('Obsolete') . qq|</th>
731		<td><input name=obsolete type=checkbox class=checkbox value=1 $checked></td>
732	      </tr>
733|;
734        $obsolete = "<input type=hidden name=obsolete value=$form->{obsolete}>"
735          if $form->{project_id};
736    }
737
738    # type=submit $locale->text('Edit Part')
739    # type=submit $locale->text('Edit Service')
740    # type=submit $locale->text('Edit Assembly')
741
742    $form->header;
743
744    print qq|
745<body>
746
747<form method=post action="$form->{script}">
748|;
749
750    $form->hide_form(
751        qw(id item title makemodel alternate onhand orphaned taxaccounts rowcount baseassembly project_id)
752    );
753
754    print qq|
755<table width="100%">
756  <tr>
757    <th class=listtop>$form->{title}</th>
758  </tr>
759  <tr height="5"></tr>
760  <tr>
761    <td>
762      <table width="100%">
763        <tr valign=top>
764          <th align=left>| . $locale->text('Number') . qq|</th>
765          <th align=left>| . $locale->text('Description') . qq|</th>
766	  <th align=left>$group</th>
767	</tr>
768	<tr valign=top>
769          <td><input name=partnumber value="$form->{partnumber}" size=20></td>
770          <td>$description</td>
771	  <td>$partsgroup</td>
772	</tr>
773      </table>
774    </td>
775  </tr>
776  <tr>
777    <td>
778      <table width="100%" height="100%">
779        <tr valign=top>
780          <td width=70%>
781            <table width="100%" height="100%">
782              <tr class="listheading">
783                <th class="listheading" align="center" colspan=2>|
784      . $locale->text('Link Accounts')
785      . qq|</th>
786              </tr>
787              $linkaccounts
788              <tr>
789                <th align="left">| . $locale->text('Notes') . qq|</th>
790              </tr>
791              <tr>
792                <td colspan=2>
793                  $notes
794                </td>
795              </tr>
796            </table>
797          </td>
798	  <td width="30%">
799	    <table width="100%">
800	      <tr>
801		<th align="right" nowrap="true">| . $locale->text('Updated') . qq|</th>
802		<td><input name="priceupdate" size="11" title="$myconfig{dateformat}" value="$form->{priceupdate}"></td>
803	      </tr>
804	      $sellprice
805	      $lastcost
806	      $avgcost
807	      <tr>
808		<th align="right" nowrap="true">| . $locale->text('Unit') . qq|</th>
809		<td><input name=unit size=5 value="$form->{unit}"></td>
810	      </tr>
811	      $weight
812	      $onhand
813	      $stock
814	      $rop
815	      $bin
816	      $obsolete
817	    </table>
818	  </td>
819	</tr>
820      </table>
821    </td>
822  </tr>
823  $imagelinks
824|;
825}
826
827sub form_footer {
828
829    print qq|
830  <tr>
831    <td><hr size=3 noshade></td>
832  </tr>
833</table>
834|;
835
836    $form->hide_form(qw(customer_rows));
837
838    if ( $form->{item} =~ /(part|assembly)/ ) {
839        $form->hide_form(qw(makemodel_rows));
840    }
841
842    if ( $form->{item} =~ /(part|service)/ ) {
843        $form->hide_form(qw(vendor_rows));
844    }
845
846    # type=submit $locale->text('Update')
847    # type=submit $locale->text('Save')
848    # type=submit $locale->text('Save as new')
849    # type=submit $locale->text('Delete')
850
851    if ( !$form->{readonly} ) {
852
853        %button = (
854            'update' =>
855              { ndx => 1, key => 'U', value => $locale->text('Update') },
856            'save' => { ndx => 3, key => 'S', value => $locale->text('Save') },
857        );
858
859        if ( $form->{id} ) {
860
861            if ( !$form->{isassemblyitem} ) {
862                $button{'save_as_new'} = {
863                    ndx   => 7,
864                    key   => 'N',
865                    value => $locale->text('Save as new')
866                };
867            }
868
869            if ( $form->{orphaned} ) {
870                $button{'delete'} =
871                  { ndx => 16, key => 'D', value => $locale->text('Delete') };
872            }
873        }
874        %button = () if $form->{isassemblyitem} && $form->{item} eq 'assembly';
875
876        for ( sort { $button{$a}->{ndx} <=> $button{$b}->{ndx} } keys %button )
877        {
878            $form->print_button( \%button, $_ );
879        }
880
881    }
882
883    if ( $form->{lynx} ) {
884        require "bin/menu.pl";
885        &menubar;
886    }
887
888    &assembly_row( ++$form->{assembly_rows} ) if $form->{item} eq 'assembly';
889
890    $form->hide_form(
891        qw(login path sessionid callback previousform isassemblyitem));
892
893    print qq|
894</form>
895
896</body>
897</html>
898|;
899
900}
901
902sub search {
903
904    $form->get_partsgroup( \%myconfig,
905        { searchitems => $form->{searchitems} } );
906
907    IC->get_warehouses( \%myconfig, \%$form )
908      unless $form->{searchitems} =~ /(service|labor)/;
909
910    if ( @{ $form->{all_partsgroup} } ) {
911        $partsgroup = qq|<option>\n|;
912
913        for ( @{ $form->{all_partsgroup} } ) {
914            $partsgroup .=
915                qq|<option value="|
916              . $form->quote( $_->{partsgroup} )
917              . qq|--$_->{id}">$_->{partsgroup}\n|;
918        }
919
920        $partsgroup = qq|
921        <th align=right nowrap>| . $locale->text('Group') . qq|</th>
922	<td><select name=partsgroup>$partsgroup</select></td>
923|;
924
925        $l_partsgroup =
926          qq|<input name=l_partsgroup class=checkbox type=checkbox value=Y> |
927          . $locale->text('Group');
928    }
929
930    $l_listprice =
931      qq|<input name=l_listprice class=checkbox type=checkbox value=Y> |
932      . $locale->text('List Price');
933    $l_sellprice =
934      qq|<input name=l_sellprice class=checkbox type=checkbox value=Y checked> |
935      . $locale->text('Sell Price');
936    $l_lastcost =
937      qq|<input name=l_lastcost class=checkbox type=checkbox value=Y checked> |
938      . $locale->text('Last Cost');
939    $l_avgcost =
940      qq|<input name=l_avgcost class=checkbox type=checkbox value=Y checked> |
941      . $locale->text('Average Cost');
942    $l_linetotal =
943      qq|<input name=l_linetotal class=checkbox type=checkbox value=Y> |
944      . $locale->text('Line Total');
945    $l_markup =
946      qq|<input name=l_markup class=checkbox type=checkbox value=Y> |
947      . $locale->text('Markup');
948    $l_account =
949      qq|<input name=l_account class=checkbox type=checkbox value=Y> |
950      . $locale->text('Accounts');
951
952    $bought = qq|
953          <td>
954	    <table>
955	      <tr>
956		<td><input name=bought class=checkbox type=checkbox value=1></td>
957		<td nowrap>| . $locale->text('Vendor Invoices') . qq|</td>
958	      </tr>
959	      <tr>
960		<td><input name=onorder class=checkbox type=checkbox value=1></td>
961		<td nowrap>| . $locale->text('Purchase Orders') . qq|</td>
962	      </tr>
963	      <tr>
964		<td><input name=rfq class=checkbox type=checkbox value=1></td>
965		<td nowrap>| . $locale->text('RFQ') . qq|</td>
966	      </tr>
967	    </table>
968	  </td>
969|;
970
971    $sold = qq|
972	  <td>
973	    <table>
974	      <tr>
975		<td><input name=sold class=checkbox type=checkbox value=1></td>
976		<td nowrap>| . $locale->text('Sales Invoices') . qq|</td>
977	      </tr>
978	      <tr>
979		<td><input name=ordered class=checkbox type=checkbox value=1></td>
980		<td nowrap>| . $locale->text('Sales Orders') . qq|</td>
981	      </tr>
982	      <tr>
983		<td><input name=quoted class=checkbox type=checkbox value=1></td>
984		<td nowrap>| . $locale->text('Quotations') . qq|</td>
985	      </tr>
986	    </table>
987	  </td>
988|;
989
990    $fromto = qq|
991	  <td>
992	    <table>
993	      <tr>
994		<td nowrap><b>| . $locale->text('From') . qq|</b>
995		<input name=transdatefrom size=11 title="$myconfig{dateformat}">
996		<b>| . $locale->text('To') . qq|</b>
997		<input name=transdateto size=11 title="$myconfig{dateformat}"></td>
998	      </tr>
999	      <tr>
1000		<td nowrap><input name=method class=radio type=radio value=accrual checked>|
1001      . $locale->text('Accrual') . qq|
1002		<input name=method class=radio type=radio value=cash>|
1003      . $locale->text('Cash')
1004      . qq|</td>
1005	      </tr>
1006	      <tr>
1007		<td nowrap>
1008		<input name=open class=checkbox type=checkbox value=1 checked> |
1009      . $locale->text('Open') . qq|
1010		<input name=closed class=checkbox type=checkbox> |
1011      . $locale->text('Closed') . qq|
1012		<input name=summary type=radio class=radio value=1> |
1013      . $locale->text('Summary') . qq|
1014		<input name=summary type=radio class=radio value=0 checked> |
1015      . $locale->text('Detail') . qq|
1016		</td>
1017	      </tr>
1018	    </table>
1019	  </td>
1020|;
1021
1022    $l_name =
1023      qq|<input name=l_name class=checkbox type=checkbox value=Y> |
1024      . $locale->text('Name');
1025    $l_curr =
1026      qq|<input name=l_curr class=checkbox type=checkbox value=Y> |
1027      . $locale->text('Currency');
1028    $l_employee =
1029      qq|<input name=l_employee class=checkbox type=checkbox value=Y> |
1030      . $locale->text('Employee');
1031    $l_serialnumber =
1032      qq|<input name=l_serialnumber class=checkbox type=checkbox value=Y> |
1033      . $locale->text('Serial Number');
1034
1035    $serialnumber = qq|
1036          <th align=right nowrap>| . $locale->text('Serial Number') . qq|</th>
1037          <td><input name=serialnumber size=20></td>
1038|;
1039
1040    $orphaned = qq|
1041            <input name=itemstatus class=radio type=radio value=orphaned>&nbsp;|
1042      . $locale->text('Orphaned');
1043
1044    if ( $form->{searchitems} =~ /(all|part|assembly)/ ) {
1045
1046        $onhand = qq|
1047            <input name=itemstatus class=radio type=radio value=onhand>&nbsp;|
1048          . $locale->text('On Hand') . qq|
1049            <input name=itemstatus class=radio type=radio value=short>&nbsp;|
1050          . $locale->text('Short') . qq|
1051|;
1052
1053        $makemodel = qq|
1054        <tr>
1055          <th align=right nowrap>| . $locale->text('Make') . qq|</th>
1056          <td><input name=make size=20></td>
1057          <th align=right nowrap>| . $locale->text('Model') . qq|</th>
1058          <td><input name=model size=20></td>
1059        </tr>
1060|;
1061
1062        $l_make =
1063          qq|<input name=l_make class=checkbox type=checkbox value=Y>&nbsp;|
1064          . $locale->text('Make');
1065        $l_model =
1066          qq|<input name=l_model class=checkbox type=checkbox value=Y>&nbsp;|
1067          . $locale->text('Model');
1068
1069        $l_bin =
1070          qq|<input name=l_bin class=checkbox type=checkbox value=Y>&nbsp;|
1071          . $locale->text('Bin');
1072
1073        $l_rop =
1074          qq|<input name=l_rop class=checkbox type=checkbox value=Y>&nbsp;|
1075          . $locale->text('ROP');
1076
1077        $l_weight =
1078          qq|<input name=l_weight class=checkbox type=checkbox value=Y>&nbsp;|
1079          . $locale->text('Weight');
1080
1081        if ( @{ $form->{all_warehouse} } ) {
1082            $selectwarehouse = "<option>\n";
1083
1084            for ( @{ $form->{all_warehouse} } ) {
1085                $selectwarehouse .=
1086qq|<option value="$_->{description}--$_->{id}">$_->{description}\n|;
1087            }
1088
1089            $warehouse = qq|
1090          <th align=right nowrap>| . $locale->text('Warehouse') . qq|</th>
1091          <td><select name=warehouse>$selectwarehouse</select></td>
1092|;
1093
1094            $l_warehouse =
1095qq|<input name=l_warehouse class=checkbox type=checkbox value=Y>&nbsp;|
1096              . $locale->text('Warehouse');
1097
1098        }
1099
1100        $drawing = qq|
1101        <tr>
1102          <th align=right nowrap>| . $locale->text('Drawing') . qq|</th>
1103          <td><input name=drawing size=20></td>
1104          <th align=right nowrap>| . $locale->text('Microfiche') . qq|</th>
1105          <td><input name=microfiche size=20></td>
1106        </tr>
1107|;
1108
1109        $l_image =
1110          qq|<input name=l_image class=checkbox type=checkbox value=Y>&nbsp;|
1111          . $locale->text('Image');
1112
1113        $l_drawing =
1114          qq|<input name=l_drawing class=checkbox type=checkbox value=Y>&nbsp;|
1115          . $locale->text('Drawing');
1116        $l_microfiche =
1117qq|<input name=l_microfiche class=checkbox type=checkbox value=Y>&nbsp;|
1118          . $locale->text('Microfiche');
1119
1120    }
1121
1122    if ( $form->{searchitems} eq 'assembly' ) {
1123
1124        $bought = "";
1125
1126        $toplevel = qq|
1127        <tr>
1128	  <td></td>
1129          <td colspan=3>
1130	  <input name=null class=radio type=radio checked>&nbsp;|
1131          . $locale->text('Top Level') . qq|
1132	  <input name=individual class=checkbox type=checkbox value=1>&nbsp;|
1133          . $locale->text('Individual Items') . qq|
1134          </td>
1135        </tr>
1136|;
1137        $bom =
1138          qq|<input name=itemstatus type=radio value=bom>&nbsp;|
1139          . $locale->text('BOM');
1140
1141    }
1142    elsif ( $form->{searchitems} eq 'component' ) {
1143
1144        $bought         = "";
1145        $sold           = "";
1146        $fromto         = "";
1147        $l_name         = "";
1148        $l_curr         = "";
1149        $l_employee     = "";
1150        $l_serialnumber = "";
1151
1152        $warehouse    = "";
1153        $serialnumber = "";
1154        $orphaned     = "";
1155        $l_warehouse  = "";
1156        $l_account    = "";
1157
1158    }
1159    elsif ( $form->{searchitems} eq 'labor' ) {
1160
1161        $sold = "";
1162
1163        $warehouse    = "";
1164        $serialnumber = "";
1165        $l_avgcost    = "";
1166
1167    }
1168
1169    @a = ();
1170    push @a,
1171qq|<input name=l_runningnumber class=checkbox type=checkbox value=Y>&nbsp;|
1172      . $locale->text('No.');
1173    push @a,
1174qq|<input name=l_partnumber class=checkbox type=checkbox value=Y checked>&nbsp;|
1175      . $locale->text('Number');
1176    push @a,
1177qq|<input name=l_description class=checkbox type=checkbox value=Y checked>&nbsp;|
1178      . $locale->text('Description');
1179    push @a,
1180      qq|<input name=l_qty class=checkbox type=checkbox value=Y checked>&nbsp;|
1181      . $locale->text('Qty');
1182    push @a,
1183      qq|<input name=l_unit class=checkbox type=checkbox value=Y checked>&nbsp;|
1184      . $locale->text('Unit');
1185    push @a,
1186      qq|<input name=l_priceupdate class=checkbox type=checkbox value=Y>&nbsp;|
1187      . $locale->text('Updated');
1188    push @a, $l_partsgroup if $l_partsgroup;
1189    push @a, $l_listprice  if $l_listprice;
1190    push @a, $l_sellprice  if $l_sellprice;
1191    push @a, $l_lastcost   if $l_lastcost;
1192    push @a, $l_avgcost    if $l_avgcost;
1193    push @a, $l_linetotal  if $l_linetotal;
1194    push @a, $l_markup     if $l_markup;
1195    push @a, $l_bin        if $l_bin;
1196    push @a, $l_rop        if $l_rop;
1197    push @a, $l_weight     if $l_weight;
1198    push @a, qq|<input name=l_notes class=checkbox type=checkbox value=Y>&nbsp;|
1199      . $locale->text('Notes');
1200    push @a, $l_image        if $l_image;
1201    push @a, $l_drawing      if $l_drawing;
1202    push @a, $l_microfiche   if $l_microfiche;
1203    push @a, $l_make         if $l_make;
1204    push @a, $l_model        if $l_model;
1205    push @a, $l_warehouse    if $l_warehouse;
1206    push @a, $l_account      if $l_account;
1207    push @a, $l_name         if $l_name;
1208    push @a, $l_curr         if $l_curr;
1209    push @a, $l_employee     if $l_employee;
1210    push @a, $l_serialnumber if $l_serialnumber;
1211
1212    %title = (
1213        all       => 'Items',
1214        part      => 'Parts',
1215        labor     => 'Labor/Overhead',
1216        service   => 'Services',
1217        assembly  => 'Assemblies',
1218        component => 'Components'
1219    );
1220
1221    # $locale->text('Items')
1222    # $locale->text('Parts')
1223    # $locale->text('Labor/Overhead')
1224    # $locale->text('Services')
1225    # $locale->text('Assemblies')
1226    # $locale->text('Components')
1227
1228    $form->{title} = $locale->text( $title{ $form->{searchitems} } );
1229
1230    $form->header;
1231
1232    print qq|
1233<body>
1234
1235<form method=post action=$form->{script}>
1236|;
1237
1238    $form->hide_form(qw(searchitems title));
1239
1240    print qq|
1241
1242<table width="100%">
1243  <tr><th class=listtop>$form->{title}</th></tr>
1244  <tr height="5"></tr>
1245  <tr valign=top>
1246    <td>
1247      <table>
1248        <tr>
1249          <th align=right nowrap>| . $locale->text('Number') . qq|</th>
1250          <td><input name=partnumber size=20></td>
1251        </tr>
1252        <tr>
1253          <th align=right nowrap>| . $locale->text('Description') . qq|</th>
1254          <td colspan=3><input name=description size=40></td>
1255        </tr>
1256	<tr>
1257	  $warehouse
1258	</tr>
1259	<tr>
1260	  $partsgroup
1261	  $serialnumber
1262	</tr>
1263	$makemodel
1264	$drawing
1265	$toplevel
1266        <tr>
1267          <td></td>
1268          <td colspan=3>
1269            <input name=itemstatus class=radio type=radio value=active checked>&nbsp;|
1270      . $locale->text('Active') . qq|
1271	    $onhand
1272            <input name=itemstatus class=radio type=radio value=obsolete>&nbsp;|
1273      . $locale->text('Obsolete') . qq|
1274	    $orphaned
1275	    $bom
1276	  </td>
1277	</tr>
1278        <tr>
1279	  <td></td>
1280          <td colspan=3>
1281	    <hr size=1 noshade>
1282	  </td>
1283	</tr>
1284	<tr>
1285	  <td></td>
1286	  $bought
1287	  $sold
1288	  $fromto
1289        <tr>
1290	  <td></td>
1291          <td colspan=3>
1292	    <hr size=1 noshade>
1293	  </td>
1294	</tr>
1295	<tr>
1296          <th align=right nowrap>|
1297      . $locale->text('Include in Report')
1298      . qq|</th>
1299          <td colspan=3>
1300            <table>
1301              <tr>
1302|;
1303
1304    while (@a) {
1305        for ( 1 .. 5 ) {
1306            print qq|<td nowrap>| . shift @a;
1307            print qq|</td>\n|;
1308        }
1309        print qq|</tr>\n|;
1310    }
1311
1312    print qq|
1313              </tr>
1314	      <tr>
1315                <td><input name=l_subtotal class=checkbox type=checkbox value=Y>&nbsp;|
1316      . $locale->text('Subtotal')
1317      . qq|</td>
1318	      </tr>
1319            </table>
1320          </td>
1321        </tr>
1322      </table>
1323    </td>
1324  </tr>
1325  <tr><td colspan=4><hr size=3 noshade></td></tr>
1326</table>
1327
1328<input type="hidden" name="nextsub" value="generate_report">
1329
1330<br>
1331<button class="submit" type="submit" name="action" value="continue">|
1332      . $locale->text('Continue')
1333      . qq|</button>|;
1334
1335    $form->hide_form(qw(path login sessionid));
1336
1337    print qq|
1338</form>
1339|;
1340
1341    if ( $form->{lynx} ) {
1342        require "bin/menu.pl";
1343        &menubar;
1344    }
1345
1346    print qq|
1347
1348</body>
1349</html>
1350|;
1351
1352}
1353
1354sub generate_report {
1355
1356    # setup $form->{sort}
1357    unless ( $form->{sort} ) {
1358        if ( $form->{description} && !( $form->{partnumber} ) ) {
1359            $form->{sort} = "description";
1360        }
1361        else {
1362            $form->{sort} = "partnumber";
1363        }
1364    }
1365
1366    if ( $form->{itemstatus} eq 'bom' ) {
1367        $form->{l_perassembly} = "Y" if $form->{l_qty} eq "Y";
1368        $form->{individual}    = 1;
1369        $form->{title}         = $locale->text('BOM');
1370    }
1371
1372    $callback = "$form->{script}?action=generate_report";
1373    for (
1374        qw(path login sessionid searchitems itemstatus individual bom l_linetotal method)
1375      )
1376    {
1377        $callback .= qq|&$_=$form->{$_}|;
1378    }
1379    for (qw(warehouse partsgroup title)) {
1380        $callback .= qq|&$_=| . $form->escape( $form->{$_}, 1 );
1381    }
1382
1383    # if we have a serialnumber limit search
1384    if ( $form->{serialnumber} || $form->{l_serialnumber} ) {
1385        $form->{l_serialnumber} = "Y";
1386        unless ( $form->{bought}
1387            || $form->{sold}
1388            || $form->{onorder}
1389            || $form->{ordered} )
1390        {
1391            if ( $form->{searchitems} eq 'assembly' ) {
1392                $form->{sold} = $form->{ordered} = 1;
1393            }
1394            else {
1395                $form->{bought} = $form->{sold} = $form->{onorder} =
1396                  $form->{ordered} = 1;
1397            }
1398        }
1399    }
1400
1401    if ( $form->{itemstatus} eq 'active' ) {
1402        $option .= $locale->text('Active') . " : ";
1403    }
1404    if ( $form->{itemstatus} eq 'obsolete' ) {
1405        $form->{onhand} = $form->{short} = 0;
1406
1407        $form->{l_qty}       = 0;
1408        $form->{warehouse}   = "";
1409        $form->{l_warehouse} = 0;
1410
1411        $option .= $locale->text('Obsolete') . " : ";
1412    }
1413    if ( $form->{itemstatus} eq 'orphaned' ) {
1414        $form->{onhand}  = $form->{short}   = 0;
1415        $form->{bought}  = $form->{sold}    = 0;
1416        $form->{onorder} = $form->{ordered} = 0;
1417        $form->{rfq}     = $form->{quoted}  = 0;
1418
1419        $form->{l_qty}       = 0;
1420        $form->{warehouse}   = "";
1421        $form->{l_warehouse} = 0;
1422
1423        $form->{transdatefrom} = $form->{transdateto} = "";
1424
1425        $option .= $locale->text('Orphaned') . " : ";
1426    }
1427    if ( $form->{itemstatus} eq 'onhand' ) {
1428        $option .= $locale->text('On Hand') . " : ";
1429        $form->{l_onhand} = "Y";
1430    }
1431    if ( $form->{itemstatus} eq 'short' ) {
1432        $option .= $locale->text('Short') . " : ";
1433        $form->{l_onhand} = "Y";
1434        $form->{l_rop} = "Y" unless $form->{searchitems} eq 'labor';
1435
1436        $form->{warehouse}   = "";
1437        $form->{l_warehouse} = 0;
1438    }
1439
1440    if ( $form->{l_account} ) {
1441        for (qw(l_name l_curr l_employee)) { delete $form->{$_} }
1442    }
1443    else {
1444        $ok = 0;
1445        foreach $l (qw(l_name l_curr l_employee)) {
1446            if ( $form->{$l} ) {
1447                foreach $v (qw(onorder ordered rfq quoted bought sold)) {
1448                    if ( $form->{$v} ) {
1449                        $ok = 1;
1450                        last;
1451                    }
1452                }
1453                if ( !$ok ) {
1454                    for (qw(onorder ordered rfq quoted bought sold)) {
1455                        $form->{$_} = 1;
1456                    }
1457                }
1458                last;
1459            }
1460        }
1461    }
1462
1463    if ( $form->{onorder} ) {
1464        $form->{l_ordnumber} = "Y";
1465        $callback .= "&onorder=$form->{onorder}";
1466        $option   .= $locale->text('Purchase Order') . " : ";
1467    }
1468    if ( $form->{ordered} ) {
1469        $form->{l_ordnumber} = "Y";
1470        $callback .= "&ordered=$form->{ordered}";
1471        $option   .= $locale->text('Sales Order') . " : ";
1472    }
1473    if ( $form->{rfq} ) {
1474        $form->{l_quonumber} = "Y";
1475        $callback .= "&rfq=$form->{rfq}";
1476        $option   .= $locale->text('RFQ') . " : ";
1477    }
1478    if ( $form->{quoted} ) {
1479        $form->{l_quonumber} = "Y";
1480        $callback .= "&quoted=$form->{quoted}";
1481        $option   .= $locale->text('Quotation') . " : ";
1482    }
1483    if ( $form->{bought} ) {
1484        $form->{l_invnumber} = "Y";
1485        $callback .= "&bought=$form->{bought}";
1486        $option   .= $locale->text('Vendor Invoice') . " : ";
1487    }
1488    if ( $form->{sold} ) {
1489        $form->{l_invnumber} = "Y";
1490        $callback .= "&sold=$form->{sold}";
1491        $option   .= $locale->text('Sales Invoice') . " : ";
1492    }
1493    if ( $form->{sold} || $form->{bought} ) {
1494        $label = ucfirst $form->{method};
1495        $option .= $locale->text($label) . " : ";
1496    }
1497
1498    if (   $form->{bought}
1499        || $form->{sold}
1500        || $form->{onorder}
1501        || $form->{ordered}
1502        || $form->{rfq}
1503        || $form->{quoted} )
1504    {
1505
1506        # warehouse stuff is meaningless
1507        $form->{warehouse}   = "";
1508        $form->{l_warehouse} = 0;
1509
1510        $form->{l_account} = "";
1511
1512        if ( $form->{open} ) {
1513            $callback .= "&open=$form->{open}";
1514            $option   .= $locale->text('Open');
1515        }
1516        if ( $form->{closed} ) {
1517            $callback .= "&closed=$form->{closed}";
1518            if ( $form->{open} ) {
1519                $option .= " : " . $locale->text('Closed');
1520            }
1521            else {
1522                $option .= $locale->text('Closed');
1523            }
1524        }
1525        if ( $form->{summary} ) {
1526            $callback .= "&summary=$form->{summary}";
1527            $option   .= " : " . $locale->text('Summary');
1528            $form->{l_ordnumber} = "";
1529            $form->{l_quonumber} = "";
1530            $form->{l_invnumber} = "";
1531        }
1532        else {
1533            $option .= " : " . $locale->text('Detail');
1534        }
1535
1536        if ( $form->{transdatefrom} ) {
1537            $callback .= "&transdatefrom=$form->{transdatefrom}";
1538            $option   .= "\n<br>"
1539              . $locale->text('From')
1540              . "&nbsp;"
1541              . $locale->date( \%myconfig, $form->{transdatefrom}, 1 );
1542        }
1543        if ( $form->{transdateto} ) {
1544            $callback .= "&transdateto=$form->{transdateto}";
1545            $option   .= "\n<br>"
1546              . $locale->text('To')
1547              . "&nbsp;"
1548              . $locale->date( \%myconfig, $form->{transdateto}, 1 );
1549        }
1550    }
1551
1552    if ( $form->{warehouse} ) {
1553        ($warehouse) = split /--/, $form->{warehouse};
1554        $option .= "<br>" . $locale->text('Warehouse') . " : $warehouse";
1555        $form->{l_warehouse} = 0;
1556    }
1557
1558    $option .= "<br>";
1559
1560    if ( $form->{partnumber} ) {
1561        $callback .= "&partnumber=" . $form->escape( $form->{partnumber}, 1 );
1562        $option .= $locale->text('Number') . qq| : $form->{partnumber}<br>|;
1563    }
1564    if ( $form->{partsgroup} ) {
1565        ($partsgroup) = split /--/, $form->{partsgroup};
1566        $option .= $locale->text('Group') . qq| : $partsgroup<br>|;
1567    }
1568    if ( $form->{serialnumber} ) {
1569        $callback .=
1570          "&serialnumber=" . $form->escape( $form->{serialnumber}, 1 );
1571        $option .=
1572          $locale->text('Serial Number') . qq| : $form->{serialnumber}<br>|;
1573    }
1574    if ( $form->{description} ) {
1575        $callback .= "&description=" . $form->escape( $form->{description}, 1 );
1576        $description = $form->{description};
1577        $description =~ s/\r?\n/<br>/g;
1578        $option .=
1579          $locale->text('Description') . qq| : $form->{description}<br>|;
1580    }
1581    if ( $form->{make} ) {
1582        $callback .= "&make=" . $form->escape( $form->{make}, 1 );
1583        $option .= $locale->text('Make') . qq| : $form->{make}<br>|;
1584    }
1585    if ( $form->{model} ) {
1586        $callback .= "&model=" . $form->escape( $form->{model}, 1 );
1587        $option .= $locale->text('Model') . qq| : $form->{model}<br>|;
1588    }
1589    if ( $form->{drawing} ) {
1590        $callback .= "&drawing=" . $form->escape( $form->{drawing}, 1 );
1591        $option .= $locale->text('Drawing') . qq| : $form->{drawing}<br>|;
1592    }
1593    if ( $form->{microfiche} ) {
1594        $callback .= "&microfiche=" . $form->escape( $form->{microfiche}, 1 );
1595        $option .= $locale->text('Microfiche') . qq| : $form->{microfiche}<br>|;
1596    }
1597
1598    if ( $form->{l_markup} ) {
1599        $form->{l_sellprice}      = "Y";
1600        $form->{l_lastcostmarkup} = "Y" if $form->{l_lastcost};
1601        $form->{l_avgcostmarkup}  = "Y" if $form->{l_avgcost};
1602    }
1603
1604    @columns =
1605      $form->sort_columns(
1606        qw(partnumber description notes assemblypartnumber partsgroup make model bin onhand perassembly rop unit listprice linetotallistprice sellprice linetotalsellprice lastcost linetotallastcost lastcostmarkup avgcost linetotalavgcost avgcostmarkup curr priceupdate weight image drawing microfiche invnumber ordnumber quonumber name employee serialnumber warehouse)
1607      );
1608    unshift @columns, "runningnumber";
1609
1610    if ( $form->{l_linetotal} ) {
1611        $form->{l_onhand}             = "Y";
1612        $form->{l_linetotalsellprice} = "Y" if $form->{l_sellprice};
1613        $form->{l_linetotallastcost}  = "Y" if $form->{l_lastcost};
1614        $form->{l_linetotalavgcost}   = "Y" if $form->{l_avgcost};
1615        $form->{l_linetotallistprice} = "Y" if $form->{l_listprice};
1616    }
1617
1618    if ( $form->{searchitems} eq 'service' ) {
1619
1620        # remove bin, weight and rop from list
1621        for (qw(bin weight rop)) { $form->{"l_$_"} = "" }
1622
1623        $form->{l_onhand} = "";
1624
1625        # qty is irrelevant unless bought or sold
1626        if (   $form->{bought}
1627            || $form->{sold}
1628            || $form->{onorder}
1629            || $form->{ordered}
1630            || $form->{rfq}
1631            || $form->{quoted} )
1632        {
1633            $form->{l_onhand} = "Y";
1634        }
1635        else {
1636            for (qw(sellprice lastcost avgcost listprice)) {
1637                $form->{"l_linetotal$_"} = "";
1638            }
1639        }
1640    }
1641    else {
1642        $form->{l_onhand} = "Y" if $form->{l_qty};
1643    }
1644
1645    foreach $item (@columns) {
1646        if ( $form->{"l_$item"} eq "Y" ) {
1647            push @column_index, $item;
1648
1649            # add column to callback
1650            $callback .= "&l_$item=Y";
1651        }
1652    }
1653
1654    if ( $form->{l_account} eq 'Y' ) {
1655        if ( $form->{searchitems} eq 'all' || $form->{searchitems} eq 'part' ) {
1656            push @column_index, (qw(inventory income expense tax));
1657        }
1658        elsif ( $form->{searchitems} eq 'service' ) {
1659            push @column_index, (qw(income expense tax));
1660        }
1661        elsif ( $form->{searchitems} eq 'assembly' ) {
1662            push @column_index, (qw(income tax));
1663        }
1664        else {
1665            push @column_index, (qw(inventory expense));
1666        }
1667
1668        $callback .= "&l_account=Y";
1669    }
1670
1671    if ( $form->{l_subtotal} eq 'Y' ) {
1672        $callback .= "&l_subtotal=Y";
1673    }
1674
1675    IC->all_parts( \%myconfig, \%$form );
1676
1677    $callback .= "&direction=$form->{direction}&oldsort=$form->{oldsort}";
1678
1679    $href = $callback;
1680
1681    $form->sort_order();
1682
1683    $callback =~ s/(direction=).*?\&/$1$form->{direction}\&/;
1684
1685    if ( $form->{searchitems} eq 'assembly' ) {
1686        if ( $form->{l_partnumber} ) {
1687
1688            # replace partnumber with partnumber_
1689            $ndx = 0;
1690            foreach $item (@column_index) {
1691                $ndx++;
1692                last if $item eq 'partnumber';
1693            }
1694
1695            splice @column_index, $ndx, 0,
1696              map { "partnumber_$_" } ( 1 .. $form->{pncol} );
1697            $colspan = $form->{pncol} + 1;
1698        }
1699    }
1700
1701    if ( $form->{searchitems} eq 'component' ) {
1702        if ( $form->{l_partnumber} ) {
1703
1704            # splice it in after the partnumber
1705            $ndx = 0;
1706            foreach $item (@column_index) {
1707                $ndx++;
1708                last if $item eq 'partnumber';
1709            }
1710
1711            @a = splice @column_index, 0, $ndx;
1712            unshift @column_index, "assemblypartnumber";
1713            unshift @column_index, @a;
1714        }
1715    }
1716
1717    $column_header{runningnumber} = qq|<th a class=listheading>&nbsp;</th>|;
1718    $column_header{partnumber} =
1719qq|<th nowrap colspan=$colspan><a class=listheading href=$href&sort=partnumber>|
1720      . $locale->text('Number')
1721      . qq|</a></th>|;
1722    $column_header{description} =
1723        qq|<th nowrap><a class=listheading href=$href&sort=description>|
1724      . $locale->text('Description')
1725      . qq|</a></th>|;
1726    $column_header{notes} =
1727      qq|<th nowrap class=listheading>| . $locale->text('Notes') . qq|</th>|;
1728    $column_header{partsgroup} =
1729        qq|<th nowrap><a class=listheading href=$href&sort=partsgroup>|
1730      . $locale->text('Group')
1731      . qq|</a></th>|;
1732    $column_header{bin} =
1733        qq|<th><a class=listheading href=$href&sort=bin>|
1734      . $locale->text('Bin')
1735      . qq|</a></th>|;
1736    $column_header{priceupdate} =
1737        qq|<th nowrap><a class=listheading href=$href&sort=priceupdate>|
1738      . $locale->text('Updated')
1739      . qq|</a></th>|;
1740    $column_header{onhand} =
1741      qq|<th class=listheading nowrap>| . $locale->text('Qty') . qq|</th>|;
1742    $column_header{perassembly} = qq|<th>&nbsp;</th>|;
1743    $column_header{unit} =
1744      qq|<th class=listheading nowrap>| . $locale->text('Unit') . qq|</th>|;
1745    $column_header{listprice} =
1746        qq|<th class=listheading nowrap>|
1747      . $locale->text('List Price')
1748      . qq|</th>|;
1749    $column_header{lastcost} =
1750        qq|<th class=listheading nowrap>|
1751      . $locale->text('Last Cost')
1752      . qq|</th>|;
1753    $column_header{avgcost} =
1754      qq|<th class=listheading nowrap>| . $locale->text('Avg Cost') . qq|</th>|;
1755    $column_header{rop} =
1756      qq|<th class=listheading nowrap>| . $locale->text('ROP') . qq|</th>|;
1757    $column_header{weight} =
1758      qq|<th class=listheading nowrap>| . $locale->text('Weight') . qq|</th>|;
1759    $column_header{avgcostmarkup}  = qq|<th class=listheading nowrap>%</th>|;
1760    $column_header{lastcostmarkup} = qq|<th class=listheading nowrap>%</th>|;
1761
1762    $column_header{make} =
1763        qq|<th nowrap><a class=listheading href=$href&sort=make>|
1764      . $locale->text('Make')
1765      . qq|</a></th>|;
1766    $column_header{model} =
1767        qq|<th nowrap><a class=listheading href=$href&sort=model>|
1768      . $locale->text('Model')
1769      . qq|</a></th>|;
1770
1771    $column_header{invnumber} =
1772        qq|<th nowrap><a class=listheading href=$href&sort=invnumber>|
1773      . $locale->text('Invoice Number')
1774      . qq|</a></th>|;
1775    $column_header{ordnumber} =
1776        qq|<th nowrap><a class=listheading href=$href&sort=ordnumber>|
1777      . $locale->text('Order Number')
1778      . qq|</a></th>|;
1779    $column_header{quonumber} =
1780        qq|<th nowrap><a class=listheading href=$href&sort=quonumber>|
1781      . $locale->text('Quotation')
1782      . qq|</a></th>|;
1783
1784    $column_header{name} =
1785        qq|<th nowrap><a class=listheading href=$href&sort=name>|
1786      . $locale->text('Name')
1787      . qq|</a></th>|;
1788
1789    $column_header{employee} =
1790        qq|<th nowrap><a class=listheading href=$href&sort=employee>|
1791      . $locale->text('Employee')
1792      . qq|</a></th>|;
1793
1794    $column_header{sellprice} =
1795        qq|<th class=listheading nowrap>|
1796      . $locale->text('Sell Price')
1797      . qq|</th>|;
1798
1799    for (qw(sellprice lastcost avgcost listprice)) {
1800        $column_header{"linetotal$_"} =
1801            qq|<th class=listheading nowrap>|
1802          . $locale->text('Extended')
1803          . qq|</th>|;
1804    }
1805
1806    $column_header{curr} =
1807        qq|<th nowrap><a class=listheading href=$href&sort=curr>|
1808      . $locale->text('Curr')
1809      . qq|</a></th>|;
1810
1811    $column_header{image} =
1812        qq|<th class=listheading nowrap>|
1813      . $locale->text('Image')
1814      . qq|</a></th>|;
1815    $column_header{drawing} =
1816        qq|<th nowrap><a class=listheading href=$href&sort=drawing>|
1817      . $locale->text('Drawing')
1818      . qq|</a></th>|;
1819    $column_header{microfiche} =
1820        qq|<th nowrap><a class=listheading href=$href&sort=microfiche>|
1821      . $locale->text('Microfiche')
1822      . qq|</a></th>|;
1823
1824    $column_header{serialnumber} =
1825        qq|<th nowrap><a class=listheading href=$href&sort=serialnumber>|
1826      . $locale->text('Serial Number')
1827      . qq|</a></th>|;
1828
1829    $column_header{assemblypartnumber} =
1830        qq|<th nowrap><a class=listheading href=$href&sort=assemblypartnumber>|
1831      . $locale->text('Assembly')
1832      . qq|</a></th>|;
1833
1834    $column_header{warehouse} =
1835        qq|<th nowrap class=listheading>|
1836      . $locale->text('Warehouse')
1837      . qq|</th>|;
1838
1839    $column_header{inventory} =
1840        qq|<th nowrap class=listheading>|
1841      . $locale->text('Inventory')
1842      . qq|</th>|;
1843    $column_header{income} =
1844      qq|<th nowrap class=listheading>| . $locale->text('Income') . qq|</th>|;
1845    $column_header{expense} =
1846      qq|<th nowrap class=listheading>| . $locale->text('Expense') . qq|</th>|;
1847    $column_header{tax} =
1848      qq|<th nowrap class=listheading>| . $locale->text('Tax') . qq|</th>|;
1849
1850    $form->header;
1851
1852    $i = 1;
1853    if ( $form->{searchitems} eq 'part' ) {
1854        $button{'Goods & Services--Add Part'}{code} =
1855qq|<button class="submit" type="submit" name="action" value="add_part">|
1856          . $locale->text('Add Part')
1857          . qq|</button> |;
1858        $button{'Goods & Services--Add Part'}{order} = $i++;
1859    }
1860    if ( $form->{searchitems} eq 'service' ) {
1861        $button{'Goods & Services--Add Service'}{code} =
1862qq|<button class="submit" type="submit" name="action" value="add_service">|
1863          . $locale->text('Add Service')
1864          . qq|</button> |;
1865        $button{'Goods & Services--Add Service'}{order} = $i++;
1866    }
1867    if ( $form->{searchitems} eq 'assembly' ) {
1868        $button{'Goods & Services--Add Assembly'}{code} =
1869qq|<button class="submit" type="submit" name="action" value="add_assembly">|
1870          . $locale->text('Add Assembly')
1871          . qq|</button> |;
1872        $button{'Goods & Services--Add Assembly'}{order} = $i++;
1873    }
1874    if ( $form->{searchitems} eq 'labor' ) {
1875        $button{'Goods & Services--Add Labor/Overhead'}{code} =
1876qq|<button class="submit" type="submit" name="action" value="add_labor_overhead">|
1877          . $locale->text('Add Labor/Overhead')
1878          . qq|</button> |;
1879        $button{'Goods & Services--Add Labor/Overhead'}{order} = $i++;
1880    }
1881
1882    foreach $item ( split /;/, $myconfig{acs} ) {
1883        delete $button{$item};
1884    }
1885
1886    print qq|
1887<body>
1888
1889<table width=100%>
1890  <tr>
1891    <th class=listtop>$form->{title}</th>
1892  </tr>
1893  <tr height="5"></tr>
1894
1895  <tr><td>$option</td></tr>
1896
1897  <tr>
1898    <td>
1899      <table width=100%>
1900        <tr class=listheading>
1901|;
1902
1903    for (@column_index) { print "\n$column_header{$_}" }
1904
1905    print qq|
1906        </tr>
1907  |;
1908
1909    # add order to callback
1910    $form->{callback} = $callback .= "&sort=$form->{sort}";
1911
1912    # escape callback for href
1913    $callback = $form->escape($callback);
1914
1915    $k       = $#{ @{ $form->{parts} } };
1916    @groupby = ( $form->{sort} );
1917
1918    if ( $form->{summary} ) {
1919        @groupby = ();
1920        for (
1921            qw(partnumber description notes partsgroup make model bin curr priceupdate image drawing microfiche invnumber ordnumber quonumber name employee serialnumber warehouse)
1922          )
1923        {
1924            $a{$_} = 1;
1925        }
1926
1927        for (@column_index) {
1928            if ( $a{$_} ) {
1929                push @groupby, $_;
1930            }
1931        }
1932        push @groupby, "id";
1933    }
1934
1935    if ( $k > 0 ) {
1936        $samegroup = "";
1937        for (@groupby) { $samegroup .= $form->{parts}->[0]->{$_} }
1938    }
1939
1940    $i = 0;
1941    $n = 0;
1942
1943    foreach $ref ( @{ $form->{parts} } ) {
1944
1945        $ref->{exchangerate} ||= 1;
1946        $ref->{discount} *= 1;
1947
1948        if ( $form->{summary} ) {
1949
1950            $summary{ $ref->{id} }{total} += $ref->{sellprice} * $ref->{onhand};
1951            $summary{ $ref->{id} }{onhand} += $ref->{onhand};
1952
1953            if ( $n < $k ) {
1954                $nextgroup = "";
1955                for (@groupby) {
1956                    $nextgroup .= $form->{parts}->[ $n + 1 ]->{$_};
1957                }
1958                $n++;
1959
1960                $form->{parts}->[$n]->{exchangerate} ||= 1;
1961
1962                if ( $samegroup eq $nextgroup ) {
1963                    for (qw(exchangerate discount)) {
1964                        $form->{parts}->[$n]->{$_} =
1965                          ( $ref->{$_} + $form->{parts}->[$n]->{$_} ) / 2;
1966                    }
1967                    next;
1968                }
1969                $samegroup = $nextgroup;
1970            }
1971
1972            $ref->{onhand} = $summary{ $ref->{id} }{onhand};
1973            $ref->{sellprice} =
1974              ( $ref->{onhand} )
1975              ? $summary{ $ref->{id} }{total} / $ref->{onhand}
1976              : 0;
1977
1978            $summary{ $ref->{id} }{total}  = 0;
1979            $summary{ $ref->{id} }{onhand} = 0;
1980
1981        }
1982
1983        if ( $form->{l_subtotal} eq 'Y' && !$ref->{assemblyitem} ) {
1984            if ( $sameitem ne $ref->{ $form->{sort} } ) {
1985                &parts_subtotal;
1986                $sameitem = $ref->{ $form->{sort} };
1987            }
1988        }
1989
1990        $i++;
1991
1992        if ( $form->{l_curr} ) {
1993            if ( $ref->{module} eq 'oe' ) {
1994                $ref->{sellprice} =
1995                  $ref->{sellprice} * ( 1 - $ref->{discount} );
1996            }
1997            else {
1998                for (qw(sellprice listprice lastcost avgcost)) {
1999                    $ref->{$_} /= $ref->{exchangerate};
2000                }
2001            }
2002        }
2003        else {
2004            if ( $ref->{module} eq 'oe' ) {
2005                $ref->{sellprice} =
2006                  $ref->{sellprice} * ( 1 - $ref->{discount} );
2007                for (qw(sellprice listprice lastcost avgcost)) {
2008                    $ref->{$_} *= $ref->{exchangerate};
2009                }
2010            }
2011        }
2012
2013        if ( !$form->{summary} ) {
2014            for (qw(sellprice listprice lastcost avgcost)) {
2015                $ref->{$_} = $form->round_amount( $ref->{$_}, 2 );
2016            }
2017        }
2018
2019        if ( $form->{l_markup} ) {
2020            $ref->{lastcostmarkup} =
2021              ( ( $ref->{sellprice} / $ref->{lastcost} ) - 1 ) * 100
2022              if $ref->{lastcost} != 0;
2023            $ref->{avgcostmarkup} =
2024              ( ( $ref->{sellprice} / $ref->{avgcost} ) - 1 ) * 100
2025              if $ref->{avgcost} != 0;
2026        }
2027
2028        # use this for assemblies
2029        $onhand = $ref->{onhand};
2030
2031        for (qw(description notes)) { $ref->{$_} =~ s/\r?\n/<br>/g }
2032
2033        for ( 1 .. $form->{pncol} ) {
2034            $column_data{"partnumber_$_"} = "<td>&nbsp;</td>";
2035        }
2036
2037        $column_data{runningnumber} = "<td align=right>$i</td>";
2038        $column_data{partnumber} =
2039"<td><a href=$form->{script}?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{partnumber}&nbsp;</a></td>";
2040
2041        if ( $ref->{assemblypartnumber} ) {
2042            if ( $sameid eq $ref->{id} ) {
2043                $i--;
2044                for (qw(runningnumber partnumber)) {
2045                    $column_data{$_} = "<td>&nbsp;</td>";
2046                }
2047            }
2048        }
2049
2050        $column_data{assemblypartnumber} =
2051"<td><a href=$form->{script}?action=edit&id=$ref->{assembly_id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{assemblypartnumber}&nbsp;</a></td>";
2052
2053        if ( $ref->{assemblyitem} ) {
2054            $onhand = 0 if $form->{sold};
2055            $ref->{income} = "";
2056
2057            for (qw(runningnumber partnumber)) {
2058                $column_data{$_} = "<td>&nbsp;</td>";
2059            }
2060            $i--;
2061
2062            $column_data{"partnumber_$ref->{stagger}"} =
2063"<td><a href=$form->{script}?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{partnumber}&nbsp;</a></td>";
2064
2065        }
2066
2067        for (qw(description notes partsgroup employee curr)) {
2068            $column_data{$_} = "<td>$ref->{$_}&nbsp;</td>";
2069        }
2070
2071        $column_data{onhand} =
2072            "<td align=right>"
2073          . $form->format_amount( \%myconfig, $ref->{onhand}, '', "&nbsp;" )
2074          . "</td>";
2075        $column_data{perassembly} =
2076          "<td align=right>"
2077          . $form->format_amount( \%myconfig, $ref->{perassembly}, '',
2078            "&nbsp;" )
2079          . "</td>";
2080
2081        if ( $form->{summary} ) {
2082            $column_data{sellprice} =
2083              "<td align=right>"
2084              . $form->format_amount( \%myconfig, $ref->{sellprice}, 4,
2085                "&nbsp;" )
2086              . "</td>";
2087        }
2088        else {
2089            $column_data{sellprice} =
2090              "<td align=right>"
2091              . $form->format_amount( \%myconfig, $ref->{sellprice}, 2,
2092                "&nbsp;" )
2093              . "</td>";
2094        }
2095        for (qw(listprice lastcost avgcost)) {
2096            $column_data{$_} =
2097                "<td align=right>"
2098              . $form->format_amount( \%myconfig, $ref->{$_}, 2, "&nbsp;" )
2099              . "</td>";
2100        }
2101
2102        for (qw(lastcost avgcost)) {
2103            $column_data{"${_}markup"} = "<td align=right>"
2104              . $form->format_amount( \%myconfig, $ref->{"${_}markup"}, 1,
2105                "&nbsp;" )
2106              . "</td>";
2107        }
2108
2109        if ( $form->{l_linetotal} ) {
2110            for (qw(sellprice lastcost avgcost listprice)) {
2111                $column_data{"linetotal$_"} = "<td align=right>"
2112                  . $form->format_amount( \%myconfig,
2113                    $ref->{onhand} * $ref->{$_},
2114                    2, "&nbsp;" )
2115                  . "</td>";
2116            }
2117        }
2118
2119        if ( $ref->{assemblyitem} && $ref->{stagger} > 1 ) {
2120            for (qw(sellprice lastcost avgcost listprice)) {
2121                $column_data{"linetotal$_"} = "<td>&nbsp;</td>";
2122            }
2123        }
2124
2125        if ( !$ref->{assemblyitem} ) {
2126            $totalsellprice += $onhand * $ref->{sellprice};
2127            $totallastcost  += $onhand * $ref->{lastcost};
2128            $totalavgcost   += $onhand * $ref->{avgcost};
2129            $totallistprice += $onhand * $ref->{listprice};
2130
2131            $subtotalonhand    += $onhand;
2132            $subtotalsellprice += $onhand * $ref->{sellprice};
2133            $subtotallastcost  += $onhand * $ref->{lastcost};
2134            $subtotalavgcost   += $onhand * $ref->{avgcost};
2135            $subtotallistprice += $onhand * $ref->{listprice};
2136        }
2137
2138        $column_data{rop} =
2139            "<td align=right>"
2140          . $form->format_amount( \%myconfig, $ref->{rop}, '', "&nbsp;" )
2141          . "</td>";
2142        $column_data{weight} =
2143            "<td align=right>"
2144          . $form->format_amount( \%myconfig, $ref->{weight}, '', "&nbsp;" )
2145          . "</td>";
2146        $column_data{unit}        = "<td>$ref->{unit}&nbsp;</td>";
2147        $column_data{bin}         = "<td>$ref->{bin}&nbsp;</td>";
2148        $column_data{priceupdate} = "<td>$ref->{priceupdate}&nbsp;</td>";
2149
2150        $ref->{module} = 'ps' if $ref->{till};
2151        $column_data{invnumber} =
2152          ( $ref->{module} ne 'oe' )
2153          ? "<td><a href=$ref->{module}.pl?action=edit&type=invoice&id=$ref->{trans_id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{invnumber}&nbsp;</a></td>"
2154          : "<td>$ref->{invnumber}&nbsp;</td>";
2155        $column_data{ordnumber} =
2156          ( $ref->{module} eq 'oe' )
2157          ? "<td><a href=$ref->{module}.pl?action=edit&type=$ref->{type}&id=$ref->{trans_id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{ordnumber}&nbsp;</a></td>"
2158          : "<td>$ref->{ordnumber}&nbsp;</td>";
2159        $column_data{quonumber} =
2160          ( $ref->{module} eq 'oe' && !$ref->{ordnumber} )
2161          ? "<td><a href=$ref->{module}.pl?action=edit&type=$ref->{type}&id=$ref->{trans_id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{quonumber}&nbsp;</a></td>"
2162          : "<td>$ref->{quonumber}&nbsp;</td>";
2163
2164        $column_data{name} = "<td>$ref->{name}&nbsp;</td>";
2165
2166        $column_data{image} =
2167          ( $ref->{image} )
2168          ? "<td><a href=$ref->{image}><img src=$ref->{image} height=32 border=0></a></td>"
2169          : "<td>&nbsp;</td>";
2170        $column_data{drawing} =
2171          ( $ref->{drawing} )
2172          ? "<td><a href=$ref->{drawing}>$ref->{drawing}</a></td>"
2173          : "<td>&nbsp;</td>";
2174        $column_data{microfiche} =
2175          ( $ref->{microfiche} )
2176          ? "<td><a href=$ref->{microfiche}>$ref->{microfiche}</a></td>"
2177          : "<td>&nbsp;</td>";
2178
2179        for (qw(make model serialnumber warehouse inventory income expense tax))
2180        {
2181            $column_data{$_} = "<td>$ref->{$_}&nbsp;</td>";
2182        }
2183
2184        $j++;
2185        $j %= 2;
2186        print "<tr class=listrow$j>";
2187
2188        for (@column_index) { print "\n$column_data{$_}" }
2189
2190        print qq|
2191    </tr>
2192|;
2193
2194        $sameid = $ref->{id};
2195
2196    }
2197
2198    if ( $form->{l_subtotal} eq 'Y' ) {
2199        &parts_subtotal;
2200    }
2201
2202    if ( $form->{"l_linetotal"} ) {
2203        for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
2204        $column_data{linetotalsellprice} =
2205            "<th class=listtotal align=right>"
2206          . $form->format_amount( \%myconfig, $totalsellprice, 2, "&nbsp;" )
2207          . "</th>";
2208        $column_data{linetotallastcost} =
2209            "<th class=listtotal align=right>"
2210          . $form->format_amount( \%myconfig, $totallastcost, 2, "&nbsp;" )
2211          . "</th>";
2212        $column_data{linetotalavgcost} =
2213            "<th class=listtotal align=right>"
2214          . $form->format_amount( \%myconfig, $totalavgcost, 2, "&nbsp;" )
2215          . "</th>";
2216        $column_data{linetotallistprice} =
2217            "<th class=listtotal align=right>"
2218          . $form->format_amount( \%myconfig, $totallistprice, 2, "&nbsp;" )
2219          . "</th>";
2220
2221        print "<tr class=listtotal>";
2222
2223        for (@column_index) { print "\n$column_data{$_}" }
2224
2225        print qq|</tr>
2226    |;
2227    }
2228
2229    print qq|
2230      </table>
2231    </td>
2232  </tr>
2233  <tr><td><hr size=3 noshade></td></tr>
2234</table>
2235
2236|;
2237
2238    print qq|
2239
2240<br>
2241
2242<form method="post" action="$form->{script}">
2243
2244<input type=hidden name=item value="$form->{searchitems}">
2245|;
2246
2247    $form->hide_form(qw(callback path login sessionid));
2248
2249    foreach $item ( sort { $a->{order} <=> $b->{order} } %button ) {
2250        print $item->{code};
2251    }
2252
2253    if ( $form->{lynx} ) {
2254        require "bin/menu.pl";
2255        &menubar;
2256    }
2257
2258    print qq|
2259  </form>
2260
2261</body>
2262</html>
2263|;
2264
2265}
2266
2267sub parts_subtotal {
2268
2269    for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
2270    $subtotalonhand = 0
2271      if ( $form->{searchitems} eq 'assembly' && $form->{individual} );
2272
2273    $column_data{onhand} =
2274        "<th class=listsubtotal align=right>"
2275      . $form->format_amount( \%myconfig, $subtotalonhand, '', "&nbsp;" )
2276      . "</th>";
2277
2278    $column_data{linetotalsellprice} =
2279        "<th class=listsubtotal align=right>"
2280      . $form->format_amount( \%myconfig, $subtotalsellprice, 2, "&nbsp;" )
2281      . "</th>";
2282    $column_data{linetotallistprice} =
2283        "<th class=listsubtotal align=right>"
2284      . $form->format_amount( \%myconfig, $subtotallistprice, 2, "&nbsp;" )
2285      . "</th>";
2286    $column_data{linetotallastcost} =
2287        "<th class=listsubtotal align=right>"
2288      . $form->format_amount( \%myconfig, $subtotallastcost, 2, "&nbsp;" )
2289      . "</th>";
2290    $column_data{linetotalavgcost} =
2291        "<th class=listsubtotal align=right>"
2292      . $form->format_amount( \%myconfig, $subtotalavgcost, 2, "&nbsp;" )
2293      . "</th>";
2294
2295    $subtotalonhand    = 0;
2296    $subtotalsellprice = 0;
2297    $subtotallistprice = 0;
2298    $subtotallastcost  = 0;
2299    $subtotalavgcost   = 0;
2300
2301    print "<tr class=listsubtotal>";
2302
2303    for (@column_index) { print "\n$column_data{$_}" }
2304
2305    print qq|
2306  </tr>
2307|;
2308
2309}
2310
2311sub requirements {
2312
2313    $form->get_partsgroup( \%myconfig, { searchitems => 'parts' } );
2314    $form->all_years( \%myconfig );
2315
2316    if ( @{ $form->{all_partsgroup} } ) {
2317        $partsgroup = qq|<option>\n|;
2318
2319        for ( @{ $form->{all_partsgroup} } ) {
2320            $partsgroup .=
2321                qq|<option value="|
2322              . $form->quote( $_->{partsgroup} )
2323              . qq|--$_->{id}">$_->{partsgroup}\n|;
2324        }
2325
2326        $partsgroup = qq|
2327        <th align=right nowrap>| . $locale->text('Group') . qq|</th>
2328	<td><select name=partsgroup>$partsgroup</select></td>
2329|;
2330
2331        $l_partsgroup =
2332          qq|<input name=l_partsgroup class=checkbox type=checkbox value=Y> |
2333          . $locale->text('Group');
2334    }
2335
2336    if ( @{ $form->{all_years} } ) {
2337
2338        # accounting years
2339        $form->{selectaccountingyear} = qq|<option>\n|;
2340        for ( @{ $form->{all_years} } ) {
2341            $form->{selectaccountingyear} .= qq|<option>$_\n|;
2342        }
2343
2344        $selectfrom = qq|
2345        <tr>
2346 	  <th align=right>| . $locale->text('Period') . qq|</th>
2347	  <td colspan=3>
2348	    <table>
2349	      <tr>
2350	        <td>
2351		<select name=year>$form->{selectaccountingyear}</select>
2352		</td>
2353		<td>
2354|;
2355
2356        $selectfrom .= qq|
2357		  <table>
2358		    <tr>
2359|;
2360
2361        for ( sort keys %{ $form->{all_month} } ) {
2362            $i = ( $_ * 1 ) - 1;
2363            if ( ( $i % 3 ) == 0 ) {
2364                $selectfrom .= qq|
2365		    </tr>
2366		    <tr>
2367|;
2368            }
2369
2370            $i = $_ * 1;
2371
2372            $selectfrom .= qq|
2373		      <td nowrap><input name="l_month_$i" class checkbox type=checkbox value=Y>&nbsp;|
2374              . $locale->text( $form->{all_month}{$_} )
2375              . qq|</td>\n|;
2376        }
2377
2378        $selectfrom .= qq|
2379		    </tr>
2380		  </table>
2381		</td>
2382	      </tr>
2383	    </table>
2384	  </td>
2385        </tr>
2386|;
2387    }
2388    else {
2389        $form->error( $locale->text('No History!') );
2390    }
2391
2392    $form->{title} = $locale->text('Parts Requirements');
2393
2394    $form->header;
2395
2396    print qq|
2397<body>
2398
2399<form method=post action=$form->{script}>
2400
2401|;
2402
2403    print qq|
2404
2405<table width="100%">
2406
2407  <tr><th class=listtop>$form->{title}</th></tr>
2408  <tr height="5"></tr>
2409  <tr valign=top>
2410    <td>
2411      <table>
2412        <tr>
2413          <th align=right nowrap>| . $locale->text('Number') . qq|</th>
2414          <td><input name=partnumber size=20></td>
2415        </tr>
2416        <tr>
2417          <th align=right nowrap>| . $locale->text('Description') . qq|</th>
2418          <td colspan=3><input name=description size=40></td>
2419        </tr>
2420	<tr>
2421	  $partsgroup
2422	</tr>
2423	$selectfrom
2424      </table>
2425    </td>
2426  </tr>
2427  <tr>
2428    <td><hr size=3 noshade></td>
2429  </tr>
2430</table>
2431
2432<input type="hidden" name="nextsub" value="requirements_report">
2433<input type="hidden" name="sort" value="partnumber">
2434
2435<br>
2436<button class="submit" type="submit" name="action" value="continue">|
2437      . $locale->text('Continue')
2438      . qq|</button>|;
2439
2440    $form->hide_form(qw(path login sessionid));
2441
2442    print qq|
2443</form>
2444|;
2445
2446    if ( $form->{lynx} ) {
2447        require "bin/menu.pl";
2448        &menubar;
2449    }
2450
2451    print qq|
2452
2453</body>
2454</html>
2455|;
2456
2457}
2458
2459sub requirements_report {
2460
2461    $callback = "$form->{script}?action=requirements_report";
2462    for (qw(path login sessionid year)) { $callback .= qq|&$_=$form->{$_}| }
2463    for (qw(partsgroup)) {
2464        $callback .= qq|&$_=| . $form->escape( $form->{$_}, 1 );
2465    }
2466
2467    if ( $form->{partnumber} ) {
2468        $callback .= "&partnumber=" . $form->escape( $form->{partnumber}, 1 );
2469        $option .= $locale->text('Number') . qq| : $form->{partnumber}<br>|;
2470    }
2471    if ( $form->{partsgroup} ) {
2472        ($partsgroup) = split /--/, $form->{partsgroup};
2473        $option .= $locale->text('Group') . qq| : $partsgroup<br>|;
2474    }
2475    if ( $form->{description} ) {
2476        $callback .= "&description=" . $form->escape( $form->{description}, 1 );
2477        $description = $form->{description};
2478        $description =~ s/\r?\n/<br>/g;
2479        $option .=
2480          $locale->text('Description') . qq| : $form->{description}<br>|;
2481    }
2482
2483    @column_index = $form->sort_columns(qw(partnumber description));
2484    unshift @column_index, "runningnumber";
2485
2486    for ( 1 .. 12 ) {
2487        if ( $form->{"l_month_$_"} ) {
2488            $callback .= qq|&l_month_$_=$form->{"l_month_$_"}|;
2489            push @column_index, $_;
2490            $month{$_} = 1;
2491        }
2492    }
2493
2494    push @column_index, "year" unless %month;
2495    push @column_index, qw(onhand so po order);
2496
2497    IC->requirements( \%myconfig, \%$form );
2498
2499    $form->sort_order();
2500
2501    $callback .= "&direction=$form->{direction}&oldsort=$form->{oldsort}";
2502
2503    $href = $callback;
2504
2505    $callback =~ s/(direction=).*?\&/$1$form->{direction}\&/;
2506
2507    if (%month) {
2508        $option .= $locale->text('Year') . qq| : $form->{year}<br>|;
2509    }
2510
2511    $column_header{runningnumber} = qq|<th a class=listheading>&nbsp;</th>|;
2512    $column_header{partnumber} =
2513qq|<th nowrap colspan=$colspan><a class=listheading href=$href&sort=partnumber>|
2514      . $locale->text('Number')
2515      . qq|</a></th>|;
2516    $column_header{description} =
2517        qq|<th nowrap><a class=listheading href=$href&sort=description>|
2518      . $locale->text('Description')
2519      . qq|</a></th>|;
2520    $column_header{onhand} =
2521      qq|<th class=listheading nowrap>| . $locale->text('Onhand') . qq|</th>|;
2522    $column_header{so} =
2523      qq|<th class=listheading nowrap>| . $locale->text('SO') . qq|</th>|;
2524    $column_header{po} =
2525      qq|<th class=listheading nowrap>| . $locale->text('PO') . qq|</th>|;
2526    $column_header{order} =
2527      qq|<th class=listheading nowrap>| . $locale->text('Order') . qq|</th>|;
2528    $column_header{year} = qq|<th class=listheading nowrap>$form->{year}</th>|;
2529
2530    for ( sort { $a <=> $b } keys %month ) {
2531        $column_header{$_} =
2532            qq|<th class=listheading nowrap>|
2533          . $locale->text( $locale->{SHORT_MONTH}[ $_ - 1 ] )
2534          . qq|</th>|;
2535    }
2536
2537    $form->{title} = $locale->text('Parts Requirements');
2538
2539    $form->header;
2540
2541    print qq|
2542<body>
2543
2544<table width=100%>
2545  <tr>
2546    <th class=listtop>$form->{title}</th>
2547  </tr>
2548  <tr height="5"></tr>
2549
2550  <tr><td>$option</td></tr>
2551
2552  <tr>
2553    <td>
2554      <table width=100%>
2555        <tr class=listheading>
2556|;
2557
2558    for (@column_index) { print "\n$column_header{$_}" }
2559
2560    print qq|
2561        </tr>
2562  |;
2563
2564    # add order to callback
2565    $form->{callback} = $callback .= "&sort=$form->{sort}";
2566
2567    # escape callback for href
2568    $callback = $form->escape($callback);
2569
2570    if ( @{ $form->{parts} } ) {
2571        $sameid = $form->{parts}->[0]->{id};
2572    }
2573
2574    for ( keys %month ) { $column_data{$_} = "<td>&nbsp;</td>" }
2575
2576    $i   = 0;
2577    $qty = 0;
2578    foreach $ref ( @{ $form->{parts} } ) {
2579
2580        if ( $ref->{id} != $sameid ) {
2581
2582            $i++;
2583            $column_data{runningnumber} = "<td align=right>$i</td>";
2584
2585            $order = 0 if $order < 0;
2586            $column_data{order} =
2587              "<td align=right>"
2588              . $form->format_amount( \%myconfig, $order, '', "-" ) . "</td>";
2589            $j++;
2590            $j %= 2;
2591            print "<tr class=listrow$j>";
2592
2593            for (@column_index) {
2594                print "\n$column_data{$_}";
2595                $column_data{$_} = "<td>&nbsp;</td>";
2596            }
2597
2598            print qq|
2599    </tr>
2600|;
2601            $qty = 0;
2602        }
2603
2604        $ref->{description} =~ s/\r?\n/<br>/g;
2605
2606        $column_data{partnumber} =
2607"<td><a href=$form->{script}?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{partnumber}&nbsp;</a></td>";
2608
2609        $column_data{description} = "<td>$ref->{description}&nbsp;</td>";
2610
2611        $column_data{onhand} =
2612            "<td align=right>"
2613          . $form->format_amount( \%myconfig, $ref->{onhand}, '', "&nbsp;" )
2614          . "</td>";
2615        $column_data{so} =
2616            "<td align=right>"
2617          . $form->format_amount( \%myconfig, $ref->{so}, '', "&nbsp;" )
2618          . "</td>";
2619        $column_data{po} =
2620            "<td align=right>"
2621          . $form->format_amount( \%myconfig, $ref->{po}, '', "&nbsp;" )
2622          . "</td>";
2623
2624        $column_data{ $ref->{month} } =
2625            "<td align=right>"
2626          . $form->format_amount( \%myconfig, $ref->{qty}, '', "&nbsp;" )
2627          . "</td>";
2628        if (%month) {
2629            $qty += $ref->{qty} if exists $month{ $ref->{month} };
2630        }
2631        else {
2632            $qty += $ref->{qty};
2633        }
2634
2635        $column_data{year} =
2636          "<td align=right>"
2637          . $form->format_amount( \%myconfig, $qty, '', "&nbsp;" ) . "</td>";
2638
2639        $order = $qty + $ref->{so} - $ref->{po} - $ref->{onhand};
2640
2641        $sameid = $ref->{id};
2642
2643    }
2644
2645    if ( @{ $form->{parts} } ) {
2646        $i++;
2647        $column_data{runningnumber} = "<td align=right>$i</td>";
2648
2649        $order = 0 if $order < 0;
2650        $column_data{order} =
2651          "<td align=right>"
2652          . $form->format_amount( \%myconfig, $order, '', "-" ) . "</td>";
2653        $j++;
2654        $j %= 2;
2655        print "<tr class=listrow$j>";
2656
2657        for (@column_index) { print "\n$column_data{$_}" }
2658
2659        print qq|
2660    </tr>
2661|;
2662    }
2663
2664    print qq|
2665      </table>
2666    </td>
2667  </tr>
2668  <tr><td><hr size=3 noshade></td></tr>
2669</table>
2670
2671|;
2672
2673    print qq|
2674
2675<br>
2676
2677<form method=post action=$form->{script}>
2678
2679|;
2680
2681    $form->hide_form(qw(callback path login sessionid));
2682
2683    if ( $form->{lynx} ) {
2684        require "bin/menu.pl";
2685        &menubar;
2686    }
2687
2688    print qq|
2689  </form>
2690
2691</body>
2692</html>
2693|;
2694
2695}
2696
2697sub makemodel_row {
2698    my ($numrows) = @_;
2699
2700    for (qw(make model)) {
2701        $form->{"${_}_$i"} = $form->quote( $form->{"${_}_$i"} );
2702    }
2703
2704    print qq|
2705  <tr>
2706    <td>
2707      <table width=100%>
2708	<tr>
2709	  <th class="listheading">| . $locale->text('Make') . qq|</th>
2710	  <th class="listheading">| . $locale->text('Model') . qq|</th>
2711	</tr>
2712|;
2713
2714    for $i ( 1 .. $numrows ) {
2715        print qq|
2716	<tr>
2717	  <td><input name="make_$i" size=30 value="$form->{"make_$i"}"></td>
2718	  <td><input name="model_$i" size=30 value="$form->{"model_$i"}"></td>
2719	</tr>
2720|;
2721    }
2722
2723    print qq|
2724      </table>
2725    </td>
2726  </tr>
2727|;
2728
2729}
2730
2731sub vendor_row {
2732    my ($numrows) = @_;
2733
2734    $form->{selectvendor} = $form->unescape( $form->{selectvendor} );
2735
2736    $currency = qq|
2737	  <th class="listheading">| . $locale->text('Curr') . qq|</th>|
2738      if $form->{selectcurrency};
2739
2740    print qq|
2741  <input type=hidden name=selectvendor value="|
2742      . $form->escape( $form->{selectvendor}, 1 ) . qq|">
2743
2744  <tr>
2745    <td>
2746      <table width=100%>
2747	<tr>
2748	  <th class="listheading">| . $locale->text('Vendor') . qq|</th>
2749	  <th class="listheading">| . $locale->text('Number') . qq|</th>
2750	  <th class="listheading">| . $locale->text('Cost') . qq|</th>
2751	  $currency
2752	  <th class="listheading">| . $locale->text('Leadtime') . qq|</th>
2753	</tr>
2754|;
2755
2756    for $i ( 1 .. $numrows ) {
2757
2758        if ( $form->{selectcurrency} ) {
2759            $form->{selectcurrency} =~ s/ selected//;
2760            $form->{selectcurrency} =~
2761s/option>$form->{"vendorcurr_$i"}/option selected>$form->{"vendorcurr_$i"}/;
2762            $currency = qq|
2763	  <td><select name="vendorcurr_$i">$form->{selectcurrency}</select></td>|;
2764        }
2765
2766        if ( $i == $numrows ) {
2767
2768            $vendor = qq|
2769          <td><input name="vendor_$i" size=35 value="$form->{"vendor_$i"}"></td>
2770|;
2771
2772            if ( $form->{selectvendor} ) {
2773                $vendor = qq|
2774	  <td width=99%><select name="vendor_$i">$form->{selectvendor}</select></td>
2775|;
2776            }
2777
2778        }
2779        else {
2780
2781            ($vendor) = split /--/, $form->{"vendor_$i"};
2782            $vendor = qq|
2783          <td>$vendor
2784	  <input type=hidden name="vendor_$i" value="$form->{"vendor_$i"}">
2785	  </td>
2786|;
2787        }
2788
2789        $form->{"partnumber_$i"} = $form->quote( $form->{"partnumber_$i"} );
2790        print qq|
2791	<tr>
2792	  $vendor
2793	  <td><input name="partnumber_$i" size=20 value="$form->{"partnumber_$i"}"></td>
2794	  <td><input name="lastcost_$i" size=10 value="|
2795          . $form->format_amount( \%myconfig, $form->{"lastcost_$i"}, 2 )
2796          . qq|"></td>
2797	  $currency
2798	  <td nowrap><input name="leadtime_$i" size=5 value="|
2799          . $form->format_amount( \%myconfig, $form->{"leadtime_$i"} )
2800          . qq|"> <b>|
2801          . $locale->text('days')
2802          . qq|</b></td>
2803	</tr>
2804|;
2805
2806    }
2807
2808    print qq|
2809      </table>
2810    </td>
2811  </tr>
2812|;
2813
2814}
2815
2816sub customer_row {
2817    my ($numrows) = @_;
2818
2819    if ( $form->{selectpricegroup} ) {
2820        $pricegroup = qq|
2821          <th class="listheading">| . $locale->text('Pricegroup') . qq|
2822          </th>
2823|;
2824    }
2825
2826    $form->{selectcustomer}   = $form->unescape( $form->{selectcustomer} );
2827    $form->{selectpricegroup} = $form->unescape( $form->{selectpricegroup} );
2828
2829    $form->hide_form(qw(selectcurrency));
2830
2831    $currency = qq|<th class="listheading">| . $locale->text('Curr') . qq|</th>|
2832      if $form->{selectcurrency};
2833
2834    print qq|
2835  <input type=hidden name=selectcustomer value="|
2836      . $form->escape( $form->{selectcustomer}, 1 ) . qq|">
2837  <input type=hidden name=selectpricegroup value="|
2838      . $form->escape( $form->{selectpricegroup}, 1 ) . qq|">
2839
2840  <tr>
2841    <td>
2842      <table width=100%>
2843	<tr>
2844	  <th class="listheading">| . $locale->text('Customer') . qq|</th>
2845	  $pricegroup
2846	  <th class="listheading">| . $locale->text('Break') . qq|</th>
2847	  <th class="listheading">| . $locale->text('Sell Price') . qq|</th>
2848	  $currency
2849	  <th class="listheading">| . $locale->text('From') . qq|</th>
2850	  <th class="listheading">| . $locale->text('To') . qq|</th>
2851	</tr>
2852|;
2853
2854    for $i ( 1 .. $numrows ) {
2855
2856        if ( $form->{selectcurrency} ) {
2857            $form->{selectcurrency} =~ s/ selected//;
2858            $form->{selectcurrency} =~
2859s/option>$form->{"customercurr_$i"}/option selected>$form->{"customercurr_$i"}/;
2860            $currency = qq|
2861	  <td><select name="customercurr_$i">$form->{selectcurrency}</select></td>|;
2862        }
2863
2864        if ( $i == $numrows ) {
2865            $customer = qq|
2866          <td><input name="customer_$i" size=35 value="$form->{"customer_$i"}"></td>
2867	  |;
2868
2869            if ( $form->{selectcustomer} ) {
2870                $customer = qq|
2871	  <td><select name="customer_$i">$form->{selectcustomer}</select></td>
2872|;
2873            }
2874
2875            if ( $form->{selectpricegroup} ) {
2876                $pricegroup = qq|
2877	  <td><select name="pricegroup_$i">$form->{selectpricegroup}</select></td>
2878|;
2879            }
2880
2881        }
2882        else {
2883            ($customer) = split /--/, $form->{"customer_$i"};
2884            $customer = qq|
2885          <td>$customer</td>
2886	  <input type=hidden name="customer_$i" value="$form->{"customer_$i"}">
2887	  |;
2888
2889            if ( $form->{selectpricegroup} ) {
2890                ($pricegroup) = split /--/, $form->{"pricegroup_$i"};
2891                $pricegroup = qq|
2892	  <td>$pricegroup</td>
2893	  <input type=hidden name="pricegroup_$i" value="$form->{"pricegroup_$i"}">
2894|;
2895            }
2896        }
2897
2898        print qq|
2899	<tr>
2900	  $customer
2901	  $pricegroup
2902
2903	  <td><input name="pricebreak_$i" size=5 value="|
2904          . $form->format_amount( \%myconfig, $form->{"pricebreak_$i"} )
2905          . qq|"></td>
2906	  <td><input name="customerprice_$i" size=10 value="|
2907          . $form->format_amount( \%myconfig, $form->{"customerprice_$i"}, 2 )
2908          . qq|"></td>
2909	  $currency
2910	  <td><input name="validfrom_$i" size=11 title="$myconfig{dateformat}" value="$form->{"validfrom_$i"}"></td>
2911	  <td><input name="validto_$i" size=11 title="$myconfig{dateformat}" value="$form->{"validto_$i"}"></td>
2912	</tr>
2913|;
2914    }
2915
2916    print qq|
2917      </table>
2918    </td>
2919  </tr>
2920|;
2921
2922}
2923
2924sub assembly_row {
2925    my ($numrows) = @_;
2926
2927    @column_index =
2928      qw(runningnumber qty unit bom adj partnumber description sellprice listprice lastcost);
2929
2930    if ( $form->{selectassemblypartsgroup} ) {
2931        $form->{selectassemblypartsgroup} =
2932          $form->unescape( $form->{selectassemblypartsgroup} );
2933        @column_index =
2934          qw(runningnumber qty unit bom adj partnumber description partsgroup sellprice listprice lastcost);
2935    }
2936
2937    delete $form->{previousform};
2938
2939    # change callback
2940    $form->{old_callback} = $form->{callback};
2941    $callback             = $form->{callback};
2942    $form->{callback}     = "$form->{script}?action=display_form";
2943
2944    # delete action
2945    for (qw(action header)) { delete $form->{$_} }
2946
2947    $form->{baseassembly} = 0;
2948    $previousform = "";
2949
2950    # save form variables in a previousform variable
2951    $form->{selectcustomer} = "";    # we seem to have run into a 40kb limit
2952    foreach $key ( sort keys %$form ) {
2953
2954        # escape ampersands
2955        $form->{$key} =~ s/&/%26/g;
2956        $previousform .= qq|$key=$form->{$key}&| if $form->{$key};
2957    }
2958    chop $previousform;
2959    $form->{previousform} = $form->escape( $previousform, 1 );
2960
2961    $form->{sellprice} = 0;
2962    $form->{listprice} = 0;
2963    $form->{lastcost}  = 0;
2964    $form->{weight}    = 0;
2965
2966    $form->{callback} = $callback;
2967
2968    $column_header{runningnumber} =
2969      qq|<th nowrap width=5%>| . $locale->text('Item') . qq|</th>|;
2970    $column_header{qty} =
2971      qq|<th align=left nowrap width=10%>| . $locale->text('Qty') . qq|</th>|;
2972    $column_header{unit} =
2973      qq|<th align=left nowrap width=5%>| . $locale->text('Unit') . qq|</th>|;
2974    $column_header{partnumber} =
2975        qq|<th align=left nowrap width=20%>|
2976      . $locale->text('Number')
2977      . qq|</th>|;
2978    $column_header{description} =
2979      qq|<th nowrap width=50%>| . $locale->text('Description') . qq|</th>|;
2980    $column_header{sellprice} =
2981      qq|<th align=right nowrap>| . $locale->text('Sell') . qq|</th>|;
2982    $column_header{listprice} =
2983      qq|<th align=right nowrap>| . $locale->text('List') . qq|</th>|;
2984    $column_header{lastcost} =
2985      qq|<th align=right nowrap>| . $locale->text('Cost') . qq|</th>|;
2986    $column_header{bom}        = qq|<th>| . $locale->text('BOM') . qq|</th>|;
2987    $column_header{adj}        = qq|<th>| . $locale->text('A') . qq|</th>|;
2988    $column_header{partsgroup} = qq|<th>| . $locale->text('Group') . qq|</th>|;
2989
2990    print qq|
2991  <p>
2992
2993  <table width=100%>
2994  <tr class=listheading>
2995    <th class=listheading>| . $locale->text('Individual Items') . qq|</th>
2996  </tr>
2997  <tr>
2998    <td>
2999      <table width=100%>
3000        <tr>
3001|;
3002
3003    for (@column_index) { print "\n$column_header{$_}" }
3004
3005    print qq|
3006        </tr>
3007|;
3008
3009    $spc = ( $form->{path} =~ /lynx/ ) ? "." : " ";
3010    $numrows-- if $form->{project_id};
3011
3012    for $i ( 1 .. $numrows ) {
3013        for (qw(partnumber description)) {
3014            $form->{"${_}_$i"} = $form->quote( $form->{"${_}_$i"} );
3015        }
3016
3017        $linetotalsellprice =
3018          $form->round_amount( $form->{"sellprice_$i"} * $form->{"qty_$i"}, 2 );
3019        $form->{sellprice} += $linetotalsellprice;
3020
3021        $linetotallistprice =
3022          $form->round_amount( $form->{"listprice_$i"} * $form->{"qty_$i"}, 2 );
3023        $form->{listprice} += $linetotallistprice;
3024
3025        $linetotallastcost =
3026          $form->round_amount( $form->{"lastcost_$i"} * $form->{"qty_$i"}, 2 );
3027        $form->{lastcost} += $linetotallastcost;
3028
3029        $form->{"qty_$i"} =
3030          $form->format_amount( \%myconfig, $form->{"qty_$i"} );
3031
3032        $linetotalsellprice =
3033          $form->format_amount( \%myconfig, $linetotalsellprice, 2 );
3034        $linetotallistprice =
3035          $form->format_amount( \%myconfig, $linetotallistprice, 2 );
3036        $linetotallastcost =
3037          $form->format_amount( \%myconfig, $linetotallastcost, 2 );
3038
3039        if ( $i == $numrows && !$form->{project_id} ) {
3040
3041            for (qw(runningnumber unit bom adj)) {
3042                $column_data{$_} = qq|<td></td>|;
3043            }
3044
3045            $column_data{qty} =
3046qq|<td><input name="qty_$i" size=6 value="$form->{"qty_$i"}" accesskey="$i" title="[Alt-$i]"></td>|;
3047            $column_data{partnumber} =
3048qq|<td><input name="partnumber_$i" size=15 value="$form->{"partnumber_$i"}"></td>|;
3049            $column_data{description} =
3050qq|<td><input name="description_$i" size=30 value="$form->{"description_$i"}"></td>|;
3051            $column_data{partsgroup} =
3052qq|<td><select name="partsgroup_$i">$form->{selectassemblypartsgroup}</select></td>|;
3053
3054        }
3055        else {
3056
3057            $column_data{partnumber} =
3058qq|<td><button class="submit" type="submit" name="action" value="$spc$form->{"partnumber_$i"}">$spc$form->{"partnumber_$i"}</button></td>
3059      <input type=hidden name="partnumber_$i" value="$form->{"partnumber_$i"}">|;
3060
3061            $column_data{runningnumber} =
3062              qq|<td><input name="runningnumber_$i" size=3 value="$i"></td>|;
3063            $column_data{qty} =
3064qq|<td><input name="qty_$i" size=6 value="$form->{"qty_$i"}" accesskey="$i" title="[Alt-$i]"></td>|;
3065
3066            for (qw(bom adj)) {
3067                $form->{"${_}_$i"} = ( $form->{"${_}_$i"} ) ? "checked" : "";
3068            }
3069            $column_data{bom} =
3070qq|<td align=center><input name="bom_$i" type=checkbox class=checkbox value=1 $form->{"bom_$i"}></td>|;
3071            $column_data{adj} =
3072qq|<td align=center><input name="adj_$i" type=checkbox class=checkbox value=1 $form->{"adj_$i"}></td>|;
3073
3074            ($partsgroup) = split /--/, $form->{"partsgroup_$i"};
3075            $column_data{partsgroup} =
3076qq|<td><input type=hidden name="partsgroup_$i" value="$form->{"partsgroup_$i"}">$partsgroup</td>|;
3077
3078            $column_data{unit} =
3079qq|<td><input type=hidden name="unit_$i" value="$form->{"unit_$i"}">$form->{"unit_$i"}</td>|;
3080            $column_data{description} =
3081qq|<td><input type=hidden name="description_$i" value="$form->{"description_$i"}">$form->{"description_$i"}</td>|;
3082
3083        }
3084
3085        $column_data{sellprice} = qq|<td align=right>$linetotalsellprice</td>|;
3086        $column_data{listprice} = qq|<td align=right>$linetotallistprice</td>|;
3087        $column_data{lastcost}  = qq|<td align=right>$linetotallastcost</td>|;
3088
3089        print qq|
3090        <tr>|;
3091
3092        for (@column_index) { print "\n$column_data{$_}" }
3093
3094        print qq|
3095        </tr>
3096|;
3097        $form->hide_form(
3098            "id_$i",     "sellprice_$i", "listprice_$i", "lastcost_$i",
3099            "weight_$i", "assembly_$i"
3100        );
3101
3102    }
3103
3104    for (@column_index) { $column_data{$_} = "<td>&nbsp;</td>" }
3105
3106    $column_data{sellprice} =
3107      "<th align=right>"
3108      . $form->format_amount( \%myconfig, $form->{sellprice}, 2 ) . "</th>";
3109    $column_data{listprice} =
3110      "<th align=right>"
3111      . $form->format_amount( \%myconfig, $form->{listprice}, 2 ) . "</th>";
3112    $column_data{lastcost} =
3113      "<th align=right>"
3114      . $form->format_amount( \%myconfig, $form->{lastcost}, 2 ) . "</th>";
3115
3116    print qq|
3117        <tr>|;
3118
3119    for (@column_index) { print "\n$column_data{$_}" }
3120
3121    print qq|
3122        </tr>
3123      </table>
3124    </td>
3125  </tr>
3126  <tr>
3127    <td><hr size=3 noshade></td>
3128  </tr>
3129  </table>
3130  <input type=hidden name=assembly_rows value=$form->{assembly_rows}>
3131  <input type=hidden name=nextsub value=edit_assemblyitem>
3132  <input type=hidden name=selectassemblypartsgroup value="|
3133      . $form->escape( $form->{selectassemblypartsgroup}, 1 ) . qq|">
3134|;
3135
3136}
3137
3138sub edit_assemblyitem {
3139
3140    $pn = substr( $form->{action}, 1 );
3141
3142    $i = 0;
3143    for ( 1 .. $form->{assembly_rows} - 1 ) {
3144        $i++;
3145        last if $form->{"partnumber_$_"} eq $pn;
3146    }
3147
3148    $form->error( $locale->text('unexpected error!') ) unless $i;
3149
3150    $form->{baseassembly} =
3151      ( $form->{baseassembly} )
3152      ? $form->{baseassembly}
3153      : $form->{"assembly_$i"};
3154
3155    $form->{callback} =
3156qq|$form->{script}?action=edit&id=$form->{"id_$i"}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&rowcount=$i&baseassembly=$form->{baseassembly}&isassemblyitem=1&previousform=$form->{previousform}|;
3157
3158    $form->redirect;
3159
3160}
3161
3162sub update {
3163
3164    if ( $form->{item} eq "assembly" ) {
3165
3166        $i = $form->{assembly_rows};
3167        $i = $form->{assembly_rows} + 1 if $form->{project_id};
3168
3169        # if last row is empty check the form otherwise retrieve item
3170        if (   ( $form->{"partnumber_$i"} eq "" )
3171            && ( $form->{"description_$i"} eq "" )
3172            && ( $form->{"partsgroup_$i"}  eq "" ) )
3173        {
3174
3175            &check_form;
3176
3177        }
3178        else {
3179
3180            IC->assembly_item( \%myconfig, \%$form );
3181
3182            $rows = scalar @{ $form->{item_list} };
3183
3184            if ($rows) {
3185                $form->{"adj_$i"} = 1;
3186
3187                if ( $rows > 1 ) {
3188                    $form->{makemodel_rows}--;
3189                    $form->{customer_rows}--;
3190                    &select_item;
3191                    exit;
3192                }
3193                else {
3194                    $form->{"qty_$i"} = 1;
3195                    $form->{"adj_$i"} = 1;
3196                    for (qw(partnumber description unit)) {
3197                        $form->{item_list}[$i]{$_} =
3198                          $form->quote( $form->{item_list}[$i]{$_} );
3199                    }
3200                    for ( keys %{ $form->{item_list}[0] } ) {
3201                        $form->{"${_}_$i"} = $form->{item_list}[0]{$_};
3202                    }
3203
3204                    if ( $form->{item_list}[0]{partsgroup_id} ) {
3205                        $form->{"partsgroup_$i"} =
3206qq|$form->{item_list}[0]{partsgroup}--$form->{item_list}[0]{partsgroup_id}|;
3207                    }
3208
3209                    $form->{"runningnumber_$i"} = $form->{assembly_rows};
3210                    $form->{assembly_rows}++;
3211
3212                    &check_form;
3213
3214                }
3215
3216            }
3217            else {
3218
3219                $form->{rowcount} = $i;
3220                $form->{assembly_rows}++;
3221
3222                &new_item;
3223
3224            }
3225        }
3226
3227    }
3228    else {
3229
3230        &check_form;
3231
3232    }
3233
3234}
3235
3236sub check_vendor {
3237
3238    @flds  = qw(vendor partnumber lastcost leadtime vendorcurr);
3239    @a     = ();
3240    $count = 0;
3241
3242    for (qw(lastcost leadtime)) {
3243        $form->{"${_}_$form->{vendor_rows}"} =
3244          $form->parse_amount( \%myconfig,
3245            $form->{"${_}_$form->{vendor_rows}"} );
3246    }
3247
3248    for $i ( 1 .. $form->{vendor_rows} - 1 ) {
3249
3250        for (qw(lastcost leadtime)) {
3251            $form->{"${_}_$i"} =
3252              $form->parse_amount( \%myconfig, $form->{"${_}_$i"} );
3253        }
3254
3255        if ( $form->{"lastcost_$i"} || $form->{"partnumber_$i"} ) {
3256
3257            push @a, {};
3258            $j = $#a;
3259            for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} }
3260            $count++;
3261
3262        }
3263    }
3264
3265    $i = $form->{vendor_rows};
3266
3267    if ( !$form->{selectvendor} ) {
3268
3269        if ( $form->{"vendor_$i"} && !$form->{"vendor_id_$i"} ) {
3270            ( $form->{vendor} ) = split /--/, $form->{"vendor_$i"};
3271            if ( ( $j = $form->get_name( \%myconfig, vendor ) ) > 1 ) {
3272                &select_name( vendor, $i );
3273                exit;
3274            }
3275
3276            if ( $j == 1 ) {
3277
3278                # we got one name
3279                $form->{"vendor_$i"} =
3280qq|$form->{name_list}[0]->{name}--$form->{name_list}[0]->{id}|;
3281            }
3282            else {
3283
3284                # name is not on file
3285                $form->error(
3286                    $locale->text(
3287                        '[_1]: Vendor not on file!',
3288                        $form->{"vendor_$i"}
3289                    )
3290                );
3291            }
3292        }
3293    }
3294
3295    if ( $form->{"vendor_$i"} ) {
3296        push @a, {};
3297        $j = $#a;
3298        for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} }
3299        $count++;
3300    }
3301
3302    $form->redo_rows( \@flds, \@a, $count, $form->{vendor_rows} );
3303    $form->{vendor_rows} = $count;
3304
3305}
3306
3307sub check_customer {
3308
3309    @flds =
3310      qw(customer validfrom validto pricebreak customerprice pricegroup customercurr);
3311    @a     = ();
3312    $count = 0;
3313
3314    for (qw(customerprice pricebreak)) {
3315        $form->{"${_}_$form->{customer_rows}"} =
3316          $form->parse_amount( \%myconfig,
3317            $form->{"${_}_$form->{customer_rows}"} );
3318    }
3319
3320    for $i ( 1 .. $form->{customer_rows} - 1 ) {
3321
3322        for (qw(customerprice pricebreak)) {
3323            $form->{"${_}_$i"} =
3324              $form->parse_amount( \%myconfig, $form->{"${_}_$i"} );
3325        }
3326
3327        if ( $form->{"customerprice_$i"} || $form->{"pricebreak_$i"} ) {
3328            if (   $form->{"pricebreak_$i"}
3329                || $form->{"customer_$i"}
3330                || $form->{"pricegroup_$i"} )
3331            {
3332
3333                push @a, {};
3334                $j = $#a;
3335                for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} }
3336                $count++;
3337
3338            }
3339        }
3340    }
3341
3342    $i = $form->{customer_rows};
3343
3344    if ( !$form->{selectcustomer} ) {
3345
3346        if ( $form->{"customer_$i"} && !$form->{"customer_id_$i"} ) {
3347            ( $form->{customer} ) = split /--/, $form->{"customer_$i"};
3348
3349            if ( ( $j = $form->get_name( \%myconfig, customer ) ) > 1 ) {
3350                &select_name( customer, $i );
3351                exit;
3352            }
3353
3354            if ( $j == 1 ) {
3355
3356                # we got one name
3357                $form->{"customer_$i"} =
3358qq|$form->{name_list}[0]->{name}--$form->{name_list}[0]->{id}|;
3359            }
3360            else {
3361
3362                # name is not on file
3363                $form->error(
3364                    $locale->text(
3365                        '[_1]: Customer not on file!',
3366                        $form->{customer}
3367                    )
3368                );
3369            }
3370        }
3371    }
3372
3373    if (   $form->{"customer_$i"}
3374        || $form->{"pricegroup_$i"}
3375        || ( $form->{"customerprice_$i"} || $form->{"pricebreak_$i"} ) )
3376    {
3377        push @a, {};
3378        $j = $#a;
3379        for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} }
3380        $count++;
3381    }
3382
3383    $form->redo_rows( \@flds, \@a, $count, $form->{customer_rows} );
3384    $form->{customer_rows} = $count;
3385
3386}
3387
3388sub select_name {
3389    my ( $table, $vr ) = @_;
3390
3391    @column_index = qw(ndx name address);
3392
3393    $label = ucfirst $table;
3394    $column_data{ndx} = qq|<th>&nbsp;</th>|;
3395    $column_data{name} =
3396      qq|<th class=listheading>| . $locale->text($label) . qq|</th>|;
3397    $column_data{address} =
3398        qq|<th class=listheading colspan=5>|
3399      . $locale->text('Address')
3400      . qq|</th>|;
3401
3402    # list items with radio button on a form
3403    $form->header;
3404
3405    $title = $locale->text('Select from one of the names below');
3406
3407    print qq|
3408<body>
3409
3410<form method=post action="$form->{script}">
3411
3412<input type=hidden name=vr value="$vr">
3413
3414<table width=100%>
3415  <tr>
3416    <th class=listtop>$title</th>
3417  </tr>
3418  <tr space=5></tr>
3419  <tr>
3420    <td>
3421      <table width=100%>
3422	<tr class=listheading>|;
3423
3424    for (@column_index) { print "\n$column_data{$_}" }
3425
3426    print qq|
3427	</tr>
3428|;
3429
3430    @column_index = qw(ndx name address city state zipcode country);
3431
3432    my $i = 0;
3433    foreach $ref ( @{ $form->{name_list} } ) {
3434        $checked = ( $i++ ) ? "" : "checked";
3435
3436        $ref->{name} = $form->quote( $ref->{name} );
3437
3438        $column_data{ndx} =
3439qq|<td><input name=ndx class=radio type=radio value="$i" $checked></td>|;
3440        $column_data{name} =
3441qq|<td><input name="new_name_$i" type=hidden value="$ref->{name}">$ref->{name}</td>|;
3442        $column_data{address} = qq|<td>$ref->{address1} $ref->{address2}|;
3443        for (qw(city state zipcode country)) {
3444            $column_data{$_} = qq|<td>$ref->{$_}&nbsp;</td>|;
3445        }
3446
3447        $j++;
3448        $j %= 2;
3449        print qq|
3450	<tr class=listrow$j>|;
3451
3452        for (@column_index) { print "\n$column_data{$_}" }
3453
3454        print qq|
3455	</tr>
3456
3457<input name="new_id_$i" type=hidden value="$ref->{id}">
3458
3459|;
3460
3461    }
3462
3463    print qq|
3464      </table>
3465    </td>
3466  </tr>
3467  <tr>
3468    <td><hr size=3 noshade></td>
3469  </tr>
3470</table>
3471
3472<input name=lastndx type=hidden value="$i">
3473
3474|;
3475
3476    # delete variables
3477    for (qw(action nextsub name_list)) { delete $form->{$_} }
3478
3479    $form->hide_form;
3480
3481    print qq|
3482<input type=hidden name=nextsub value=name_selected>
3483<input type=hidden name=vc value="$table">
3484<br>
3485<button class="submit" type="submit" name="action" value="continue">|
3486      . $locale->text('Continue')
3487      . qq|</button>
3488</form>
3489
3490</body>
3491</html>
3492|;
3493
3494}
3495
3496sub name_selected {
3497
3498    # replace the variable with the one checked
3499
3500    # index for new item
3501    $i = $form->{ndx};
3502
3503    $form->{"$form->{vc}_$form->{vr}"} =
3504      qq|$form->{"new_name_$i"}--$form->{"new_id_$i"}|;
3505    $form->{"$form->{vc}_id_$form->{vr}"} = $form->{"new_id_$i"};
3506
3507    # delete all the new_ variables
3508    for $i ( 1 .. $form->{lastndx} ) {
3509        for (qw(id name)) { delete $form->{"new_${_}_$i"} }
3510    }
3511
3512    for (qw(ndx lastndx nextsub)) { delete $form->{$_} }
3513
3514    &update;
3515
3516}
3517
3518sub save {
3519
3520    if ( $form->{obsolete} ) {
3521        $form->error(
3522            $locale->text(
3523"Inventory quantity must be zero before you can set this $form->{item} obsolete!"
3524            )
3525        ) if ( $form->{onhand} );
3526    }
3527
3528# expand dynamic strings
3529# $locale->text('Inventory quantity must be zero before you can set this part obsolete!')
3530# $locale->text('Inventory quantity must be zero before you can set this assembly obsolete!')
3531
3532    $olditem = $form->{id};
3533
3534    # save part
3535    $rc = IC->save( \%myconfig, \%$form );
3536
3537    $parts_id = $form->{id};
3538
3539    # load previous variables
3540    if ( $form->{previousform} && !$form->{callback} ) {
3541
3542        # save the new form variables before splitting previousform
3543        for ( keys %$form ) { $newform{$_} = $form->{$_} }
3544
3545        $previousform = $form->unescape( $form->{previousform} );
3546        $baseassembly = $form->{baseassembly};
3547
3548        # don't trample on previous variables
3549        for ( keys %newform ) { delete $form->{$_} if $_ ne 'dbh' }
3550
3551        # now take it apart and restore original values
3552        foreach $item ( split /&/, $previousform ) {
3553            ( $key, $value ) = split /=/, $item, 2;
3554            $value =~ s/%26/&/g;
3555            $form->{$key} = $value if $key ne 'dbh';
3556        }
3557
3558        if ( $form->{item} eq 'assembly' ) {
3559
3560            if ($baseassembly) {
3561
3562                #redo the assembly
3563                $previousform =~ /\&id=(\d+)/;
3564                $form->{id} = $1;
3565
3566                # restore original callback
3567                $form->{callback} = $form->unescape( $form->{old_callback} );
3568
3569                &edit;
3570                exit;
3571            }
3572
3573            # undo number formatting
3574            for (qw(weight listprice sellprice lastcost rop)) {
3575                $form->{$_} = $form->parse_amount( \%myconfig, $form->{$_} );
3576            }
3577
3578            $form->{assembly_rows}-- if $olditem;
3579            $i = $newform{rowcount};
3580            $form->{"qty_$i"} = 1 unless ( $form->{"qty_$i"} );
3581
3582            $form->{listprice} -= $form->{"listprice_$i"} * $form->{"qty_$i"};
3583            $form->{sellprice} -= $form->{"sellprice_$i"} * $form->{"qty_$i"};
3584            $form->{lastcost}  -= $form->{"lastcost_$i"} * $form->{"qty_$i"};
3585            $form->{weight}    -= $form->{"weight_$i"} * $form->{"qty_$i"};
3586
3587            # change/add values for assembly item
3588            for (
3589                qw(partnumber description bin unit weight listprice sellprice lastcost)
3590              )
3591            {
3592                $form->{"${_}_$i"} = $newform{$_};
3593            }
3594
3595            foreach $item (qw(listprice sellprice lastcost)) {
3596                $form->{$item} += $form->{"${item}_$i"} * $form->{"qty_$i"};
3597                $form->{$item} = $form->round_amount( $form->{$item}, 2 );
3598            }
3599
3600            $form->{weight} += $form->{"weight_$i"} * $form->{"qty_$i"};
3601
3602            $form->{"adj_$i"} = 1 if !$olditem;
3603
3604            $form->{customer_rows}--;
3605
3606        }
3607        else {
3608
3609            # set values for last invoice/order item
3610            $i = $form->{rowcount};
3611            $form->{"qty_$i"} = 1 unless ( $form->{"qty_$i"} );
3612
3613            for (
3614                qw(partnumber description bin unit listprice sellprice partsgroup)
3615              )
3616            {
3617                $form->{"${_}_$i"} = $newform{$_};
3618            }
3619            for (qw(inventory income expense)) {
3620                $form->{"${_}_accno_id_$i"} = $newform{"IC_$_"};
3621                $form->{"${_}_accno_id_$i"} =~ s/--.*//;
3622            }
3623            $form->{"sellprice_$i"} = $newform{lastcost}
3624              if ( $form->{vendor_id} );
3625
3626            if ( $form->{exchangerate} != 0 ) {
3627                $form->{"sellprice_$i"} =
3628                  $form->round_amount(
3629                    $form->{"sellprice_$i"} / $form->{exchangerate}, 2 );
3630            }
3631
3632            for ( split / /, $newform{taxaccounts} ) {
3633                $form->{"taxaccounts_$i"} .= "$_ " if ( $newform{"IC_tax_$_"} );
3634            }
3635            chop $form->{"taxaccounts_$i"};
3636
3637            # credit remaining calculation
3638            $amount =
3639              $form->{"sellprice_$i"} * ( 1 - $form->{"discount_$i"} / 100 ) *
3640              $form->{"qty_$i"};
3641            for ( split / /, $form->{"taxaccounts_$i"} ) {
3642                $form->{"${_}_base"} += $amount;
3643            }
3644            if ( !$form->{taxincluded} ) {
3645                my @taxlist = Tax::init_taxes( $form, $form->{"taxaccounts_$i"},
3646                    $form->{taxaccounts} );
3647                $amount += Tax::calculate_taxes( \@taxlist, $form, $amount, 0 );
3648            }
3649
3650            $ml = 1;
3651            if ( $form->{type} =~ /invoice/ ) {
3652                $ml = -1 if $form->{type} =~ /_invoice/;
3653            }
3654            $form->{creditremaining} -= ( $amount * $ml );
3655
3656        }
3657
3658        $form->{"id_$i"} = $parts_id;
3659        delete $form->{action};
3660
3661        # restore original callback
3662        $callback = $form->unescape( $form->{callback} );
3663        $form->{callback} = $form->unescape( $form->{old_callback} );
3664        delete $form->{old_callback};
3665
3666        $form->{makemodel_rows}--;
3667
3668        # put callback together
3669        foreach $key ( keys %$form ) {
3670
3671            # do single escape for Apache 2.0
3672            $value = $form->escape( $form->{$key}, 1 );
3673            $callback .= qq|&$key=$value|;
3674        }
3675        $form->{callback} = $callback;
3676    }
3677
3678    if ($rc) {
3679
3680        # redirect
3681        $form->redirect("Part Saved");
3682    }
3683    else {
3684        $form->error;
3685    }
3686
3687}
3688
3689sub save_as_new {
3690
3691    $form->{id} = 0;
3692    &save;
3693
3694}
3695
3696sub delete {
3697
3698    # redirect
3699    if ( IC->delete( \%myconfig, \%$form ) ) {
3700        $form->redirect( $locale->text('Item deleted!') );
3701    }
3702    else {
3703        $form->error( $locale->text('Cannot delete item!') );
3704    }
3705
3706}
3707
3708sub stock_assembly {
3709
3710    $form->{title} = $locale->text('Stock Assembly');
3711
3712    $form->header;
3713
3714    print qq|
3715<body>
3716
3717<form method=post action=$form->{script}>
3718
3719<table width="100%">
3720  <tr>
3721    <th class=listtop>$form->{title}</th>
3722  </tr>
3723  <tr height="5"></tr>
3724  <tr valign=top>
3725    <td>
3726      <table>
3727        <tr>
3728          <th align="right" nowrap="true">| . $locale->text('Number') . qq|</th>
3729          <td><input name=partnumber size=20></td>
3730          <td>&nbsp;</td>
3731        </tr>
3732        <tr>
3733          <th align="right" nowrap="true">|
3734      . $locale->text('Description')
3735      . qq|</th>
3736          <td><input name=description size=40></td>
3737        </tr>
3738        <tr>
3739          <td></td>
3740	  <td><input name=checkinventory class=checkbox type=checkbox value=1>&nbsp;|
3741      . $locale->text('Check Inventory')
3742      . qq|</td>
3743        </tr>
3744      </table>
3745    </td>
3746  </tr>
3747  <tr><td><hr size=3 noshade></td></tr>
3748</table>
3749
3750<input type=hidden name=sort value=partnumber>
3751|;
3752
3753    $form->hide_form(qw(path login sessionid));
3754
3755    print qq|
3756<input type="hidden" name="nextsub" value="list_assemblies">
3757
3758<br>
3759<button class="submit" type="submit" name="action" value="continue">|
3760      . $locale->text('Continue')
3761      . qq|</button>
3762</form>
3763|;
3764
3765    if ( $form->{lynx} ) {
3766        require "bin/menu.pl";
3767        &menubar;
3768    }
3769
3770    print qq|
3771
3772</body>
3773</html>
3774|;
3775
3776}
3777
3778sub list_assemblies {
3779
3780    IC->retrieve_assemblies( \%myconfig, \%$form );
3781
3782    $callback =
3783"$form->{script}?action=list_assemblies&direction=$form->{direction}&oldsort=$form->{oldsort}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&checkinventory=$form->{checkinventory}";
3784
3785    $form->sort_order();
3786    $href =
3787"$form->{script}?action=list_assemblies&direction=$form->{direction}&oldsort=$form->{oldsort}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&checkinventory=$form->{checkinventory}";
3788
3789    if ( $form->{partnumber} ) {
3790        $callback .= "&partnumber=" . $form->escape( $form->{partnumber}, 1 );
3791        $href .= "&partnumber=" . $form->escape( $form->{partnumber} );
3792        $form->{sort} = "partnumber" unless $form->{sort};
3793    }
3794    if ( $form->{description} ) {
3795        $callback .= "&description=" . $form->escape( $form->{description}, 1 );
3796        $href .= "&description=" . $form->escape( $form->{description} );
3797        $form->{sort} = "description" unless $form->{sort};
3798    }
3799
3800    $column_header{partnumber} =
3801        qq|<th><a class=listheading href=$href&sort=partnumber>|
3802      . $locale->text('Number')
3803      . qq|</th>|;
3804    $column_header{description} =
3805        qq|<th><a class=listheading href=$href&sort=description>|
3806      . $locale->text('Description')
3807      . qq|</th>|;
3808    $column_header{bin} =
3809        qq|<th><a class=listheading href=$href&sort=bin>|
3810      . $locale->text('Bin')
3811      . qq|</th>|;
3812    $column_header{onhand} =
3813      qq|<th class=listheading>| . $locale->text('Qty') . qq|</th>|;
3814    $column_header{rop} =
3815      qq|<th class=listheading>| . $locale->text('ROP') . qq|</th>|;
3816    $column_header{stock} =
3817      qq|<th class=listheading>| . $locale->text('Add') . qq|</th>|;
3818
3819    @column_index =
3820      $form->sort_columns(qw(partnumber description bin onhand rop stock));
3821
3822    $form->{title} = $locale->text('Stock Assembly');
3823
3824    $form->header;
3825
3826    print qq|
3827<body>
3828
3829<form method=post action=$form->{script}>
3830
3831<table width=100%>
3832  <tr>
3833    <th class=listtop>$form->{title}</th>
3834  </tr>
3835  <tr size=5></tr>
3836  <tr>
3837    <td>
3838      <table width=100%>
3839	<tr class=listheading>
3840|;
3841
3842    for (@column_index) { print "\n$column_header{$_}" }
3843
3844    print qq|
3845	</tr>
3846|;
3847
3848    # add sort and escape callback
3849    $form->{callback} = $callback .= "&sort=$form->{sort}";
3850
3851    # escape callback for href
3852    $callback = $form->escape($callback);
3853
3854    $i = 1;
3855    foreach $ref ( @{ $form->{assembly_items} } ) {
3856
3857        for (qw(partnumber description)) {
3858            $ref->{$_} = $form->quote( $ref->{$_} );
3859        }
3860
3861        $column_data{partnumber} =
3862"<td width=20%><a href=$form->{script}?action=edit&id=$ref->{id}&path=$form->{path}&login=$form->{login}&sessionid=$form->{sessionid}&callback=$callback>$ref->{partnumber}&nbsp;</a></td>";
3863
3864        $column_data{description} =
3865          qq|<td width=50%>$ref->{description}&nbsp;</td>|;
3866        $column_data{bin} = qq|<td>$ref->{bin}&nbsp;</td>|;
3867        $column_data{onhand} =
3868            qq|<td align=right>|
3869          . $form->format_amount( \%myconfig, $ref->{onhand}, "", "&nbsp;" )
3870          . qq|</td>|;
3871        $column_data{rop} =
3872            qq|<td align=right>|
3873          . $form->format_amount( \%myconfig, $ref->{rop}, '', "&nbsp;" )
3874          . qq|</td>|;
3875        $column_data{stock} =
3876            qq|<td width=10%><input name="qty_$i" size=10 value="|
3877          . $form->format_amount( \%myconfig, $ref->{stock} )
3878          . qq|"></td>
3879    <input type=hidden name="stock_$i" value="$ref->{stock}">|;
3880
3881        $j++;
3882        $j %= 2;
3883        print
3884qq|<tr class="listrow$j"><input name="id_$i" type=hidden value="$ref->{id}">\n|;
3885
3886        for (@column_index) { print "\n$column_data{$_}" }
3887
3888        print qq|
3889	</tr>
3890|;
3891
3892        $i++;
3893
3894    }
3895
3896    $i--;
3897    print qq|
3898      </td>
3899    </table>
3900  <tr>
3901    <td><hr size=3 noshade>
3902  </tr>
3903</table>
3904|;
3905
3906    $form->hide_form(qw(checkinventory path login sessionid callback));
3907
3908    print qq|
3909<input type="hidden" name="rowcount" value="$i">
3910<input type="hidden" name="nextsub" value="restock_assemblies">
3911
3912<br>
3913<button class="submit" type="submit" name="action" value="continue">|
3914      . $locale->text('Continue')
3915      . qq|</button>
3916
3917</form>
3918
3919</body>
3920</html>
3921|;
3922
3923}
3924
3925sub restock_assemblies {
3926
3927    if ( $form->{checkinventory} ) {
3928        for ( 1 .. $form->{rowcount} ) {
3929            $form->error(
3930                $locale->text('Quantity exceeds available units to stock!') )
3931              if $form->parse_amount( $myconfig, $form->{"qty_$_"} ) >
3932              $form->{"stock_$_"};
3933        }
3934    }
3935
3936    if ( IC->restock_assemblies( \%myconfig, \%$form ) ) {
3937        if ( $form->{callback} =~ /(direction=)(.*?)\&/ ) {
3938            $direction = ( $2 eq 'ASC' ) ? 'DESC' : 'ASC';
3939        }
3940        $form->{callback} =~ s/direction=(.*?)\&/direction=$direction\&/;
3941        $form->redirect( $locale->text('Assemblies restocked!') );
3942    }
3943    else {
3944        $form->error( $locale->text('Cannot stock assemblies!') );
3945    }
3946
3947}
3948
3949sub continue { &{ $form->{nextsub} } }
3950
3951sub add_part           { &add }
3952sub add_service        { &add }
3953sub add_assembly       { &add }
3954sub add_labor_overhead { &add }
3955
3956