6822a0435858dc1e57fdd89d1c5c00ffc25e6e0c
[srvgit] / t / db_dependent / Reserves / CancelExpiredReserves.t
1 #!/usr/bin/perl
2
3 use Modern::Perl;
4 use Test::More tests => 4;
5
6 use t::lib::Mocks;
7 use t::lib::TestBuilder;
8
9 use C4::Members;
10 use C4::Reserves;
11 use Koha::Database;
12 use Koha::DateUtils;
13 use Koha::Holds;
14
15 my $schema = Koha::Database->new->schema;
16 $schema->storage->txn_begin;
17
18 subtest 'CancelExpiredReserves tests incl. holidays' => sub {
19     plan tests => 4;
20
21     my $builder = t::lib::TestBuilder->new();
22
23     t::lib::Mocks::mock_preference('ExpireReservesOnHolidays', 0);
24     # Waiting holds could be cancelled only if ExpireReservesMaxPickUpDelay is set to "allow", see bug 19260
25     t::lib::Mocks::mock_preference('ExpireReservesMaxPickUpDelay', 1);
26
27
28     my $today = dt_from_string();
29     my $reserve_reservedate = $today->clone;
30     $reserve_reservedate->subtract(days => 30);
31
32     my $reserve1_expirationdate = $today->clone;
33     $reserve1_expirationdate->add(days => 1);
34
35     # Reserve not expired
36     my $reserve1 = $builder->build({
37         source => 'Reserve',
38         value => {
39             reservedate => $reserve_reservedate,
40             expirationdate => $reserve1_expirationdate,
41             cancellationdate => undef,
42             priority => 0,
43             found => 'W',
44         },
45     });
46
47     CancelExpiredReserves();
48     my $r1 = Koha::Holds->find($reserve1->{reserve_id});
49     ok($r1, 'Reserve 1 should not be canceled.');
50
51     my $reserve2_expirationdate = $today->clone;
52     $reserve2_expirationdate->subtract(days => 1);
53
54     # Reserve expired
55     my $reserve2 = $builder->build({
56         source => 'Reserve',
57         value => {
58             reservedate => $reserve_reservedate,
59             expirationdate => $reserve2_expirationdate,
60             cancellationdate => undef,
61             priority => 0,
62             found => 'W',
63         },
64     });
65
66     CancelExpiredReserves();
67     my $r2 = Koha::Holds->find($reserve2->{reserve_id});
68     is($r2, undef,'reserve 2 should be canceled.');
69
70     # Reserve expired on holiday
71     my $reserve3 = $builder->build({
72         source => 'Reserve',
73         value => {
74             reservedate => $reserve_reservedate,
75             expirationdate => $reserve2_expirationdate,
76             branchcode => 'LIB1',
77             cancellationdate => undef,
78             priority => 0,
79             found => 'W',
80         },
81     });
82
83     Koha::Caches->get_instance()->flush_all();
84     my $holiday = $builder->build({
85         source => 'SpecialHoliday',
86         value => {
87             branchcode => 'LIB1',
88             day => $today->day,
89             month => $today->month,
90             year => $today->year,
91             title => 'My holiday',
92             isexception => 0
93         },
94     });
95
96     CancelExpiredReserves();
97     my $r3 = Koha::Holds->find($reserve3->{reserve_id});
98     ok($r3,'Reserve 3 should not be canceled.');
99
100     t::lib::Mocks::mock_preference('ExpireReservesOnHolidays', 1);
101     CancelExpiredReserves();
102     $r3 = Koha::Holds->find($reserve3->{reserve_id});
103     is($r3, undef,'Reserve 3 should be canceled.');
104 };
105
106 subtest 'Test handling of waiting reserves by CancelExpiredReserves' => sub {
107     plan tests => 2;
108
109     Koha::Holds->delete;
110
111     my $builder = t::lib::TestBuilder->new();
112     my $category = $builder->build({ source => 'Category' });
113     my $branchcode = $builder->build({ source => 'Branch' })->{ branchcode };
114     my $item = $builder->build_sample_item;
115     my $itemnumber = $item->itemnumber;
116     my $borrowernumber = $builder->build({ source => 'Borrower', value => { categorycode => $category->{categorycode}, branchcode => $branchcode }})->{borrowernumber};
117
118     my $resdate = dt_from_string->add( days => -20 );
119     my $expdate = dt_from_string->add( days => -2 );
120     my $notexpdate = dt_from_string->add( days => 2 );
121
122     my $hold1 = Koha::Hold->new({
123         branchcode => $branchcode,
124         borrowernumber => $borrowernumber,
125         biblionumber => $item->biblionumber,
126         priority => 1,
127         reservedate => $resdate,
128         expirationdate => $notexpdate,
129         found => undef,
130     })->store;
131
132     my $hold2 = Koha::Hold->new({
133         branchcode => $branchcode,
134         borrowernumber => $borrowernumber,
135         biblionumber => $item->biblionumber,
136         priority => 2,
137         reservedate => $resdate,
138         expirationdate => $expdate,
139         found => undef,
140     })->store;
141
142     my $hold3 = Koha::Hold->new({
143         branchcode => $branchcode,
144         borrowernumber => $borrowernumber,
145         biblionumber => $item->biblionumber,
146         itemnumber => $itemnumber,
147         priority => 0,
148         reservedate => $resdate,
149         expirationdate => $expdate,
150         found => 'W',
151     })->store;
152
153     t::lib::Mocks::mock_preference( 'ExpireReservesMaxPickUpDelay', 0 );
154     CancelExpiredReserves();
155     my $count1 = Koha::Holds->search->count;
156     is( $count1, 2, 'Only the non-waiting expired holds should be cancelled');
157
158     t::lib::Mocks::mock_preference( 'ExpireReservesMaxPickUpDelay', 1 );
159     CancelExpiredReserves();
160     my $count2 = Koha::Holds->search->count;
161     is( $count2, 1, 'Also the waiting expired hold should be cancelled now');
162
163 };
164
165 subtest 'Test handling of in transit reserves by CancelExpiredReserves' => sub {
166     plan tests => 2;
167
168     my $builder = t::lib::TestBuilder->new();
169
170     t::lib::Mocks::mock_preference( 'ExpireReservesMaxPickUpDelay', 1 );
171     my $expdate = dt_from_string->add( days => -2 );
172     my $reserve = $builder->build({
173         source => 'Reserve',
174         value  => {
175             expirationdate => '2018-01-01',
176             found => 'T',
177             cancellationdate => undef,
178             suspend => 0,
179             suspend_until => undef
180         }
181     });
182     my $count = Koha::Holds->search->count;
183     CancelExpiredReserves();
184     is(Koha::Holds->search->count, $count-1, "Transit hold is cancelled if ExpireReservesMaxPickUpDelay set");
185
186     t::lib::Mocks::mock_preference( 'ExpireReservesMaxPickUpDelay', 0 );
187     my $reserve2 = $builder->build({
188         source => 'Reserve',
189         value  => {
190             expirationdate => '2018-01-01',
191             found => 'T',
192             cancellationdate => undef,
193             suspend => 0,
194             suspend_until => undef
195         }
196     });
197     CancelExpiredReserves();
198     is(Koha::Holds->search->count, $count-1, "Transit hold is cancelled if ExpireReservesMaxPickUpDelay unset");
199
200 };
201
202 subtest 'Test handling of cancellation reason if passed' => sub {
203     plan tests => 2;
204
205     my $builder = t::lib::TestBuilder->new();
206
207     my $expdate = dt_from_string->add( days => -2 );
208     my $reserve = $builder->build({
209         source => 'Reserve',
210         value  => {
211             expirationdate => '2018-01-01',
212             found => 'T',
213             cancellationdate => undef,
214             suspend => 0,
215             suspend_until => undef
216         }
217     });
218     my $reserve_id = $reserve->{reserve_id};
219     my $count = Koha::Holds->search->count;
220     CancelExpiredReserves("EXPIRED");
221     is(Koha::Holds->search->count, $count-1, "Hold is cancelled when reason is passed");
222     my $old_reserve = Koha::Old::Holds->find($reserve_id);
223     is($old_reserve->cancellation_reason, 'EXPIRED', "Hold cancellation_reason was set correctly");
224 };
225
226 $schema->storage->txn_rollback;