3 # This file is part of Koha.
5 # Koha is free software; you can redistribute it and/or modify it under the
6 # terms of the GNU General Public License as published by the Free Software
7 # Foundation; either version 3 of the License, or (at your option) any later
10 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License along
15 # with Koha; if not, see <http://www.gnu.org/licenses>.
18 use Test::More tests => 7;
27 use Koha::DateUtils qw( dt_from_string );
30 use t::lib::TestBuilder;
33 my $schema = Koha::Database->new->schema;
34 $schema->storage->txn_begin;
36 our $dbh = C4::Context->dbh;
38 $dbh->do(q|DELETE FROM issues|);
39 $dbh->do(q|DELETE FROM items|);
40 $dbh->do(q|DELETE FROM borrowers|);
41 $dbh->do(q|DELETE FROM branches|);
42 $dbh->do(q|DELETE FROM categories|);
43 $dbh->do(q|DELETE FROM accountlines|);
44 $dbh->do(q|DELETE FROM itemtypes|);
45 $dbh->do(q|DELETE FROM branch_item_rules|);
46 $dbh->do(q|DELETE FROM branch_borrower_circ_rules|);
47 $dbh->do(q|DELETE FROM default_branch_circ_rules|);
48 $dbh->do(q|DELETE FROM default_circ_rules|);
49 $dbh->do(q|DELETE FROM default_branch_item_rules|);
50 $dbh->do(q|DELETE FROM issuingrules|);
52 my $builder = t::lib::TestBuilder->new();
53 t::lib::Mocks::mock_preference('item-level_itypes', 1); # Assuming the item type is defined at item level
55 my $branch = $builder->build({
59 my $category = $builder->build({
63 my $patron = $builder->build({
66 categorycode => $category->{categorycode},
67 branchcode => $branch->{branchcode},
71 my $biblio = $builder->build({
74 branchcode => $branch->{branchcode},
77 my $item = $builder->build({
80 biblionumber => $biblio->{biblionumber},
81 homebranch => $branch->{branchcode},
82 holdingbranch => $branch->{branchcode},
86 C4::Context->_new_userenv ('DUMMY_SESSION_ID');
87 C4::Context->set_userenv($patron->{borrowernumber}, $patron->{userid}, 'usercnum', 'First name', 'Surname', $branch->{branchcode}, 'My Library', 0);
89 # TooMany return ($current_loan_count, $max_loans_allowed) or undef
91 # OSCO: On-site checkout
93 subtest 'no rules exist' => sub {
96 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
97 { reason => 'NO_RULE_DEFINED', max_allowed => 0 },
98 'CO should not be allowed, in any cases'
101 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
102 { reason => 'NO_RULE_DEFINED', max_allowed => 0 },
103 'OSCO should not be allowed, in any cases'
107 subtest '1 Issuingrule exist 0 0: no issue allowed' => sub {
109 my $issuingrule = $builder->build({
110 source => 'Issuingrule',
112 branchcode => $branch->{branchcode},
113 categorycode => $category->{categorycode},
116 maxonsiteissueqty => 0,
119 t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 0);
121 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
123 reason => 'TOO_MANY_CHECKOUTS',
127 'CO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
130 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
132 reason => 'TOO_MANY_ONSITE_CHECKOUTS',
136 'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
139 t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 1);
141 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
143 reason => 'TOO_MANY_CHECKOUTS',
147 'CO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
150 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
152 reason => 'TOO_MANY_ONSITE_CHECKOUTS',
156 'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
162 subtest '1 Issuingrule exist with onsiteissueqty=unlimited' => sub {
164 my $issuingrule = $builder->build({
165 source => 'Issuingrule',
167 branchcode => $branch->{branchcode},
168 categorycode => $category->{categorycode},
171 maxonsiteissueqty => undef,
174 my $issue = C4::Circulation::AddIssue( $patron, $item->{barcode}, dt_from_string() );
175 t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 0);
177 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
179 reason => 'TOO_MANY_CHECKOUTS',
183 'CO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
186 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
188 'OSCO should be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
191 t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 1);
193 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
195 reason => 'TOO_MANY_CHECKOUTS',
199 'CO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
202 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
204 reason => 'TOO_MANY_CHECKOUTS',
208 'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
215 subtest '1 Issuingrule exist 1 1: issue is allowed' => sub {
217 my $issuingrule = $builder->build({
218 source => 'Issuingrule',
220 branchcode => $branch->{branchcode},
221 categorycode => $category->{categorycode},
224 maxonsiteissueqty => 1,
227 t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 0);
229 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
231 'CO should be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
234 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
236 'OSCO should be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
239 t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 1);
241 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
243 'CO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
246 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
248 'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
254 subtest '1 Issuingrule exist: 1 CO allowed, 1 OSCO allowed. Do a CO' => sub {
256 my $issuingrule = $builder->build({
257 source => 'Issuingrule',
259 branchcode => $branch->{branchcode},
260 categorycode => $category->{categorycode},
263 maxonsiteissueqty => 1,
267 my $issue = C4::Circulation::AddIssue( $patron, $item->{barcode}, dt_from_string() );
268 like( $issue->issue_id, qr|^\d+$|, 'The issue should have been inserted' );
270 t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 0);
272 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
274 reason => 'TOO_MANY_CHECKOUTS',
278 'CO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
281 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
283 'OSCO should be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
286 t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 1);
288 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
290 reason => 'TOO_MANY_CHECKOUTS',
294 'CO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
297 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
299 reason => 'TOO_MANY_CHECKOUTS',
303 'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
309 subtest '1 Issuingrule exist: 1 CO allowed, 1 OSCO allowed, Do a OSCO' => sub {
311 my $issuingrule = $builder->build({
312 source => 'Issuingrule',
314 branchcode => $branch->{branchcode},
315 categorycode => $category->{categorycode},
318 maxonsiteissueqty => 1,
322 my $issue = C4::Circulation::AddIssue( $patron, $item->{barcode}, dt_from_string(), undef, undef, undef, { onsite_checkout => 1 } );
323 like( $issue->issue_id, qr|^\d+$|, 'The issue should have been inserted' );
325 t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 0);
327 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
329 'CO should be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
332 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
334 reason => 'TOO_MANY_ONSITE_CHECKOUTS',
338 'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
341 t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 1);
343 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
345 reason => 'TOO_MANY_CHECKOUTS',
349 'CO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
352 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
354 reason => 'TOO_MANY_ONSITE_CHECKOUTS',
358 'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
364 subtest '1 BranchBorrowerCircRule exist: 1 CO allowed, 1 OSCO allowed' => sub {
365 # Note: the same test coul be done for
366 # DefaultBorrowerCircRule, DefaultBranchCircRule, DefaultBranchItemRule ans DefaultCircRule.pm
369 my $issuingrule = $builder->build({
370 source => 'BranchBorrowerCircRule',
372 branchcode => $branch->{branchcode},
373 categorycode => $category->{categorycode},
375 maxonsiteissueqty => 1,
379 my $issue = C4::Circulation::AddIssue( $patron, $item->{barcode}, dt_from_string(), undef, undef, undef );
380 like( $issue->issue_id, qr|^\d+$|, 'The issue should have been inserted' );
382 t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 0);
384 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
386 reason => 'TOO_MANY_CHECKOUTS',
390 'CO should be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
393 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
395 'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
398 t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 1);
400 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
402 reason => 'TOO_MANY_CHECKOUTS',
406 'CO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
409 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
411 reason => 'TOO_MANY_CHECKOUTS',
415 'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
420 $issue = C4::Circulation::AddIssue( $patron, $item->{barcode}, dt_from_string(), undef, undef, undef, { onsite_checkout => 1 } );
421 like( $issue->issue_id, qr|^\d+$|, 'The issue should have been inserted' );
423 t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 0);
425 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
427 'CO should be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
430 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
432 reason => 'TOO_MANY_ONSITE_CHECKOUTS',
436 'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 0'
439 t::lib::Mocks::mock_preference('ConsiderOnSiteCheckoutsAsNormalCheckouts', 1);
441 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item ),
443 reason => 'TOO_MANY_CHECKOUTS',
447 'CO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
450 C4::Circulation::TooMany( $patron, $biblio->{biblionumber}, $item, { onsite_checkout => 1 } ),
452 reason => 'TOO_MANY_ONSITE_CHECKOUTS',
456 'OSCO should not be allowed if ConsiderOnSiteCheckoutsAsNormalCheckouts == 1'
462 $schema->storage->txn_rollback;
465 $dbh->do(q|DELETE FROM issues|);
466 $dbh->do(q|DELETE FROM issuingrules|);