Subversion Repositories OpenARM Single-board Computer

Rev

Rev 417 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 417 Rev 419
Line 1... Line 1...
1
#!/usr/bin/perl -w
1
#!/usr/bin/perl -w
2
use strict;
2
use strict;
3
# $Id: inventory.pl 417 2009-05-15 17:21:21Z agaran $
3
# $Id: inventory.pl 419 2009-05-16 00:01:56Z 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 17... Line 17...
17
use Text::Table;
17
use Text::Table;
18
18
19
19
20
my %Config;
20
my %Config;
21
21
22
# ==================================================
22
# ===[ SETUP DEFAULTS ]=============================
23
$Config{docdir} = '.';
23
$Config{docdir} = '.';
24
$Config{bomdir} = '.';
24
$Config{bomdir} = '.';
25
$Config{verbose} = 1;
25
$Config{verbose} = 1;
26
26
27
# 0 mean not show, -1 show all, positive value limits depth of shown
27
# 0 mean not show, -1 show all, positive value limits depth of shown
28
$Config{dbg_showdirs} = 0;
28
$Config{dbg_showdirs} = 0;
29
29
30
30
31
# modes
31
# modes
32
my $build_inventory = 0;
-
 
33
my $build_bom = 0;
-
 
34
my $show_conf = 0;
32
my $show_conf = 0;
35
my $show_help = 0;
33
my $show_help = 0;
36
34
37
# ==================================================
35
# ==================================================
38
36
39
my %Inv_By_PartNo;
37
my %Inv_By_PartNo;
40
my @Inv;
38
my @Inv;
41
my %BomData;
39
my %BomData;
42
my %Files;
40
my %Files;
-
 
41
my ($file_name, $file_line);
43
42
44
sub err_printf($@) {
43
sub err_printf($@) {
45
        my ($format, @args) = @_;
44
        my ($format, @args) = @_;
46
45
-
 
46
        if (defined $file_name && defined $file_line) {
-
 
47
                $format = '(%s:%d) '.$format;
-
 
48
                unshift @args, shortdir($file_name), $file_line;
-
 
49
        }
-
 
50
47
        printf STDERR "-E- ".$format."\n", @args;
51
        printf STDERR "-E- ".$format."\n", @args;
48
        # exit? or fail-exit here
52
        # exit? or fail-exit here
49
}
53
}
50
54
51
sub wrn_printf($@) {
55
sub wrn_printf($@) {
52
        my ($format, @args) = @_;
56
        my ($format, @args) = @_;
53
        return if ($Config{verbose} <= 1) ;
57
        return if ($Config{verbose} <= 1) ;
-
 
58
-
 
59
        if (defined $file_name && defined $file_line) {
-
 
60
                $format = '(%s:%d) '.$format;
-
 
61
                unshift @args, shortdir($file_name), $file_line;
-
 
62
        }
-
 
63
54
        printf STDERR "-W- ".$format."\n", @args;
64
        printf STDERR "-W- ".$format."\n", @args;
55
}
65
}
56
66
57
sub inf_printf($@) {
67
sub inf_printf($@) {
58
        my ($format, @args) = @_;
68
        my ($format, @args) = @_;
59
        return if ($Config{verbose} <= 2) ;
69
        return if ($Config{verbose} <= 2) ;
-
 
70
-
 
71
        if (defined $file_name && defined $file_line) {
-
 
72
                $format = '(%s:%d) '.$format;
-
 
73
                unshift @args, shortdir($file_name), $file_line;
-
 
74
        }
-
 
75
60
        printf STDERR "-I- ".$format."\n", @args;
76
        printf STDERR "-I- ".$format."\n", @args;
61
}
77
}
62
78
-
 
79
sub nfo_printf($@) {
-
 
80
        my ($format, @args) = @_;
-
 
81
-
 
82
        return if ($Config{verbose} <= 0) ;
-
 
83
-
 
84
        if (defined $file_name && defined $file_line) {
-
 
85
                $format = '(%s:%d) '.$format;
-
 
86
                unshift @args, shortdir($file_name), $file_line;
-
 
87
        }
-
 
88
-
 
89
        printf STDERR "-N- ".$format."\n", @args;
-
 
90
        # exit? or fail-exit here
-
 
91
}
-
 
92
-
 
93
-
 
94
63
sub Config_Show {
95
sub Config_Show {
64
        printf "Config for %s\n----------------------------------------\n", basename($0);
96
        printf "Config for %s\n----------------------------------------\n", basename($0);
65
        foreach my $name (sort keys %Config) {
97
        foreach my $name (sort keys %Config) {
66
                printf "%-20s %s\n", $name, $Config{$name};
98
                printf "%-20s %s\n", $name, $Config{$name};
67
        }
99
        }
Line 71... Line 103...
71
        printf "Help for %s\n----------------------------------------\n", basename($0);
103
        printf "Help for %s\n----------------------------------------\n", basename($0);
72
        unless (defined($_[1]) && length($_[1]) != 0) {
104
        unless (defined($_[1]) && length($_[1]) != 0) {
73
                print "Basic help\n\t--showrc|showconf shows current configuration\n".
105
                print "Basic help\n\t--showrc|showconf shows current configuration\n".
74
                        "\t--docdir|-d <dir> tells script where information.txt files should be searched\n".
106
                        "\t--docdir|-d <dir> tells script where information.txt files should be searched\n".
75
                        "\t--define <something>=<somethingelseornot> defines some configration value\n".
107
                        "\t--define <something>=<somethingelseornot> defines some configration value\n".
76
                        "\t--verbose|-v [level] sets verbosity level\nOrder of options DOES matter\n".
108
                        "\t--verbose|-v [level] increases or sets verbosity level\nOrder of options DOES matter\n".
77
                        "\t--bomdir|-b <dir> tells script where boms should be searched\n".
109
                        "\t--bomdir|-b <dir> tells script where boms should be searched\n".
78
                        "\t--outfile|-o <file> tells where script shall save output data\n".
110
                        "\t--outfile|-o <file> tells where script shall save output data\n".
79
                        "\t--force|-f forces script to save data even if file exist already\n".
111
                        "\t--force|-f forces script to save data even if file exist already\n".
80
                        "\t-l <num> repeat title for output tables every <num> rows\n";
112
                        "\t-l <num> repeat title for output tables every <num> rows\n";
81
113
Line 178... Line 210...
178
210
179
211
180
        open(IN, $filepath) or return 1;
212
        open(IN, $filepath) or return 1;
181
213
182
        my %data;
214
        my %data;
-
 
215
-
 
216
        $file_name = $filepath;
183
        my $lineno = 0;
217
        $file_line = 0;
184
218
185
        my $_ok;
219
        my $_ok;
186
220
187
        while (not eof IN) {
221
        while (not eof IN) {
188
                my $line = <IN>;
222
                my $line = <IN>;
189
                $lineno++;
223
                $file_line++;
190
224
191
                chomp $line;
225
                chomp $line;
192
226
193
                next if ($line =~ /^[   ]*$/);
227
                next if ($line =~ /^[   ]*$/);
194
                next if ($line =~ /^;/);
228
                next if ($line =~ /^;/);
Line 204... Line 238...
204
                                        # printf STDERR "Price %.3f\n", $value;
238
                                        # printf STDERR "Price %.3f\n", $value;
205
                                        if (!defined($data{price})) {
239
                                        if (!defined($data{price})) {
206
                                                $data{price} = $value;
240
                                                $data{price} = $value;
207
                                                $_ok->{$name} = 1;
241
                                                $_ok->{$name} = 1;
208
                                        } else {
242
                                        } else {
209
                                                wrn_printf("Duplicated price field in file %s", shortdir($filepath));
243
                                                wrn_printf("Duplicated price field.");
210
                                        }
244
                                        }
211
                                } else {
245
                                } else {
212
                                        err_printf("Bad price field in file %s", shortdir($filepath));
246
                                        err_printf("Bad data in price field.");
213
                                }
247
                                }
214
                        } elsif ($name =~ /^manufacturer$/i) {
248
                        } elsif ($name =~ /^manufacturer$/i) {
215
                                # printf STDERR "Manufacturer %s\n", $value;
249
                                # printf STDERR "Manufacturer %s\n", $value;
216
                                if (!defined($data{manufacturer})) {
250
                                if (!defined($data{manufacturer})) {
217
                                        $data{manufacturer} = $value;
251
                                        $data{manufacturer} = $value;
218
                                        $_ok->{$name} = 1;
252
                                        $_ok->{$name} = 1;
219
                                } else {
253
                                } else {
220
                                        wrn_printf("Duplicated manufacturer field in file %s", shortdir($filepath));
254
                                        wrn_printf("Duplicated manufacturer field.");
221
                                }
255
                                }
222
                        } elsif ($name =~ /^manufacturer part no$/ ) {
256
                        } elsif ($name =~ /^manufacturer part no$/ ) {
223
                                # printf STDERR "ManPartNo %s\n", $value;
257
                                # printf STDERR "ManPartNo %s\n", $value;
224
                                if (!defined($data{manufact_partno})) {
258
                                if (!defined($data{manufact_partno})) {
225
                                        $data{manufact_partno} = trim($value);
259
                                        $data{manufact_partno} = trim($value);
226
                                        $_ok->{$name} = 1;
260
                                        $_ok->{$name} = 1;
227
                                } else {
261
                                } else {
228
                                        wrn_printf("Duplicated manufacturer part no field in file %s",
262
                                        wrn_printf("Duplicated manufacturer part no field.");
229
                                                shortdir($filepath));
-
 
230
                                }
263
                                }
231
                        } elsif ($name =~ /^description$/i) {
264
                        } elsif ($name =~ /^description$/i) {
232
                                if (!defined($data{desc})) {
265
                                if (!defined($data{desc})) {
233
                                        $data{desc} = $value;
266
                                        $data{desc} = $value;
234
                                } else {
267
                                } else {
235
                                        wrn_printf("Duplicated description no field in file %s",
268
                                        wrn_printf("Duplicated description no field.");
236
                                                shortdir($filepath));
-
 
237
                                }
269
                                }
238
                        } elsif ($name =~ /^datasheet$/i) {
270
                        } elsif ($name =~ /^datasheet$/i) {
239
                                $data{datasheet} = [] unless defined $data{datasheet};
271
                                $data{datasheet} = [] unless defined $data{datasheet};
240
                                push @{$data{datasheet}}, $value;
272
                                push @{$data{datasheet}}, $value;
241
                                # printf STDERR "Datasheet %s\n", $value;
273
                                # printf STDERR "Datasheet %s\n", $value;
Line 243... Line 275...
243
                                # printf STDERR "Supplier %s\n", $value;
275
                                # printf STDERR "Supplier %s\n", $value;
244
                                if (!defined($data{supplier})) {
276
                                if (!defined($data{supplier})) {
245
                                        $data{supplier} = $value;
277
                                        $data{supplier} = $value;
246
                                        $_ok->{$name} = 1;
278
                                        $_ok->{$name} = 1;
247
                                } else {
279
                                } else {
248
                                        wrn_printf("Duplicated supplier field in file %s",
280
                                        wrn_printf("Duplicated supplier field.");
249
                                                shortdir($filepath));
-
 
250
                                }
281
                                }
251
                        } elsif ($name =~ /^order code$/) {
282
                        } elsif ($name =~ /^order code$/) {
252
                                # printf STDERR "Order Code %s\n", $value;
-
 
253
                                if (!defined($data{ordercode})) {
283
                                if (!defined($data{ordercode})) {
254
                                        $data{ordercode} = $value;
284
                                        $data{ordercode} = $value;
255
                                        $_ok->{$name} = 1;
285
                                        $_ok->{$name} = 1;
256
                                } else {
286
                                } else {
257
                                        wrn_printf("Duplicated order code field in file %s",
287
                                        wrn_printf("Duplicated order code field.");
258
                                                shortdir($filepath));
-
 
259
                                }
288
                                }
260
                                #push @DATA, { $name => $value };
289
                                #push @DATA, { $name => $value };
261
                        } elsif ($name =~ /^url .*$/) {
290
                        } elsif ($name =~ /^url .*$/) {
262
                                # printf STDERR "URL %s\n", $value;
291
                                # printf STDERR "URL %s\n", $value;
263
                        } elsif ($name =~ /^catalog(ue|) page$/) {
292
                        } elsif ($name =~ /^catalog(ue|) page$/) {
264
                                # printf STDERR "Catalogue Page %s\n", $value;
293
                                # printf STDERR "Catalogue Page %s\n", $value;
265
                        } else {
294
                        } else {
266
                                err_printf("Unhandled field %s in file %s", $name,
295
                                err_printf("Unhandled field type `%s'.",$name);
267
                                        shortdir($filepath));
-
 
268
                        }
296
                        }
269
                } elsif ($line =~ /^([A-Za-z ]+)[ \t]*\(([A-Za-z 0-9\(\)\-]+)\)[ \t]*:(.*)$/) {
297
                } elsif ($line =~ /^([A-Za-z ]+)[ \t]*\(([A-Za-z 0-9\(\)\-]+)\)[ \t]*:(.*)$/) {
270
                        my ($name, $extdata, $value) = (lc etrim($1),etrim($2),etrim($3));
298
                        my ($name, $extdata, $value) = (lc etrim($1),etrim($2),etrim($3));
271
                        if ($name =~ /^price$/) {
299
                        if ($name =~ /^price$/) {
272
                                $extdata =~ s/ //g;
300
                                $extdata =~ s/ //g;
Line 277... Line 305...
277
                                        $value =~ s/[^0-9\.\,]//g; # remove any characters beside DIGITS
305
                                        $value =~ s/[^0-9\.\,]//g; # remove any characters beside DIGITS
278
                                        if ($value =~ s/^([0-9]+)[,.]([0-9]+)$/$1.$2/) {
306
                                        if ($value =~ s/^([0-9]+)[,.]([0-9]+)$/$1.$2/) {
279
                                                push @{$data{price}}, [ $extdata, $value ];
307
                                                push @{$data{price}}, [ $extdata, $value ];
280
                                                $_ok->{$name} = 1;
308
                                                $_ok->{$name} = 1;
281
                                        } else {
309
                                        } else {
282
                                                err_printf("Bad price field in file %s:%d", shortdir($filepath), $lineno);
310
                                                err_printf("Bad extended price field.");
283
                                        }
311
                                        }
284
                                }
312
                                }
285
                        } else {
313
                        } else {
286
                                wrn_printf("Got: <%s> <%s> <%s> at %s:%s", $name, $extdata, $value, $line, shortdir($filepath));
314
                                wrn_printf("Unrecognized extended data `%s'.", $name);
287
                        }
315
                        }
288
                } else {
316
                } else {
289
                        wrn_printf("Unparseable line `%s', forgot ; to set it as comment in file %s", $line,
317
                        wrn_printf("Unparseable line, is it an comment?");
290
                                shortdir($filepath));
-
 
291
                }
318
                }
292
        }
319
        }
293
        close(IN);
320
        close(IN);
294
321
295
        if (scalar keys %data == 0) {
322
        if (scalar keys %data == 0) {
296
                inf_printf("Skipping file %s because contain no data for me", shortdir($filepath));
323
                inf_printf("No data for me, skipping.");
297
                return;
324
                return;
298
        }
325
        }
299
326
300
        foreach my $field (split /\!/, q/price!manufacturer part no!order code/) {
327
        foreach my $field (split /\!/, q/price!manufacturer part no!order code/) {
301
                wrn_printf("Missing ".(ucfirst $field)." in file %s", shortdir($filepath)) unless ($_ok->{$field});
328
                wrn_printf("Missing required field `".(ucfirst $field)."'.") unless ($_ok->{$field});
302
        }
329
        }
303
       
330
       
304
331
305
        my $id = scalar @Inv;
332
        my $id = scalar @Inv;
306
333
Line 321... Line 348...
321
                        $Inv[$id]{Manufacturer_Partno}, $id);
348
                        $Inv[$id]{Manufacturer_Partno}, $id);
322
        }
349
        }
323
350
324
        #inf_printf("Part %s defined in file %s", $Inv[$id]{Manufacturer_Partno}, shortdir($filepath));
351
        #inf_printf("Part %s defined in file %s", $Inv[$id]{Manufacturer_Partno}, shortdir($filepath));
325
       
352
       
326
        wrn_printf("Unhandled data from parsing: %s", Dumper(\%data)) if (scalar keys %data > 0);
353
        wrn_printf("Bug in parser, please report: %s", Dumper(\%data)) if (scalar keys %data > 0);
327
}
354
}
328
355
329
356
330
sub parse_bom ($) {
357
sub parse_bom ($) {
331
        my ($filepath) = @_;
358
        my ($filepath) = @_;
332
359
333
        open(IN, $filepath) or return 1;
360
        open(IN, $filepath) or return 1;
334
        my $fkey = substr(basename($filepath),0,length(basename($filepath))-4);
361
        my $fkey = substr(basename($filepath),0,length(basename($filepath))-4);
335
362
-
 
363
        $file_name = $filepath;
-
 
364
        $file_line = 0;
-
 
365
336
        #wrn_printf("GotARg: %s", shortdir($filepath));
366
        #wrn_printf("GotARg: %s", shortdir($filepath));
337
367
338
        my @Fields;
368
        my @Fields;
339
369
340
        my %data;
370
        my %data;
341
        my $v = '';
371
        my $v = '';
342
        while (not eof IN) {
372
        while (not eof IN) {
343
                my $line = <IN>;
373
                my $line = <IN>;
-
 
374
                $file_line++;
344
375
345
                chomp $line;
376
                chomp $line;
346
377
347
                if ($line =~ /^\.START$/) {
378
                if ($line =~ /^\.START$/) {
348
                        $v = 'boms';
379
                        $v = 'boms';
Line 368... Line 399...
368
                        $device = trim($device);
399
                        $device = trim($device);
369
400
370
#                       wrn_printf("Device: %s (value: %s) at refdes %s, %d pcs", $device, $value, $refdes, $quantity);
401
#                       wrn_printf("Device: %s (value: %s) at refdes %s, %d pcs", $device, $value, $refdes, $quantity);
371
402
372
                        if (!defined $Inv_By_PartNo{$device}) {
403
                        if (!defined $Inv_By_PartNo{$device}) {
373
                                wrn_printf("Device %s not found in inventory in file %s", $device, shortdir($filepath));
404
                                wrn_printf("Device %s not found in inventory.", $device);
374
                                next;
405
                                next;
375
                        }
406
                        }
376
                        my $id = $Inv_By_PartNo{$device};
407
                        my $id = $Inv_By_PartNo{$device};
377
                        next if ($Inv[$id]{Manufacturer} =~ /none/i); # skip parts whose manufacturer is none
408
                        next if ($Inv[$id]{Manufacturer} =~ /none/i); # skip parts whose manufacturer is none
378
                        #inf_printf("Found in Inventory at %d %s", $id, $Inv[$id]{Manufacturer_Partno});
409
                        #inf_printf("Found in Inventory at %d %s", $id, $Inv[$id]{Manufacturer_Partno});
Line 389... Line 420...
389
                }
420
                }
390
        }
421
        }
391
        close(IN);
422
        close(IN);
392
423
393
        if (scalar keys %data == 0) {
424
        if (scalar keys %data == 0) {
394
                inf_printf("Skipping file %s because contain no data for me",
425
                inf_printf("No data for me, skipping.");
395
                        shortdir($filepath));
-
 
396
                return;
426
                return;
397
        }
427
        }
398
428
399
        foreach my $id (keys %data) {
429
        foreach my $id (keys %data) {
400
                my %tmp;
430
                my %tmp;
Line 418... Line 448...
418
#               %BomData{ById}{$id}{RefDes}
448
#               %BomData{ById}{$id}{RefDes}
419
        }
449
        }
420
}
450
}
421
451
422
sub file_lookup ($$$$) ;
452
sub file_lookup ($$$$) ;
423
sub file_lookup ($$$$) {
453
sub file_lookup ($$$$) { # {{{1
424
        my ($dir, $depth, $regexp, $callback) = @_;
454
        my ($dir, $depth, $regexp, $callback) = @_;
425
455
426
        err_printf("Sorry, callback must be CODE ref") unless (ref $callback eq 'CODE');
456
        err_printf("BUG: Sorry, callback must be CODE ref") unless (ref $callback eq 'CODE');
427
457
428
        if ( -d $dir) {
458
        if ( -d $dir) {
429
                my $d = IO::Dir->new($dir);
459
                my $d = IO::Dir->new($dir);
430
                return 1 if (!defined $d);
460
                return 1 if (!defined $d);
431
461
Line 433... Line 463...
433
                while (defined(my $e = $d->read)) {
463
                while (defined(my $e = $d->read)) {
434
                        my $fe = $dir .'/'. $e;
464
                        my $fe = $dir .'/'. $e;
435
                        if ( -f $fe) {
465
                        if ( -f $fe) {
436
                                if ($fe =~ $regexp) {
466
                                if ($fe =~ $regexp) {
437
                                        &$callback($fe);
467
                                        &$callback($fe);
-
 
468
                                        $file_name = undef;
438
                                }
469
                                }
439
                        } elsif (-d $fe) { # now its dir...
470
                        } elsif (-d $fe) { # now its dir...
440
                                if ($e eq '.svn') { # if entry name is equal to svn
471
                                if ($e eq '.svn') { # if entry name is equal to svn
441
                                        next; # go to next entry in foreach loop
472
                                        next; # go to next entry in foreach loop
442
                                }
473
                                }
443
                                next if ($e eq '.' or $e eq '..'); # skip to next if dir entry is . or ..
474
                                next if ($e eq '.' or $e eq '..'); # skip to next if dir entry is . or ..
444
475
445
                                if ($Config{dbg_showdirs} == -1 or $Config{dbg_showdirs} > $depth) {
476
                                if ($Config{dbg_showdirs} == -1 or $Config{dbg_showdirs} > $depth) {
-
 
477
                                        $file_name = undef;
446
                                        printf STDERR "Entering directory %s\n", shortdir($fe);
478
                                        dbg_printf("Entering directory %s", shortdir($fe));
447
                                }
479
                                }
448
                                return 1 if (file_lookup($fe, $depth+1, $regexp, $callback) == 1);
480
                                return 1 if (file_lookup($fe, $depth+1, $regexp, $callback) == 1);
449
                        } else {
481
                        } else {
450
                                # symlink or other mysterius beast
482
                                # symlink or other mysterius beast
451
                        }
483
                        }
452
                }
484
                }
453
        }
485
        }
454
        return 0;
486
        return 0;
-
 
487
} # }}}
-
 
488
-
 
489
sub gen_bomfile ($) { # {{{1
-
 
490
        my $outfile = shift @_;
-
 
491
-
 
492
        if (-e $outfile) {
-
 
493
                wrn_printf("File already exist");
-
 
494
        }
-
 
495
-
 
496
        my $out = new IO::File $outfile, 'w';
-
 
497
-
 
498
        my $bomtable = Text::Table->new(
-
 
499
                { title => '| ', is_sep => 1 },
-
 
500
                { title => 'id', align => 'right', align_title => 'left' },
-
 
501
                { title => ' | ', is_sep => 1 },
-
 
502
                { title => 'description', align => 'left', align_title => 'left' },
-
 
503
                { title => ' | ', is_sep => 1 },
-
 
504
                { title => 'manufacturer partid', align => 'left', align_title => 'left' },
-
 
505
                { title => ' | ', is_sep => 1 },
-
 
506
                { title => 'manufacturer', align => 'left', align_title => 'left' },
-
 
507
                { title => ' | ', is_sep => 1 },
-
 
508
                { title => 'order code', align => 'left', align_title => 'left' },
-
 
509
                { title => ' | ', is_sep => 1 },
-
 
510
                { title => 'quantity', align => 'right', align_title => 'left' },
-
 
511
                { title => ' | ', is_sep => 1 },
-
 
512
                { title => "price", align => 'right', align_title => 'left' },
-
 
513
                { title => ' | ', is_sep => 1 },
-
 
514
                { title => "cost", align => 'right', align_title => 'left' },
-
 
515
                { title => ' |', is_sep => 1 },
-
 
516
        );
-
 
517
-
 
518
        # counters
-
 
519
        my ($bn,$totalcost,$partcount) = (1,0,0);
-
 
520
-
 
521
        foreach my $id ( sort {my $p = $Inv[$a]{Manufacturer} cmp $Inv[$b]{Manufacturer}; if ($p == 0) {
-
 
522
#               return $Inv[$a]{Manufacturer_Partno} cmp $Inv[$b]{Manufacturer_Partno}}; return $p; }  keys %BomData) {
-
 
523
                        return $Inv[$a]{Description} cmp $Inv[$b]{Description}}; return $p; }  keys %BomData) {
-
 
524
                my %tmp;
-
 
525
-
 
526
                map { $tmp{$_} = 1 } @{$BomData{$id}{RefDes}}; # duplicated refdes removal
-
 
527
                @{$BomData{$id}{RefDes}} = keys %tmp;
-
 
528
-
 
529
                my $quant = scalar @{$BomData{$id}{RefDes}}; # quantity based on number of refdes..
-
 
530
-
 
531
                my $price = get_price($id,$quant);
-
 
532
                if ($price == 0) {
-
 
533
                        wrn_printf("%s has zero price", $Inv[$id]{Manufacturer_Partno});
-
 
534
                }
-
 
535
                my $icost = $quant * $price;
-
 
536
               
-
 
537
                $bomtable->add($bn++, $Inv[$id]{Description}, $Inv[$id]{Manufacturer_Partno}, $Inv[$id]{Manufacturer},
-
 
538
                        $Inv[$id]{Ordercode},$quant, sprintf("%.3f",$price), sprintf("%.3f", $icost));
-
 
539
-
 
540
                $totalcost += $icost;
-
 
541
                $partcount += $quant;
-
 
542
        }
-
 
543
-
 
544
        printf $out "file generated at %s\n\n", scalar localtime(time());
-
 
545
-
 
546
        print $out $bomtable->rule('-','+');
-
 
547
        print $out $bomtable->title();
-
 
548
        print $out $bomtable->rule('-','+');
-
 
549
-
 
550
        # repeat header every NTH lines or not
-
 
551
        unless (defined $Config{'lines'}) {
-
 
552
                print $out $bomtable->body();
-
 
553
        } else {
-
 
554
                my @p = split(/\n/,$bomtable->body());
-
 
555
                while (@p) {
-
 
556
                        my @sub = splice @p,0,$Config{'lines'};
-
 
557
                        print $out join("\n",@sub)."\n";
-
 
558
                        if (scalar @p > 0) {
-
 
559
                                print $out $bomtable->rule('-','+');
-
 
560
                                print $out $bomtable->title();
-
 
561
                                print $out $bomtable->rule('-','+');
-
 
562
                        }
-
 
563
                }
-
 
564
        }
-
 
565
        print $out $bomtable->rule('-','+');
-
 
566
-
 
567
        printf $out "\nTotal cost: %.3f\nTotal part count: %d\n\n", $totalcost, $partcount;
-
 
568
-
 
569
        $out->close;
-
 
570
} # }}}
-
 
571
-
 
572
sub gen_mapfile ($) { # {{{1
-
 
573
        my $outfile = shift @_;
-
 
574
-
 
575
        if (-e $outfile) {
-
 
576
                wrn_printf("File already exist");
-
 
577
        }
-
 
578
-
 
579
        my $out = new IO::File $outfile, 'w';
-
 
580
-
 
581
        my $parttable = Text::Table->new(
-
 
582
                { title => '| ', is_sep => 1 },
-
 
583
                { title => 'id', align => 'right', align_title => 'center' },
-
 
584
                { title => ' | ', is_sep => 1 },
-
 
585
                { title => 'description', align => 'left', align_title => 'center' },
-
 
586
                { title => ' | ', is_sep => 1 },
-
 
587
                { title => 'manufacturer partid', align => 'left', align_title => 'center' },
-
 
588
                { title => ' | ', is_sep => 1 },
-
 
589
                { title => 'footprint', align => 'left', align_title => 'center' },
-
 
590
                { title => ' | ', is_sep => 1 },
-
 
591
                { title => 'refdes', align => 'left', align_title => 'center' },
-
 
592
                { title => ' | ', is_sep => 1 },
-
 
593
                { title => 'sheet', align => 'left', align_title => 'center' },
-
 
594
                { title => ' |', is_sep => 1 },
-
 
595
        );
-
 
596
       
-
 
597
        my ($pn) = (1);
-
 
598
       
-
 
599
        foreach my $fkey (sort keys %Files) {
-
 
600
                my $rowblock = 0;
-
 
601
                foreach my $id ( sort {my $p = $Inv[$a]{Manufacturer} cmp $Inv[$b]{Manufacturer}; if ($p == 0) {
-
 
602
                        return $Inv[$a]{Description} cmp $Inv[$b]{Description}}; return $p; }  keys %{$Files{$fkey}}) {
-
 
603
       
-
 
604
                        if ($Config{'no-repeat-columns'}) {
-
 
605
                                my @p = split(/\n/, strbreak(join (', ', sort @{$Files{$fkey}{$id}{RefDes}}),43));
-
 
606
       
-
 
607
                                $parttable->add($pn, $Inv[$id]{Description}, $Inv[$id]{Manufacturer_Partno}, $BomData{$id}{Footprint},
-
 
608
                                        etrim(trim(shift @p)), $fkey);
-
 
609
       
-
 
610
                                while (@p) {
-
 
611
                                        $parttable->add('++', '', '', '', etrim(trim(shift @p)), '');
-
 
612
                                }
-
 
613
                        } else {
-
 
614
                                my @p = split(/\n/, strbreak(join (', ', sort @{$Files{$fkey}{$id}{RefDes}}),43));
-
 
615
                                while (@p) {
-
 
616
                                        $parttable->add($pn, $Inv[$id]{Description}, $Inv[$id]{Manufacturer_Partno}, $BomData{$id}{Footprint},
-
 
617
                                                etrim(trim(shift @p)), $fkey);
-
 
618
                                }
-
 
619
                        }
-
 
620
       
-
 
621
       
-
 
622
                        $pn++;
-
 
623
                }
-
 
624
                $parttable->add('--','=========','==========','==========','==========','==========');
-
 
625
        }
-
 
626
       
-
 
627
        print $out $parttable->rule('-','+');
-
 
628
        print $out $parttable->title();
-
 
629
        print $out $parttable->rule('-','+');
-
 
630
        unless (defined $Config{'lines'}) {
-
 
631
                print $out $parttable->body();
-
 
632
        } else {
-
 
633
                my @p = split(/\n/,$parttable->body());
-
 
634
                while (@p) {
-
 
635
                        my @sub = splice @p,0,$Config{'lines'};
-
 
636
                        print $out join("\n",@sub)."\n";
-
 
637
                        if (scalar @p > 0) {
-
 
638
                                print $out $parttable->rule('-','+');
-
 
639
                                print $out $parttable->title();
-
 
640
                                print $out $parttable->rule('-','+');
-
 
641
                        }
-
 
642
                }
455
}
643
        }
-
 
644
        print $out $parttable->rule('-','+');
-
 
645
-
 
646
        $out->close(); 
-
 
647
} #}}}1
456
648
457
Getopt::Long::Configure("bundling");
649
Getopt::Long::Configure("bundling");
458
650
459
if (scalar @ARGV == 0) {
651
if (scalar @ARGV == 0) {
460
        Help_Show();
652
        Help_Show();
Line 464... Line 656...
464
my $result = Getopt::Long::GetOptions (
656
my $result = Getopt::Long::GetOptions (
465
        "showrc|showconf" => sub { $show_conf = 1 },
657
        "showrc|showconf" => sub { $show_conf = 1 },
466
        "docdir|d=s" => sub { $Config{docdir} = $_[1]; },
658
        "docdir|d=s" => sub { $Config{docdir} = $_[1]; },
467
        # not sure if bomdir or SCH dir
659
        # not sure if bomdir or SCH dir
468
        "bomdir|b=s" => sub { $Config{$_[0]} = $_[1]; },  # $_[0] contain basename of option, so in few cases could be (ab)used
660
        "bomdir|b=s" => sub { $Config{$_[0]} = $_[1]; },  # $_[0] contain basename of option, so in few cases could be (ab)used
469
        "define|D=s" => sub { my ($p,$q) = split(/=/,$_[1],2); $Config{$p} = $q; },
661
        "define|D=s" => sub { my ($p,$q) = split(/=/,$_[1],2); $Config{$p} = ($q||1); },
470
        "verbose|v:+" => sub { $Config{$_[0]} = ($_[1]>1?0:$Config{$_[0]}) + $_[1]; },
662
        "verbose|v:+" => \$Config{'verbose'},
471
        "help|h|?:s" => sub { $show_help = 1; },
663
        "help|h|?:s" => sub { $show_help = 1; },
472
        "outfile|o=s" => sub { $Config{$_[0]} = $_[1]; },
664
        "outfile|o=s" => sub { $Config{$_[0]} = $_[1]; },
473
        "force|f" => sub { $Config{$_[0]} = 1 },
665
        "force|f" => sub { $Config{$_[0]} = 1 },
474
        "lines|l=i" => sub { $Config{$_[0]} = abs(int($_[1]));},
666
        "lines|l=i" => sub { $Config{$_[0]} = abs(int($_[1]));},
475
667
Line 496... Line 688...
496
        Config_Show();
688
        Config_Show();
497
        exit;
689
        exit;
498
}
690
}
499
691
500
# make Inventory
692
# make Inventory
501
printf STDERR "Indexing information.txt (under %s)\n",shortdir($Config{docdir});
693
nfo_printf("Fetching data from information.txt (under %s)",shortdir($Config{docdir}));
502
file_lookup($Config{docdir}, 0, qr/\/information.txt$/, \&parse_ifile);
694
file_lookup($Config{docdir}, 0, qr/\/information.txt$/, \&parse_ifile);
503
printf STDERR "\tFinished, %d entries loaded\n", scalar(@Inv)+1;
695
nfo_printf("Finished, %d entries loaded.", scalar(@Inv)+1);
504
696
505
# process BOM files
697
# process BOM files
506
printf STDERR "Loading bom data from %s\n", shortdir($Config{bomdir});
698
nfo_printf("Fetching BOM data from %s", shortdir($Config{bomdir}));
507
file_lookup($Config{bomdir}, 0, qr/\.bom$/, \&parse_bom);
699
file_lookup($Config{bomdir}, 0, qr/\.bom$/, \&parse_bom);
508
printf STDERR "\tLoaded, now processing\n";
700
nfo_printf("Finished, %d entries loaded.", scalar keys %BomData);
509
-
 
510
my ($bn,$pn) = (1,1);
-
 
511
my $cost = 0.0;
-
 
512
701
513
my $out;
-
 
514
if (!defined $Config{outfile}) {
702
if (!defined $Config{outfile}) {
515
        $Config{outfile} = './output.txt';
703
        $Config{outfile} = './output';
516
        wrn_printf("Output file not specified, saving out in ".$Config{outfile});
704
        wrn_printf("Output file not specified, saving out in ".$Config{outfile});
517
}
705
}
518
706
519
if ( -e $Config{outfile}) {
707
if ($Config{outfile} =~ /^(.*)\.txt$/) {
520
        unless (defined $Config{force} && $Config{force} == 1) {
-
 
521
                inf_printf("Unlinking output.txt before owrewriting");
-
 
522
                unlink($Config{outfile});
708
        $Config{outfile} = $1;
523
        } else {
-
 
524
                wrn_printf("Output file already exist, add --force if i shall overwrite it");
709
        inf_printf("Please specify output name without extension, -bom.txt and -map.txt will be added automatically");
525
                exit;
-
 
526
        }
-
 
527
}
710
}
528
711
529
$out = new IO::File $Config{outfile}, 'w';
712
gen_bomfile($Config{'outfile'}.'-bom.txt');
530
713
531
my $bomtable = Text::Table->new(
-
 
532
        { title => '| ', is_sep => 1 },
-
 
533
        { title => 'id', align => 'right', align_title => 'left' },
-
 
534
        { title => ' | ', is_sep => 1 },
-
 
535
        { title => 'description', align => 'left', align_title => 'left' },
-
 
536
        { title => ' | ', is_sep => 1 },
-
 
537
        { title => 'manufacturer partid', align => 'left', align_title => 'left' },
-
 
538
        { title => ' | ', is_sep => 1 },
-
 
539
        { title => 'manufacturer', align => 'left', align_title => 'left' },
-
 
540
        { title => ' | ', is_sep => 1 },
-
 
541
        { title => 'order code', align => 'left', align_title => 'left' },
-
 
542
        { title => ' | ', is_sep => 1 },
-
 
543
        { title => 'quantity', align => 'right', align_title => 'left' },
-
 
544
        { title => ' | ', is_sep => 1 },
-
 
545
        { title => "price", align => 'right', align_title => 'left' },
-
 
546
        { title => ' | ', is_sep => 1 },
-
 
547
        { title => "cost", align => 'right', align_title => 'left' },
-
 
548
        { title => ' |', is_sep => 1 },
-
 
549
);
-
 
550
-
 
551
my $parttable = Text::Table->new(
-
 
552
        { title => '| ', is_sep => 1 },
-
 
553
        { title => 'id', align => 'right', align_title => 'center' },
-
 
554
        { title => ' | ', is_sep => 1 },
-
 
555
        { title => 'description', align => 'left', align_title => 'center' },
-
 
556
        { title => ' | ', is_sep => 1 },
-
 
557
        { title => 'manufacturer partid', align => 'left', align_title => 'center' },
-
 
558
        { title => ' | ', is_sep => 1 },
-
 
559
        { title => 'footprint', align => 'left', align_title => 'center' },
-
 
560
        { title => ' | ', is_sep => 1 },
-
 
561
        { title => 'refdes', align => 'left', align_title => 'center' },
-
 
562
        { title => ' | ', is_sep => 1 },
-
 
563
        { title => 'sheet', align => 'left', align_title => 'center' },
-
 
564
        { title => ' |', is_sep => 1 },
-
 
565
);
-
 
566
               
-
 
567
foreach my $id ( sort {my $p = $Inv[$a]{Manufacturer} cmp $Inv[$b]{Manufacturer}; if ($p == 0) {
-
 
568
#               return $Inv[$a]{Manufacturer_Partno} cmp $Inv[$b]{Manufacturer_Partno}}; return $p; }  keys %BomData) {
-
 
569
                return $Inv[$a]{Description} cmp $Inv[$b]{Description}}; return $p; }  keys %BomData) {
-
 
570
        my %tmp;
-
 
571
        map { $tmp{$_} = 1 } @{$BomData{$id}{RefDes}};
-
 
572
        @{$BomData{$id}{RefDes}} = keys %tmp;
-
 
573
        my $quant = scalar @{$BomData{$id}{RefDes}};
-
 
574
        my $price = get_price($id,$quant);
714
gen_mapfile($Config{'outfile'}.'-map.txt');
575
        if ($price == 0) {
-
 
576
                wrn_printf("%s has zero price", $Inv[$id]{Manufacturer_Partno});
-
 
577
        }
-
 
578
        my $icost = $quant * $price;
-
 
579
               
-
 
580
#       printf PARTMAP "%-35s|%s\n", shortstring($Inv[$id]{Description},35), join (', ', sort @{$BomData{$id}{RefDes}});
-
 
581
        $cost += $icost;
-
 
582
#       %BomData{ById}{$id}{RefDes}
-
 
583
#       $bomtable->add(' '.$n.' ', $Inv[$id]{Description}.' ', $Inv[$id]{Manufacturer_Partno}.' ', $Inv[$id]{Manufacturer}.' ',
-
 
584
#               $Inv[$id]{Ordercode}.' ', ' '.$quant.' ', sprintf("%.3f ",$Inv[$id]{Price}), sprintf("%.3f ",$icost));
-
 
585
        $bomtable->add($bn++, $Inv[$id]{Description}, $Inv[$id]{Manufacturer_Partno}, $Inv[$id]{Manufacturer},
-
 
586
                $Inv[$id]{Ordercode},$quant, sprintf("%.3f",$price), sprintf("%.3f",$icost));
-
 
587
       
-
 
588
#       $parttable->add($pn++, $Inv[$id]{Description}, $Inv[$id]{Manufacturer_Partno}, $BomData{$id}{Footprint}, 
-
 
589
#               strbreak(join (', ', sort @{$BomData{$id}{RefDes}}),43), join("\n",@{$BomData{$id}{Files}}));
-
 
590
}
-
 
591
715
-
 
716
nfo_printf("Script finished, output saved in %s-{map,bom}.txt", $Config{outfile});
592
717
593
printf $out "file generated at %s\n\n", scalar localtime(time());
-
 
594
-
 
595
print $out $bomtable->rule('-','+');
-
 
596
print $out $bomtable->title();
-
 
597
print $out $bomtable->rule('-','+');
-
 
598
unless (defined $Config{'lines'}) {
-
 
599
        print $out $bomtable->body();
-
 
600
} else {
718
__END__
601
        my @p = split(/\n/,$bomtable->body());
-
 
602
        while (@p) {
-
 
603
                my @sub = splice @p,0,$Config{'lines'};
-
 
604
                print $out join("\n",@sub)."\n";
-
 
605
                if (scalar @p > 0) {
-
 
606
                        print $out $bomtable->rule('-','+');
-
 
607
                        print $out $bomtable->title();
-
 
608
                        print $out $bomtable->rule('-','+');
-
 
609
                }
-
 
610
        }
-
 
611
}
-
 
612
print $out $bomtable->rule('-','+');
-
 
613
-
 
614
printf $out "\nTotal cost: %.3f\n\n\n", $cost;
-
 
615
-
 
616
-
 
617
$pn = 1;
-
 
618
foreach my $fkey (sort keys %Files) {
-
 
619
        my $rowblock = 0;
-
 
620
        foreach my $id ( sort {my $p = $Inv[$a]{Manufacturer} cmp $Inv[$b]{Manufacturer}; if ($p == 0) {
-
 
621
                return $Inv[$a]{Description} cmp $Inv[$b]{Description}}; return $p; }  keys %{$Files{$fkey}}) {
-
 
622
719
623
                my @p = split(/\n/, strbreak(join (', ', sort @{$Files{$fkey}{$id}{RefDes}}),43));
-
 
624
                while (@p) {
720
        if ( -e $Config{outfile}) {
625
                        $parttable->add($pn, $Inv[$id]{Description}, $Inv[$id]{Manufacturer_Partno}, $BomData{$id}{Footprint},
-
 
626
                                etrim(trim(shift @p)), $fkey);
721
                unless (defined $Config{force} && $Config{force} == 1) {
627
                }
-
 
628
-
 
629
                $pn++;
-
 
630
        }
-
 
631
        $parttable->add('--','=========','==========','==========','==========','==========');
-
 
632
}
-
 
633
-
 
634
print $out $parttable->rule('-','+');
-
 
635
print $out $parttable->title();
-
 
636
print $out $parttable->rule('-','+');
722
                        inf_printf("Unlinking output.txt before owrewriting");
637
unless (defined $Config{'lines'}) {
723
                        unlink($Config{outfile});
638
        print $out $parttable->body();
-
 
639
} else {
724
                } else {
640
        my @p = split(/\n/,$parttable->body());
725
                        wrn_printf("Output file already exist, add --force if i shall overwrite it");
641
        while (@p) {
726
                        exit;
642
                my @sub = splice @p,0,$Config{'lines'};
-
 
643
                print $out join("\n",@sub)."\n";
-
 
644
                if (scalar @p > 0) {
-
 
645
                        print $out $parttable->rule('-','+');
-
 
646
                        print $out $parttable->title();
-
 
647
                        print $out $parttable->rule('-','+');
-
 
648
                }
727
                }
649
        }
728
        }
650
}
-
 
651
print $out $parttable->rule('-','+');
-
 
652
-
 
653
-
 
654
#close PARTMAP;
-
 
655
-
 
656
printf STDERR "\tFinished, output saved in %s\n", $Config{outfile};
-