From b9f8147cdff878165dd2cb12e7554c123111b223 Mon Sep 17 00:00:00 2001 From: Marcel de Rooy Date: Thu, 16 Mar 2023 14:34:58 +0000 Subject: [PATCH] Bug 33245: Introduce patron->is_active Does only add the new patron method. NOTE: We may define additional criteria at some point, but I think that this is a good starting point. Test plan: Run perl -MKoha::Patron -e'print Koha::Patrons->find(X)->is_active(Y);' Note: replace X by a valid borrowernumber and Y by date criterium. Signed-off-by: Marcel de Rooy Signed-off-by: Matt Blenkinsop Signed-off-by: Jonathan Druart Signed-off-by: Tomas Cohen Arazi --- Koha/Patron.pm | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/Koha/Patron.pm b/Koha/Patron.pm index 5d7ca9b782..df9b6b9313 100644 --- a/Koha/Patron.pm +++ b/Koha/Patron.pm @@ -24,6 +24,7 @@ use List::MoreUtils qw( any uniq ); use JSON qw( to_json ); use Unicode::Normalize qw( NFKD ); use Try::Tiny; +use DateTime (); use C4::Auth qw( checkpw_hash ); use C4::Context; @@ -808,6 +809,73 @@ sub is_expired { return 0; } +=head3 is_active + +$patron->is_active({ [ since => $date ], [ days|weeks|months|years => $value ] }) + +A patron is considered 'active' if their account did not expire, and has not been anonymized, +and patron logged in recently, or placed a hold, article request or borrowed a book recently. +A recent enrollment as new patron counts too. + +Recently is defined by $date or $value in days, weeks or months. You should +pass one of those; otherwise an exception is thrown. + +=cut + +sub is_active { + my ( $self, $params ) = @_; + return 0 if $self->is_expired or $self->anonymized; + + my $dt; + if ( $params->{since} ) { + $dt = dt_from_string( $params->{since}, 'iso' ); + } elsif ( grep { $params->{$_} } qw(days weeks months years) ) { + $dt = dt_from_string(); + foreach my $duration (qw(days weeks months years)) { + $dt = $dt->subtract( $duration => $params->{$duration} ) if $params->{$duration}; + } + } else { + Koha::Exceptions::MissingParameter->throw('is_active needs date or period'); + } + + # Enrollment within this period? + return 1 if DateTime->compare( dt_from_string( $self->dateenrolled ), $dt ) > -1; + + # Last seen? Updated each login when you track patron activity + if ( C4::Context->preference('TrackLastPatronActivity') ) { + return 1 if DateTime->compare( dt_from_string( $self->lastseen ), $dt ) > -1; + } + + # Check holds, issues and article requests + return 1 if $self->holds->filter_by_last_update( + { + timestamp_column_name => 'timestamp', from => $dt, + } + )->count; + return 1 if $self->old_holds->filter_by_last_update( + { + timestamp_column_name => 'timestamp', from => $dt, + } + )->count; + return 1 if $self->checkouts->filter_by_last_update( + { + timestamp_column_name => 'timestamp', from => $dt, + } + )->count; + return 1 if $self->old_checkouts->filter_by_last_update( + { + timestamp_column_name => 'timestamp', from => $dt, + } + )->count; + return 1 if $self->article_requests->filter_by_last_update( + { + timestamp_column_name => 'updated_on', from => $dt, + } + )->count; + + return 0; +} + =head3 password_expired my $password_expired = $patron->password_expired; -- 2.20.1