From 85cec37ce5370ec0333d05438fc3537833942160 Mon Sep 17 00:00:00 2001 From: Saiful Amin Date: Mon, 8 Dec 2025 19:18:32 +0000 Subject: [PATCH] Bug 41383: SIP2 server does not search patrons by unique patron attributes (alternate IDs unusable in SIP2) Currently, Koha::Patrons->find_by_identifier only searches for patrons by userid and cardnumber. This patch extends this method to also search by unique borrower attributes (where unique_id=1). This enhancement allows modules like SIP2 to identify patrons using alternative unique identifiers defined in the system. Test Plan: 1. Test current behaviour: - Go to Administration -> Patron attribute types - Create a new Patron attribute with: - Patron attribute type code = "AltID" - Description = "Alternate ID" - Unique identifier checkbox selected - Save - Edit any patron record and go to Additional attributes and identifiers - Add a value "altid123" to "Alternate ID" - Save - Use any SIP2 client to search for the patron using this attribute value. e.g., `perl misc/sip_cli_emulator.pl -su term1 -sp term1 -l CPL --host localhost --patron altid123 -m patron_information` - Verify that the patron is NOT found with this message: 'AFInvalid cardnumber' e.g.: READ: 64YYYY 00120260304 104611000000000000000000000000AOCPL|AAaltid123|AE|BLN|AFInvalid cardnumber| 2. Apply the patch. 3. Run the tests: prove t/db_dependent/Koha/Patrons.t - Verify that all tests pass, including the new cases for unique attribute lookup. 4. Test with patch applied: - Use any SIP2 client to search for the patron using this attribute value. e.g., `perl misc/sip_cli_emulator.pl -su term1 -sp term1 -l CPL --host localhost --patron altid123 -m patron_information` - Verify that the patron is found with this message: 'AFGreetings from Koha.' e.g.: READ: 64 00120260304 104328000000000000000000000000AOCPL|AA23529001000463|AEEdna Acosta|BLY|BHUSD|BV0|CC5|BD7896 Library Rd. Portland, OR 44240|BF(212) 555-1212|PB19800424|PCPT|PIY|AFGreetings from Koha. | 5. Test non-unique attribute: - Go to Administration -> Patron attribute types - Edit "Alternate ID" attribute type - Unique identifier checkbox NOT selected - Save - Use any SIP2 client to search for the patron using this attribute value. e.g., `perl misc/sip_cli_emulator.pl -su term1 -sp term1 -l CPL --host localhost --patron altid123 -m patron_information` - Verify that the patron is NOT found with this message: 'AFInvalid cardnumber' e.g.: READ: 64YYYY 00120260304 104611000000000000000000000000AOCPL|AAaltid123|AE|BLN|AFInvalid cardnumber| 6. Sign-off Signed-off-by: Syed Faheemuddin Signed-off-by: Martin Renvoize --- Koha/Patrons.pm | 14 ++++++++++ t/db_dependent/Koha/Patrons.t | 51 ++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/Koha/Patrons.pm b/Koha/Patrons.pm index 8b802bdb53a..2bafea19ea5 100644 --- a/Koha/Patrons.pm +++ b/Koha/Patrons.pm @@ -64,6 +64,20 @@ sub find_by_identifier { # If not found by userid, try cardnumber $patron = $self->search( { cardnumber => $identifier } )->next unless $patron; + # If not found by cardnumber, try unique patron attributes + unless ($patron) { + $patron = $self->search( + { + 'borrower_attributes.attribute' => $identifier, + 'code.unique_id' => 1, + }, + { + join => { 'borrower_attributes' => 'code' }, + rows => 1, + } + )->single; + } + return $patron; } diff --git a/t/db_dependent/Koha/Patrons.t b/t/db_dependent/Koha/Patrons.t index ac59a91f522..0636b90105e 100755 --- a/t/db_dependent/Koha/Patrons.t +++ b/t/db_dependent/Koha/Patrons.t @@ -39,6 +39,8 @@ use Koha::Holds; use Koha::Old::Holds; use Koha::Patrons; use Koha::Old::Patrons; +use Koha::Patron::Attribute; +use Koha::Patron::Attribute::Type; use Koha::Patron::Attribute::Types; use Koha::Patron::Categories; use Koha::Patron::Relationship; @@ -3764,7 +3766,7 @@ subtest 'filter_by_expired_opac_registrations' => sub { subtest 'find_by_identifier() tests' => sub { - plan tests => 7; + plan tests => 9; $schema->storage->txn_begin; @@ -3804,6 +3806,53 @@ subtest 'find_by_identifier() tests' => sub { $found_patron = Koha::Patrons->find_by_identifier(undef); is( $found_patron, undef, 'Returns undef for undef identifier' ); + # Test with unique attributes + my $unique_code = 'UA_' . int( rand(100000) ); + Koha::Patron::Attribute::Type->new( + { + code => $unique_code, + description => 'Unique Attribute', + unique_id => 1, + repeatable => 0, + } + )->store; + + my $non_unique_code = 'NUA_' . int( rand(100000) ); + Koha::Patron::Attribute::Type->new( + { + code => $non_unique_code, + description => 'Non-Unique Attribute', + unique_id => 0, + repeatable => 0, + } + )->store; + + my $patron_u = $builder->build_object( { class => 'Koha::Patrons' } ); + my $val_u = 'VAL_U_' . int( rand(100000) ); + Koha::Patron::Attribute->new( + { + borrowernumber => $patron_u->borrowernumber, + code => $unique_code, + attribute => $val_u, + } + )->store; + + my $patron_nu = $builder->build_object( { class => 'Koha::Patrons' } ); + my $val_nu = 'VAL_NU_' . int( rand(100000) ); + Koha::Patron::Attribute->new( + { + borrowernumber => $patron_nu->borrowernumber, + code => $non_unique_code, + attribute => $val_nu, + } + )->store; + + $found_patron = Koha::Patrons->find_by_identifier($val_u); + is( $found_patron ? $found_patron->id : undef, $patron_u->id, 'Found patron by unique attribute' ); + + $found_patron = Koha::Patrons->find_by_identifier($val_nu); + is( $found_patron, undef, 'Did not find patron by non-unique attribute' ); + $schema->storage->txn_rollback; }; -- 2.53.0