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

(-)a/C4/Barcodes.pm (+2 lines)
Lines 27-32 use C4::Barcodes::hbyymmincr; Link Here
27
use C4::Barcodes::annual;
27
use C4::Barcodes::annual;
28
use C4::Barcodes::incremental;
28
use C4::Barcodes::incremental;
29
use C4::Barcodes::EAN13;
29
use C4::Barcodes::EAN13;
30
use C4::Barcodes::preyymmddts;
30
31
31
use vars qw($max $prefformat);
32
use vars qw($max $prefformat);
32
33
Lines 174-179 our $types = { Link Here
174
    hbyymmincr  => sub { C4::Barcodes::hbyymmincr->new_object(@_); },
175
    hbyymmincr  => sub { C4::Barcodes::hbyymmincr->new_object(@_); },
175
    OFF         => sub { C4::Barcodes::OFF->new_object(@_); },
176
    OFF         => sub { C4::Barcodes::OFF->new_object(@_); },
176
    EAN13       => sub { C4::Barcodes::EAN13->new_object(@_); },
177
    EAN13       => sub { C4::Barcodes::EAN13->new_object(@_); },
178
    preyymmddts => sub { C4::Barcodes::preyymmddts->new_object(@_); },
177
};
179
};
178
180
179
sub new {
181
sub new {
(-)a/C4/Barcodes/ValueBuilder.pm (+54 lines)
Lines 92-97 sub get_barcode { Link Here
92
    return $nextnum;
92
    return $nextnum;
93
}
93
}
94
94
95
package C4::Barcodes::ValueBuilder::preyymmddts;
96
use C4::Context;
97
use YAML::XS;
98
use Time::HiRes qw(time);
99
use POSIX qw(strftime);
100
my $DEBUG = 0;
101
102
sub get_barcode {
103
    my ($args) = @_;
104
    my $nextnum;
105
    my $barcode;
106
    my $branchcode = $args->{branchcode};
107
    my $query;
108
    my $sth;
109
110
    # Getting the barcodePrefixes
111
    my $branchPrefixes = C4::Context->preference("BarcodePrefix");
112
    my $yaml           = YAML::XS::Load(
113
        Encode::encode(
114
            'UTF-8',
115
            $branchPrefixes,
116
            Encode::FB_CROAK
117
        )
118
    );
119
120
    my $prefix = $yaml->{$branchcode} || $yaml->{'Default'};
121
    my $date   = strftime "%H%M%S", localtime;
122
    my $year   = substr( $args->{year}, -2 );
123
    $query = "SELECT MAX(CAST(SUBSTRING(barcode,-1) AS signed)) from items where barcode REGEXP ?";
124
    $sth   = C4::Context->dbh->prepare($query);
125
    $sth->execute("^$prefix$year$args->{mon}$args->{day}$date");
126
127
    while ( my ($count) = $sth->fetchrow_array ) {
128
        $nextnum = $count if $count;
129
        $nextnum = 0      if $nextnum && $nextnum == 9;
130
    }
131
132
    $nextnum++;
133
    $barcode = $prefix . $year . $args->{mon} . $args->{day} . $date . $nextnum;
134
135
    my $scr = qq~
136
        let elt = \$("#"+id);
137
        let branchcode = elt.parents('fieldset.rows:first')
138
                            .find('input[name="kohafield"][value="items.homebranch"]')
139
                            .siblings("select")
140
                            .val();
141
        if ( \$(elt).val() == '' ) {
142
            \$(elt).val('$barcode');
143
        }
144
    ~;
145
146
    return $barcode, $scr;
147
}
148
95
1;
149
1;
96
150
97
=head1 Barcodes::ValueBuilder
151
=head1 Barcodes::ValueBuilder
(-)a/C4/Barcodes/preyymmddts.pm (+114 lines)
Line 0 Link Here
1
package C4::Barcodes::preyymmddts;
2
3
# Copyright 2022 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 strict;
21
use warnings;
22
23
use Carp qw( carp );
24
25
use C4::Context;
26
27
use Koha::DateUtils qw( dt_from_string output_pref );
28
use POSIX qw( strftime );
29
30
use vars qw(@ISA);
31
32
BEGIN {
33
    @ISA = qw(C4::Barcodes);
34
}
35
36
sub new_object {
37
    my $class = shift;
38
    my $type  = ref($class) || $class;
39
    my $self  = $type->default_self('preyymmddts');
40
41
    my $branchcode     = C4::Context->userenv->{'branch'};
42
    my $branchPrefixes = C4::Context->preference("BarcodePrefix");
43
    my $yaml           = YAML::XS::Load(
44
        Encode::encode(
45
            'UTF-8',
46
            $branchPrefixes,
47
            Encode::FB_CROAK
48
        )
49
    );
50
    my $prefix = $yaml->{$branchcode} || $yaml->{'Default'};
51
52
    $self->{prefix}   = $prefix;
53
    $self->{datetime} = output_pref( { dt => dt_from_string, dateformat => 'iso', dateonly => 1 } );
54
55
    return bless $self, $type;
56
}
57
58
sub initial {
59
    my $self = shift;
60
61
    return get_head($self) . '1';
62
}
63
64
sub db_max {
65
    my $self = shift;
66
67
    my $barcode = get_head($self);
68
69
    my $query = "SELECT MAX(CAST(SUBSTRING(barcode,-1) AS signed)) from items where barcode REGEXP ?";
70
    my $sth   = C4::Context->dbh->prepare($query);
71
    $sth->execute("^$barcode");
72
73
    my $nextnum;
74
    while ( my ($count) = $sth->fetchrow_array ) {
75
        $nextnum = $count if $count;
76
        $nextnum = 0      if $nextnum && $nextnum == 9;
77
    }
78
79
    return $nextnum;
80
}
81
82
sub parse {
83
    my $self = shift;
84
85
    my $head    = get_head($self);
86
    my $incr    = (@_) ? shift : $self->value;
87
    my $barcode = $head . $incr;
88
    unless ($incr) {
89
        carp "Barcode '$barcode' has no incrementing part!";
90
        return ( $barcode, undef, undef );
91
    }
92
93
    return ( $head, $incr, '' );
94
}
95
96
sub get_head {
97
    my $self = shift;
98
99
    my $prefix = $self->{prefix};
100
    my ( $year, $month, $day ) = split( '-', $self->{datetime} );
101
    $year = substr( $year, -2 );
102
    my $date = strftime "%H%M%S", localtime;
103
104
    my $barcode = $prefix . $year . $month . $day . $date;
105
106
    return $barcode;
107
}
108
109
BEGIN {
110
    @ISA = qw(C4::Barcodes);
111
}
112
113
1;
114
__END__
(-)a/cataloguing/additem.pl (-2 / +8 lines)
Lines 426-433 if ( $op eq "cud-additem" ) { Link Here
426
                if ($barcodevalue) {
426
                if ($barcodevalue) {
427
427
428
                    # Getting a new barcode (if it is not the first iteration or the barcode we tried already exists)
428
                    # Getting a new barcode (if it is not the first iteration or the barcode we tried already exists)
429
                    $barcodevalue = $barcodeobj->next_value($oldbarcode)
429
                    if ( C4::Context->preference("autoBarcode") eq 'preyymmddts' ) {
430
                        if ( $i > 0 || $exist_itemnumber );
430
                        my $barcodeobj2 = C4::Barcodes->new('preyymmddts');
431
                        $barcodevalue = $barcodeobj2->value()
432
                            if ( $i > 0 || $exist_itemnumber );
433
                    } else {
434
                        $barcodevalue = $barcodeobj->next_value($oldbarcode)
435
                            if ( $i > 0 || $exist_itemnumber );
436
                    }
431
437
432
                    # Putting it into the record
438
                    # Putting it into the record
433
                    if ($barcodevalue) {
439
                    if ($barcodevalue) {
(-)a/cataloguing/value_builder/barcode.pl (+4 lines)
Lines 47-52 my $builder = sub { Link Here
47
    # find today's date
47
    # find today's date
48
    ( $args{year}, $args{mon}, $args{day} ) = split( '-', dt_from_string()->ymd() );
48
    ( $args{year}, $args{mon}, $args{day} ) = split( '-', dt_from_string()->ymd() );
49
    ( $args{tag}, $args{subfield} ) = GetMarcFromKohaField("items.barcode");
49
    ( $args{tag}, $args{subfield} ) = GetMarcFromKohaField("items.barcode");
50
    ( $args{branchcode} ) = C4::Context->userenv->{'branch'};
50
51
51
    my $nextnum;
52
    my $nextnum;
52
    my $scr;
53
    my $scr;
Lines 82-87 my $builder = sub { Link Here
82
            warn "ERROR: invalid EAN-13 $nextnum, using increment";
83
            warn "ERROR: invalid EAN-13 $nextnum, using increment";
83
            $nextnum++;
84
            $nextnum++;
84
        }
85
        }
86
    } elsif ( $autoBarcodeType eq 'preyymmddts' )
87
    { # Generates a barcode where pre = branch specific prefix set on systempreference BarcodePrefix, yymmdd = year/month/day catalogued, ts = timestamp catalogued
88
        ( $nextnum, $scr ) = C4::Barcodes::ValueBuilder::preyymmddts::get_barcode( \%args );
85
    } else {
89
    } else {
86
        warn "ERROR: unknown autoBarcode: $autoBarcodeType";
90
        warn "ERROR: unknown autoBarcode: $autoBarcodeType";
87
    }
91
    }
(-)a/cataloguing/value_builder/barcode_manual.pl (+4 lines)
Lines 48-53 my $builder = sub { Link Here
48
    # find today's date
48
    # find today's date
49
    ( $args{year}, $args{mon}, $args{day} ) = split( '-', dt_from_string()->ymd() );
49
    ( $args{year}, $args{mon}, $args{day} ) = split( '-', dt_from_string()->ymd() );
50
    ( $args{tag}, $args{subfield} ) = GetMarcFromKohaField("items.barcode");
50
    ( $args{tag}, $args{subfield} ) = GetMarcFromKohaField("items.barcode");
51
    ( $args{branchcode} ) = C4::Context->userenv->{'branch'};
51
52
52
    my $nextnum;
53
    my $nextnum;
53
    my $scr;
54
    my $scr;
Lines 64-69 my $builder = sub { Link Here
64
    } elsif ( $autoBarcodeType eq 'hbyymmincr' )
65
    } elsif ( $autoBarcodeType eq 'hbyymmincr' )
65
    { # Generates a barcode where hb = home branch Code, yymm = year/month catalogued, incr = incremental number, reset yearly -fbcit
66
    { # Generates a barcode where hb = home branch Code, yymm = year/month catalogued, incr = incremental number, reset yearly -fbcit
66
        ( $nextnum, $scr ) = C4::Barcodes::ValueBuilder::hbyymmincr::get_barcode( \%args );
67
        ( $nextnum, $scr ) = C4::Barcodes::ValueBuilder::hbyymmincr::get_barcode( \%args );
68
    } elsif ( $autoBarcodeType eq 'preyymmddts' )
69
    { # Generates a barcode where pre = branch specific prefix set on systempreference BarcodePrefix, yymmdd = year/month/day catalogued, ts = timestamp catalogued
70
        ( $nextnum, $scr ) = C4::Barcodes::ValueBuilder::preyymmddts::get_barcode( \%args );
67
    }
71
    }
68
72
69
    # default js body (if not filled by hbyymmincr)
73
    # default js body (if not filled by hbyymmincr)
(-)a/installer/data/mysql/atomicupdate/bug_30328.pl (+21 lines)
Line 0 Link Here
1
use Modern::Perl;
2
3
return {
4
    bug_number  => "30328",
5
    description => "Add option to create barcode with branch specific prefix",
6
    up          => sub {
7
        my ($args) = @_;
8
        my ( $dbh, $out ) = @$args{qw(dbh out)};
9
10
        # Do you stuffs here
11
        $dbh->do(
12
            q{ UPDATE IGNORE systempreferences SET options = 'incremental|annual|hbyymmincr|EAN13|preyymmddts|OFF' , explanation = 'Used to autogenerate a barcode: incremental will be of the form 1, 2, 3; annual of the form 2007-0001, 2007-0002; hbyymmincr of the form HB08010001 where HB=Home Branch; preyymmddts of the form PRE2021030001 where PRE = branch specific prefix set on systempreference BarcodePrefix' WHERE variable = 'autoBarcode'}
13
        );
14
        $dbh->do(
15
            q{ INSERT IGNORE INTO systempreferences ( variable, value, options, explanation, type ) VALUES ('BarcodePrefix','','','Defines the barcode prefixes when the autoBarcode value is set as preyymmddts','Free')}
16
        );
17
18
        # Print useful stuff here
19
        say $out "Update is going well so far";
20
    },
21
};
(-)a/installer/data/mysql/mandatory/sysprefs.sql (-1 / +2 lines)
Lines 87-93 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
87
('AuthorLinkSortOrder','asc','asc|dsc|az|za','Specify the default sort order for author links','Choice'),
87
('AuthorLinkSortOrder','asc','asc|dsc|az|za','Specify the default sort order for author links','Choice'),
88
('AuthSuccessLog','0',NULL,'If enabled, log successful authentications','YesNo'),
88
('AuthSuccessLog','0',NULL,'If enabled, log successful authentications','YesNo'),
89
('AutoApprovePatronProfileSettings', '0', '', 'Automatically approve patron profile changes from the OPAC.', 'YesNo'),
89
('AutoApprovePatronProfileSettings', '0', '', 'Automatically approve patron profile changes from the OPAC.', 'YesNo'),
90
('autoBarcode','OFF','incremental|annual|hbyymmincr|EAN13|OFF','Used to autogenerate a barcode: incremental will be of the form 1, 2, 3; annual of the form 2007-0001, 2007-0002; hbyymmincr of the form HB08010001 where HB=Home Branch','Choice'),
90
('autoBarcode','OFF','incremental|annual|hbyymmincr|EAN13|preyymmddts|OFF','Used to autogenerate a barcode: incremental will be of the form 1, 2, 3; annual of the form 2007-0001, 2007-0002; hbyymmincr of the form HB08010001 where HB=Home Branch; preyymmddts of the form PRE2021030001 where PRE = branch specific prefix set on systempreference BarcodePrefix','Choice'),
91
('AutoClaimReturnStatusOnCheckin','','NULL','When in use this system preference will automatically resolve the claim return and will update the lost authorized value upon check in.','Free'),
91
('AutoClaimReturnStatusOnCheckin','','NULL','When in use this system preference will automatically resolve the claim return and will update the lost authorized value upon check in.','Free'),
92
('AutoClaimReturnStatusOnCheckout','','NULL','When in use this system preference will automatically resolve the claim return and will update the lost authorized value upon check out.','Free'),
92
('AutoClaimReturnStatusOnCheckout','','NULL','When in use this system preference will automatically resolve the claim return and will update the lost authorized value upon check out.','Free'),
93
('autoControlNumber','OFF','biblionumber|OFF','Used to autogenerate a Control Number: biblionumber will be as biblionumber, OFF will leave the field as it is;','Choice'),
93
('autoControlNumber','OFF','biblionumber|OFF','Used to autogenerate a Control Number: biblionumber will be as biblionumber, OFF will leave the field as it is;','Choice'),
Lines 117-122 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
117
('BakerTaylorEnabled','0','','Enable or disable all Baker & Taylor features.','YesNo'),
117
('BakerTaylorEnabled','0','','Enable or disable all Baker & Taylor features.','YesNo'),
118
('BakerTaylorPassword','','','Baker & Taylor Password for Content Cafe (external content)','Free'),
118
('BakerTaylorPassword','','','Baker & Taylor Password for Content Cafe (external content)','Free'),
119
('BakerTaylorUsername','','','Baker & Taylor Username for Content Cafe (external content)','Free'),
119
('BakerTaylorUsername','','','Baker & Taylor Username for Content Cafe (external content)','Free'),
120
('BarcodePrefix','','','Defines the barcode prefixes when the autoBarcode value is set as preyymmddts','Free'),
120
('BarcodeSeparators','\\s\\r\\n','','Splitting characters for barcodes','Free'),
121
('BarcodeSeparators','\\s\\r\\n','','Splitting characters for barcodes','Free'),
121
('BasketConfirmations','1','always ask for confirmation.|do not ask for confirmation.','When closing or reopening a basket,','Choice'),
122
('BasketConfirmations','1','always ask for confirmation.|do not ask for confirmation.','When closing or reopening a basket,','Choice'),
122
('BatchCheckouts','0','','Enable or disable batch checkouts','YesNo'),
123
('BatchCheckouts','0','','Enable or disable batch checkouts','YesNo'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref (-1 / +8 lines)
Lines 143-148 Cataloging: Link Here
143
                  annual: generated in the form <year>-0001, <year>-0002.
143
                  annual: generated in the form <year>-0001, <year>-0002.
144
                  hbyymmincr: generated in the form <branchcode>yymm0001.
144
                  hbyymmincr: generated in the form <branchcode>yymm0001.
145
                  EAN13: incremental EAN-13 barcodes.
145
                  EAN13: incremental EAN-13 barcodes.
146
                  preyymmddts: generated in the form <prefix>yymmdd<timestamp>.
146
                  "OFF": not generated automatically.
147
                  "OFF": not generated automatically.
147
        -
148
        -
148
            - When a new item is added,
149
            - When a new item is added,
Lines 217-222 Cataloging: Link Here
217
                  1: Strip
218
                  1: Strip
218
                  0: "Don't strip"
219
                  0: "Don't strip"
219
            - leading and trailing whitespace characters (including spaces, tabs, line breaks and carriage returns) and inner newlines from data fields when cataloguing bibliographic and authority records. The leader and control fields will not be affected.
220
            - leading and trailing whitespace characters (including spaces, tabs, line breaks and carriage returns) and inner newlines from data fields when cataloguing bibliographic and authority records. The leader and control fields will not be affected.
221
        -
222
            - "Define branch specific barcode prefix:"
223
            - "This is a YAML config."
224
            - pref: BarcodePrefix
225
              type: textarea
226
              class: code
220
    Display:
227
    Display:
221
        -
228
        -
222
            - 'Separate main entry and subdivisions with '
229
            - 'Separate main entry and subdivisions with '
Lines 408-411 Cataloging: Link Here
408
            - "<br/>"
415
            - "<br/>"
409
            - "All values of repeating tags and subfields will be printed with the given RIS tag."
416
            - "All values of repeating tags and subfields will be printed with the given RIS tag."
410
            - "<br/>"
417
            - "<br/>"
411
            - "Use of TY ( record type ) as a key will <em>replace</em> the default TY with the field value of your choosing."
418
            - "Use of TY ( record type ) as a key will <em>replace</em> the default TY with the field value of your choosing."
(-)a/t/Barcodes_preyymmddts.t (+11 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
use strict;
4
use warnings;
5
6
use Test::NoWarnings;
7
use Test::More tests => 2;
8
9
BEGIN {
10
    use_ok('C4::Barcodes::preyymmddts');
11
}
(-)a/t/db_dependent/Barcodes_ValueBuilder.t (-2 / +31 lines)
Lines 17-28 Link Here
17
use Modern::Perl;
17
use Modern::Perl;
18
18
19
use Test::NoWarnings;
19
use Test::NoWarnings;
20
use Test::More tests => 10;
20
use Test::More tests => 13;
21
use Test::MockModule;
21
use Test::MockModule;
22
use t::lib::TestBuilder;
22
use t::lib::TestBuilder;
23
23
24
use Koha::Database;
24
use Koha::Database;
25
25
26
use t::lib::Mocks;
27
26
BEGIN {
28
BEGIN {
27
    use_ok( 'C4::Barcodes::ValueBuilder', qw( get_barcode ) );
29
    use_ok( 'C4::Barcodes::ValueBuilder', qw( get_barcode ) );
28
}
30
}
Lines 66-69 my $item_5 = $builder->build_sample_item( { barcode => '978e0143019375' } ); Link Here
66
is( $nextnum, '979', 'incremental barcode' );
68
is( $nextnum, '979', 'incremental barcode' );
67
is( $scr,     undef, 'incremental javascript' );
69
is( $scr,     undef, 'incremental javascript' );
68
70
71
$dbh->do(q|DELETE FROM items|);
72
my $library_1 = $builder->build_object( { class => 'Koha::Libraries' } );
73
74
my $prefix_yaml = 'Default: DEF
75
' . $library_1->branchcode . ': TEST';
76
t::lib::Mocks::mock_preference( 'BarcodePrefix', $prefix_yaml );
77
78
my $item_6 = $builder->build_sample_item(
79
    {
80
        barcode    => 'TEST1207301414381',
81
        homebranch => $library_1->branchcode
82
    }
83
);
84
85
( $args{branchcode} ) = $library_1->branchcode;
86
( $nextnum, $scr ) = C4::Barcodes::ValueBuilder::preyymmddts::get_barcode( \%args );
87
88
# test if begining of new barcode matches prefix and date args
89
like( $nextnum, qr/TEST120730/, 'preyymmddts barcode test branch specific prefix' );
90
ok( length($scr) > 0, 'preyymmddtsr javascript' );
91
92
$dbh->do(q|DELETE FROM items|);
93
my $library_2 = $builder->build_object( { class => 'Koha::Libraries' } );
94
95
( $args{branchcode} ) = $library_2->branchcode;
96
( $nextnum, $scr ) = C4::Barcodes::ValueBuilder::preyymmddts::get_barcode( \%args );
97
like( $nextnum, qr/DEF120730/, 'preyymmddts barcode test default prefix' );
98
69
$schema->storage->txn_rollback;
99
$schema->storage->txn_rollback;
70
- 

Return to bug 30328