@@ -, +, @@ flexible -branch. Set the expiry date for patron B to now+11. --- C4/Members.pm | 43 +++++++++--- misc/cronjobs/membership_expiry.pl | 26 ++++++- .../Members/GetUpcomingMembershipExpires.t | 79 ++++++++++++---------- 3 files changed, 101 insertions(+), 47 deletions(-) --- a/C4/Members.pm +++ a/C4/Members.pm @@ -1330,25 +1330,48 @@ sub GetExpiryDate { =head2 GetUpcomingMembershipExpires - my $upcoming_mem_expires = GetUpcomingMembershipExpires(); + my $expires = GetUpcomingMembershipExpires({ + branch => $branch, before => $before, after => $after, + }); + + $branch is an optional branch code. + $before/$after is an optional number of days before/after the date that + is set by the preference MembershipExpiryDaysNotice. + If the pref would be 14, before 2 and after 3, you will get all expires + from 12 to 17 days. =cut sub GetUpcomingMembershipExpires { + my ( $params ) = @_; + my $before = $params->{before} || 0; + my $after = $params->{after} || 0; + my $branch = $params->{branch}; + my $dbh = C4::Context->dbh; my $days = C4::Context->preference("MembershipExpiryDaysNotice") || 0; - my $dateexpiry = output_pref({ dt => (dt_from_string()->add( days => $days)), dateformat => 'iso', dateonly => 1 }); + my $date1 = dt_from_string->add( days => $days - $before ); + my $date2 = dt_from_string->add( days => $days + $after ); + $date1= output_pref({ dt => $date1, dateformat => 'iso', dateonly => 1 }); + $date2= output_pref({ dt => $date2, dateformat => 'iso', dateonly => 1 }); - my $query = " + my $query = q| SELECT borrowers.*, categories.description, branches.branchname, branches.branchemail FROM borrowers - LEFT JOIN branches on borrowers.branchcode = branches.branchcode - LEFT JOIN categories on borrowers.categorycode = categories.categorycode - WHERE dateexpiry = ?; - "; - my $sth = $dbh->prepare($query); - $sth->execute($dateexpiry); - my $results = $sth->fetchall_arrayref({}); + LEFT JOIN branches USING (branchcode) + LEFT JOIN categories USING (categorycode) + |; + if( $branch ) { + $query.= 'WHERE branchcode=? AND dateexpiry BETWEEN ? AND ?'; + } else { + $query.= 'WHERE dateexpiry BETWEEN ? AND ?'; + } + + my $sth = $dbh->prepare( $query ); + my @pars = $branch? ( $branch ): (); + push @pars, $date1, $date2; + $sth->execute( @pars ); + my $results = $sth->fetchall_arrayref( {} ); return $results; } --- a/misc/cronjobs/membership_expiry.pl +++ a/misc/cronjobs/membership_expiry.pl @@ -61,6 +61,20 @@ the patrons are printed to standard out. Confirm flag: Add this option. The script will only print a usage statement otherwise. +=item B<-branch> + +Optional branchcode to restrict the cronjob to that branch. + +=item B<-before> + +Optional parameter to extend the selection with a number of days BEFORE +the date set by the preference. + +=item B<-after> + +Optional parameter to extend the selection with a number of days AFTER +the date set by the preference. + =back =head1 CONFIGURATION @@ -115,9 +129,12 @@ use C4::Log; # These are defaults for command line options. my $confirm; # -c: Confirm that the user has read and configured this script. my $nomail; # -n: No mail. Will not send any emails. -my $verbose= 0; # -v: verbose +my $verbose = 0; # -v: verbose my $help = 0; my $man = 0; +my $before = 0; +my $after = 0; +my $branch; GetOptions( 'help|?' => \$help, @@ -125,6 +142,9 @@ GetOptions( 'c' => \$confirm, 'n' => \$nomail, 'v' => \$verbose, + 'branch:s' => \$branch, + 'before:i' => \$before, + 'after:i' => \$after, ) or pod2usage(2); pod2usage( -verbose => 2 ) if $man; @@ -142,7 +162,7 @@ if( !$expdays ) { my $admin_adress = C4::Context->preference('KohaAdminEmailAddress'); warn 'getting upcoming membership expires' if $verbose; -my $upcoming_mem_expires = C4::Members::GetUpcomingMembershipExpires(); +my $upcoming_mem_expires = C4::Members::GetUpcomingMembershipExpires({ branch => $branch, before => $before, after => $after }); warn 'found ' . scalar( @$upcoming_mem_expires ) . ' soon expiring members' if $verbose; @@ -164,7 +184,7 @@ foreach my $recent ( @$upcoming_mem_expires ) { }); if ($letter) { if ($nomail) { - print $letter->{'content'}; + print $letter->{'content'}."\n"; } else { C4::Letters::EnqueueLetter({ letter => $letter, --- a/t/db_dependent/Members/GetUpcomingMembershipExpires.t +++ a/t/db_dependent/Members/GetUpcomingMembershipExpires.t @@ -1,5 +1,7 @@ #!/usr/bin/perl +# Tests for C4::Members::GetUpcomingMembershipExpires + # This file is part of Koha. # # Copyright 2015 Biblibre @@ -19,17 +21,13 @@ use Modern::Perl; -use Test::More tests => 5; use Test::MockModule; -use t::lib::TestBuilder; -use t::lib::Mocks qw( mock_preference ); +use Test::More tests => 6; -use C4::Members; +use C4::Members qw|GetUpcomingMembershipExpires|; use Koha::Database; - -BEGIN { - use_ok('C4::Members'); -} +use t::lib::TestBuilder; +use t::lib::Mocks qw( mock_preference ); my $schema = Koha::Database->new->schema; $schema->storage->txn_begin; @@ -42,10 +40,9 @@ $date_time->mock( month => 6, day => 15, ); - }); -t::lib::Mocks::mock_preference('MembershipExpiryDaysNotice', 15); +t::lib::Mocks::mock_preference( 'MembershipExpiryDaysNotice', 15 ); my $builder = t::lib::TestBuilder->new(); $builder->build({ @@ -59,13 +56,17 @@ $builder->build({ }, }); -$builder->build({ +my $branch = $builder->build({ source => 'Branch', value => { - branchcode => 'CR', branchname => 'My branch', }, }); +my $branchcode = $branch->{branchcode}; +# before we add borrowers to this branch, add the expires we have now +# note that this pertains to the current mocked setting of the pref +# for this reason we add the new branchcode to most of the tests +my $expires = scalar @{ GetUpcomingMembershipExpires() }; $builder->build({ source => 'Borrower', @@ -74,7 +75,7 @@ $builder->build({ surname => 'Martin', cardnumber => '80808081', categorycode => 'AD', - branchcode => 'CR', + branchcode => $branchcode, dateexpiry => '2015-06-30' }, }); @@ -86,7 +87,7 @@ $builder->build({ surname => 'Dupont', cardnumber => '80808082', categorycode => 'AD', - branchcode => 'CR', + branchcode => $branchcode, dateexpiry => '2015-06-29' }, }); @@ -98,28 +99,38 @@ $builder->build({ surname => 'Dupond', cardnumber => '80808083', categorycode => 'AD', - branchcode => 'CR', + branchcode => $branchcode, dateexpiry => '2015-07-02' }, }); -my $upcoming_mem_expires = C4::Members::GetUpcomingMembershipExpires(); -is(scalar(@$upcoming_mem_expires), 1, 'Get upcoming membership expires should return 1 borrower.'); - -is($upcoming_mem_expires->[0]{surname}, 'Martin', 'Get upcoming membership expires should return borrower "Martin".'); - -# Test GetUpcomingMembershipExpires() with MembershipExpiryDaysNotice == 0 -t::lib::Mocks::mock_preference('MembershipExpiryDaysNotice', 0); - -$upcoming_mem_expires = C4::Members::GetUpcomingMembershipExpires(); -is(scalar(@$upcoming_mem_expires), 0, 'Get upcoming membership expires with 0 MembershipExpiryDaysNotice should return 0.'); - -# Test GetUpcomingMembershipExpires() with MembershipExpiryDaysNotice == undef -t::lib::Mocks::mock_preference('MembershipExpiryDaysNotice', undef); - -$upcoming_mem_expires = C4::Members::GetUpcomingMembershipExpires(); -is(scalar(@$upcoming_mem_expires), 0, 'Get upcoming membership expires without MembershipExpiryDaysNotice should return 0.'); - +# Test without extra parameters +my $upcoming_mem_expires = GetUpcomingMembershipExpires(); +is( scalar(@$upcoming_mem_expires), $expires + 1, 'Get upcoming membership expires should return one new borrower.' ); + +# Test with branch +$upcoming_mem_expires = GetUpcomingMembershipExpires({ branch => $branchcode }); +is( @$upcoming_mem_expires==1 && $upcoming_mem_expires->[0]{surname} eq 'Martin',1 , 'Get upcoming membership expires should return borrower "Martin".' ); + +# Test MembershipExpiryDaysNotice == 0 +t::lib::Mocks::mock_preference( 'MembershipExpiryDaysNotice', 0 ); +$upcoming_mem_expires = GetUpcomingMembershipExpires({ branch => $branchcode }); +is( scalar(@$upcoming_mem_expires), 0, 'Get upcoming membership expires with MembershipExpiryDaysNotice==0 should not return new records.' ); + +# Test MembershipExpiryDaysNotice == undef +t::lib::Mocks::mock_preference( 'MembershipExpiryDaysNotice', undef ); +$upcoming_mem_expires = GetUpcomingMembershipExpires({ branch => $branchcode }); +is( scalar(@$upcoming_mem_expires), 0, 'Get upcoming membership expires without MembershipExpiryDaysNotice should not return new records.' ); + +# Test the before parameter +t::lib::Mocks::mock_preference( 'MembershipExpiryDaysNotice', 15 ); +$upcoming_mem_expires = GetUpcomingMembershipExpires({ branch => $branchcode, before => 1 }); +# Expect 29/6 and 30/6 +is( scalar(@$upcoming_mem_expires), 2, 'Expect two results for before==1'); +# Test after parameter also +$upcoming_mem_expires = GetUpcomingMembershipExpires({ branch => $branchcode, before => 1, after => 2 }); +# Expect 29/6, 30/6 and 2/7 +is( scalar(@$upcoming_mem_expires), 3, 'Expect three results when adding after' ); + +# End $schema->storage->txn_rollback; - -1; --