[Koha-patches] [PATCH] Bug 8524: Add a non-automatic barcode plugin
Jared Camins-Esakov
jcamins at cpbibliography.com
Wed Aug 1 18:27:09 CEST 2012
In addition to adding a new barcode plugin, this commit begins
refactoring the barcode generation code using a new module,
C4::Barcodes::ValueBuilder. From the POD:
This module is intended as a shim to ease the eventual transition
from having all barcode-related code in the value builder plugin
barcode.pl file to using C4::Barcodes. Since the shift will require
a rather significant amount of refactoring, this module will return
value builder-formatted results, at first by merely running the
code that was formerly in the barcodes.pl value builder, but later
by using C4::Barcodes.
---
C4/Barcodes/ValueBuilder.pm | 109 ++++++++++++++++++++++
cataloguing/value_builder/barcode.pl | 53 ++---------
cataloguing/value_builder/barcode_manual.pl | 132 +++++++++++++++++++++++++++
t/Barcodes_ValueBuilder.t | 78 ++++++++++++++++
4 files changed, 327 insertions(+), 45 deletions(-)
create mode 100644 C4/Barcodes/ValueBuilder.pm
create mode 100755 cataloguing/value_builder/barcode_manual.pl
create mode 100644 t/Barcodes_ValueBuilder.t
diff --git a/C4/Barcodes/ValueBuilder.pm b/C4/Barcodes/ValueBuilder.pm
new file mode 100644
index 0000000..10cd504
--- /dev/null
+++ b/C4/Barcodes/ValueBuilder.pm
@@ -0,0 +1,109 @@
+#!/usr/bin/perl
+#
+# Copyright 2008-2010 Foundations Bible College
+# Parts copyright 2012 C & P Bibliography Services
+#
+# 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 2 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, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+package C4::Barcodes::ValueBuilder::incremental;
+use C4::Context;
+my $DEBUG = 0;
+
+sub get_barcode {
+ my ($args) = @_;
+ my $nextnum;
+ # not the best, two catalogers could add the same barcode easily this way :/
+ my $query = "select max(abs(barcode)) from items";
+ my $sth = C4::Context->dbh->prepare($query);
+ $sth->execute();
+ while (my ($count)= $sth->fetchrow_array) {
+ $nextnum = $count;
+ }
+ $nextnum++;
+ return $nextnum;
+}
+
+1;
+
+package C4::Barcodes::ValueBuilder::hbyymmincr;
+use C4::Context;
+my $DEBUG = 0;
+
+sub get_barcode {
+ my ($args) = @_;
+ my $nextnum;
+ my $year = substr($args->{year}, -2);
+ my $query = "SELECT MAX(CAST(SUBSTRING(barcode,-4) AS signed)) AS number FROM items WHERE barcode REGEXP ?";
+ my $sth = C4::Context->dbh->prepare($query);
+ $sth->execute("^[-a-zA-Z]{1,}$year");
+ while (my ($count)= $sth->fetchrow_array) {
+ $nextnum = $count if $count;
+ $nextnum = 0 if $nextnum == 9999; # this sequence only allows for cataloging 10000 books per month
+ warn "Existing incremental number = $nextnum" if $DEBUG;
+ }
+ $nextnum++;
+ $nextnum = sprintf("%0*d", "4",$nextnum);
+ $nextnum = $year . $args->{mon} . $nextnum;
+ warn "New hbyymmincr Barcode = $nextnum" if $DEBUG;
+ my $scr = "
+ for (i=0 ; i<document.f.field_value.length ; i++) {
+ if (document.f.tag[i].value == '$args->{loctag}' && document.f.subfield[i].value == '$args->{locsubfield}') {
+ fnum = i;
+ }
+ }
+ if (\$('#' + id).val() == '' || force) {
+ \$('#' + id).val(document.f.field_value[fnum].value + '$nextnum');
+ }
+ ";
+ return $nextnum, $scr;
+}
+
+
+package C4::Barcodes::ValueBuilder::annual;
+use C4::Context;
+my $DEBUG = 0;
+
+sub get_barcode {
+ my ($args) = @_;
+ my $nextnum;
+ my $query = "select max(cast( substring_index(barcode, '-',-1) as signed)) from items where barcode like ?";
+ my $sth=C4::Context->dbh->prepare($query);
+ $sth->execute("$args->{year}%");
+ while (my ($count)= $sth->fetchrow_array) {
+ warn "Examining Record: $count" if $DEBUG;
+ $nextnum = $count if $count;
+ }
+ $nextnum++;
+ $nextnum = sprintf("%0*d", "4",$nextnum);
+ $nextnum = "$args->{year}-$nextnum";
+ return $nextnum;
+}
+
+1;
+
+
+=head1 Barcodes::ValueBuilder
+
+This module is intended as a shim to ease the eventual transition from
+having all barcode-related code in the value builder plugin .pl file
+to using C4::Barcodes. Since the shift will require a rather significant
+amount of refactoring, this module will return value builder-formatted
+results, at first by merely running the code that was formerly in the
+barcodes.pl value builder, but later by using C4::Barcodes.
+
+=cut
+
+1;
diff --git a/cataloguing/value_builder/barcode.pl b/cataloguing/value_builder/barcode.pl
index c5e1fd3..cb89a32 100755
--- a/cataloguing/value_builder/barcode.pl
+++ b/cataloguing/value_builder/barcode.pl
@@ -22,6 +22,7 @@ use warnings;
no warnings 'redefine'; # otherwise loading up multiple plugins fills the log with subroutine redefine warnings
use C4::Context;
+require C4::Barcodes::ValueBuilder;
require C4::Dates;
my $DEBUG = 0;
@@ -55,14 +56,14 @@ the 3 scripts are inserted after the <input> in the html code
sub plugin_javascript {
my ($dbh,$record,$tagslib,$field_number,$tabloop) = @_;
my $function_name= "barcode".(int(rand(100000))+1);
+ my %args;
# find today's date
- my ($year, $mon, $day) = split('-', C4::Dates->today('iso'));
- my ($tag,$subfield) = GetMarcFromKohaField("items.barcode", '');
- my ($loctag,$locsubfield) = GetMarcFromKohaField("items.homebranch", '');
+ ($args{year}, $args{mon}, $args{day}) = split('-', C4::Dates->today('iso'));
+ ($args{tag},$args{subfield}) = GetMarcFromKohaField("items.barcode", '');
+ ($args{loctag},$args{locsubfield}) = GetMarcFromKohaField("items.homebranch", '');
my $nextnum;
- my $query;
my $scr;
my $autoBarcodeType = C4::Context->preference("autoBarcode");
warn "Barcode type = $autoBarcodeType" if $DEBUG;
@@ -77,51 +78,13 @@ sub plugin_javascript {
</script>");
}
if ($autoBarcodeType eq 'annual') {
- $query = "select max(cast( substring_index(barcode, '-',-1) as signed)) from items where barcode like ?";
- my $sth=$dbh->prepare($query);
- $sth->execute("$year%");
- while (my ($count)= $sth->fetchrow_array) {
- warn "Examining Record: $count" if $DEBUG;
- $nextnum = $count if $count;
- }
- $nextnum++;
- $nextnum = sprintf("%0*d", "4",$nextnum);
- $nextnum = "$year-$nextnum";
+ ($nextnum, $scr) = C4::Barcodes::ValueBuilder::annual::get_barcode(\%args);
}
elsif ($autoBarcodeType eq 'incremental') {
- # not the best, two catalogers could add the same barcode easily this way :/
- $query = "select max(abs(barcode)) from items";
- my $sth = $dbh->prepare($query);
- $sth->execute();
- while (my ($count)= $sth->fetchrow_array) {
- $nextnum = $count;
- }
- $nextnum++;
+ ($nextnum, $scr) = C4::Barcodes::ValueBuilder::incremental::get_barcode(\%args);
}
elsif ($autoBarcodeType eq 'hbyymmincr') { # Generates a barcode where hb = home branch Code, yymm = year/month catalogued, incr = incremental number, reset yearly -fbcit
- $year = substr($year, -2);
- $query = "SELECT MAX(CAST(SUBSTRING(barcode,-4) AS signed)) AS number FROM items WHERE barcode REGEXP ?";
- my $sth = $dbh->prepare($query);
- $sth->execute("^[-a-zA-Z]{1,}$year");
- while (my ($count)= $sth->fetchrow_array) {
- $nextnum = $count if $count;
- $nextnum = 0 if $nextnum == 9999; # this sequence only allows for cataloging 10000 books per month
- warn "Existing incremental number = $nextnum" if $DEBUG;
- }
- $nextnum++;
- $nextnum = sprintf("%0*d", "4",$nextnum);
- $nextnum = $year . $mon . $nextnum;
- warn "New hbyymmincr Barcode = $nextnum" if $DEBUG;
- $scr = "
- for (i=0 ; i<document.f.field_value.length ; i++) {
- if (document.f.tag[i].value == '$loctag' && document.f.subfield[i].value == '$locsubfield') {
- fnum = i;
- }
- }
- if (\$('#' + id).val() == '' || force) {
- \$('#' + id).val(document.f.field_value[fnum].value + '$nextnum');
- }
- ";
+ ($nextnum, $scr) = C4::Barcodes::ValueBuilder::hbyymmincr::get_barcode(\%args);
}
# default js body (if not filled by hbyymmincr)
diff --git a/cataloguing/value_builder/barcode_manual.pl b/cataloguing/value_builder/barcode_manual.pl
new file mode 100755
index 0000000..b2f4105
--- /dev/null
+++ b/cataloguing/value_builder/barcode_manual.pl
@@ -0,0 +1,132 @@
+#!/usr/bin/perl
+# Copyright 2000-2002 Katipo Communications
+# Parts copyright 2008-2010 Foundations Bible College
+#
+# 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 2 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, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use strict;
+use warnings;
+no warnings 'redefine'; # otherwise loading up multiple plugins fills the log with subroutine redefine warnings
+
+use C4::Context;
+require C4::Barcodes::ValueBuilder;
+require C4::Dates;
+
+my $DEBUG = 0;
+
+=head1
+
+plugin_parameters : other parameters added when the plugin is called by the dopop function
+
+=cut
+
+sub plugin_parameters {
+# my ($dbh,$record,$tagslib,$i,$tabloop) = @_;
+ return "";
+}
+
+=head1
+
+plugin_javascript : the javascript function called when the user enters the subfield.
+contain 3 javascript functions :
+* one called when the field is entered (OnFocus). Named FocusXXX
+* one called when the field is leaved (onBlur). Named BlurXXX
+* one called when the ... link is clicked (<a href="javascript:function">) named ClicXXX
+
+returns :
+* XXX
+* a variable containing the 3 scripts.
+the 3 scripts are inserted after the <input> in the html code
+
+=cut
+
+sub plugin_javascript {
+ my ($dbh,$record,$tagslib,$field_number,$tabloop) = @_;
+ my $function_name= "barcode".(int(rand(100000))+1);
+ my %args;
+
+ $args{dbh} = $dbh;
+
+# find today's date
+ ($args{year}, $args{mon}, $args{day}) = split('-', C4::Dates->today('iso'));
+ ($args{tag},$args{subfield}) = GetMarcFromKohaField("items.barcode", '');
+ ($args{loctag},$args{locsubfield}) = GetMarcFromKohaField("items.homebranch", '');
+
+ my $nextnum;
+ my $scr;
+ my $autoBarcodeType = C4::Context->preference("autoBarcode");
+ warn "Barcode type = $autoBarcodeType" if $DEBUG;
+ if ((not $autoBarcodeType) or $autoBarcodeType eq 'OFF') {
+# don't return a value unless we have the appropriate syspref set
+ return ($function_name,
+ "<script type=\"text/javascript\">
+ // autoBarcodeType OFF (or not defined)
+ function Focus$function_name() { return 0;}
+ function Clic$function_name() { return 0;}
+ function Blur$function_name() { return 0;}
+ </script>");
+ }
+ if ($autoBarcodeType eq 'annual') {
+ ($nextnum, $scr) = C4::Barcodes::ValueBuilder::annual::get_barcode(\%args);
+ }
+ elsif ($autoBarcodeType eq 'incremental') {
+ ($nextnum, $scr) = C4::Barcodes::ValueBuilder::incremental::get_barcode(\%args);
+ }
+ 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);
+ }
+
+# default js body (if not filled by hbyymmincr)
+ $scr or $scr = <<END_OF_JS;
+ if (\$('#' + id).val() == '' || force) {
+ \$('#' + id).val('$nextnum');
+ }
+END_OF_JS
+
+ my $js = <<END_OF_JS;
+ <script type="text/javascript">
+ //<![CDATA[
+
+ function Blur$function_name(index) {
+ //barcode validation might go here
+ }
+
+ function Focus$function_name(subfield_managed, id, force) {
+ return 0;
+ }
+
+ function Clic$function_name(id) {
+ $scr
+ return 0;
+ }
+ //]]>
+ </script>
+END_OF_JS
+ return ($function_name, $js);
+}
+
+=head1
+
+plugin: useless here
+
+=cut
+
+sub plugin {
+# my ($input) = @_;
+ return "";
+}
+
+1;
diff --git a/t/Barcodes_ValueBuilder.t b/t/Barcodes_ValueBuilder.t
new file mode 100644
index 0000000..c3d816e
--- /dev/null
+++ b/t/Barcodes_ValueBuilder.t
@@ -0,0 +1,78 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use DBI;
+use Test::More tests => 15;
+use Test::MockModule;
+
+BEGIN {
+ use_ok('C4::Barcodes::ValueBuilder');
+}
+
+
+my $module = new Test::MockModule('C4::Context');
+$module->mock('_new_dbh', sub {
+ my $dbh = DBI->connect( 'DBI:Mock:', '', '' )
+ || die "Cannot create handle: $DBI::errstr\n";
+ return $dbh });
+
+# Mock data
+my $incrementaldata = [
+ ['max(abs(barcode))'],
+ ['33333074344563'],
+];
+
+
+my $dbh = C4::Context->dbh();
+
+my %args = (
+ year => '2012',
+ mon => '07',
+ day => '30',
+ tag => '952',
+ subfield => 'p',
+ loctag => '952',
+ locsubfield => 'a'
+);
+
+$dbh->{mock_add_resultset} = $incrementaldata;
+my ($nextnum, $scr, $history);
+
+($nextnum, $scr) = C4::Barcodes::ValueBuilder::incremental::get_barcode(\%args);
+is($nextnum, 33333074344564, 'incremental barcode');
+ok(length($scr) == 0, 'incremental javascript');
+
+# This should run exactly one query so we can test
+$history = $dbh->{mock_all_history};
+is(scalar(@{$history}), 1, 'Correct number of statements executed for incremental barcode') ;
+
+my $hbyymmincrdata = [
+ ['number'],
+ ['890'],
+];
+
+$dbh->{mock_add_resultset} = $hbyymmincrdata;
+$dbh->{mock_clear_history} = 1;
+($nextnum, $scr) = C4::Barcodes::ValueBuilder::hbyymmincr::get_barcode(\%args);
+is($nextnum, '12070891', 'hbyymmincr barcode');
+ok(length($scr) > 0, 'hbyymmincr javascript');
+
+# This should run exactly one query so we can test
+$history = $dbh->{mock_all_history};
+is(scalar(@{$history}), 1, 'Correct number of statements executed for hbyymmincr barcode') ;
+
+my $annualdata = [
+ ['max(cast( substring_index(barcode, \'-\',-1) as signed))'],
+ ['34'],
+];
+
+$dbh->{mock_add_resultset} = $annualdata;
+$dbh->{mock_clear_history} = 1;
+($nextnum, $scr) = C4::Barcodes::ValueBuilder::annual::get_barcode(\%args);
+is($nextnum, '2012-0035', 'annual barcode');
+ok(length($scr) == 0, 'annual javascript');
+
+# This should run exactly one query so we can test
+$history = $dbh->{mock_all_history};
+is(scalar(@{$history}), 1, 'Correct number of statements executed for hbyymmincr barcode') ;
+
--
1.7.2.5
More information about the Koha-patches
mailing list