Rev 329 | Rev 331 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 329 | Rev 330 | ||
|---|---|---|---|
| Line 1... | Line 1... | ||
| 1 | #!/usr/bin/perl -w
|
1 | #!/usr/bin/perl -w
|
| 2 | use strict; |
2 | use strict; |
| 3 | # $Id: inventory.pl 329 2008-12-29 18:21:45Z jelle $
|
3 | # $Id: inventory.pl 330 2008-12-29 19:49:46Z agaran $
|
| 4 | # Thu, 13 Nov 2008 21:06:23 +0100
|
4 | # Thu, 13 Nov 2008 21:06:23 +0100
|
| 5 | # Maciej 'agaran' Pijanka <agaran@pld-linux.org>
|
5 | # Maciej 'agaran' Pijanka <agaran@pld-linux.org>
|
| 6 | # for OpenARM SBC Project
|
6 | # for OpenARM SBC Project
|
| 7 | # license: gpl v3
|
7 | # license: gpl v3
|
| 8 | 8 | ||
| Line 19... | Line 19... | ||
| 19 | my %Config; |
19 | my %Config; |
| 20 | 20 | ||
| 21 | # ==================================================
|
21 | # ==================================================
|
| 22 | $Config{docdir} = '.'; |
22 | $Config{docdir} = '.'; |
| 23 | $Config{bomdir} = '.'; |
23 | $Config{bomdir} = '.'; |
| 24 | $Config{outdir} = '.'; |
- | |
| 25 | $Config{verbose} = 1; |
24 | $Config{verbose} = 1; |
| 26 | 25 | ||
| 27 | # 0 mean not show, -1 show all, positive value limits depth of shown
|
26 | # 0 mean not show, -1 show all, positive value limits depth of shown
|
| 28 | $Config{dbg_showdirs} = 0; |
27 | $Config{dbg_showdirs} = 0; |
| 29 | 28 | ||
| Line 71... | Line 70... | ||
| 71 | unless (defined($_[1]) && length($_[1]) != 0) { |
70 | unless (defined($_[1]) && length($_[1]) != 0) { |
| 72 | print "Basic help\n\t--showrc|showconf shows current configuration\n". |
71 | print "Basic help\n\t--showrc|showconf shows current configuration\n". |
| 73 | "\t--docdir|-d <dir> tells script where information.txt files should be searched\n". |
72 | "\t--docdir|-d <dir> tells script where information.txt files should be searched\n". |
| 74 | "\t--define <something>=<somethingelseornot> defines some configration value\n". |
73 | "\t--define <something>=<somethingelseornot> defines some configration value\n". |
| 75 | "\t--verbose|-v [level] sets verbosity level\nOrder of options DOES matter\n". |
74 | "\t--verbose|-v [level] sets verbosity level\nOrder of options DOES matter\n". |
| 76 | "\t--bomdir|-b <dir> tells script where boms should be searched\n"; |
75 | "\t--bomdir|-b <dir> tells script where boms should be searched\n". |
| - | 76 | "\t--output|-o <file> tells where script shall save output data\n". |
|
| - | 77 | "\t--force|-f forces script to save data even if file exist already\n"; |
|
| 77 | 78 | ||
| 78 | print "\t\e[0;31mThis Help Is created especially for \e[0;33mJelle\e[0;29m\n". |
79 | print "\t\e[0;31mThis Help Is created especially for \e[0;33mJelle\e[0;29m\n". |
| 79 | "\tThis script search all directories below specified ones to find interesting files\n"; |
80 | "\tThis script search all directories below specified ones to find interesting files\n"; |
| 80 | return; |
81 | return; |
| 81 | }
|
82 | }
|
| Line 121... | Line 122... | ||
| 121 | $value =~ s/^[ ]+//; |
122 | $value =~ s/^[ ]+//; |
| 122 | $value =~ s/[ ]+$//; |
123 | $value =~ s/[ ]+$//; |
| 123 | return $value; |
124 | return $value; |
| 124 | }
|
125 | }
|
| 125 | 126 | ||
| 126 | sub shortstring($$) { |
127 | sub strbreak($$) { |
| 127 | my ($str,$lim) = @_; |
128 | my ($str,$lim) = @_; |
| - | 129 | my @p = split / /,$str; |
|
| - | 130 | $str = ''; |
|
| - | 131 | my $l = 0; |
|
| - | 132 | while (@p) { |
|
| - | 133 | my $e = shift @p; |
|
| 128 | return substr($str,0,$lim-4).'(..)' if (length ($str) > $lim); |
134 | if ($l + length ($e) +1 > $lim) { |
| - | 135 | $str .= "\n".$e; |
|
| - | 136 | $l = length $e; |
|
| - | 137 | } else { |
|
| - | 138 | $str .= " ".$e; |
|
| - | 139 | $l += length($e) + 1; |
|
| - | 140 | }
|
|
| - | 141 | }
|
|
| 129 | return $str; |
142 | return $str; |
| 130 | }
|
143 | }
|
| 131 | 144 | ||
| 132 | # this subroutine is used as callback function
|
145 | # this subroutine is used as callback function
|
| 133 | # executed by file_lookup
|
146 | # executed by file_lookup
|
| Line 319... | Line 332... | ||
| 319 | }
|
332 | }
|
| 320 | my $id = $Inv_By_PartNo{$device}; |
333 | my $id = $Inv_By_PartNo{$device}; |
| 321 | next if ($Inv[$id]{Manufacturer} =~ /none/i); # skip parts whose manufacturer is none |
334 | next if ($Inv[$id]{Manufacturer} =~ /none/i); # skip parts whose manufacturer is none |
| 322 | #inf_printf("Found in Inventory at %d %s", $id, $Inv[$id]{Manufacturer_Partno});
|
335 | #inf_printf("Found in Inventory at %d %s", $id, $Inv[$id]{Manufacturer_Partno});
|
| 323 | push @{$data{$id}{RefDes}}, $refdes; |
336 | push @{$data{$id}{RefDes}}, $refdes; |
| - | 337 | if (!defined $data{$id}{Footprint}) { |
|
| - | 338 | $data{$id}{Footprint} = $footprint; |
|
| - | 339 | } else { |
|
| - | 340 | if ($data{$id}{Footprint} ne $footprint) { |
|
| - | 341 | err_printf("Different footprints for same device in within single bom file, script ". |
|
| - | 342 | "cannot work around this, will use first one, but expect that output file ". |
|
| - | 343 | "might have errors."); |
|
| - | 344 | }
|
|
| - | 345 | }
|
|
| 324 | }
|
346 | }
|
| 325 | }
|
347 | }
|
| 326 | close(IN); |
348 | close(IN); |
| 327 | 349 | ||
| 328 | if (scalar keys %data == 0) { |
350 | if (scalar keys %data == 0) { |
| Line 339... | Line 361... | ||
| 339 | if (!defined $Inv[$id]{Price}) { |
361 | if (!defined $Inv[$id]{Price}) { |
| 340 | wrn_printf("%s has no price, setting to 0.0", $Inv[$id]{Manufacturer_Partno}); |
362 | wrn_printf("%s has no price, setting to 0.0", $Inv[$id]{Manufacturer_Partno}); |
| 341 | $Inv[$id]{Price} = 0; |
363 | $Inv[$id]{Price} = 0; |
| 342 | }
|
364 | }
|
| 343 | push @{$BomData{$id}{RefDes}}, @{$data{$id}{RefDes}}; |
365 | push @{$BomData{$id}{RefDes}}, @{$data{$id}{RefDes}}; |
| - | 366 | if (!defined $BomData{$id}{Footprint}) { |
|
| - | 367 | $BomData{$id}{Footprint} = $data{$id}{Footprint}; |
|
| - | 368 | } else { |
|
| - | 369 | if ($data{$id}{Footprint} ne $data{$id}{Footprint}) { |
|
| - | 370 | err_printf("Different footprints for same device between sheets, script cannot ". |
|
| - | 371 | "work around this, will use first one, but expect that output file might ". |
|
| - | 372 | "have errors."); |
|
| - | 373 | }
|
|
| - | 374 | }
|
|
| - | 375 | push @{$BomData{$id}{Files}}, substr(basename($filepath),0,length(basename($filepath))-4); |
|
| 344 | 376 | ||
| 345 | # printf "%-20s %.4f %s\n", $Inv[$id]{Manufacturer_Partno}, $cnt, $icost, join (', ', @{$data{$id}{RefDes}});
|
377 | # printf "%-20s %.4f %s\n", $Inv[$id]{Manufacturer_Partno}, $cnt, $icost, join (', ', @{$data{$id}{RefDes}});
|
| 346 | # %BomData{ById}{$id}{RefDes}
|
378 | # %BomData{ById}{$id}{RefDes}
|
| 347 | }
|
379 | }
|
| 348 | }
|
380 | }
|
| Line 394... | Line 426... | ||
| 394 | "docdir|d=s" => sub { $Config{docdir} = $_[1]; }, |
426 | "docdir|d=s" => sub { $Config{docdir} = $_[1]; }, |
| 395 | # not sure if bomdir or SCH dir
|
427 | # not sure if bomdir or SCH dir
|
| 396 | "bomdir|b=s" => sub { $Config{$_[0]} = $_[1]; }, # $_[0] contain basename of option, so in few cases could be (ab)used |
428 | "bomdir|b=s" => sub { $Config{$_[0]} = $_[1]; }, # $_[0] contain basename of option, so in few cases could be (ab)used |
| 397 | "define|D=s" => sub { my ($p,$q) = split(/=/,$_[1],2); $Config{$p} = $q; }, |
429 | "define|D=s" => sub { my ($p,$q) = split(/=/,$_[1],2); $Config{$p} = $q; }, |
| 398 | "verbose|v:+" => sub { $Config{$_[0]} = ($_[1]>1?0:$Config{$_[0]}) + $_[1]; }, |
430 | "verbose|v:+" => sub { $Config{$_[0]} = ($_[1]>1?0:$Config{$_[0]}) + $_[1]; }, |
| 399 | "help|h|?:s" => sub { $show_help = 1 }, |
431 | "help|h|?:s" => sub { $show_help = 1; }, |
| 400 | "outdir|o=s" => sub { $Config{$_[0]} = $_[1]; }, |
432 | "outfile|o=s" => sub { $Config{$_[0]} = $_[1]; }, |
| - | 433 | "force|f" => sub { $Config{$_[0]} = 1 }, |
|
| 401 | 434 | ||
| 402 | # options
|
435 | # options
|
| 403 | ); |
436 | ); |
| 404 | if (!$result) { |
437 | if (!$result) { |
| 405 | printf "Usage: %s [-d directory] [-v]\n",basename($0); |
438 | printf "Usage: %s [-d directory] [-v]\n",basename($0); |
| Line 431... | Line 464... | ||
| 431 | # process BOM files
|
464 | # process BOM files
|
| 432 | printf STDERR "Loading bom data from %s\n", shortdir($Config{bomdir}); |
465 | printf STDERR "Loading bom data from %s\n", shortdir($Config{bomdir}); |
| 433 | file_lookup($Config{bomdir}, 0, qr/\.bom$/, \&parse_bom); |
466 | file_lookup($Config{bomdir}, 0, qr/\.bom$/, \&parse_bom); |
| 434 | printf STDERR "\tLoaded, now processing\n"; |
467 | printf STDERR "\tLoaded, now processing\n"; |
| 435 | 468 | ||
| 436 | my $n = 1; |
469 | my ($bn,$pn) = (1,1); |
| 437 | my $cost = 0.0; |
470 | my $cost = 0.0; |
| 438 | 471 | ||
| - | 472 | my $out; |
|
| - | 473 | if (!defined $Config{outfile}) { |
|
| - | 474 | $Config{outfile} = './output.txt'; |
|
| - | 475 | wrn_printf("Output file not specified, saving out in ".$Config{outfile}); |
|
| - | 476 | }
|
|
| 439 | 477 | ||
| - | 478 | if ( -e $Config{outfile}) { |
|
| 440 | my $out = new IO::File $Config{outdir}.'/output.txt', 'w'; |
479 | unless (defined $Config{force} && $Config{force} == 1) { |
| - | 480 | inf_printf("Unlinking output.txt before owrewriting"); |
|
| - | 481 | unlink($Config{outfile}); |
|
| - | 482 | } else { |
|
| - | 483 | wrn_printf("Output file already exist, add --force if i shall overwrite it"); |
|
| - | 484 | exit; |
|
| - | 485 | }
|
|
| 441 | 486 | }
|
|
| 442 | open (PARTMAP, '>output.map') || die 'cant open output.map: $!'; |
- | |
| 443 | 487 | ||
| 444 | printf PARTMAP "%-35s| refdes\n\n", 'part'; |
488 | $out = new IO::File $Config{outfile}, 'w'; |
| 445 | 489 | ||
| 446 | my $bomtable = Text::Table->new( |
490 | my $bomtable = Text::Table->new( |
| 447 | { title => '| ', is_sep => 1 }, |
491 | { title => '| ', is_sep => 1 }, |
| 448 | { title => 'id', align => 'right', align_title => 'left' }, |
492 | { title => 'id', align => 'right', align_title => 'left' }, |
| 449 | { title => ' | ', is_sep => 1 }, |
493 | { title => ' | ', is_sep => 1 }, |
| Line 460... | Line 504... | ||
| 460 | { title => "price", align => 'right', align_title => 'left' }, |
504 | { title => "price", align => 'right', align_title => 'left' }, |
| 461 | { title => ' | ', is_sep => 1 }, |
505 | { title => ' | ', is_sep => 1 }, |
| 462 | { title => "cost", align => 'right', align_title => 'left' }, |
506 | { title => "cost", align => 'right', align_title => 'left' }, |
| 463 | { title => ' |', is_sep => 1 }, |
507 | { title => ' |', is_sep => 1 }, |
| 464 | ); |
508 | ); |
| - | 509 | ||
| - | 510 | my $parttable = Text::Table->new( |
|
| - | 511 | { title => '| ', is_sep => 1 }, |
|
| - | 512 | { title => 'id', align => 'right', align_title => 'center' }, |
|
| - | 513 | { title => ' | ', is_sep => 1 }, |
|
| - | 514 | { title => 'description', align => 'left', align_title => 'center' }, |
|
| - | 515 | { title => ' | ', is_sep => 1 }, |
|
| - | 516 | { title => 'manufacturer partno', align => 'left', align_title => 'center' }, |
|
| - | 517 | { title => ' | ', is_sep => 1 }, |
|
| - | 518 | { title => 'footprint', align => 'left', align_title => 'center' }, |
|
| - | 519 | { title => ' | ', is_sep => 1 }, |
|
| - | 520 | { title => 'refdes', align => 'left', align_title => 'center' }, |
|
| - | 521 | { title => ' | ', is_sep => 1 }, |
|
| - | 522 | { title => 'sheet', align => 'left', align_title => 'center' }, |
|
| - | 523 | { title => ' |', is_sep => 1 }, |
|
| - | 524 | ); |
|
| 465 | 525 | ||
| 466 | foreach my $id ( sort {my $p = $Inv[$a]{Manufacturer} cmp $Inv[$b]{Manufacturer}; if ($p == 0) { |
526 | foreach my $id ( sort {my $p = $Inv[$a]{Manufacturer} cmp $Inv[$b]{Manufacturer}; if ($p == 0) { |
| 467 | # return $Inv[$a]{Manufacturer_Partno} cmp $Inv[$b]{Manufacturer_Partno}}; return $p; } keys %BomData) {
|
527 | # return $Inv[$a]{Manufacturer_Partno} cmp $Inv[$b]{Manufacturer_Partno}}; return $p; } keys %BomData) {
|
| 468 | return $Inv[$a]{Description} cmp $Inv[$b]{Description}}; return $p; } keys %BomData) { |
528 | return $Inv[$a]{Description} cmp $Inv[$b]{Description}}; return $p; } keys %BomData) { |
| 469 | my %tmp; |
529 | my %tmp; |
| Line 474... | Line 534... | ||
| 474 | wrn_printf("%s has no price, setting to 0.0", $Inv[$id]{Manufacturer_Partno}); |
534 | wrn_printf("%s has no price, setting to 0.0", $Inv[$id]{Manufacturer_Partno}); |
| 475 | $Inv[$id]{Price} = 0; |
535 | $Inv[$id]{Price} = 0; |
| 476 | }
|
536 | }
|
| 477 | my $icost = $quant * $Inv[$id]{Price}; |
537 | my $icost = $quant * $Inv[$id]{Price}; |
| 478 | 538 | ||
| 479 | printf PARTMAP "%-35s|%s\n", shortstring($Inv[$id]{Description},35), join (', ', sort @{$BomData{$id}{RefDes}}); |
539 | # printf PARTMAP "%-35s|%s\n", shortstring($Inv[$id]{Description},35), join (', ', sort @{$BomData{$id}{RefDes}});
|
| 480 | $cost += $icost; |
540 | $cost += $icost; |
| 481 | # %BomData{ById}{$id}{RefDes}
|
541 | # %BomData{ById}{$id}{RefDes}
|
| 482 | # $bomtable->add(' '.$n.' ', $Inv[$id]{Description}.' ', $Inv[$id]{Manufacturer_Partno}.' ', $Inv[$id]{Manufacturer}.' ',
|
542 | # $bomtable->add(' '.$n.' ', $Inv[$id]{Description}.' ', $Inv[$id]{Manufacturer_Partno}.' ', $Inv[$id]{Manufacturer}.' ',
|
| 483 | # $Inv[$id]{Ordercode}.' ', ' '.$quant.' ', sprintf("%.3f ",$Inv[$id]{Price}), sprintf("%.3f ",$icost));
|
543 | # $Inv[$id]{Ordercode}.' ', ' '.$quant.' ', sprintf("%.3f ",$Inv[$id]{Price}), sprintf("%.3f ",$icost));
|
| 484 | $bomtable->add($n, $Inv[$id]{Description}, $Inv[$id]{Manufacturer_Partno}, $Inv[$id]{Manufacturer}, |
544 | $bomtable->add($bn++, $Inv[$id]{Description}, $Inv[$id]{Manufacturer_Partno}, $Inv[$id]{Manufacturer}, |
| 485 | $Inv[$id]{Ordercode},$quant, sprintf("%.3f",$Inv[$id]{Price}), sprintf("%.3f",$icost)); |
545 | $Inv[$id]{Ordercode},$quant, sprintf("%.3f",$Inv[$id]{Price}), sprintf("%.3f",$icost)); |
| 486 | $n ++; |
546 | |
| - | 547 | $parttable->add($pn++, $Inv[$id]{Description}, $Inv[$id]{Manufacturer_Partno}, $BomData{$id}{Footprint}, |
|
| - | 548 | strbreak(join (', ', sort @{$BomData{$id}{RefDes}}),43), join("\n",@{$BomData{$id}{Files}})); |
|
| 487 | }
|
549 | }
|
| 488 | 550 | ||
| 489 | printf $out "file generated at %s\n\n", scalar localtime(time()); |
551 | printf $out "file generated at %s\n\n", scalar localtime(time()); |
| 490 | 552 | ||
| 491 | print $out $bomtable->rule('-','+'); |
553 | print $out $bomtable->rule('-','+'); |
| 492 | print $out $bomtable->title(); |
554 | print $out $bomtable->title(); |
| 493 | print $out $bomtable->rule('-','+'); |
555 | print $out $bomtable->rule('-','+'); |
| 494 | print $out $bomtable->body(); |
556 | print $out $bomtable->body(); |
| 495 | print $out $bomtable->rule('-','+'); |
557 | print $out $bomtable->rule('-','+'); |
| 496 | 558 | ||
| 497 | printf $out "\nTotal cost: %.3f\n", $cost; |
559 | printf $out "\nTotal cost: %.3f\n\n\n", $cost; |
| - | 560 | ||
| - | 561 | print $out $parttable->rule('-','+'); |
|
| - | 562 | print $out $parttable->title(); |
|
| - | 563 | print $out $parttable->rule('-','+'); |
|
| - | 564 | print $out $parttable->body(); |
|
| - | 565 | print $out $parttable->rule('-','+'); |
|
| - | 566 | ||
| 498 | 567 | ||
| 499 | close PARTMAP; |
568 | #close PARTMAP;
|
| 500 | 569 | ||
| 501 | printf STDERR "\tFinished, output saved in %s\n", $Config{outdir}.'/output.txt'; |
570 | printf STDERR "\tFinished, output saved in %s\n", $Config{outfile}; |