Bugzilla – Attachment 139350 Details for
Bug 30328
Add ability to generate barcode with library specific prefix
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 30328: Add ability to generate barcode with branch specific prefix
0001-Bug-30328-Add-ability-to-generate-barcode-with-branc.patch (text/plain), 19.05 KB, created by
Emmi Takkinen
on 2022-08-18 09:47:16 UTC
(
hide
)
Description:
Bug 30328: Add ability to generate barcode with branch specific prefix
Filename:
MIME Type:
Creator:
Emmi Takkinen
Created:
2022-08-18 09:47:16 UTC
Size:
19.05 KB
patch
obsolete
>From c089b1338037b0fc5fc84a5ca9082c55cd067618 Mon Sep 17 00:00:00 2001 >From: Emmi Takkinen <emmi.takkinen@koha-suomi.fi> >Date: Tue, 22 Mar 2022 13:17:19 +0200 >Subject: [PATCH] Bug 30328: Add ability to generate barcode with branch > specific prefix > >We should add more flexibility to generating barcodes by letting libraries >define branch specific prefix for their barcodes. This patch adds new option >"preyyyymmincr" in systempreference "autoBarcode" and new systempreference >"BarcodePrefix" to define branch specific prefix > >Test plan for adding item: > >1. Apply patch and update database >2. Set syspref "autoBarcode" as >3. Add some values to syspref "Barcodeprefix" e.g.: > Default: DEF > CPL: CPL > FFL: FFL >4. Now change your library to CPL (if needed) and add an item >5. Click barcode input field > => barcode should be CPL<current_year><current_month>00001 >6. Add another item and click barcode field > => barcode should be CPL<current_year><current_month>00002 >7. Change your library to FFL and add an item > => barcode should now be FFL<current_year><current_month>00001 >8. Change your library to e.g. FPL (or another as long as it doesn't have prefix value >in "Barcodeprefix"), add an item and click barcode field > => barcode should now be DEF<current_year><current_month>00001 >9. Try to add multiple items > => barcodes incremental value should increase in order (no skipping values, no errors) > >Test plan for adding multiple aqcuisitions: > >1. Set syspref "AcqCreateItem" as "placing order". >2. Create an order and add multiple items to it. >3. Save the order. >4. Navigate to that biblios detail page to which you added items. > => ordered items barcodes incremental value should increase in order (no skipping > values, no errors) > >Also prove t/db_dependent/Barcodes_ValueBuilder.t and t/Barcodes_preyyyymmincr.t > >Sponsored-by: Koha-Suomi Oy >--- > C4/Barcodes.pm | 12 +- > C4/Barcodes/ValueBuilder.pm | 54 +++++++++ > C4/Barcodes/preyyyymmincr.pm | 105 ++++++++++++++++++ > cataloguing/additem.pl | 6 +- > cataloguing/value_builder/barcode.pl | 4 + > cataloguing/value_builder/barcode_manual.pl | 4 + > .../data/mysql/atomicupdate/bug_30328.pl | 15 +++ > installer/data/mysql/mandatory/sysprefs.sql | 3 +- > .../admin/preferences/cataloguing.pref | 10 ++ > t/Barcodes_preyyyymmincr.t | 10 ++ > t/db_dependent/Barcodes_ValueBuilder.t | 30 ++++- > 11 files changed, 244 insertions(+), 9 deletions(-) > create mode 100644 C4/Barcodes/preyyyymmincr.pm > create mode 100755 installer/data/mysql/atomicupdate/bug_30328.pl > create mode 100755 t/Barcodes_preyyyymmincr.t > >diff --git a/C4/Barcodes.pm b/C4/Barcodes.pm >index 957d60f283..8342ae1c68 100644 >--- a/C4/Barcodes.pm >+++ b/C4/Barcodes.pm >@@ -27,6 +27,7 @@ use C4::Barcodes::hbyymmincr; > use C4::Barcodes::annual; > use C4::Barcodes::incremental; > use C4::Barcodes::EAN13; >+use C4::Barcodes::preyyyymmincr; > > use vars qw($max $prefformat); > >@@ -154,11 +155,12 @@ sub default_self { > } > > our $types = { >- annual => sub {C4::Barcodes::annual->new_object(@_); }, >- incremental => sub {C4::Barcodes::incremental->new_object(@_);}, >- hbyymmincr => sub {C4::Barcodes::hbyymmincr->new_object(@_); }, >- OFF => sub {C4::Barcodes::OFF->new_object(@_); }, >- EAN13 => sub {C4::Barcodes::EAN13->new_object(@_); }, >+ annual => sub {C4::Barcodes::annual->new_object(@_); }, >+ incremental => sub {C4::Barcodes::incremental->new_object(@_); }, >+ hbyymmincr => sub {C4::Barcodes::hbyymmincr->new_object(@_); }, >+ OFF => sub {C4::Barcodes::OFF->new_object(@_); }, >+ EAN13 => sub {C4::Barcodes::EAN13->new_object(@_); }, >+ preyyyymmincr => sub {C4::Barcodes::preyyyymmincr->new_object(@_);}, > }; > > sub new { >diff --git a/C4/Barcodes/ValueBuilder.pm b/C4/Barcodes/ValueBuilder.pm >index 76464ccd4b..abfdaf8bdb 100644 >--- a/C4/Barcodes/ValueBuilder.pm >+++ b/C4/Barcodes/ValueBuilder.pm >@@ -89,6 +89,60 @@ sub get_barcode { > return $nextnum; > } > >+package C4::Barcodes::ValueBuilder::preyyyymmincr; >+use C4::Context; >+use YAML::XS; >+my $DEBUG = 0; >+ >+sub get_barcode { >+ my ($args) = @_; >+ my $nextnum; >+ my $barcode; >+ my $branchcode = $args->{branchcode}; >+ my $query; >+ my $sth; >+ >+ # Getting the barcodePrefixes >+ my $branchPrefixes = C4::Context->preference("BarcodePrefix"); >+ my $yaml = YAML::XS::Load( >+ Encode::encode( >+ 'UTF-8', >+ $branchPrefixes, >+ Encode::FB_CROAK >+ ) >+ ); >+ >+ my $prefix = $yaml->{$branchcode} || $yaml->{'Default'}; >+ >+ $query = "SELECT MAX(CAST(SUBSTRING(barcode,-4) AS signed)) from items where barcode REGEXP ?"; >+ $sth=C4::Context->dbh->prepare($query); >+ $sth->execute("^$prefix$args->{year}$args->{mon}"); >+ >+ while (my ($count)= $sth->fetchrow_array) { >+ $nextnum = $count if $count; >+ $nextnum = 0 if $nextnum && $nextnum == 9999; >+ } >+ >+ $nextnum++; >+ $nextnum = sprintf("%0*d", "5",$nextnum); >+ >+ $barcode = $prefix; >+ $barcode .= $args->{year}.$args->{mon}.$nextnum; >+ >+ my $scr = qq~ >+ let elt = \$("#"+id); >+ let branchcode = elt.parents('fieldset.rows:first') >+ .find('input[name="kohafield"][value="items.homebranch"]') >+ .siblings("select") >+ .val(); >+ if ( \$(elt).val() == '' ) { >+ \$(elt).val('$barcode'); >+ } >+ ~; >+ >+ return $barcode, $scr; >+} >+ > 1; > > >diff --git a/C4/Barcodes/preyyyymmincr.pm b/C4/Barcodes/preyyyymmincr.pm >new file mode 100644 >index 0000000000..41fcec2378 >--- /dev/null >+++ b/C4/Barcodes/preyyyymmincr.pm >@@ -0,0 +1,105 @@ >+package C4::Barcodes::preyyyymmincr; >+ >+# Copyright 2022 Koha Development team >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use strict; >+use warnings; >+ >+use Carp qw( carp ); >+ >+use C4::Context; >+ >+use Koha::DateUtils qw( dt_from_string output_pref ); >+ >+use vars qw(@ISA); >+ >+BEGIN { >+ @ISA = qw(C4::Barcodes); >+} >+ >+sub new_object { >+ my $class = shift; >+ my $type = ref($class) || $class; >+ my $self = $type->default_self('preyyyymmincr'); >+ >+ my $branchcode = C4::Context->userenv->{'branch'}; >+ my $branchPrefixes = C4::Context->preference("BarcodePrefix"); >+ my $yaml = YAML::XS::Load( >+ Encode::encode( >+ 'UTF-8', >+ $branchPrefixes, >+ Encode::FB_CROAK >+ ) >+ ); >+ my $prefix = $yaml->{$branchcode} || $yaml->{'Default'}; >+ >+ $self->{prefix} = $prefix; >+ $self->{datetime} = output_pref({ dt => dt_from_string, dateformat => 'iso', dateonly => 1 }); >+ >+ return bless $self, $type; >+} >+ >+sub initial { >+ my $self = shift; >+ >+ my $prefix = $self->{prefix}; >+ my ($year, $month, $day) = split('-', $self->{datetime}); >+ >+ return $prefix.$year.$month.'00001'; >+} >+ >+sub db_max { >+ my $self = shift; >+ >+ my $prefix = $self->{prefix}; >+ my ($year, $month, $day) = split('-', $self->{datetime}); >+ >+ my $query = "SELECT MAX(CAST(SUBSTRING(barcode,-4) AS signed)) from items where barcode REGEXP ?"; >+ my $sth=C4::Context->dbh->prepare($query); >+ $sth->execute("^$prefix$year$month"); >+ >+ my $nextnum; >+ while (my ($count)= $sth->fetchrow_array) { >+ $nextnum = $count if $count; >+ $nextnum = 0 if $nextnum && $nextnum == 9999; >+ } >+ >+ $nextnum = sprintf("%0*d", "5",$nextnum); >+ >+ return $nextnum; >+} >+ >+sub parse { >+ my $self = shift; >+ >+ my $prefix = $self->{prefix}; >+ my ($year, $month, $day) = split('-', $self->{datetime}); >+ >+ my $head = $prefix.$year.$month; >+ my $incr = (@_) ? shift : $self->value; >+ my $barcode = $head.$incr; >+ unless ($incr){ >+ carp "Barcode '$barcode' has no incrementing part!"; >+ return ($barcode,undef,undef); >+ } >+ >+ return ($head, $incr, ''); >+} >+ >+1; >+__END__ >\ No newline at end of file >diff --git a/cataloguing/additem.pl b/cataloguing/additem.pl >index 49571e790d..5c866305fb 100755 >--- a/cataloguing/additem.pl >+++ b/cataloguing/additem.pl >@@ -316,8 +316,10 @@ if ($op eq "additem") { > if ($barcodevalue) { > > # Getting a new barcode (if it is not the first iteration or the barcode we tried already exists) >- $barcodevalue = $barcodeobj->next_value($oldbarcode) >- if ( $i > 0 || $exist_itemnumber ); >+ my $aBpref = C4::Context->preference('autoBarcode'); >+ my $barcodeobj2 = C4::Barcodes->new($aBpref); >+ $barcodevalue = $barcodeobj2->value() >+ if ( $i > 0 || $exist_itemnumber ); > > # Putting it into the record > if ($barcodevalue) { >diff --git a/cataloguing/value_builder/barcode.pl b/cataloguing/value_builder/barcode.pl >index 8fcd45beae..5f8756d476 100755 >--- a/cataloguing/value_builder/barcode.pl >+++ b/cataloguing/value_builder/barcode.pl >@@ -37,6 +37,7 @@ my $builder = sub { > # find today's date > ($args{year}, $args{mon}, $args{day}) = split('-', output_pref({ dt => dt_from_string, dateformat => 'iso', dateonly => 1 })); > ($args{tag},$args{subfield}) = GetMarcFromKohaField( "items.barcode" ); >+ ($args{branchcode}) = C4::Context->userenv->{'branch'}; > > my $nextnum; > my $scr; >@@ -73,6 +74,9 @@ my $builder = sub { > $nextnum++; > } > } >+ elsif ($autoBarcodeType eq 'preyyyymmincr') { # Generates a barcode where pre = branch specific prefix set on systempreference BarcodePrefix, yyyymm = year/month catalogued, incr = incremental number >+ ($nextnum, $scr) = C4::Barcodes::ValueBuilder::preyyyymmincr::get_barcode(\%args); >+ } > else { > warn "ERROR: unknown autoBarcode: $autoBarcodeType"; > } >diff --git a/cataloguing/value_builder/barcode_manual.pl b/cataloguing/value_builder/barcode_manual.pl >index d2b7f7a414..d667fc2573 100755 >--- a/cataloguing/value_builder/barcode_manual.pl >+++ b/cataloguing/value_builder/barcode_manual.pl >@@ -38,6 +38,7 @@ my $builder = sub { > # find today's date > ($args{year}, $args{mon}, $args{day}) = split('-', output_pref({ dt => dt_from_string, dateformat => 'iso', dateonly => 1 })); > ($args{tag},$args{subfield}) = GetMarcFromKohaField( "items.barcode" ); >+ ($args{branchcode}) = C4::Context->userenv->{'branch'}; > > my $nextnum; > my $scr; >@@ -55,6 +56,9 @@ my $builder = sub { > elsif ($autoBarcodeType eq 'hbyymmincr') { # Generates a barcode where hb = home branch Code, yymm = year/month catalogued, incr = incremental number, reset yearly -fbcit > ($nextnum, $scr) = C4::Barcodes::ValueBuilder::hbyymmincr::get_barcode(\%args); > } >+ elsif ($autoBarcodeType eq 'preyyyymmincr') { # Generates a barcode where pre = branch specific prefix set on systempreference BarcodePrefix, yyyymm = year/month catalogued, incr = incremental number >+ ($nextnum, $scr) = C4::Barcodes::ValueBuilder::preyyyymmincr::get_barcode(\%args); >+ } > > # default js body (if not filled by hbyymmincr) > $scr or $scr = <<END_OF_JS; >diff --git a/installer/data/mysql/atomicupdate/bug_30328.pl b/installer/data/mysql/atomicupdate/bug_30328.pl >new file mode 100755 >index 0000000000..bf6bc31be0 >--- /dev/null >+++ b/installer/data/mysql/atomicupdate/bug_30328.pl >@@ -0,0 +1,15 @@ >+use Modern::Perl; >+ >+return { >+ bug_number => "30328", >+ description => "Add option to create barcode with branch specific prefix", >+ up => sub { >+ my ($args) = @_; >+ my ($dbh, $out) = @$args{qw(dbh out)}; >+ # Do you stuffs here >+ $dbh->do(q{ UPDATE IGNORE systempreferences SET options = 'incremental|annual|hbyymmincr|EAN13|preyyyymmincr|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; preyyyymmincr of the form PRE2021030001 where PRE = branch specific prefix set on systempreference BarcodePrefix' WHERE variable = 'autoBarcode'}); >+ $dbh->do(q{ INSERT IGNORE INTO systempreferences ( variable, value, options, explanation, type ) VALUES ('BarcodePrefix','','','Defines the barcode prefixes when the autoBarcode value is set as preyyyymmincr','Textarea')}); >+ # Print useful stuff here >+ say $out "Update is going well so far"; >+ }, >+}; >diff --git a/installer/data/mysql/mandatory/sysprefs.sql b/installer/data/mysql/mandatory/sysprefs.sql >index 227049afe5..5a470c8f4d 100644 >--- a/installer/data/mysql/mandatory/sysprefs.sql >+++ b/installer/data/mysql/mandatory/sysprefs.sql >@@ -72,7 +72,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` > ('AuthoritySeparator','--','10','Used to separate a list of authorities in a display. Usually --','free'), > ('AuthorityXSLTResultsDisplay','','','Enable XSL stylesheet control over authority results page display on intranet','Free'), > ('AuthSuccessLog','0',NULL,'If enabled, log successful authentications','YesNo'), >-('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'), >+('autoBarcode','OFF','incremental|annual|hbyymmincr|EAN13|preyyyymmincr|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; preyyyymmincr of the form PRE2021030001 where PRE = branch specific prefix set on systempreference BarcodePrefix','Choice'), > ('AutoCreateAuthorities','0',NULL,'Automatically create authorities that do not exist when cataloging records.','YesNo'), > ('AutoCreditNumber', '', '', 'Automatically generate a number for account credits', 'Choice'), > ('AutoEmailNewUser','0',NULL,'Send an email to newly created patrons.','YesNo'), >@@ -96,6 +96,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` > ('BakerTaylorEnabled','0','','Enable or disable all Baker & Taylor features.','YesNo'), > ('BakerTaylorPassword','','','Baker & Taylor Password for Content Cafe (external content)','Free'), > ('BakerTaylorUsername','','','Baker & Taylor Username for Content Cafe (external content)','Free'), >+('BarcodePrefix','','','Defines the barcode prefixes when the autoBarcode value is set as preyyyymmincr','Textarea'), > ('BarcodeSeparators','\\s\\r\\n','','Splitting characters for barcodes','Free'), > ('BasketConfirmations','1','always ask for confirmation.|do not ask for confirmation.','When closing or reopening a basket,','Choice'), > ('BatchCheckouts','0','','Enable or disable batch checkouts','YesNo'), >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref >index 4aad6fc775..ad7e21b3a1 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref >@@ -123,7 +123,9 @@ Cataloging: > annual: generated in the form <year>-0001, <year>-0002. > hbyymmincr: generated in the form <branchcode>yymm0001. > EAN13: incremental EAN-13 barcodes. >+ preyyyymmincr: generated in the form <prefix>yyyymm00001. > "OFF": not generated automatically. >+ - Define the behavior of the <code><​prefix>yyyymm00001</code> option using <a href="/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=BarcodePrefix">BarcodePrefix</a>. > - > - When a new item is added, > - pref: PrefillItem >@@ -165,6 +167,14 @@ Cataloging: > - and record's last modifier name in MARC subfield > - pref: MarcFieldForModifierName > - ". <br/><strong>NOTE:</strong> Use a dollar sign between field and subfield like 123$a." >+ - >+ - "Define branch specific barcode prefixes in a YAML format." >+ - "This defines the behavior of the <code><​prefix>yyyymm00001</code> option of <a href='/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=autoBarcode'>autoBarcode</a>." >+ - "Barcodes generated look like: <code>DEF20220400001</code>" >+ - pref: BarcodePrefix >+ type: textarea >+ syntax: text/x-yaml >+ class: code > Display: > - > - 'Separate main entry and subdivisions with ' >diff --git a/t/Barcodes_preyyyymmincr.t b/t/Barcodes_preyyyymmincr.t >new file mode 100755 >index 0000000000..c3ab5d8e9a >--- /dev/null >+++ b/t/Barcodes_preyyyymmincr.t >@@ -0,0 +1,10 @@ >+#!/usr/bin/perl >+ >+use strict; >+use warnings; >+ >+use Test::More tests => 1; >+ >+BEGIN { >+ use_ok('C4::Barcodes::preyyyymmincr'); >+} >\ No newline at end of file >diff --git a/t/db_dependent/Barcodes_ValueBuilder.t b/t/db_dependent/Barcodes_ValueBuilder.t >index 84fcce1983..1879e341f8 100755 >--- a/t/db_dependent/Barcodes_ValueBuilder.t >+++ b/t/db_dependent/Barcodes_ValueBuilder.t >@@ -16,12 +16,14 @@ > > use Modern::Perl; > >-use Test::More tests => 9; >+use Test::More tests => 12; > use Test::MockModule; > use t::lib::TestBuilder; > > use Koha::Database; > >+use t::lib::Mocks; >+ > BEGIN { > use_ok('C4::Barcodes::ValueBuilder', qw( get_barcode )); > }; >@@ -85,4 +87,30 @@ my $item_5 = $builder->build_sample_item( > is($nextnum, '979', 'incremental barcode'); > is($scr, undef, 'incremental javascript'); > >+$dbh->do(q|DELETE FROM items|); >+my $library_1 = $builder->build_object( { class => 'Koha::Libraries' } ); >+ >+my $prefix_yaml = 'Default: DEF >+'.$library_1->branchcode.': TEST'; >+t::lib::Mocks::mock_preference( 'BarcodePrefix', $prefix_yaml ); >+ >+my $item_6 = $builder->build_sample_item( >+ { >+ barcode => 'TEST20120700001', >+ homebranch => $library_1->branchcode >+ } >+); >+ >+($args{branchcode}) = $library_1->branchcode; >+($nextnum, $scr) = C4::Barcodes::ValueBuilder::preyyyymmincr::get_barcode(\%args); >+is($nextnum, 'TEST20120700002', 'preyyyymmincr barcode test branch specific prefix'); >+ok(length($scr) > 0, 'preyyyymmincr javascript'); >+ >+$dbh->do(q|DELETE FROM items|); >+my $library_2 = $builder->build_object( { class => 'Koha::Libraries' } ); >+ >+($args{branchcode}) = $library_2->branchcode; >+($nextnum, $scr) = C4::Barcodes::ValueBuilder::preyyyymmincr::get_barcode(\%args); >+is($nextnum, 'DEF20120700001', 'preyyyymmincr barcode test default prefix'); >+ > $schema->storage->txn_rollback; >-- >2.25.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 30328
:
132221
|
132954
|
134009
|
134202
|
134206
| 139350