From 5fc06aa9330d9451922ab405cafbd35494899511 Mon Sep 17 00:00:00 2001 From: Ian Walls 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 + .../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 + 20 files changed, 329 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/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 @@
  • Can be entered as a single IP, or a subnet such as 192.168.1.*
  • + [% IF ( itembarcodelength ) %] +
  • + [% END %] + [% IF ( patronbarcodelength ) %] +
  • + [% END %]