From a68c04a4677811b5e2135f8eea1536b2066248cc Mon Sep 17 00:00:00 2001 From: Saiful Amin Date: Mon, 8 Dec 2025 19:18:32 +0000 Subject: [PATCH] Bug 41383: Allow patron identification by custom unique attributes in find_by_identifier 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. Apply the patch. 2. Run the tests: prove t/db_dependent/Koha/Patrons.t - Verify that all tests pass, including the new cases for unique attribute lookup. 3. Functional Verification: - Define a new patron attribute type with 'unique_id' set to 1. - Assign a value to a patron for this attribute. - Use a tool (like the SIP2 emulator) that utilizes Koha::Patrons->find_by_identifier 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 the patron is found. - Try with a non-unique attribute (unique_id=0) and verify the patron is NOT found. --- Koha/Patrons.pm | 13 +++++++++ t/db_dependent/Koha/Patrons.t | 51 ++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/Koha/Patrons.pm b/Koha/Patrons.pm index 064ee9f..4efbb48 100644 --- a/Koha/Patrons.pm +++ b/Koha/Patrons.pm @@ -63,6 +63,19 @@ 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' }, + } + )->next; + } + return $patron; } diff --git a/t/db_dependent/Koha/Patrons.t b/t/db_dependent/Koha/Patrons.t index 6dad68f..fbc3ab1 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; @@ -3582,7 +3584,7 @@ subtest 'filter_by_expired_opac_registrations' => sub { subtest 'find_by_identifier() tests' => sub { - plan tests => 7; + plan tests => 9; $schema->storage->txn_begin; @@ -3622,6 +3624,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.39.5