View | Details | Raw Unified | Return to bug 37356
Collapse All | Expand All

(-)a/C4/Barcodes/Drawer.pm (+159 lines)
Line 0 Link Here
1
package C4::Barcodes::Drawer;
2
3
# Copyright 2024 Koha Development Team
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
=head1 NAME
23
24
C4::Barcodes::Drawer - Common Barcode Drawer
25
26
=head1 SYNOPSIS
27
28
use C4::Barcodes::Drawer;
29
30
C4::Barcodes::Drawer::draw_barcode();
31
32
=head1 FUNCTIONS
33
34
=head2 draw_barcode()
35
36
    Invoking the I<draw_barcode> method generates a barcode for the label object and inserts it into the current pdf stream. This method accepts the following parameters as key => value
37
    pairs (C<barcode_data> is optional and omitting it will cause the barcode from the current item to be used. C<barcode_type> is also optional. Omission results in the barcode
38
    type of the current template being used.):
39
40
        C<llx>                  The lower-left x coordinate for the barcode block (The point of origin for all PDF's is the lower left of the page per ISO 32000-1)
41
        C<lly>                  The lower-left y coordinate for the barcode block
42
        C<width>                The width of the barcode block
43
        C<y_scale_factor>       The scale factor to be applied to the y axis of the barcode block
44
        C<barcode_data>         The data to be encoded in the barcode
45
        C<barcode_type>         The barcode type (See the C<new()> method for supported barcode types)
46
47
    example:
48
       C<$label->barcode(
49
                    llx                 => $barcode_llx,
50
                    lly                 => $barcode_lly,
51
                    width               => $barcode_width,
52
                    y_scale_factor      => $barcode_y_scale_factor,
53
                    barcode_data        => $barcode,
54
                    barcode_type        => $barcodetype,
55
        );>
56
57
=cut
58
59
sub draw_barcode {
60
    my $self = shift;
61
    my %params = @_;
62
    #    $params{'barcode_data'} = ($self->{'barcode'} || _get_label_item($self->{'item_number'}, 1)) if !$params{'barcode_data'};
63
    $params{'barcode_type'} = $self->{'barcode_type'} if !$params{'barcode_type'};
64
    my $x_scale_factor = 1;
65
    my $num_of_bars = length($params{'barcode_data'});
66
    my $tot_bar_length = 0;
67
    my $bar_length = 0;
68
    my $guard_length = 10;
69
    my $hide_text = 'yes';
70
    if ($params{'barcode_type'} =~ m/CODE39/) {
71
        $bar_length = '17.5';
72
        $tot_bar_length = ($bar_length * $num_of_bars) + ($guard_length * 2);
73
        $x_scale_factor = ($params{'width'} / $tot_bar_length);
74
        if ($params{'barcode_type'} eq 'CODE39MOD') {
75
            my $c39 = CheckDigits('code_39');   # get modulo43 checksum
76
            $params{'barcode_data'} = $c39->complete($params{'barcode_data'});
77
        }
78
        elsif ($params{'barcode_type'} eq 'CODE39MOD10') {
79
            my $c39_10 = CheckDigits('siret');   # get modulo43 checksum
80
            $params{'barcode_data'} = $c39_10->complete($params{'barcode_data'});
81
            $hide_text = '';
82
        }
83
        eval {
84
            PDF::Reuse::Barcode::Code39(
85
                x                   => $params{'llx'},
86
                y                   => $params{'lly'},
87
                value               => "*$params{barcode_data}*",
88
                xSize               => $x_scale_factor,
89
                ySize               => $params{'y_scale_factor'},
90
                hide_asterisk       => 1,
91
                text                => $hide_text,
92
                mode                => 'graphic',
93
            );
94
        };
95
        if ($@) {
96
            warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@);
97
        }
98
    }
99
    elsif ($params{'barcode_type'} eq 'COOP2OF5') {
100
        $bar_length = '9.43333333333333';
101
        $tot_bar_length = ($bar_length * $num_of_bars) + ($guard_length * 2);
102
        $x_scale_factor = ($params{'width'} / $tot_bar_length) * 0.9;
103
        eval {
104
            PDF::Reuse::Barcode::COOP2of5(
105
                x                   => $params{'llx'},
106
                y                   => $params{'lly'},
107
                value               => $params{barcode_data},
108
                xSize               => $x_scale_factor,
109
                ySize               => $params{'y_scale_factor'},
110
                mode                    => 'graphic',
111
            );
112
        };
113
        if ($@) {
114
            warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@);
115
        }
116
    }
117
    elsif ( $params{'barcode_type'} eq 'INDUSTRIAL2OF5' ) {
118
        $bar_length = '13.1333333333333';
119
        $tot_bar_length = ($bar_length * $num_of_bars) + ($guard_length * 2);
120
        $x_scale_factor = ($params{'width'} / $tot_bar_length) * 0.9;
121
        eval {
122
            PDF::Reuse::Barcode::Industrial2of5(
123
                x                   => $params{'llx'},
124
                y                   => $params{'lly'},
125
                value               => $params{barcode_data},
126
                xSize               => $x_scale_factor,
127
                ySize               => $params{'y_scale_factor'},
128
                mode                    => 'graphic',
129
            );
130
        };
131
        if ($@) {
132
            warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@);
133
        }
134
    }
135
    elsif ($params{'barcode_type'} eq 'EAN13') {
136
        $bar_length = 4; # FIXME
137
    $num_of_bars = 13;
138
        $tot_bar_length = ($bar_length * $num_of_bars) + ($guard_length * 2);
139
        $x_scale_factor = ($params{'width'} / $tot_bar_length) * 0.9;
140
        eval {
141
            PDF::Reuse::Barcode::EAN13(
142
                x                   => $params{'llx'},
143
                y                   => $params{'lly'},
144
                value               => sprintf('%013d',$params{barcode_data}),
145
#                xSize               => $x_scale_factor,
146
#                ySize               => $params{'y_scale_factor'},
147
                mode                    => 'graphic',
148
            );
149
        };
150
        if ($@) {
151
            warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@);
152
        }
153
    }
154
    else {
155
    warn "unknown barcode_type: $params{barcode_type}";
156
    }
157
}
158
159
1;
(-)a/C4/Labels/Label.pm (-124 / +3 lines)
Lines 14-19 use Koha::Biblios; Link Here
14
use Koha::ClassSources;
14
use Koha::ClassSources;
15
use Koha::ClassSortRules;
15
use Koha::ClassSortRules;
16
use Koha::ClassSplitRules;
16
use Koha::ClassSplitRules;
17
use C4::Barcodes::Drawer;
17
use C4::ClassSplitRoutine::Dewey;
18
use C4::ClassSplitRoutine::Dewey;
18
use C4::ClassSplitRoutine::LCC;
19
use C4::ClassSplitRoutine::LCC;
19
use C4::ClassSplitRoutine::Generic;
20
use C4::ClassSplitRoutine::Generic;
Lines 353-363 sub create_label { Link Here
353
                                    );
354
                                    );
354
    }
355
    }
355
    if ($self->{'printing_type'} =~ /BAR/) {
356
    if ($self->{'printing_type'} =~ /BAR/) {
356
        barcode(    $self,
357
        C4::Barcodes::Drawer::draw_barcode(    $self,
357
                    llx                 => $barcode_llx,
358
                    llx                 => $barcode_llx,
358
                    lly                 => $barcode_lly,
359
                    lly                 => $barcode_lly,
359
                    width               => $barcode_width,
360
                    width               => $barcode_width,
360
                    y_scale_factor      => $barcode_y_scale_factor,
361
                    y_scale_factor      => $barcode_y_scale_factor,
362
                    barcode_data        => $self->{'barcode'} || _get_label_item($self->{'item_number'}, 1),
361
        );
363
        );
362
    }
364
    }
363
    return $label_text if $label_text;
365
    return $label_text if $label_text;
Lines 486-591 sub draw_guide_box { Link Here
486
    return $_[0]->{'guidebox'};
488
    return $_[0]->{'guidebox'};
487
}
489
}
488
490
489
sub barcode {
490
    my $self = shift;
491
    my %params = @_;
492
    $params{'barcode_data'} = ($self->{'barcode'} || _get_label_item($self->{'item_number'}, 1)) if !$params{'barcode_data'};
493
    $params{'barcode_type'} = $self->{'barcode_type'} if !$params{'barcode_type'};
494
    my $x_scale_factor = 1;
495
    my $num_of_bars = length($params{'barcode_data'});
496
    my $tot_bar_length = 0;
497
    my $bar_length = 0;
498
    my $guard_length = 10;
499
    my $hide_text = 'yes';
500
    if ($params{'barcode_type'} =~ m/CODE39/) {
501
        $bar_length = '17.5';
502
        $tot_bar_length = ($bar_length * $num_of_bars) + ($guard_length * 2);
503
        $x_scale_factor = ($params{'width'} / $tot_bar_length);
504
        if ($params{'barcode_type'} eq 'CODE39MOD') {
505
            my $c39 = CheckDigits('code_39');   # get modulo43 checksum
506
            $params{'barcode_data'} = $c39->complete($params{'barcode_data'});
507
        }
508
        elsif ($params{'barcode_type'} eq 'CODE39MOD10') {
509
            my $c39_10 = CheckDigits('siret');   # get modulo43 checksum
510
            $params{'barcode_data'} = $c39_10->complete($params{'barcode_data'});
511
            $hide_text = '';
512
        }
513
        eval {
514
            PDF::Reuse::Barcode::Code39(
515
                x                   => $params{'llx'},
516
                y                   => $params{'lly'},
517
                value               => "*$params{barcode_data}*",
518
                xSize               => $x_scale_factor,
519
                ySize               => $params{'y_scale_factor'},
520
                hide_asterisk       => 1,
521
                text                => $hide_text,
522
                mode                => 'graphic',
523
            );
524
        };
525
        if ($@) {
526
            warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@);
527
        }
528
    }
529
    elsif ($params{'barcode_type'} eq 'COOP2OF5') {
530
        $bar_length = '9.43333333333333';
531
        $tot_bar_length = ($bar_length * $num_of_bars) + ($guard_length * 2);
532
        $x_scale_factor = ($params{'width'} / $tot_bar_length) * 0.9;
533
        eval {
534
            PDF::Reuse::Barcode::COOP2of5(
535
                x                   => $params{'llx'},
536
                y                   => $params{'lly'},
537
                value               => $params{barcode_data},
538
                xSize               => $x_scale_factor,
539
                ySize               => $params{'y_scale_factor'},
540
                mode                    => 'graphic',
541
            );
542
        };
543
        if ($@) {
544
            warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@);
545
        }
546
    }
547
    elsif ( $params{'barcode_type'} eq 'INDUSTRIAL2OF5' ) {
548
        $bar_length = '13.1333333333333';
549
        $tot_bar_length = ($bar_length * $num_of_bars) + ($guard_length * 2);
550
        $x_scale_factor = ($params{'width'} / $tot_bar_length) * 0.9;
551
        eval {
552
            PDF::Reuse::Barcode::Industrial2of5(
553
                x                   => $params{'llx'},
554
                y                   => $params{'lly'},
555
                value               => $params{barcode_data},
556
                xSize               => $x_scale_factor,
557
                ySize               => $params{'y_scale_factor'},
558
                mode                    => 'graphic',
559
            );
560
        };
561
        if ($@) {
562
            warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@);
563
        }
564
    }
565
    elsif ($params{'barcode_type'} eq 'EAN13') {
566
        $bar_length = 4; # FIXME
567
    $num_of_bars = 13;
568
        $tot_bar_length = ($bar_length * $num_of_bars) + ($guard_length * 2);
569
        $x_scale_factor = ($params{'width'} / $tot_bar_length) * 0.9;
570
        eval {
571
            PDF::Reuse::Barcode::EAN13(
572
                x                   => $params{'llx'},
573
                y                   => $params{'lly'},
574
                value               => sprintf('%013d',$params{barcode_data}),
575
#                xSize               => $x_scale_factor,
576
#                ySize               => $params{'y_scale_factor'},
577
                mode                    => 'graphic',
578
            );
579
        };
580
        if ($@) {
581
            warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@);
582
        }
583
    }
584
    else {
585
    warn "unknown barcode_type: $params{barcode_type}";
586
    }
587
}
588
589
sub csv_data {
491
sub csv_data {
590
    my $self = shift;
492
    my $self = shift;
591
    my $label_fields = _get_text_fields($self->{'format_string'});
493
    my $label_fields = _get_text_fields($self->{'format_string'});
Lines 776-804 R = Right Link Here
776
                                                justify             => $text_justification,
678
                                                justify             => $text_justification,
777
                        );>
679
                        );>
778
680
779
=head2 barcode()
780
781
    Invoking the I<barcode> method generates a barcode for the label object and inserts it into the current pdf stream. This method accepts the following parameters as key => value
782
    pairs (C<barcode_data> is optional and omitting it will cause the barcode from the current item to be used. C<barcode_type> is also optional. Omission results in the barcode
783
    type of the current template being used.):
784
785
        C<llx>                  The lower-left x coordinate for the barcode block (The point of origin for all PDF's is the lower left of the page per ISO 32000-1)
786
        C<lly>                  The lower-left y coordinate for the barcode block
787
        C<width>                The width of the barcode block
788
        C<y_scale_factor>       The scale factor to be applied to the y axis of the barcode block
789
        C<barcode_data>         The data to be encoded in the barcode
790
        C<barcode_type>         The barcode type (See the C<new()> method for supported barcode types)
791
792
    example:
793
       C<$label->barcode(
794
                    llx                 => $barcode_llx,
795
                    lly                 => $barcode_lly,
796
                    width               => $barcode_width,
797
                    y_scale_factor      => $barcode_y_scale_factor,
798
                    barcode_data        => $barcode,
799
                    barcode_type        => $barcodetype,
800
        );>
801
802
=head2 csv_data()
681
=head2 csv_data()
803
682
804
    Invoking the I<csv_data> method returns an arrayref of an array containing the label data suitable for passing to Text::CSV_XS->combine() to produce csv output.
683
    Invoking the I<csv_data> method returns an arrayref of an array containing the label data suitable for passing to Text::CSV_XS->combine() to produce csv output.
(-)a/C4/Patroncards/Patroncard.pm (-85 / +2 lines)
Lines 23-28 use warnings; Link Here
23
use autouse 'Data::Dumper' => qw(Dumper);
23
use autouse 'Data::Dumper' => qw(Dumper);
24
#use Font::TTFMetrics;
24
#use Font::TTFMetrics;
25
25
26
use C4::Barcodes::Drawer;
26
use C4::Creators::Lib qw( get_unit_values );
27
use C4::Creators::Lib qw( get_unit_values );
27
use C4::Creators::PDF qw(StrWidth);
28
use C4::Creators::PDF qw(StrWidth);
28
use C4::Patroncards::Lib qw(
29
use C4::Patroncards::Lib qw(
Lines 100-106 sub draw_barcode { Link Here
100
    my $llx_layout           = $self->{'layout'}->{'barcode'}->[0]->{'llx'} || 0;
101
    my $llx_layout           = $self->{'layout'}->{'barcode'}->[0]->{'llx'} || 0;
101
    my $lly                  = $self->{'lly'} || 0;
102
    my $lly                  = $self->{'lly'} || 0;
102
    my $lly_layout           = $self->{'layout'}->{'barcode'}->[0]->{'lly'} || 0;
103
    my $lly_layout           = $self->{'layout'}->{'barcode'}->[0]->{'lly'} || 0;
103
    _draw_barcode(
104
    C4::Barcodes::Drawer::draw_barcode(
104
        $self,
105
        $self,
105
        llx            => $llx + $llx_layout * $self->{'unitvalue'},
106
        llx            => $llx + $llx_layout * $self->{'unitvalue'},
106
        lly            => $lly + $lly_layout * $self->{'unitvalue'},
107
        lly            => $lly + $lly_layout * $self->{'unitvalue'},
Lines 378-466 sub draw_image { Link Here
378
    }
379
    }
379
}
380
}
380
381
381
=head2 draw_barcode
382
383
    $patron_card->draw_barcode($pdf)
384
385
Draws a barcode to PDF output ($pdf)
386
387
=cut
388
389
sub _draw_barcode {   # this is cut-and-paste from Label.pm because there is no common place for it atm...
390
    my $self = shift;
391
    my %params = @_;
392
393
    my $x_scale_factor = 1;
394
    my $num_of_chars = length($params{'barcode_data'});
395
    my $tot_bar_length = 0;
396
    my $bar_length = 0;
397
    my $guard_length = 10;
398
    if ($params{'barcode_type'} =~ m/CODE39/) {
399
        $bar_length = '17.5';
400
        $tot_bar_length = ($bar_length * $num_of_chars) + ($guard_length * 2);  # not sure what all is going on here and on the next line; this is old (very) code
401
        $x_scale_factor = ($params{'width'} / $tot_bar_length);
402
        if ($params{'barcode_type'} eq 'CODE39MOD') {
403
            my $c39 = CheckDigits('code_39');   # get modulo 43 checksum
404
            $params{'barcode_data'} = $c39->complete($params{'barcode_data'});
405
        }
406
        elsif ($params{'barcode_type'} eq 'CODE39MOD10') {
407
            my $c39_10 = CheckDigits('siret');   # get modulo 10 checksum
408
            $params{'barcode_data'} = $c39_10->complete($params{'barcode_data'});
409
        }
410
        eval {
411
            PDF::Reuse::Barcode::Code39(
412
                x                   => $params{'llx'},
413
                y                   => $params{'lly'},
414
                value               => "*$params{barcode_data}*",
415
                xSize               => $x_scale_factor,
416
                ySize               => $params{'y_scale_factor'},
417
                hide_asterisk       => 1,
418
                text                => $params{'text'},
419
                mode                => 'graphic',
420
            );
421
        };
422
        if ($@) {
423
            warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@);
424
        }
425
    }
426
    elsif ($params{'barcode_type'} eq 'COOP2OF5') {
427
        $bar_length = '9.43333333333333';
428
        $tot_bar_length = ($bar_length * $num_of_chars) + ($guard_length * 2);
429
        $x_scale_factor = ($params{'width'} / $tot_bar_length) * 0.9;
430
        eval {
431
            PDF::Reuse::Barcode::COOP2of5(
432
                x                   => $params{'llx'},
433
                y                   => $params{'lly'},
434
                value               => $params{barcode_data},
435
                xSize               => $x_scale_factor,
436
                ySize               => $params{'y_scale_factor'},
437
                mode                    => 'graphic',
438
            );
439
        };
440
        if ($@) {
441
            warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@);
442
        }
443
    }
444
    elsif ( $params{'barcode_type'} eq 'INDUSTRIAL2OF5' ) {
445
        $bar_length = '13.1333333333333';
446
        $tot_bar_length = ($bar_length * $num_of_chars) + ($guard_length * 2);
447
        $x_scale_factor = ($params{'width'} / $tot_bar_length) * 0.9;
448
        eval {
449
            PDF::Reuse::Barcode::Industrial2of5(
450
                x                   => $params{'llx'},
451
                y                   => $params{'lly'},
452
                value               => $params{barcode_data},
453
                xSize               => $x_scale_factor,
454
                ySize               => $params{'y_scale_factor'},
455
                mode                    => 'graphic',
456
            );
457
        };
458
        if ($@) {
459
            warn sprintf('Barcode generation failed for item %s with this error: %s', $self->{'item_number'}, $@);
460
        }
461
    }
462
}
463
464
1;
382
1;
465
__END__
383
__END__
466
384
467
- 

Return to bug 37356