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"}> <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"> | 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 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 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 $form->{weight} 604 <input type="hidden" name="weight" value="$form->{weight}"> 605 </td> 606 <th> 607 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"> | 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> | 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> | 1048 . $locale->text('On Hand') . qq| 1049 <input name=itemstatus class=radio type=radio value=short> | 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> | 1064 . $locale->text('Make'); 1065 $l_model = 1066 qq|<input name=l_model class=checkbox type=checkbox value=Y> | 1067 . $locale->text('Model'); 1068 1069 $l_bin = 1070 qq|<input name=l_bin class=checkbox type=checkbox value=Y> | 1071 . $locale->text('Bin'); 1072 1073 $l_rop = 1074 qq|<input name=l_rop class=checkbox type=checkbox value=Y> | 1075 . $locale->text('ROP'); 1076 1077 $l_weight = 1078 qq|<input name=l_weight class=checkbox type=checkbox value=Y> | 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> | 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> | 1111 . $locale->text('Image'); 1112 1113 $l_drawing = 1114 qq|<input name=l_drawing class=checkbox type=checkbox value=Y> | 1115 . $locale->text('Drawing'); 1116 $l_microfiche = 1117qq|<input name=l_microfiche class=checkbox type=checkbox value=Y> | 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> | 1131 . $locale->text('Top Level') . qq| 1132 <input name=individual class=checkbox type=checkbox value=1> | 1133 . $locale->text('Individual Items') . qq| 1134 </td> 1135 </tr> 1136|; 1137 $bom = 1138 qq|<input name=itemstatus type=radio value=bom> | 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> | 1172 . $locale->text('No.'); 1173 push @a, 1174qq|<input name=l_partnumber class=checkbox type=checkbox value=Y checked> | 1175 . $locale->text('Number'); 1176 push @a, 1177qq|<input name=l_description class=checkbox type=checkbox value=Y checked> | 1178 . $locale->text('Description'); 1179 push @a, 1180 qq|<input name=l_qty class=checkbox type=checkbox value=Y checked> | 1181 . $locale->text('Qty'); 1182 push @a, 1183 qq|<input name=l_unit class=checkbox type=checkbox value=Y checked> | 1184 . $locale->text('Unit'); 1185 push @a, 1186 qq|<input name=l_priceupdate class=checkbox type=checkbox value=Y> | 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> | 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> | 1270 . $locale->text('Active') . qq| 1271 $onhand 1272 <input name=itemstatus class=radio type=radio value=obsolete> | 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> | 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 .= ""ed=$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 . " " 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 . " " 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 .= "µfiche=" . $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> </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> </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> </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} </a></td>"; 2040 2041 if ( $ref->{assemblypartnumber} ) { 2042 if ( $sameid eq $ref->{id} ) { 2043 $i--; 2044 for (qw(runningnumber partnumber)) { 2045 $column_data{$_} = "<td> </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} </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> </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} </a></td>"; 2064 2065 } 2066 2067 for (qw(description notes partsgroup employee curr)) { 2068 $column_data{$_} = "<td>$ref->{$_} </td>"; 2069 } 2070 2071 $column_data{onhand} = 2072 "<td align=right>" 2073 . $form->format_amount( \%myconfig, $ref->{onhand}, '', " " ) 2074 . "</td>"; 2075 $column_data{perassembly} = 2076 "<td align=right>" 2077 . $form->format_amount( \%myconfig, $ref->{perassembly}, '', 2078 " " ) 2079 . "</td>"; 2080 2081 if ( $form->{summary} ) { 2082 $column_data{sellprice} = 2083 "<td align=right>" 2084 . $form->format_amount( \%myconfig, $ref->{sellprice}, 4, 2085 " " ) 2086 . "</td>"; 2087 } 2088 else { 2089 $column_data{sellprice} = 2090 "<td align=right>" 2091 . $form->format_amount( \%myconfig, $ref->{sellprice}, 2, 2092 " " ) 2093 . "</td>"; 2094 } 2095 for (qw(listprice lastcost avgcost)) { 2096 $column_data{$_} = 2097 "<td align=right>" 2098 . $form->format_amount( \%myconfig, $ref->{$_}, 2, " " ) 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 " " ) 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, " " ) 2115 . "</td>"; 2116 } 2117 } 2118 2119 if ( $ref->{assemblyitem} && $ref->{stagger} > 1 ) { 2120 for (qw(sellprice lastcost avgcost listprice)) { 2121 $column_data{"linetotal$_"} = "<td> </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}, '', " " ) 2141 . "</td>"; 2142 $column_data{weight} = 2143 "<td align=right>" 2144 . $form->format_amount( \%myconfig, $ref->{weight}, '', " " ) 2145 . "</td>"; 2146 $column_data{unit} = "<td>$ref->{unit} </td>"; 2147 $column_data{bin} = "<td>$ref->{bin} </td>"; 2148 $column_data{priceupdate} = "<td>$ref->{priceupdate} </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} </a></td>" 2154 : "<td>$ref->{invnumber} </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} </a></td>" 2158 : "<td>$ref->{ordnumber} </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} </a></td>" 2162 : "<td>$ref->{quonumber} </td>"; 2163 2164 $column_data{name} = "<td>$ref->{name} </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> </td>"; 2170 $column_data{drawing} = 2171 ( $ref->{drawing} ) 2172 ? "<td><a href=$ref->{drawing}>$ref->{drawing}</a></td>" 2173 : "<td> </td>"; 2174 $column_data{microfiche} = 2175 ( $ref->{microfiche} ) 2176 ? "<td><a href=$ref->{microfiche}>$ref->{microfiche}</a></td>" 2177 : "<td> </td>"; 2178 2179 for (qw(make model serialnumber warehouse inventory income expense tax)) 2180 { 2181 $column_data{$_} = "<td>$ref->{$_} </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> </td>" } 2204 $column_data{linetotalsellprice} = 2205 "<th class=listtotal align=right>" 2206 . $form->format_amount( \%myconfig, $totalsellprice, 2, " " ) 2207 . "</th>"; 2208 $column_data{linetotallastcost} = 2209 "<th class=listtotal align=right>" 2210 . $form->format_amount( \%myconfig, $totallastcost, 2, " " ) 2211 . "</th>"; 2212 $column_data{linetotalavgcost} = 2213 "<th class=listtotal align=right>" 2214 . $form->format_amount( \%myconfig, $totalavgcost, 2, " " ) 2215 . "</th>"; 2216 $column_data{linetotallistprice} = 2217 "<th class=listtotal align=right>" 2218 . $form->format_amount( \%myconfig, $totallistprice, 2, " " ) 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> </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, '', " " ) 2276 . "</th>"; 2277 2278 $column_data{linetotalsellprice} = 2279 "<th class=listsubtotal align=right>" 2280 . $form->format_amount( \%myconfig, $subtotalsellprice, 2, " " ) 2281 . "</th>"; 2282 $column_data{linetotallistprice} = 2283 "<th class=listsubtotal align=right>" 2284 . $form->format_amount( \%myconfig, $subtotallistprice, 2, " " ) 2285 . "</th>"; 2286 $column_data{linetotallastcost} = 2287 "<th class=listsubtotal align=right>" 2288 . $form->format_amount( \%myconfig, $subtotallastcost, 2, " " ) 2289 . "</th>"; 2290 $column_data{linetotalavgcost} = 2291 "<th class=listsubtotal align=right>" 2292 . $form->format_amount( \%myconfig, $subtotalavgcost, 2, " " ) 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> | 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> </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> </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> </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} </a></td>"; 2608 2609 $column_data{description} = "<td>$ref->{description} </td>"; 2610 2611 $column_data{onhand} = 2612 "<td align=right>" 2613 . $form->format_amount( \%myconfig, $ref->{onhand}, '', " " ) 2614 . "</td>"; 2615 $column_data{so} = 2616 "<td align=right>" 2617 . $form->format_amount( \%myconfig, $ref->{so}, '', " " ) 2618 . "</td>"; 2619 $column_data{po} = 2620 "<td align=right>" 2621 . $form->format_amount( \%myconfig, $ref->{po}, '', " " ) 2622 . "</td>"; 2623 2624 $column_data{ $ref->{month} } = 2625 "<td align=right>" 2626 . $form->format_amount( \%myconfig, $ref->{qty}, '', " " ) 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, '', " " ) . "</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> </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> </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->{$_} </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> </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> | 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} </a></td>"; 3863 3864 $column_data{description} = 3865 qq|<td width=50%>$ref->{description} </td>|; 3866 $column_data{bin} = qq|<td>$ref->{bin} </td>|; 3867 $column_data{onhand} = 3868 qq|<td align=right>| 3869 . $form->format_amount( \%myconfig, $ref->{onhand}, "", " " ) 3870 . qq|</td>|; 3871 $column_data{rop} = 3872 qq|<td align=right>| 3873 . $form->format_amount( \%myconfig, $ref->{rop}, '', " " ) 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