Bug 26352: Add plugin hooks to transform patron barcodes

Some of our partners have unusual barcode requirements that have
required us to transform scanned barcodes using javascript. This is not
the most reliable method. It would make more sense to have Koha
transform the barcodes on the backend using a plugin. We should add
hooks to transform and generate new item and patron barcodes.

Test Plan:
1) Apply this patch
2) Download and install the Barcode Transformer plugin
   https://github.com/bywatersolutions/koha-plugin-barcode-transformer/releases/download/v1.0.1/koha-plugin-barcode-transformer-v1.0.1.kpz
3) Go to the plugin configuration page, set the configuration to the example configuration from the same page
4) In the patron search and anywhere else you can scan a patron
   cardnumber, type in some cardnumbers but prefix them with A and postfix
   them with A or B, e.g. A12345A, A12345B
5) Note the letters are removed by Koha!
6) Try a cardnumber like X123456Y
7) Note Koha converts it to Z13456Z

Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
This commit is contained in:
Kyle M Hall 2020-09-02 09:22:57 -04:00 committed by Jonathan Druart
parent b2b1483f4d
commit aea8ce7fcc
5 changed files with 31 additions and 2 deletions

View File

@ -20,6 +20,7 @@ use C4::Auth qw(&check_api_auth);
use Koha::Patrons;
use Koha::Patron::Attributes;
use Koha::Plugins;
use Koha::Items;
use UNIVERSAL::can;
@ -520,6 +521,7 @@ sub handle_checkout {
$fields = $self->{fields};
$patron_id = $fields->{ (FID_PATRON_ID) };
($patron_id) = Koha::Plugins->call('patron_barcode_transform', $patron_id ) || $patron_id;
$item_id = $fields->{ (FID_ITEM_ID) };
my $fee_ack = $fields->{ (FID_FEE_ACK) };
@ -741,6 +743,8 @@ sub handle_block_patron {
$patron_id = $fields->{ (FID_PATRON_ID) };
$terminal_pwd = $fields->{ (FID_TERMINAL_PWD) };
($patron_id) = Koha::Plugins->call('patron_barcode_transform', $patron_id ) || $patron_id;
# Terminal passwords are different from account login
# passwords, but I have no idea what to do with them. So,
# I'll just ignore them for now.
@ -965,6 +969,8 @@ sub handle_patron_info {
$start = $fields->{ (FID_START_ITEM) };
$end = $fields->{ (FID_END_ITEM) };
($patron_id) = Koha::Plugins->call('patron_barcode_transform', $patron_id ) || $patron_id;
$patron = $ils->find_patron($patron_id);
$resp = (PATRON_INFO_RESP);
@ -1122,6 +1128,8 @@ sub handle_fee_paid {
$fee_id = $fields->{ (FID_FEE_ID) };
$trans_id = $fields->{ (FID_TRANSACTION_ID) };
($patron_id) = Koha::Plugins->call('patron_barcode_transform', $patron_id ) || $patron_id;
$ils->check_inst_id( $inst_id, "handle_fee_paid" );
my $pay_result = $ils->pay_fee( $patron_id, $patron_pwd, $fee_amt, $fee_type, $pay_type, $fee_id, $trans_id, $currency, $is_writeoff, $disallow_overpayment, $register_id );
@ -1324,6 +1332,8 @@ sub handle_patron_enable {
$patron_id = $fields->{ (FID_PATRON_ID) };
$patron_pwd = $fields->{ (FID_PATRON_PWD) };
($patron_id) = Koha::Plugins->call('patron_barcode_transform', $patron_id ) || $patron_id;
siplog( "LOG_DEBUG", "handle_patron_enable: patron_id: '%s', patron_pwd: '%s'", $patron_id, $patron_pwd );
$patron = $ils->find_patron($patron_id);
@ -1387,6 +1397,8 @@ sub handle_hold {
$title_id = $fields->{ (FID_TITLE_ID) } || '';
$fee_ack = $fields->{ (FID_FEE_ACK) } || 'N';
($patron_id) = Koha::Plugins->call('patron_barcode_transform', $patron_id ) || $patron_id;
if ( $hold_mode eq '+' ) {
$status = $ils->add_hold( $patron_id, $patron_pwd, $item_id, $title_id, $expiry_date, $pickup_locn, $hold_type, $fee_ack );
} elsif ( $hold_mode eq '-' ) {
@ -1452,6 +1464,8 @@ sub handle_renew {
$item_props = $fields->{ (FID_ITEM_PROPS) };
$fee_ack = $fields->{ (FID_FEE_ACK) };
($patron_id) = Koha::Plugins->call('patron_barcode_transform', $patron_id ) || $patron_id;
$status = $ils->renew( $patron_id, $patron_pwd, $item_id, $title_id, $no_block, $nb_due_date, $third_party, $item_props, $fee_ack );
$patron = $status->patron;
@ -1533,6 +1547,8 @@ sub handle_renew_all {
$terminal_pwd = $fields->{ (FID_TERMINAL_PWD) };
$fee_ack = $fields->{ (FID_FEE_ACK) };
($patron_id) = Koha::Plugins->call('patron_barcode_transform', $patron_id ) || $patron_id;
$status = $ils->renew_all( $patron_id, $patron_pwd, $fee_ack );
$resp .= $status->ok ? '1' : '0';

View File

@ -111,7 +111,10 @@ Autogenerate next cardnumber from highest value found in database
sub fixup_cardnumber {
my ( $self ) = @_;
my $max = Koha::Patrons->search({
my ( $max ) = Koha::Plugins->call( 'barcode_generate', 'patron', $self );
$max ||= Koha::Patrons->search({
cardnumber => {-regexp => '^-?[0-9]+$'}
}, {
select => \'CAST(cardnumber AS SIGNED)',
@ -198,6 +201,9 @@ sub store {
$self->trim_whitespaces;
my ( $new_cardnumber ) = Koha::Plugins->call( 'patron_barcode_transform', $self->cardnumber ) || $self->cardnumber;
$self->cardnumber( $new_cardnumber );
# Set surname to uppercase if uppercasesurname is true
$self->surname( uc($self->surname) )
if C4::Context->preference("uppercasesurnames");

View File

@ -75,7 +75,8 @@ my $autoswitched;
my $borrowernumber = $query->param('borrowernumber');
if (C4::Context->preference("AutoSwitchPatron") && $barcode) {
if (Koha::Patrons->search( { cardnumber => $barcode} )->count() > 0) {
my ( $new_barcode ) = Koha::Plugins->call( 'patron_barcode_transform', $findborrower ) || $findborrower;
if (Koha::Patrons->search( { cardnumber => $new_barcode} )->count() > 0) {
$findborrower = $barcode;
undef $barcode;
undef $borrowernumber;
@ -220,6 +221,7 @@ if ( @$barcodes == 0 && $charges eq 'yes' ) {
#
my $message;
if ($findborrower) {
( $findborrower ) = Koha::Plugins->call( 'patron_barcode_transform', $findborrower ) || $findborrower;
my $patron = Koha::Patrons->find( { cardnumber => $findborrower } );
if ( $patron ) {
$borrowernumber = $patron->borrowernumber;

View File

@ -44,6 +44,7 @@ use Koha::Patron::Attribute::Types;
use Koha::Patron::Categories;
use Koha::Patron::HouseboundRole;
use Koha::Patron::HouseboundRoles;
use Koha::Plugins;
use Koha::Token;
use Koha::SMS::Providers;
@ -324,6 +325,9 @@ if ($op eq 'save' || $op eq 'insert'){
# If the cardnumber is blank, treat it as null.
$newdata{'cardnumber'} = undef if $newdata{'cardnumber'} =~ /^\s*$/;
my ( $new_barcode ) = Koha::Plugins->call( 'patron_barcode_transform', $newdata{'cardnumber'} ) || $newdata{'cardnumber'};
$newdata{'cardnumber'} = $new_barcode;
if (my $error_code = checkcardnumber( $newdata{cardnumber}, $borrowernumber )){
push @errors, $error_code == 1
? 'ERROR_cardnumber_already_exists'

View File

@ -120,6 +120,7 @@ if (C4::Context->preference('SelfCheckoutByLogin') && !$patronid) {
my ( $borrower, $patron );
if ( $patronid ) {
( $patronid ) = Koha::Plugins->call( 'patron_barcode_transform', $patronid ) || $patronid;
$patron = Koha::Patrons->find( { cardnumber => $patronid } );
$borrower = $patron->unblessed if $patron;
}