2 use strict; use warnings;
3 use Test::More tests => 18;
4 use OpenILS::Utils::TestUtils;
5 use OpenILS::Const qw(:const);
6 use OpenILS::Utils::DateTime;
8 use DateTime::TimeZone;
9 use DateTime::Format::ISO8601;
11 # We need the local timezone for later.
12 my $localTZ = DateTime::TimeZone->new(name => 'local');
14 my $script = OpenILS::Utils::TestUtils->new();
15 my $U = 'OpenILS::Application::AppUtils';
17 diag("Test LP 1861319 Allow Circulation Renewal for Expired Patrons");
22 BR1_WORKSTATION => 'BR1-lp1861319-test-renewal',
23 BR2_WORKSTATION => 'BR2-lp1861319-test renewal',
24 ADMIN_USER => 'admin',
25 ADMIN_PASS => 'demo123'
29 $script->authenticate({
30 username => ADMIN_USER,
31 password => ADMIN_PASS,
34 BAIL_OUT('Failed to Login') unless ($script->authtoken);
36 # Register BR1 workstation.
37 my $ws = $script->find_or_register_workstation(BR1_WORKSTATION, BR1_ID);
38 BAIL_OUT("Failed to register " . BR1_WORKSTATION) unless($ws);
43 # Login with BR1 Workstation
44 $script->authenticate({
45 username => ADMIN_USER,
46 password => ADMIN_PASS,
48 workstation => BR1_WORKSTATION
50 BAIL_OUT('Failed to login with ' . BR1_WORKSTATION) unless($script->authtoken);
52 # Get a cstore editor for later use.
53 my $editor = $script->editor(authtoken=>$script->authtoken);
55 # Check that the circ.renew.expired_patron_allow setting constant is defined
56 ok(defined(OILS_SETTING_ALLOW_RENEW_FOR_EXPIRED_PATRON),
57 'OILS_SETTING_ALLOW_RENEW_FOR_EXPIRED_PATRON constant exists');
59 # Check that the circ.renew.expired_patron_allow setting exists in the database
60 my $setting = $editor->search_config_org_unit_setting_type(
61 {name => OILS_SETTING_ALLOW_RENEW_FOR_EXPIRED_PATRON}
63 # Get the first/only one:
64 $setting = (defined($setting)) ? $setting->[0] : $setting;
65 ok(defined($setting), OILS_SETTING_ALLOW_RENEW_FOR_EXPIRED_PATRON . ' setting exists in database');
67 # Find a circulation with renewals remaining
68 my $circ = $editor->search_action_circulation([
71 checkin_time => undef,
72 renewal_remaining => {'>' => 0}
76 $circ = defined($circ) ? $circ->[0] : $circ;
77 isa_ok($circ, 'Fieldmapper::action::circulation', 'Found open circulation at BR1');
79 # Get the circ patron information.
80 my $patron = $editor->retrieve_actor_user($circ->usr);
81 isa_ok($patron, 'Fieldmapper::actor::user', 'Found circulation user');
83 # Expire the patron if they are not already expired.
84 my ($saved_expire_date);
86 if (check_usr_expired($patron)) {
87 skip 'Patron already expired', 1;
89 $saved_expire_date = $patron->expire_date;
90 $patron->expire_date(DateTime->now()->set_time_zone($localTZ)->subtract(days => 1)->strftime('%FT%T%z'));
92 if ($editor->update_actor_user($patron)) {
95 $editor->xact_rollback;
96 BAIL_OUT("Patron update failed");
98 $patron = $editor->retrieve_actor_user($patron->id);
99 ok(check_usr_expired($patron), 'Patron set to expired.');
103 # Attempt a renewal. It should fail.
105 copy_id => $circ->target_copy,
106 patron_id => $circ->usr,
109 my $result = $U->simplereq(
111 'open-ils.circ.renew.override',
115 if (ref($result) eq 'ARRAY') {
116 $result = $result->[0];
118 is($result->{textcode}, 'PATRON_ACCOUNT_EXPIRED', 'Renewal failed: ' . $result->{textcode});
120 # Set the circ.renew.expired_patron_allow setting at BR1
121 $setting = Fieldmapper::actor::org_unit_setting->new;
122 $setting->name(OILS_SETTING_ALLOW_RENEW_FOR_EXPIRED_PATRON);
123 $setting->org_unit(BR1_ID);
124 $setting->value('true');
126 $result = $editor->create_actor_org_unit_setting($setting);
128 $editor->xact_commit;
129 ok($result, 'Set ' . OILS_SETTING_ALLOW_RENEW_FOR_EXPIRED_PATRON . ' for BR1');
131 $editor->xact_rollback;
132 BAIL_OUT("Failed to set " . OILS_SETTING_ALLOW_RENEW_FOR_EXPIRED_PATRON . ' for BR1');
135 # Attempt the renewal again, expect success.
136 $result = $U->simplereq(
138 'open-ils.circ.renew.override',
142 if (ref($result) eq 'ARRAY') {
143 $result = $result->[0];
145 isnt($result->{textcode}, 'PATRON_ACCOUNT_EXPIRED', 'Renewal Result: ' . $result->{textcode});
147 # Find a circulating copy at BR1 that is not checked out.
148 my $copy = $editor->search_asset_copy([
151 status => OILS_COPY_STATUS_AVAILABLE,
156 $copy = defined($copy) ? $copy->[0] : $copy;
157 isa_ok($copy, 'Fieldmapper::asset::copy', 'Found copy at BR1');
159 # Check it out, expect failure
160 my $checkout_params = {
161 copy_id => $copy->id,
162 patron_id => $patron->id
164 $result = $U->simplereq(
166 'open-ils.circ.checkout.full.override',
170 if (ref($result) eq 'ARRAY') {
171 $result = $result->[0];
173 is($result->{textcode}, 'PATRON_ACCOUNT_EXPIRED', 'Checkout failed: ' . $result->{textcode});
175 # Reset the patron expire_date
176 if (defined($saved_expire_date)) {
177 $patron->expire_date($saved_expire_date);
179 if ($editor->update_actor_user($patron)) {
180 $editor->xact_commit;
182 $editor->xact_rollback;
184 undef($saved_expire_date);
190 # Destroy our editor.
194 $script->authenticate({
195 username => ADMIN_USER,
196 password => ADMIN_PASS,
199 BAIL_OUT('Failed to Login') unless ($script->authtoken);
201 # Register BR2 workstation.
202 $ws = $script->find_or_register_workstation(BR2_WORKSTATION, BR2_ID);
203 BAIL_OUT("Failed to register " . BR2_WORKSTATION) unless($ws);
208 # Login with BR2 Workstation
209 $script->authenticate({
210 username => ADMIN_USER,
211 password => ADMIN_PASS,
213 workstation => BR2_WORKSTATION
215 BAIL_OUT('Failed to login with ' . BR2_WORKSTATION) unless($script->authtoken);
217 # Get a new editor with our authtoken.
218 $editor = $script->editor(authtoken=>$script->authtoken);
220 # Find a circulation with renewals remaining at BR2
221 $circ = $editor->search_action_circulation([
224 checkin_time => undef,
225 renewal_remaining => {'>' => 0}
229 $circ = defined($circ) ? $circ->[0] : $circ;
230 isa_ok($circ, 'Fieldmapper::action::circulation', 'Found open circulation at BR2');
232 # Get the circ patron information.
233 $patron = $editor->retrieve_actor_user($circ->usr);
234 isa_ok($patron, 'Fieldmapper::actor::user', 'Found circulation user');
236 # Expire the patron if they are not already expired.
238 if (check_usr_expired($patron)) {
239 skip 'Patron already expired', 1;
241 $saved_expire_date = $patron->expire_date;
242 $patron->expire_date(DateTime->now()->set_time_zone($localTZ)->subtract(days => 1)->strftime('%FT%T%z'));
244 if ($editor->update_actor_user($patron)) {
245 $editor->xact_commit;
246 $patron = $editor->retrieve_actor_user($patron->id);
247 ok(check_usr_expired($patron), 'Patron set to expired.');
249 $editor->xact_rollback;
250 BAIL_OUT("Patron update failed");
255 # Attempt a renewal. It should fail.
257 copy_id => $circ->target_copy,
258 patron_id => $circ->usr,
261 $result = $U->simplereq(
263 'open-ils.circ.renew.override',
267 if (ref($result) eq 'ARRAY') {
268 $result = $result->[0];
270 is($result->{textcode}, 'PATRON_ACCOUNT_EXPIRED', 'Renewal failed: ' . $result->{textcode});
272 # Reset the patron expire_date
273 if (defined($saved_expire_date)) {
274 $patron->expire_date($saved_expire_date);
276 if ($editor->update_actor_user($patron)) {
277 $editor->xact_commit;
278 ok(!check_usr_expired($patron), 'Patron set to not expired');
280 $editor->xact_rollback;
281 BAIL_OUT('Patron expire date reset failed');
283 undef($saved_expire_date);
285 # Set patron expire date to 30 days in the future.
286 $saved_expire_date = $patron->expire_date;
287 $patron->expire_date(DateTime->now()->set_time_zone($localTZ)->add(days => 30)->strftime('%FT%T%z'));
289 if ($editor->update_actor_user($patron)) {
290 $editor->xact_commit;
291 $patron = $editor->retrieve_actor_user($patron->id);
292 ok(!check_usr_expired($patron), 'Patron is not expired.');
294 $editor->xact_rollback;
295 BAIL_OUT("Patron update failed");
299 # Attempt renewal, expect success.
300 $result = $U->simplereq(
302 'open-ils.circ.renew.override',
306 if (ref($result) eq 'ARRAY') {
307 $result = $result->[0];
309 isnt($result->{textcode}, 'PATRON_ACCOUNT_EXPIRED', 'Renewal Result: ' . $result->{textcode});
311 # Find a circulating copy at BR2 that is not checked out.
312 $copy = $editor->search_asset_copy([
315 status => OILS_COPY_STATUS_AVAILABLE,
320 $copy = defined($copy) ? $copy->[0] : $copy;
321 isa_ok($copy, 'Fieldmapper::asset::copy', 'Found copy at BR2');
323 # Check it out, expect failure
325 copy_id => $copy->id,
326 patron_id => $patron->id
328 $result = $U->simplereq(
330 'open-ils.circ.checkout.full.override',
334 if (ref($result) eq 'ARRAY') {
335 $result = $result->[0];
337 isnt($result->{textcode}, 'PATRON_ACCOUNT_EXPIRED', 'Checkout result: ' . $result->{textcode});
339 # Reset the patron expire_date if necessary
340 if (defined($saved_expire_date)) {
341 $patron->expire_date($saved_expire_date);
343 if ($editor->update_actor_user($patron)) {
344 $editor->xact_commit;
346 $editor->xact_rollback;
348 undef($saved_expire_date);
351 # Delete the setting from actor.org_unit_setting
353 if ($editor->delete_actor_org_unit_setting($setting)) {
354 $editor->commit; # Commit so that we disconnect.
360 $script->logout(); # Not a test, just to be pedantic.
363 sub check_usr_expired {
365 my $expire = DateTime::Format::ISO8601->new->parse_datetime(
366 OpenILS::Utils::DateTime->clean_ISO8601($user->expire_date));
367 return (time > $expire->epoch);