Bug 37155: Refactor GetAgeRestrictions

This routine currently takes the agerestriction value from biblioitems and an unblessed borrower object
and uses the date of birth to calculate whether the ptrons DOB is before or after the minimum value required
against the age restriction

We have a routine in the patron object to get the patron's age - we cna use this against the parsed agerestriction
value in a simple comparison and remove the need to unbless and pass the patron.

FIXME: We should move this to a biblioitems or biblio object method

To test:
0 - In Admin -> Koha to MARC mapping, set biblioitems.agerestriction to 521,a
1 - Set syspref AgeRestrictionMarker to 'Age'
2 - Edit a record and set 521$a to 'Age 14'
3 - Add an item or copy the barcode of the item on that record
4 - Attempt to checkout item to Lisa Charles in sample data, or a 15 year old patron
5 - It should checkout fine
6 - Check in item
7 - Edit patron  Joyce Gaines to set age to 13 DOB:06/20/2011, or create a 13 year old patron
8 - Attempt to checkout item
9 - Item is blocked
10 - Apply patch
11 - Repeat tests, confirm no change

Signed-off-by: Brendan Lawlor <blawlor@clamsnet.org>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de>
This commit is contained in:
Nick Clemens 2024-06-21 13:39:38 +00:00 committed by Katrin Fischer
parent a1cfe67d5e
commit 11c5abda48
Signed by: kfischer
GPG key ID: 0EF6E2C03357A834
3 changed files with 9 additions and 81 deletions

View file

@ -1266,9 +1266,8 @@ sub CanBookBeIssued {
## CHECK AGE RESTRICTION ## CHECK AGE RESTRICTION
my $agerestriction = $biblioitem->agerestriction; my $agerestriction = $biblioitem->agerestriction;
my ( $restriction_age, $daysToAgeRestriction ) = my $restriction_age = GetAgeRestriction( $agerestriction );
GetAgeRestriction( $agerestriction, $patron->unblessed ); if ( $restriction_age && $patron->dateofbirth && $restriction_age > $patron->get_age() ) {
if ( $daysToAgeRestriction && $daysToAgeRestriction > 0 ) {
if ( C4::Context->preference('AgeRestrictionOverride') ) { if ( C4::Context->preference('AgeRestrictionOverride') ) {
$needsconfirmation{AGE_RESTRICTION} = "$agerestriction"; $needsconfirmation{AGE_RESTRICTION} = "$agerestriction";
} }
@ -4421,21 +4420,15 @@ sub IsItemIssued {
=head2 GetAgeRestriction =head2 GetAgeRestriction
my ($ageRestriction, $daysToAgeRestriction) = GetAgeRestriction($record_restrictions, $borrower); my $ageRestriction = GetAgeRestriction($record_restrictions);
my ($ageRestriction, $daysToAgeRestriction) = GetAgeRestriction($record_restrictions);
if($daysToAgeRestriction <= 0) { #Borrower is allowed to access this material, as they are older or as old as the agerestriction }
if($daysToAgeRestriction > 0) { #Borrower is this many days from meeting the agerestriction }
@PARAM1 the koha.biblioitems.agerestriction value, like K18, PEGI 13, ... @PARAM1 the koha.biblioitems.agerestriction value, like K18, PEGI 13, ...
@PARAM2 a borrower-object with koha.borrowers.dateofbirth. (OPTIONAL) @RETURNS The age restriction age in years.
@RETURNS The age restriction age in years and the days to fulfill the age restriction for the given borrower.
Negative days mean the borrower has gone past the age restriction age.
=cut =cut
sub GetAgeRestriction { sub GetAgeRestriction {
my ($record_restrictions, $borrower) = @_; my ($record_restrictions) = @_;
my $markers = C4::Context->preference('AgeRestrictionMarker'); my $markers = C4::Context->preference('AgeRestrictionMarker');
return unless $record_restrictions; return unless $record_restrictions;
@ -4470,26 +4463,7 @@ sub GetAgeRestriction {
last if ( $restriction_year > 0 ); last if ( $restriction_year > 0 );
} }
#Check if the borrower is age restricted for this material and for how long. return $restriction_year;
if ($restriction_year && $borrower) {
if ( $borrower->{'dateofbirth'} ) {
my @alloweddate = split /-/, $borrower->{'dateofbirth'};
$alloweddate[0] += $restriction_year;
#Prevent runime eror on leap year (invalid date)
if ( ( $alloweddate[1] == 2 ) && ( $alloweddate[2] == 29 ) ) {
$alloweddate[2] = 28;
}
#Get how many days the borrower has to reach the age restriction
my @Today = split /-/, dt_from_string()->ymd();
my $daysToAgeRestriction = Date_to_Days(@alloweddate) - Date_to_Days(@Today);
#Negative days means the borrower went past the age restriction age
return ($restriction_year, $daysToAgeRestriction);
}
}
return ($restriction_year);
} }

View file

@ -497,9 +497,8 @@ sub CanItemBeReserved {
if( GetMarcFromKohaField('biblioitems.agerestriction') ){ if( GetMarcFromKohaField('biblioitems.agerestriction') ){
my $biblio = $item->biblio; my $biblio = $item->biblio;
# Check for the age restriction # Check for the age restriction
my ( $ageRestriction, $daysToAgeRestriction ) = my $ageRestriction = C4::Circulation::GetAgeRestriction( $biblio->biblioitem->agerestriction );
C4::Circulation::GetAgeRestriction( $biblio->biblioitem->agerestriction, $borrower ); return _cache { status => 'ageRestricted' } if $ageRestriction && $patron->dateofbirth && $ageRestriction > $patron->get_age();
return _cache { status => 'ageRestricted' } if $daysToAgeRestriction && $daysToAgeRestriction > 0;
} }
# Check that the patron doesn't have an item level hold on this item already # Check that the patron doesn't have an item level hold on this item already

View file

@ -22,7 +22,7 @@ use Modern::Perl;
use DateTime; use DateTime;
use Koha::DateUtils qw( dt_from_string ); use Koha::DateUtils qw( dt_from_string );
use Test::More tests => 8; use Test::More tests => 6;
use Test::Warn; use Test::Warn;
use t::lib::Mocks; use t::lib::Mocks;
@ -37,35 +37,6 @@ is ( C4::Circulation::GetAgeRestriction('PEGI16'), '16', 'PEGI16 returns 16' );
is ( C4::Circulation::GetAgeRestriction('Age 16'), '16', 'Age 16 returns 16' ); is ( C4::Circulation::GetAgeRestriction('Age 16'), '16', 'Age 16 returns 16' );
is ( C4::Circulation::GetAgeRestriction('K16'), '16', 'K16 returns 16' ); is ( C4::Circulation::GetAgeRestriction('K16'), '16', 'K16 returns 16' );
subtest 'Patron tests - 15 years old' => sub {
plan tests => 5;
##Testing age restriction for a borrower.
my $now = dt_from_string();
my $borrower = { dateofbirth => $now->add( years => -15 )->strftime("%Y-%m-%d") };
TestPatron($borrower,0);
};
subtest 'Patron tests - 15 years old (Time Zone shifts)' => sub {
my $CheckTimeFake = eval { require Time::Fake; 1; } || 0;
SKIP: {
skip "Install Time::Fake to regression test for Bug 14362.", 115 if $CheckTimeFake!=1;
# 115 regression tests = 5 tests (see TestPatron) for 23 timezones.
plan tests => 115;
my $offset = 1;
# <24 hours in a day.
while ($offset<24) {
Time::Fake->offset("+${offset}h");
##Testing age restriction for a borrower.
my $now = dt_from_string();
my $borrower = { dateofbirth => $now->add( years => -15 )->strftime("%Y-%m-%d") };
TestPatron($borrower,$offset);
$offset++;
}
}
};
subtest 'No age restriction' => sub { subtest 'No age restriction' => sub {
plan tests => 1; plan tests => 1;
@ -76,19 +47,3 @@ subtest 'No age restriction' => sub {
}; };
# The Patron tests
sub TestPatron {
my ($borrower,$offset) = @_;
my ($restriction_age, $daysToAgeRestriction) = C4::Circulation::GetAgeRestriction('FSK 16', $borrower);
is ( ($daysToAgeRestriction > 0), 1, "FSK 16 blocked for a 15 year old - $offset hours" );
($restriction_age, $daysToAgeRestriction) = C4::Circulation::GetAgeRestriction('PEGI 15', $borrower);
is ( ($daysToAgeRestriction <= 0), 1, "PEGI 15 allowed for a 15 year old - $offset hours" );
($restriction_age, $daysToAgeRestriction) = C4::Circulation::GetAgeRestriction('PEGI14', $borrower);
is ( ($daysToAgeRestriction <= 0), 1, "PEGI14 allowed for a 15 year old - $offset hours" );
($restriction_age, $daysToAgeRestriction) = C4::Circulation::GetAgeRestriction('Age 10', $borrower);
is ( ($daysToAgeRestriction <= 0), 1, "Age 10 allowed for a 15 year old - $offset hours" );
($restriction_age, $daysToAgeRestriction) = C4::Circulation::GetAgeRestriction('K18', $borrower);
is ( ($daysToAgeRestriction > 0), 1, "K18 blocked for a 15 year old - $offset hours" );
return;
}