From 67ddfc47e3736f88985c23d24f0be11b6965c3a1 Mon Sep 17 00:00:00 2001 From: Jake Deery Date: Wed, 11 Feb 2026 09:16:49 +0000 Subject: [PATCH] Bug 41814: Add PatronAgeRestriction syspref and code This patch adds a new PatronAgeRestriction, which acts in the same way PatronSelfRegistrationAgeRestriction (a restriction on the maximum age of a borrower), except for the intranet. It will also act as the maximum age restrictor on the OPAC, in the event that the PatronSelfRegistrationAgeRestriction is not set. To test: == APPLY PATCH == a) updatedatabase b) Set the PatronAgeRestriction syspref to 20, set the PatronSelfRegistrationAgeRestriction to 30 c) On the OPAC, try to create or modify a patron whose age is 35 years *) Note the error message presented, suggesting the age exceeds the maximum d) On the OPAC, try to create or modify a patron whose age is 25 years *) Note the submission succeeds e) On the staff client, try to create or modify a patron whose age is 25 years *) Note the error message presented, suggesting the age exceeds the maximum f) Set the PatronSelfRegistrationAgeRestriction to empty g) On the OPAC, try to create or modify a patron whose age is 25 years *) Note the error message presented, suggesting the age exceeds the maximum h) On the OPAC, try to create or modify a patron whose age is 19 years *) Note the submission succeeds i) Set the PatronAgeRestriction to empty j) On the staff client, try to create or modify a patron whose age is 75 years *) Note the submission succeeds k) On the OPAC, try to create or modify a patron whose age is 75 years *) Note the submission succeeds == SIGN OFF == Signed-off-by: Owen Leonard Signed-off-by: Katrin Fischer --- .../data/mysql/atomicupdate/bug_xxxxx.pl | 26 +++++++++++++++++++ installer/data/mysql/mandatory/sysprefs.sql | 3 ++- .../prog/en/includes/patron_messages.inc | 10 ++++++- .../en/modules/admin/preferences/opac.pref | 2 +- .../en/modules/admin/preferences/patrons.pref | 5 ++++ .../prog/en/modules/members/memberentrygen.tt | 3 +++ .../bootstrap/en/modules/opac-memberentry.tt | 4 +-- members/memberentry.pl | 7 +++++ opac/opac-memberentry.pl | 11 +++++--- 9 files changed, 63 insertions(+), 8 deletions(-) create mode 100755 installer/data/mysql/atomicupdate/bug_xxxxx.pl diff --git a/installer/data/mysql/atomicupdate/bug_xxxxx.pl b/installer/data/mysql/atomicupdate/bug_xxxxx.pl new file mode 100755 index 00000000000..6cba0c59ddc --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_xxxxx.pl @@ -0,0 +1,26 @@ +use Modern::Perl; +use Koha::Installer::Output qw(say_warning say_success say_info); + +return { + bug_number => "XXXXX", + description => "Add a new syspref for PatronAgeRestriction", + up => sub { + my ($args) = @_; + my ( $dbh, $out ) = @$args{qw(dbh out)}; + + # Do you stuffs here + $dbh->do( + q{ + INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES ('PatronAgeRestriction', '', NULL, 'Patron\'s maximum age during registration. If empty, no age restriction is applied.', 'Integer') + } + ); + say $out "Added new syspref 'PatronAgeRestriction'"; + + $dbh->do( + q{ + UPDATE IGNORE systempreferences SET `explanation` = 'Patron\'s maximum age during self registration. If empty, honor PatronAgeRestriction.' WHERE `variable` = 'PatronSelfRegistrationAgeRestriction' + } + ); + say $out "Updated explanation for syspref 'PatronSelfRegistrationAgeRestriction'"; + }, +}; diff --git a/installer/data/mysql/mandatory/sysprefs.sql b/installer/data/mysql/mandatory/sysprefs.sql index 585d7a5d8d8..19273debb3a 100644 --- a/installer/data/mysql/mandatory/sysprefs.sql +++ b/installer/data/mysql/mandatory/sysprefs.sql @@ -624,6 +624,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('OverduesBlockCirc','noblock','noblock|confirmation|block','When checking out an item should overdues block checkout, generate a confirmation dialogue, or allow checkout','Choice'), ('OverduesBlockRenewing','allow','allow|blockitem|block','If any of patron checked out documents is late, should renewal be allowed, blocked only on overdue items or blocked on whatever checked out document','Choice'), ('PassItemMarcToXSLT','0',NULL,'If enabled, item fields in the MARC record will be made available to XSLT sheets. Otherwise they will be removed.','YesNo'), +('PatronAgeRestriction', '', NULL, 'Patron\'s maximum age during registration. If empty, no age restriction is applied.', 'Integer'), ('PatronAnonymizeDelay','',NULL,'Delay for anonymizing patrons', 'Integer'), ('PatronAutoComplete','1',NULL,'to guess the patron being entered while typing a patron search for circulation or patron search. Only returns the first 10 results at a time.','YesNo'), ('PatronDuplicateMatchingAddFields','surname|firstname|dateofbirth', NULL,'A list of fields separated by "|" to deduplicate patrons when created','Free'), @@ -634,7 +635,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('PatronSelfModificationBorrowerUnwantedField','',NULL,'Name the fields you don\'t want to display when a patron is editing their information via the OPAC.','Free'), ('PatronSelfModificationMandatoryField','',NULL,'Define the required fields when a patron is editing their information via the OPAC','Free'), ('PatronSelfRegistration','0',NULL,'If enabled, patrons will be able to register themselves via the OPAC.','YesNo'), -('PatronSelfRegistrationAgeRestriction', '', NULL, 'Patron\'s maximum age during self registration. If empty, no age restriction is applied.', 'Integer'), +('PatronSelfRegistrationAgeRestriction', '', NULL, 'Patron\'s maximum age during self registration. If empty, honor PatronAgeRestriction.', 'Integer'), ('PatronSelfRegistrationAlert','0',NULL,'If enabled, an alter will be shown on staff interface home page when there are self-registered patrons.','YesNo'), ('PatronSelfRegistrationBorrowerMandatoryField','surname|firstname',NULL,'Choose the mandatory fields for a patron\'s account, when registering via the OPAC.','Free'), ('PatronSelfRegistrationBorrowerUnwantedField','',NULL,'Name the fields you don\'t want to display when registering a new patron via the OPAC.','Free'), diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/patron_messages.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/patron_messages.inc index dbabcef9aa4..c0fcc0a5758 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/patron_messages.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/patron_messages.inc @@ -5,7 +5,7 @@ [% SET return_claims = patron.return_claims %] [% SET logged_in_branchcode = Branches.GetLoggedInBranchcode() %] -[% IF ( has_modifications || warndeparture || returnbeforeexpiry || expired || patron.gonenoaddress || patron.lost || userdebarred || odues || ( return_claims.count > ClaimReturnedWarningThreshold ) || age_limitations || limited_category || charges || charges_guarantors_guarantees || charges_guarantees || credits || patron.account_locked ) %] +[% IF ( has_modifications || warndeparture || returnbeforeexpiry || expired || patron.gonenoaddress || patron.lost || userdebarred || odues || ( return_claims.count > ClaimReturnedWarningThreshold ) || age_out_of_range || age_limitations || limited_category || charges || charges_guarantors_guarantees || charges_guarantees || credits || patron.account_locked ) %]

Attention

    [% IF ( has_modifications ) %] @@ -137,6 +137,14 @@ [% END %] + [% IF age_out_of_range %] +
  • + Patron's age exceeds the maximum age allowed. + Maximum permitted age is [% age_max | html %] + Change category +
  • + [% END %] + [% IF limited_category %]
  • The patron's current category ([% Categories.GetName(patron.categorycode) | html %]) is limited to other libraries. diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref index 37202dc17c6..6b41d130f7a 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref @@ -921,7 +921,7 @@ OPAC: - "Patron's maximum age when registering: " - pref: PatronSelfRegistrationAgeRestriction class: integer - - "
    Note: If empty, do not restrict patron's age during self registration" + - "
    Note: If empty, honor the PatronAgeRestriction preference." Suggestions: - - pref: OpacSuggestionManagedBy diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref index d94bc0dd4bc..fa9a6ceea63 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref @@ -324,6 +324,11 @@ Patrons: type: modalselect source: borrowers - "will be added to the patron quick add form when entering a new patron. Displays only mandatory fields and fields specified here. If applicable the guarantor form will be shown as well, individual fields in that form will be ignored." + - + - "Patron's maximum age when registering: " + - pref: PatronAgeRestriction + class: integer + - "
    Note: If this field is left empty, no age restriction is applied." - - "When adding new patrons or editing existing patrons, collapse the following fields from the full form (can still be expanded later):" - pref: CollapseFieldsPatronAddForm diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt index 561b0d9aa0a..cb9ca5228b2 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt @@ -148,6 +148,9 @@ [% IF ( ERROR_age_limitations ) %]
  • Patron's age is incorrect for their category. Ages allowed are [% age_low | html %]-[% age_high | html %].
  • [% END %] + [% IF ( ERROR_age_out_of_range ) %] +
  • Patron's age exceeds the maximum age allowed. Maximum permitted age is [% age_max | html %]
  • + [% END %] [% IF ( ERROR_branch ) %]
  • Library is invalid.
  • [% END %] diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt index 8a7563c7756..1aa849b2b98 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt @@ -125,8 +125,8 @@ [% IF field == "ERROR_age_limitations" %]
  • Patron's age is incorrect for their category.
  • [% END %] - [% IF field == "ERROR_age_limitations_self_registration" %] -
  • Patron's age exceeds the maximum age allowed.
  • + [% IF field == "ERROR_age_out_of_range" %] +
  • Patron's age exceeds the maximum age allowed.
  • [% END %] [% END %]
diff --git a/members/memberentry.pl b/members/memberentry.pl index bade3ad35e6..9245f9d630a 100755 --- a/members/memberentry.pl +++ b/members/memberentry.pl @@ -392,11 +392,18 @@ if ( $op eq 'cud-save' || $op eq 'cud-insert' ) { my $patron = Koha::Patron->new( { dateofbirth => $dateofbirth } ); my $age = $patron->get_age; my ( $low, $high ) = ( $category->dateofbirthrequired, $category->upperagelimit ); + my $age_restriction = C4::Context->preference("PatronAgeRestriction"); + if ( ( $high && ( $age > $high ) ) or ( $age < $low ) ) { push @errors, 'ERROR_age_limitations'; $template->param( age_low => $low ); $template->param( age_high => $high ); } + + if ( $age_restriction && $age > $age_restriction ) { + push @errors, 'ERROR_age_out_of_range'; + $template->param( age_max => $age_restriction ); + } } if ( C4::Context->preference("IndependentBranches") ) { diff --git a/opac/opac-memberentry.pl b/opac/opac-memberentry.pl index 1daa2daf2c0..d0eb483889d 100755 --- a/opac/opac-memberentry.pl +++ b/opac/opac-memberentry.pl @@ -558,12 +558,17 @@ sub CheckForInvalidFields { my $age = $patron->get_age; my $borrowercategory = Koha::Patron::Categories->find( $borrower->{'categorycode'} ); my ( $low, $high ) = ( $borrowercategory->dateofbirthrequired, $borrowercategory->upperagelimit ); - my $upper_registration_age_restriction = C4::Context->preference("PatronSelfRegistrationAgeRestriction"); + my $age_restriction = + C4::Context->preference("PatronSelfRegistrationAgeRestriction") + || C4::Context->preference("PatronAgeRestriction") + || undef; + if ( ( $high && ( $age > $high ) ) or ( $age < $low ) ) { push @invalidFields, 'ERROR_age_limitations'; } - if ( $upper_registration_age_restriction && $age > $upper_registration_age_restriction ) { - push @invalidFields, 'ERROR_age_limitations_self_registration'; + + if ( $age_restriction && $age > $age_restriction ) { + push @invalidFields, 'ERROR_age_out_of_range'; } } -- 2.39.5