Bugzilla – Attachment 8094 Details for
Bug 7676
Barcode Prefixes
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Barcode Prefixes
Barcode-Prefixes.patch (text/plain), 36.20 KB, created by
Kyle M Hall
on 2012-03-08 15:56:22 UTC
(
hide
)
Description:
Barcode Prefixes
Filename:
MIME Type:
Creator:
Kyle M Hall
Created:
2012-03-08 15:56:22 UTC
Size:
36.20 KB
patch
obsolete
>From 250af11e05d24eab0a53855612a9a7d11c8eb21b Mon Sep 17 00:00:00 2001 >From: Ian Walls <ian.walls@bywatersolutions.com> >Date: Fri, 14 Oct 2011 14:02:13 -0400 >Subject: [PATCH] Barcode Prefixes > >Allows for specification, on a per branch basis, of barcode prefixes for both items and patrons. >Barcodes must come to a specific length (as set in system preferences), and barcodes shorter than >this length will be auto-prefixed with the currently-logged-in branch's prefix. > >Currently supports: >Circulation (checkout, return) >Patron lookup >Item creation >Patron creation >Bulk patron import >Inventory >Offline Circ >ILSDI > >http://bugs.koha-community.org/show_bug.cgi?id=7676 >--- > C4/Barcodes.pm | 2 + > C4/Barcodes/prefix.pm | 126 ++++++++++++++++++++ > C4/Circulation.pm | 5 + > C4/ILSDI/Services.pm | 3 +- > C4/Items.pm | 29 +++++ > C4/Members.pm | 97 +++++++++++++-- > admin/branches.pl | 38 ++++--- > admin/systempreferences.pl | 2 + > cataloguing/additem.pl | 8 ++ > circ/circulation.pl | 3 +- > circ/returns.pl | 6 +- > installer/data/mysql/kohastructure.sql | 2 + > installer/data/mysql/sysprefs.sql | 2 + > installer/data/mysql/updatedatabase.pl | 11 ++ > .../prog/en/modules/admin/branches.tt | 6 + > .../prog/en/modules/admin/preferences/admin.pref | 10 ++ > .../en/modules/admin/preferences/cataloguing.pref | 1 + > members/memberentry.pl | 15 ++- > offline_circ/process_koc.pl | 4 +- > tools/import_borrowers.pl | 10 ++- > tools/inventory.pl | 6 + > 21 files changed, 340 insertions(+), 46 deletions(-) > create mode 100644 C4/Barcodes/prefix.pm > >diff --git a/C4/Barcodes.pm b/C4/Barcodes.pm >index a528bd9..e26fb64 100644 >--- a/C4/Barcodes.pm >+++ b/C4/Barcodes.pm >@@ -28,6 +28,7 @@ use C4::Dates; > use C4::Barcodes::hbyymmincr; > use C4::Barcodes::annual; > use C4::Barcodes::incremental; >+use C4::Barcodes::prefix; > > use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); > use vars qw($debug $cgi_debug); # from C4::Debug, of course >@@ -173,6 +174,7 @@ sub default_self (;$) { > } > > our $types = { >+ prefix_incr => sub {C4::Barcodes::prefix->new_object(@_); }, > annual => sub {C4::Barcodes::annual->new_object(@_); }, > incremental => sub {C4::Barcodes::incremental->new_object(@_);}, > hbyymmincr => sub {C4::Barcodes::hbyymmincr->new_object(@_); }, >diff --git a/C4/Barcodes/prefix.pm b/C4/Barcodes/prefix.pm >new file mode 100644 >index 0000000..12c8c9f >--- /dev/null >+++ b/C4/Barcodes/prefix.pm >@@ -0,0 +1,126 @@ >+package C4::Barcodes::prefix; >+ >+# Copyright 2011 ByWater Solutions >+# >+# 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; >+use Carp; >+ >+use C4::Context; >+use C4::Branch; >+use C4::Debug; >+use C4::Dates; >+ >+use vars qw($VERSION @ISA); >+use vars qw($debug $cgi_debug); # from C4::Debug, of course >+use vars qw($branch $width); >+ >+BEGIN { >+ $VERSION = 0.01; >+ @ISA = qw(C4::Barcodes); >+ $width = C4::Context->preference('itembarcodelength'); >+ my $prefix = ''; >+} >+ >+ >+# This package generates auto-incrementing barcodes where branch-specific prefixes are being used. >+# For a library with 10-digit barcodes, and a prefix of T123, this should generate on a range of >+# T123000000 and T123999999 >+# >+# There are a couple of problems with treating barcodes as straight-numerics and just incrementing >+# them. The first, and most-obvious, is that barcodes need not be numeric, particularly in the prefix >+# part! The second, as noted in C4::Barcodes.pm, is that you might not actually be able to handle very >+# large ints like that... >+ >+ >+sub db_max ($;$) { >+ my $self = shift; >+ my $sth = C4::Context->dbh->prepare("SELECT MAX(barcode) AS biggest FROM items where barcode LIKE ? AND length(barcode) =?"); >+ my $prefix_search = $self->prefix . '%'; >+ $sth->execute($prefix_search, $self->width); >+ return $self->initial unless ($sth->rows); >+ my ($row) = $sth->fetchrow_hashref(); >+ >+ my $max = $row->{biggest}; >+ return ($max || 0); >+} >+ >+sub initial () { >+ my $self = shift; >+ my $increment_width = $self->width - length($self->prefix); >+ return $self->prefix . sprintf("%"."$increment_width.$increment_width"."d",1); >+} >+ >+sub parse ($;$) { # return 3 parts of barcode: non-incrementing, incrementing, non-incrementing >+ my $self = shift; >+ my $barcode = (@_) ? shift : $self->value; >+ my $prefix = $self->prefix; >+ unless ($barcode =~ /($prefix)(.+)$/) { >+ return($barcode,undef,undef); >+ } >+ return ($1,$2,''); # the third part is in anticipation of barcodes that include checkdigits >+} >+ >+sub prefix ($;$) { >+ my $self = shift; >+ (@_) and $self->{prefix} = shift; >+ return C4::Branch::GetBranchDetail(C4::Context->userenv->{'branch'})->{'itembarcodeprefix'}; >+} >+ >+sub width ($;$) { >+ my $self = shift; >+ (@_) and $width = shift; # hitting the class variable. >+ return $width; >+} >+ >+sub next_value ($;$) { >+ my $self = shift; >+ my $specific = (scalar @_) ? 1 : 0; >+ my $max = $specific ? shift : $self->max; >+ return $self->initial unless ($max); >+ my ($head,$incr,$tail) = $self->parse($max); >+ return undef unless (defined $incr); >+ my $incremented = ''; >+ >+ while ($incr =~ /([a-zA-Z]*[0-9]*)\z/ ){ >+ my $fragment = $1; >+ $fragment++; #yes, you can do that with strings. Clever. >+ if (length($fragment) > length($1)){ #uhoh. got to carry something over. >+ $incremented = substr($fragment,1) . $incremented; >+ $incr = $`; #prematch. grab everything *before* $1 from above, and go back thru this. >+ } >+ else { #we're okay now. >+ $incr = $` . $fragment . $incremented; >+ last; >+ } >+ } >+ >+ my $next_val = $head . $incr .$tail; >+ return $next_val; >+} >+ >+sub new_object { >+ my $class_or_object = shift; >+ my $type = ref($class_or_object) || $class_or_object; >+ my $self = $type->default_self('prefix_incr'); >+ # take the prefix from argument, or the existing object, or get it from the userenv, in that order >+ return bless $self, $type; >+} >+ >+1; >+__END__ >diff --git a/C4/Circulation.pm b/C4/Circulation.pm >index 1a156d9..70c576e 100644 >--- a/C4/Circulation.pm >+++ b/C4/Circulation.pm >@@ -177,6 +177,11 @@ sub barcodedecode { > } > } > } >+ if(C4::Context->preference('itembarcodelength') && (length($barcode) < C4::Context->preference('itembarcodelength'))) { >+ my $prefix = GetBranchDetail(C4::Context->userenv->{'branch'})->{'itembarcodeprefix'} ; >+ my $padding = C4::Context->preference('itembarcodelength') - length($prefix) - length($barcode) ; >+ $barcode = $prefix . '0' x $padding . $barcode if($padding >= 0) ; >+ } > return $barcode; # return barcode, modified or not > } > >diff --git a/C4/ILSDI/Services.pm b/C4/ILSDI/Services.pm >index 067afd7..d4bddde 100644 >--- a/C4/ILSDI/Services.pm >+++ b/C4/ILSDI/Services.pm >@@ -508,7 +508,8 @@ sub GetServices { > > # Issuing management > my $barcode = $item->{'barcode'} || ''; >- $barcode = barcodedecode($barcode) if ( $barcode && C4::Context->preference('itemBarcodeInputFilter') ); >+ $barcode = barcodedecode($barcode) if ( $barcode && C4::Context->preference('itemBarcodeInputFilter') >+ || C4::Context->preference('itembarcodelength') ); > if ($barcode) { > my ( $issuingimpossible, $needsconfirmation ) = CanBookBeIssued( $borrower, $barcode ); > >diff --git a/C4/Items.pm b/C4/Items.pm >index 8025529..3ddf1e0 100644 >--- a/C4/Items.pm >+++ b/C4/Items.pm >@@ -255,6 +255,7 @@ sub AddItem { > $sth->execute( $item->{'biblionumber'} ); > ($item->{'biblioitemnumber'}) = $sth->fetchrow; > >+ _check_itembarcode($item) if (C4::Context->preference('itembarcodelength')); > _set_defaults_for_add($item); > _set_derived_columns_for_add($item); > $item->{'more_subfields_xml'} = _get_unlinked_subfields_xml($unlinked_item_subfields); >@@ -355,6 +356,7 @@ sub AddItemBatchFromMarc { > next ITEMFIELD; > } > >+ _check_itembarcode($item) if (C4::Context->preference('itembarcodelength')); > _set_defaults_for_add($item); > _set_derived_columns_for_add($item); > my ( $itemnumber, $error ) = _koha_new_item( $item, $item->{barcode} ); >@@ -2489,6 +2491,7 @@ sub GetItemHolds { > $holds = $sth->fetchrow; > return $holds; > } >+ > =head1 OTHER FUNCTIONS > > =head2 _find_value >@@ -2755,4 +2758,30 @@ sub PrepareItemrecordDisplay { > }; > } > >+=head2 _check_itembarcode >+ >+=over 4 >+ >+&_check_itembarcode >+ >+=back >+ >+Modifies item barcode value to include prefix defined in branches.itembarcodeprefix >+if the length is less than the syspref itembarcodelength . >+ >+=cut >+sub _check_itembarcode($) { >+ my $item = shift; >+ return(0) unless $item->{'barcode'}; # only modify if we've been passed a barcode. >+ # check item barcode prefix >+ # note this doesn't enforce barcodelength. >+ my $branch_prefix = GetBranchDetail($item->{'homebranch'})->{'itembarcodeprefix'}; >+ if(length($item->{'barcode'}) < C4::Context->preference('itembarcodelength')) { >+ my $padding = C4::Context->preference('itembarcodelength') - length($branch_prefix) - length($item->{'barcode'}) ; >+ $item->{'barcode'} = $branch_prefix . '0' x $padding . $item->{'barcode'} if($padding >= 0) ; >+ } else { >+ # $errors{'invalid_barcode'} = $item->{'barcode'}; >+ } >+} >+ > 1; >diff --git a/C4/Members.pm b/C4/Members.pm >index b81872c..4c5db97 100644 >--- a/C4/Members.pm >+++ b/C4/Members.pm >@@ -33,6 +33,7 @@ use C4::Accounts; > use C4::Biblio; > use C4::SQLHelper qw(InsertInTable UpdateInTable SearchInTable); > use C4::Members::Attributes qw(SearchIdMatchingAttribute); >+use C4::Branch qw(GetBranchDetail); > > our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug); > >@@ -168,10 +169,10 @@ sub _express_member_find { > # so we can check an exact match first, if that works return, otherwise do the rest > my $dbh = C4::Context->dbh; > my $query = "SELECT borrowernumber FROM borrowers WHERE cardnumber = ?"; >- if ( my $borrowernumber = $dbh->selectrow_array($query, undef, $filter) ) { >+ my $cardnum = _prefix_cardnum($filter); >+ if ( my $borrowernumber = $dbh->selectrow_array($query, undef, $cardnum) ) { > return( {"borrowernumber"=>$borrowernumber} ); > } >- > my ($search_on_fields, $searchtype); > if ( length($filter) == 1 ) { > $search_on_fields = [ qw(surname) ]; >@@ -710,6 +711,12 @@ sub ModMember { > $data{password} = md5_base64($data{password}); > } > } >+ >+ # modify cardnumber with prefix, if needed. >+ if(C4::Context->preference('patronbarcodelength') && exists($data{'cardnumber'})){ >+ $data{'cardnumber'} = _prefix_cardnum($data{'cardnumber'}); >+ } >+ > my $execute_success=UpdateInTable("borrowers",\%data); > if ($execute_success) { # only proceed if the update was a success > # ok if its an adult (type) it may have borrowers that depend on it as a guarantor >@@ -745,6 +752,8 @@ sub AddMember { > $data{'userid'} = Generate_Userid($data{'borrowernumber'}, $data{'firstname'}, $data{'surname'}) if $data{'userid'} eq ''; > # create a disabled account if no password provided > $data{'password'} = ($data{'password'})? md5_base64($data{'password'}) : '!'; >+ $data{'cardnumber'} = _prefix_cardnum($data{'cardnumber'}) if(C4::Context->preference('patronbarcodelength')); >+ > $data{'borrowernumber'}=InsertInTable("borrowers",\%data); > # mysql_insertid is probably bad. not necessarily accurate and mysql-specific at best. > logaction("MEMBERS", "CREATE", $data{'borrowernumber'}, "") if C4::Context->preference("BorrowersLog"); >@@ -838,8 +847,8 @@ mode, to avoid database corruption. > use vars qw( @weightings ); > my @weightings = ( 8, 4, 6, 3, 5, 2, 1 ); > >-sub fixup_cardnumber ($) { >- my ($cardnumber) = @_; >+sub fixup_cardnumber { >+ my ($cardnumber,$branch) = @_; > my $autonumber_members = C4::Context->boolean_preference('autoMemberNum') || 0; > > # Find out whether member numbers should be generated >@@ -887,17 +896,47 @@ sub fixup_cardnumber ($) { > > return "V$cardnumber$rem"; > } else { >+ my $cardlength = C4::Context->preference('patronbarcodelength'); >+ if (defined($cardnumber) && (length($cardnumber) == $cardlength) && $cardnumber =~ m/^$branch->{'patronbarcodeprefix'}/ ) { >+ return $cardnumber; >+ } > >- # MODIFIED BY JF: mysql4.1 allows casting as an integer, which is probably >- # better. I'll leave the original in in case it needs to be changed for you >- # my $sth=$dbh->prepare("select max(borrowers.cardnumber) from borrowers"); >- my $sth = $dbh->prepare( >- "select max(cast(cardnumber as signed)) from borrowers" >- ); >- $sth->execute; >- my ($result) = $sth->fetchrow; >- return $result + 1; >- } >+ # increment operator without cast(int) should be safe, and should properly increment >+ # whether the string is numeric or not. >+ # FIXME : This needs to be pulled out into an ajax function, since the interface allows on-the-fly changing of patron home library. >+ # >+ my $query = "select max(borrowers.cardnumber) from borrowers "; >+ my @bind; >+ my $firstnumber = 0; >+ if($branch->{'patronbarcodeprefix'} && $cardlength) { >+ my $cardnum_search = $branch->{'patronbarcodeprefix'} . '%'; >+ $query .= " WHERE cardnumber LIKE ?"; >+ $query .= " AND length(cardnumber) = ?"; >+ @bind = ($cardnum_search,$cardlength ) ; >+ } >+ my $sth= $dbh->prepare($query); >+ $sth->execute(@bind); >+ my ($result) = $sth->fetchrow; >+ $sth->finish; >+ if($result) { >+ my $cnt = 0; >+ $result =~ s/^$branch->{'patronbarcodeprefix'}//; >+ while ( $result =~ /([a-zA-Z]*[0-9]*)\z/ ) { # use perl's magical stringcrement behavior (++). >+ my $incrementable = $1; >+ $incrementable++; >+ if ( length($incrementable) > length($1) ) { # carry a digit to next incrementable fragment >+ $cardnumber = substr($incrementable,1) . $cardnumber; >+ $result = $`; >+ } else { >+ $cardnumber = $branch->{'patronbarcodeprefix'} . $` . $incrementable . $cardnumber ; >+ last; >+ } >+ last if(++$cnt>10); >+ } >+ } else { >+ $cardnumber = ++$firstnumber ; >+ } >+ } > return $cardnumber; # just here as a fallback/reminder > } > >@@ -2229,6 +2268,36 @@ sub DeleteMessage { > logaction("MEMBERS", "DELCIRCMESSAGE", $message->{'borrowernumber'}, $message->{'message'}) if C4::Context->preference("BorrowersLog"); > } > >+=head2 _prefix_cardnum >+ >+=over 4 >+ >+$cardnum = _prefix_cardnum($cardnum,$branchcode); >+ >+If a system-wide barcode length is defined, and a prefix defined for the passed branch or the user's branch, >+modify the barcode by prefixing and padding. >+ >+=back >+=cut >+ >+sub _prefix_cardnum{ >+ my ($cardnum,$branchcode) = @_; >+ >+ if(C4::Context->preference('patronbarcodelength') && (length($cardnum) < C4::Context->preference('patronbarcodelength'))) { >+ #if we have a system-wide cardnum length and a branch prefix, prepend the prefix. >+ if( ! $branchcode && defined(C4::Context->userenv) ) { >+ $branchcode = C4::Context->userenv->{'branch'}; >+ } >+ return $cardnum unless $branchcode; >+ my $branch = GetBranchDetail( $branchcode ); >+ return $cardnum unless( defined($branch) && defined($branch->{'patronbarcodeprefix'}) ); >+ my $prefix = $branch->{'patronbarcodeprefix'} ; >+ my $padding = C4::Context->preference('patronbarcodelength') - length($prefix) - length($cardnum) ; >+ $cardnum = $prefix . '0' x $padding . $cardnum if($padding >= 0) ; >+ } >+ return $cardnum; >+} >+ > END { } # module clean-up code here (global destructor) > > 1; >diff --git a/admin/branches.pl b/admin/branches.pl >index 12c49e2..123999e 100755 >--- a/admin/branches.pl >+++ b/admin/branches.pl >@@ -68,8 +68,10 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user( > } > ); > $template->param( >- script_name => $script_name, >- action => $script_name, >+ script_name => $script_name, >+ action => $script_name, >+ itembarcodelength => C4::Context->preference('itembarcodelength'), >+ patronbarcodelength => C4::Context->preference('patronbarcodelength'), > ); > $template->param( ($op || 'else') => 1 ); > >@@ -393,21 +395,23 @@ sub branchinfotable { > sub _branch_to_template { > my ($data, $template) = @_; > $template->param( >- branchcode => $data->{'branchcode'}, >- branch_name => $data->{'branchname'}, >- branchaddress1 => $data->{'branchaddress1'}, >- branchaddress2 => $data->{'branchaddress2'}, >- branchaddress3 => $data->{'branchaddress3'}, >- branchzip => $data->{'branchzip'}, >- branchcity => $data->{'branchcity'}, >- branchstate => $data->{'branchstate'}, >- branchcountry => $data->{'branchcountry'}, >- branchphone => $data->{'branchphone'}, >- branchfax => $data->{'branchfax'}, >- branchemail => $data->{'branchemail'}, >- branchurl => $data->{'branchurl'}, >- branchip => $data->{'branchip'}, >- branchnotes => $data->{'branchnotes'}, >+ branchcode => $data->{'branchcode'}, >+ branch_name => $data->{'branchname'}, >+ branchaddress1 => $data->{'branchaddress1'}, >+ branchaddress2 => $data->{'branchaddress2'}, >+ branchaddress3 => $data->{'branchaddress3'}, >+ branchzip => $data->{'branchzip'}, >+ branchcity => $data->{'branchcity'}, >+ branchstate => $data->{'branchstate'}, >+ branchcountry => $data->{'branchcountry'}, >+ branchphone => $data->{'branchphone'}, >+ branchfax => $data->{'branchfax'}, >+ branchemail => $data->{'branchemail'}, >+ branchurl => $data->{'branchurl'}, >+ branchip => $data->{'branchip'}, >+ branchnotes => $data->{'branchnotes'}, >+ itembarcodeprefix => $data->{'itembarcodeprefix'}, >+ patronbarcodeprefix => $data->{'patronbarcodeprefix'}, > ); > } > >diff --git a/admin/systempreferences.pl b/admin/systempreferences.pl >index f4069ae..f349390 100755 >--- a/admin/systempreferences.pl >+++ b/admin/systempreferences.pl >@@ -124,6 +124,8 @@ $tabsysprefs{soundon} = "Admin"; > $tabsysprefs{SpineLabelShowPrintOnBibDetails} = "Admin"; > $tabsysprefs{WebBasedSelfCheckHeader} = "Admin"; > $tabsysprefs{WebBasedSelfCheckTimeout} = "Admin"; >+$tabsysprefs{itembarcodelength} = "Admin"; >+$tabsysprefs{patronbarcodelength} = "Admin"; > > # Authorities > $tabsysprefs{authoritysep} = "Authorities"; >diff --git a/cataloguing/additem.pl b/cataloguing/additem.pl >index 4bf06b5..794bb44 100755 >--- a/cataloguing/additem.pl >+++ b/cataloguing/additem.pl >@@ -348,6 +348,14 @@ if ($op eq "additem") { > push @errors,"barcode_not_unique" if($exist_itemnumber); > # if barcode exists, don't create, but report The problem. > unless ($exist_itemnumber) { >+ unless ($addedolditem->{'barcode'}) { >+ use C4::Barcodes; >+ my $barcodeobj = C4::Barcodes->new(); >+ my $db_max = $barcodeobj->db_max(); >+ my $nextbarcode = $barcodeobj->next_value($db_max); >+ my ($tagfield,$tagsubfield) = &GetMarcFromKohaField("items.barcode",$frameworkcode); >+ $record->field($tagfield)->update($tagsubfield => "$nextbarcode") if ($nextbarcode); >+ } > my ($oldbiblionumber,$oldbibnum,$oldbibitemnum) = AddItemFromMarc($record,$biblionumber); > set_item_default_location($oldbibitemnum); > } >diff --git a/circ/circulation.pl b/circ/circulation.pl >index e8d22cb..5023e3b 100755 >--- a/circ/circulation.pl >+++ b/circ/circulation.pl >@@ -119,7 +119,8 @@ if (C4::Context->preference("UseTablesortForCirc")) { > my $barcode = $query->param('barcode') || ''; > $barcode =~ s/^\s*|\s*$//g; # remove leading/trailing whitespace > >-$barcode = barcodedecode($barcode) if( $barcode && C4::Context->preference('itemBarcodeInputFilter')); >+$barcode = barcodedecode($barcode) if( $barcode && (C4::Context->preference('itemBarcodeInputFilter') >+ || C4::Context->preference('itembarcodelength'))); > my $stickyduedate = $query->param('stickyduedate') || $session->param('stickyduedate'); > my $duedatespec = $query->param('duedatespec') || $session->param('stickyduedate'); > my $issueconfirmed = $query->param('issueconfirmed'); >diff --git a/circ/returns.pl b/circ/returns.pl >index e142117..5014121 100755 >--- a/circ/returns.pl >+++ b/circ/returns.pl >@@ -107,7 +107,8 @@ foreach ( $query->param ) { > > # decode barcode ## Didn't we already decode them before passing them back last time?? > $barcode =~ s/^\s*|\s*$//g; # remove leading/trailing whitespace >- $barcode = barcodedecode($barcode) if(C4::Context->preference('itemBarcodeInputFilter')); >+ $barcode = barcodedecode($barcode) if(C4::Context->preference('itemBarcodeInputFilter') >+ || C4::Context->preference('itembarcodelength')); > > ###################### > #Are these lines still useful ? >@@ -201,7 +202,8 @@ if ($canceltransfer){ > # actually return book and prepare item table..... > if ($barcode) { > $barcode =~ s/^\s*|\s*$//g; # remove leading/trailing whitespace >- $barcode = barcodedecode($barcode) if C4::Context->preference('itemBarcodeInputFilter'); >+ $barcode = barcodedecode($barcode) if (C4::Context->preference('itemBarcodeInputFilter') >+ || C4::Context->preference('itembarcodelength')); > $itemnumber = GetItemnumberFromBarcode($barcode); > > if ( C4::Context->preference("InProcessingToShelvingCart") ) { >diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql >index 597a8be..4bf9249 100644 >--- a/installer/data/mysql/kohastructure.sql >+++ b/installer/data/mysql/kohastructure.sql >@@ -361,6 +361,8 @@ CREATE TABLE `branches` ( -- information about your libraries or branches are st > `branchip` varchar(15) default NULL, -- the IP address for your library or branch > `branchprinter` varchar(100) default NULL, -- unused in Koha > `branchnotes` mediumtext, -- notes related to your library or branch >+ `itembarcodeprefix` varchar(10) default NULL, -- branch's item barcode prefix >+ `patronbarcodeprefix` varchar(10) default NULL, -- branch's patron barcode prefix > UNIQUE KEY `branchcode` (`branchcode`) > ) ENGINE=InnoDB DEFAULT CHARSET=utf8; > >diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql >index 8f289d6..3729a3c 100644 >--- a/installer/data/mysql/sysprefs.sql >+++ b/installer/data/mysql/sysprefs.sql >@@ -53,6 +53,7 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES > INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('IssuingInProcess',0,'If ON, disables fines if the patron is issuing item that accumulate debt',NULL,'YesNo'); > INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('item-level_itypes',1,'If ON, enables Item-level Itemtype / Issuing Rules','','YesNo'); > INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('itemcallnumber','082ab','The MARC field/subfield that is used to calculate the itemcallnumber (Dewey would be 082ab or 092ab; LOC would be 050ab or 090ab) could be 852hi from an item record',NULL,'free'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('itembarcodelength','','Number of characters in system-wide barcode schema (item barcodes).','','Integer'); > INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('DefaultClassificationSource','ddc','Default classification scheme used by the collection. E.g., Dewey, LCC, etc.', NULL,'ClassSources'); > INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('KohaAdminEmailAddress','root@localhost','Define the email address where patron modification requests are sent','','free'); > INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('LabelMARCView','standard','Define how a MARC record will display','standard|economical','Choice'); >@@ -95,6 +96,7 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES > INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('OpacPublic',1,'Turn on/off public OPAC',NULL,'YesNo'); > INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opacuserjs','','Define custom javascript for inclusion in OPAC','70|10','Textarea'); > INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('opacuserlogin',1,'Enable or disable display of user login features',NULL,'YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('patronbarcodelength','','Number of characters in system-wide barcode schema (patron cardnumbers).','','Integer'); > INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('patronimages',0,'Enable patron images for the Staff Client',NULL,'YesNo'); > INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('printcirculationslips',1,'If ON, enable printing circulation receipts','','YesNo'); > INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('RecordLocalUseOnReturn',0,'If ON, statistically record returns of unissued items as local use, instead of return',NULL,'YesNo'); >diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl >index e540874..353b2a0 100755 >--- a/installer/data/mysql/updatedatabase.pl >+++ b/installer/data/mysql/updatedatabase.pl >@@ -4734,6 +4734,17 @@ if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { > SetVersion($DBversion); > } > >+ >+$DBversion = "3.07.00.XXX"; >+if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { >+ $dbh->do("ALTER TABLE `branches` ADD `itembarcodeprefix` VARCHAR( 10 ) NULL AFTER `branchnotes`"); >+ $dbh->do("ALTER TABLE `branches` ADD `patronbarcodeprefix` VARCHAR( 10 ) NULL AFTER `itembarcodeprefix`"); >+ $dbh->do("INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('itembarcodelength','','Number of characters in system-wide barcode schema (item barcodes).','','Integer')"); >+ $dbh->do("INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('patronbarcodelength','','Number of characters in system-wide barcode schema (patron cardnumbers).','','Integer')"); >+ print "Upgrade to $DBversion done (Add barcode prefix feature. Add fields itembarcodeprefix and patronbarcodeprefix to table branches, add sysprefs itembarcodelength and patronbarcodelength)\n"; >+ SetVersion($DBversion); >+} >+ > =head1 FUNCTIONS > > =head2 DropAllForeignKeys($table) >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/branches.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/branches.tt >index df5e56c..e9d8d9f 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/branches.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/branches.tt >@@ -123,6 +123,12 @@ > <li><label for="branchemail">Email</label><input type="text" name="branchemail" id="branchemail" value="[% branchemail |html %]" /></li> > <li><label for="branchurl">url</label><input type="text" name="branchurl" id="branchurl" value="[% branchurl |html %]" /></li> > <li><label for="branchip">IP</label><input type="text" name="branchip" id="branchip" value="[% branchip |html %]" /> <span class="hint">Can be entered as a single IP, or a subnet such as 192.168.1.*</span></li> >+ [% IF ( itembarcodelength ) %] >+ <li><label for="itembarcodeprefix">Item Barcode Prefix</label><input type="text" name="itembarcodeprefix" id="itembarcodeprefix" value="[% itembarcodeprefix |html %]" /></li> >+ [% END %] >+ [% IF ( patronbarcodelength ) %] >+ <li><label for="patronbarcodeprefix">Patron Barcode Prefix</label><input type="text" name="patronbarcodeprefix" id="patronbarcodeprefix" value="[% patronbarcodeprefix |html %]" /></li> >+ [% END %] > <!-- > <li><label for="branchprinter">Library Printer</label> > <select id="branchprinter" name="branchprinter"> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/admin.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/admin.pref >index f026c7e..d9d71ad 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/admin.pref >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/admin.pref >@@ -40,6 +40,16 @@ Administration: > yes: Allow > no: "Don't allow" > - staff and patrons to create and view saved lists of books. >+ - >+ - Use branch prefixes to ensure that item barcodes are >+ - pref: itembarcodelength >+ class: integer >+ - digits long >+ - >+ - Use branch prefixes to ensure that patron barcodes are >+ - pref: patronbarcodelength >+ class: integer >+ - digits long > Login options: > - > - pref: insecure >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 10e1d13..7673cd4 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 >@@ -86,6 +86,7 @@ Cataloging: > - Barcodes are > - pref: autoBarcode > choices: >+ prefix_incr: generated with the branch prefix, followed by a zero-padded form of 1, 2, 3. > incremental: generated in the form 1, 2, 3. > annual: generated in the form <year>-0001, <year>-0002. > hbyymmincr: generated in the form <branchcode>yymm0001. >diff --git a/members/memberentry.pl b/members/memberentry.pl >index 86dd6ed..b44f784 100755 >--- a/members/memberentry.pl >+++ b/members/memberentry.pl >@@ -422,7 +422,14 @@ if ( $op eq "duplicate" ) { > $template->param( step_1 => 1, step_2 => 1, step_3 => 1, step_4 => 1, step_5 => 1, step_6 => 1 ) unless $step; > } > >-$data{'cardnumber'}=fixup_cardnumber($data{'cardnumber'}) if $op eq 'add'; >+my $onlymine=(C4::Context->preference('IndependantBranches') && >+ C4::Context->userenv && >+ C4::Context->userenv->{flags} % 2 !=1 && >+ C4::Context->userenv->{branch}?1:0); >+ >+my $branches=GetBranches($onlymine); >+$data{'cardnumber'}=fixup_cardnumber( $data{'cardnumber'}, $branches->{C4::Context->userenv->{'branch'}} ) if $op eq 'add'; >+ > if(!defined($data{'sex'})){ > $template->param( none => 1); > } elsif($data{'sex'} eq 'F'){ >@@ -559,12 +566,6 @@ my @branches; > my @select_branch; > my %select_branches; > >-my $onlymine=(C4::Context->preference('IndependantBranches') && >- C4::Context->userenv && >- C4::Context->userenv->{flags} % 2 !=1 && >- C4::Context->userenv->{branch}?1:0); >- >-my $branches=GetBranches($onlymine); > my $default; > my $CGIbranch; > for my $branch (sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } keys %$branches) { >diff --git a/offline_circ/process_koc.pl b/offline_circ/process_koc.pl >index 736d918..ccd54f6 100755 >--- a/offline_circ/process_koc.pl >+++ b/offline_circ/process_koc.pl >@@ -240,7 +240,7 @@ sub arguments_for_command { > sub kocIssueItem { > my $circ = shift; > >- $circ->{ 'barcode' } = barcodedecode($circ->{'barcode'}) if( $circ->{'barcode'} && C4::Context->preference('itemBarcodeInputFilter')); >+ $circ->{ 'barcode' } = barcodedecode($circ->{'barcode'}) if( $circ->{'barcode'} && (C4::Context->preference('itemBarcodeInputFilter') || C4::Context->preference('itembarcodelength'))); > my $branchcode = C4::Context->userenv->{branch}; > my $borrower = GetMember( 'cardnumber'=>$circ->{ 'cardnumber' } ); > my $item = GetBiblioFromItemNumber( undef, $circ->{ 'barcode' } ); >@@ -318,7 +318,7 @@ sub kocIssueItem { > > sub kocReturnItem { > my ( $circ ) = @_; >- $circ->{'barcode'} = barcodedecode($circ->{'barcode'}) if( $circ->{'barcode'} && C4::Context->preference('itemBarcodeInputFilter')); >+ $circ->{'barcode'} = barcodedecode($circ->{'barcode'}) if( $circ->{'barcode'} && (C4::Context->preference('itemBarcodeInputFilter') || C4::Context->preference('itembarcodelength'))); > my $item = GetBiblioFromItemNumber( undef, $circ->{ 'barcode' } ); > #warn( Data::Dumper->Dump( [ $circ, $item ], [ qw( circ item ) ] ) ); > my $borrowernumber = _get_borrowernumber_from_barcode( $circ->{'barcode'} ); >diff --git a/tools/import_borrowers.pl b/tools/import_borrowers.pl >index 83db522..26bf52a 100755 >--- a/tools/import_borrowers.pl >+++ b/tools/import_borrowers.pl >@@ -41,7 +41,7 @@ use C4::Auth; > use C4::Output; > use C4::Dates qw(format_date_in_iso); > use C4::Context; >-use C4::Branch qw(GetBranchName); >+use C4::Branch qw(GetBranchName GetBranches); > use C4::Members; > use C4::Members::Attributes qw(:all); > use C4::Members::AttributeTypes; >@@ -271,7 +271,13 @@ if ( $uploadborrowers && length($uploadborrowers) > 0 ) { > # FIXME: fixup_cardnumber says to lock table, but the web interface doesn't so this doesn't either. > # At least this is closer to AddMember than in members/memberentry.pl > if (!$borrower{'cardnumber'}) { >- $borrower{'cardnumber'} = fixup_cardnumber(undef); >+ my $onlymine=(C4::Context->preference('IndependantBranches') && >+ C4::Context->userenv && >+ C4::Context->userenv->{flags} % 2 !=1 && >+ C4::Context->userenv->{branch}?1:0); >+ >+ my $branches=GetBranches($onlymine); >+ $borrower{'cardnumber'} = fixup_cardnumber(undef,$branches->{$borrower{'branchcode'}}); > } > if ($borrowernumber = AddMember(%borrower)) { > if ($extended) { >diff --git a/tools/inventory.pl b/tools/inventory.pl >index 5e7b198..9641658 100755 >--- a/tools/inventory.pl >+++ b/tools/inventory.pl >@@ -150,6 +150,12 @@ if ($uploadbarcodes && length($uploadbarcodes)>0){ > my $count=0; > while (my $barcode=<$uploadbarcodes>){ > $barcode =~ s/\r?\n$//; >+ if(C4::Context->preference('itembarcodelength') && (length($barcode) < C4::Context->preference('itembarcodelength'))) { >+ my $prefix = GetBranchDetail(C4::Context->userenv->{'branch'})->{'itembarcodeprefix'} ; >+ my $padding = C4::Context->preference('itembarcodelength') - length($prefix) - length($barcode) ; >+ $barcode = $prefix . '0' x $padding . $barcode if($padding >= 0) ; >+ } >+ > if ($qwthdrawn->execute($barcode) &&$qwthdrawn->rows){ > push @errorloop, {'barcode'=>$barcode,'ERR_WTHDRAWN'=>1}; > }else{ >-- >1.7.2.5
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 7676
:
8090
|
8091
|
8094
|
8673
|
8674
|
10720
|
10721
|
10819
|
13249