From 623109f114d7b310f89166a0ab61712009806bd6 Mon Sep 17 00:00:00 2001
From: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Date: Thu, 11 Oct 2018 15:34:48 +0200
Subject: [PATCH] Bug 21549: Lock expired patron accounts
Content-Type: text/plain; charset=utf-8

Adding a search on locked patrons to the search_expired in cron script.
This prevents relocking.

Test plan:
Prove Koha/Patrons.t

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>

Signed-off-by: Michal Denar <black23@gmail.com>
---
 Koha/Patrons.pm                   | 18 ++++++++++++++++++
 misc/cronjobs/cleanup_database.pl | 13 +++++++++++++
 t/db_dependent/Koha/Patrons.t     | 14 +++++++++++++-
 3 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/Koha/Patrons.pm b/Koha/Patrons.pm
index 3b3b4b1cb6..9a3977704f 100644
--- a/Koha/Patrons.pm
+++ b/Koha/Patrons.pm
@@ -233,6 +233,24 @@ sub delete {
     return $patrons_deleted;
 }
 
+=head3 search_expired
+
+    Koha::Patrons->search_expired{{ days => $x });
+
+    Returns set of Koha patron objects expired $x days.
+
+=cut
+
+sub search_expired {
+    my ( $class, $params ) = @_;
+    my $days = $params->{days} || 0;
+    my $parser = Koha::Database->new->schema->storage->datetime_parser;
+    my $dt = dt_from_string()->subtract( days => $days );
+    return $class->search({
+        dateexpiry => { '<=' => $parser->format_datetime($dt) },
+    });
+}
+
 =head3 search_unsubscribed
 
     Koha::Patrons->search_unsubscribed;
diff --git a/misc/cronjobs/cleanup_database.pl b/misc/cronjobs/cleanup_database.pl
index 062efe6041..07bd2622f9 100755
--- a/misc/cronjobs/cleanup_database.pl
+++ b/misc/cronjobs/cleanup_database.pl
@@ -400,7 +400,20 @@ if($allDebarments) {
     }
 }
 
+# Lock expired patrons?
+my $days = C4::Context->preference('LockExpiredDelay');
+if( defined $days && $days ne q{} ) {
+    say "Start locking expired patrons" if $verbose;
+    my $expired_patrons = Koha::Patrons->search_expired({ days => $days })->search({ login_attempts => { '!=' => -1 } });
+    my $count = $expired_patrons->count;
+    $expired_patrons->lock({ remove => 1 }) if $confirm;
+    if( $verbose ) {
+        say $confirm ? sprintf("Locked %d patrons", $count) : sprintf("Found %d patrons", $count);
+    }
+}
+
 # Handle unsubscribe requests from GDPR consent form, depends on UnsubscribeReflectionDelay preference
+say "Start lock unsubscribed, anonymize and delete" if $verbose;
 my $unsubscribed_patrons = Koha::Patrons->search_unsubscribed;
 my $count = $unsubscribed_patrons->count;
 $unsubscribed_patrons->lock( { expire => 1, remove => 1 } ) if $confirm;
diff --git a/t/db_dependent/Koha/Patrons.t b/t/db_dependent/Koha/Patrons.t
index c2824082e7..26e3366855 100755
--- a/t/db_dependent/Koha/Patrons.t
+++ b/t/db_dependent/Koha/Patrons.t
@@ -19,7 +19,7 @@
 
 use Modern::Perl;
 
-use Test::More tests => 41;
+use Test::More tests => 42;
 use Test::Warn;
 use Test::Exception;
 use Test::MockModule;
@@ -1798,6 +1798,18 @@ subtest '->set_password' => sub {
 };
 
 $schema->storage->txn_begin;
+subtest 'search_expired' => sub {
+    plan tests => 3;
+    my $count1 = Koha::Patrons->search_expired({ days => 28 })->count;
+    my $patron1 = $builder->build_object({ class => 'Koha::Patrons' });
+    $patron1->dateexpiry( dt_from_string->subtract(days => 27) )->store;
+    is( Koha::Patrons->search_expired({ days => 28 })->count, $count1, 'No more expired' );
+    $patron1->dateexpiry( dt_from_string->subtract(days => 28) )->store;
+    is( Koha::Patrons->search_expired({ days => 28 })->count, $count1 + 1, 'One more expired' );
+    $patron1->dateexpiry( dt_from_string->subtract(days => 29) )->store;
+    is( Koha::Patrons->search_expired({ days => 28 })->count, $count1 + 1, 'Same number again' );
+};
+
 subtest 'search_unsubscribed' => sub {
     plan tests => 4;
 
-- 
2.11.0