3 # Copyright 2016 Koha Development team
5 # This file is part of Koha
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
22 use Test
::More tests
=> 11;
29 use Koha
::Item
::Transfer
::Limits
;
32 use Koha
::DateUtils
qw( dt_from_string );
34 use t
::lib
::TestBuilder
;
38 my $schema = Koha
::Database
->new->schema;
39 $schema->storage->txn_begin;
41 my $dbh = C4
::Context
->dbh;
43 my $builder = t
::lib
::TestBuilder
->new;
44 my $library = $builder->build( { source
=> 'Branch' } );
45 my $nb_of_items = Koha
::Items
->search->count;
46 my $biblio = $builder->build_sample_biblio();
47 my $new_item_1 = $builder->build_sample_item({
48 biblionumber
=> $biblio->biblionumber,
49 homebranch
=> $library->{branchcode
},
50 holdingbranch
=> $library->{branchcode
},
52 my $new_item_2 = $builder->build_sample_item({
53 biblionumber
=> $biblio->biblionumber,
54 homebranch
=> $library->{branchcode
},
55 holdingbranch
=> $library->{branchcode
},
59 t
::lib
::Mocks
::mock_userenv
({ branchcode
=> $library->{branchcode
} });
61 like
( $new_item_1->itemnumber, qr
|^\d
+$|, 'Adding a new item should have set the itemnumber' );
62 is
( Koha
::Items
->search->count, $nb_of_items + 2, 'The 2 items should have been added' );
64 my $retrieved_item_1 = Koha
::Items
->find( $new_item_1->itemnumber );
65 is
( $retrieved_item_1->barcode, $new_item_1->barcode, 'Find a item by id should return the correct item' );
67 subtest
'store' => sub {
70 my $biblio = $builder->build_sample_biblio;
71 my $today = dt_from_string
->set( hour
=> 0, minute
=> 0, second
=> 0 );
72 my $item = Koha
::Item
->new(
74 homebranch
=> $library->{branchcode
},
75 holdingbranch
=> $library->{branchcode
},
76 biblionumber
=> $biblio->biblionumber,
79 )->store->get_from_storage;
81 is
( t
::lib
::Dates
::compare
( $item->replacementpricedate, $today ),
82 0, 'replacementpricedate must have been set to today if not given' );
83 is
( t
::lib
::Dates
::compare
( $item->datelastseen, $today ),
84 0, 'datelastseen must have been set to today if not given' );
87 $biblio->biblioitem->itemtype,
88 'items.itype must have been set to biblioitem.itemtype is not given'
90 is
( $item->permanent_location, $item->location,
91 'permanent_location must have been set to location if not given' );
94 subtest
'*_on updates' => sub {
97 # Once the '_on' value is set (triggered by the related field turning from false to true)
98 # it should not be re-set for any changes outside of the related field being 'unset'.
100 my @fields = qw( itemlost withdrawn damaged );
101 my $today = dt_from_string
();
102 my $yesterday = $today->clone()->subtract( days
=> 1 );
104 for my $field ( @fields ) {
105 my $item = $builder->build_sample_item(
108 itemlost_on
=> undef,
110 withdrawn_on
=> undef,
115 my $field_on = $field . '_on';
117 # Set field for the first time
118 Time
::Fake
->offset( $yesterday->epoch );
119 $item->$field(1)->store;
120 $item->get_from_storage;
121 is
($item->$field_on, DateTime
::Format
::MySQL
->format_datetime($yesterday), $field_on . " was set upon first truthy setting");
123 # Update the field to a new 'true' value
124 Time
::Fake
->offset( $today->epoch );
125 $item->$field(2)->store;
126 $item->get_from_storage;
127 is
($item->$field_on, DateTime
::Format
::MySQL
->format_datetime($yesterday), $field_on . " was not updated upon second truthy setting");
129 # Update the field to a new 'false' value
130 $item->$field(0)->store;
131 $item->get_from_storage;
132 is
($item->$field_on, undef, $field_on . " was unset upon untruthy setting");
138 subtest
'_lost_found_trigger' => sub {
141 t
::lib
::Mocks
::mock_preference
( 'WhenLostChargeReplacementFee', 1 );
142 t
::lib
::Mocks
::mock_preference
( 'WhenLostForgiveFine', 0 );
144 my $processfee_amount = 20;
145 my $replacement_amount = 99.00;
146 my $item_type = $builder->build_object(
148 class => 'Koha::ItemTypes',
152 defaultreplacecost
=> undef,
153 processfee
=> $processfee_amount,
154 rentalcharge_daily
=> 0,
158 my $library = $builder->build_object( { class => 'Koha::Libraries' } );
160 $biblio = $builder->build_sample_biblio( { author
=> 'Hall, Daria' } );
162 subtest
'Full write-off tests' => sub {
166 my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
168 $builder->build_object( { class => "Koha::Patrons" } );
169 t
::lib
::Mocks
::mock_userenv
(
170 { patron
=> $manager, branchcode
=> $manager->branchcode } );
172 my $item = $builder->build_sample_item(
174 biblionumber
=> $biblio->biblionumber,
175 library
=> $library->branchcode,
176 replacementprice
=> $replacement_amount,
177 itype
=> $item_type->itemtype,
181 C4
::Circulation
::AddIssue
( $patron->unblessed, $item->barcode );
183 # Simulate item marked as lost
184 $item->itemlost(3)->store;
185 C4
::Circulation
::LostItem
( $item->itemnumber, 1 );
187 my $processing_fee_lines = Koha
::Account
::Lines
->search(
189 borrowernumber
=> $patron->id,
190 itemnumber
=> $item->itemnumber,
191 debit_type_code
=> 'PROCESSING'
194 is
( $processing_fee_lines->count,
195 1, 'Only one processing fee produced' );
196 my $processing_fee_line = $processing_fee_lines->next;
197 is
( $processing_fee_line->amount + 0,
199 'The right PROCESSING amount is generated' );
200 is
( $processing_fee_line->amountoutstanding + 0,
202 'The right PROCESSING amountoutstanding is generated' );
204 my $lost_fee_lines = Koha
::Account
::Lines
->search(
206 borrowernumber
=> $patron->id,
207 itemnumber
=> $item->itemnumber,
208 debit_type_code
=> 'LOST'
211 is
( $lost_fee_lines->count, 1, 'Only one lost item fee produced' );
212 my $lost_fee_line = $lost_fee_lines->next;
213 is
( $lost_fee_line->amount + 0,
214 $replacement_amount, 'The right LOST amount is generated' );
215 is
( $lost_fee_line->amountoutstanding + 0,
217 'The right LOST amountoutstanding is generated' );
218 is
( $lost_fee_line->status, undef, 'The LOST status was not set' );
220 my $account = $patron->account;
221 my $debts = $account->outstanding_debits;
224 my $credit = $account->add_credit(
226 amount
=> $account->balance,
232 { debits
=> [ $debts->as_list ], offset_type
=> 'Writeoff' } );
234 # Simulate item marked as found
235 $item->itemlost(0)->store;
236 is
( $item->{_refunded
}, undef, 'No LOST_FOUND account line added' );
238 $lost_fee_line->discard_changes; # reload from DB
239 is
( $lost_fee_line->amountoutstanding + 0,
240 0, 'Lost fee has no outstanding amount' );
241 is
( $lost_fee_line->debit_type_code,
242 'LOST', 'Lost fee now still has account type of LOST' );
243 is
( $lost_fee_line->status, 'FOUND',
244 "Lost fee now has account status of FOUND - No Refund" );
246 is
( $patron->account->balance,
247 -0, 'The patron balance is 0, everything was written off' );
250 subtest
'Full payment tests' => sub {
254 my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
256 my $item = $builder->build_sample_item(
258 biblionumber
=> $biblio->biblionumber,
259 library
=> $library->branchcode,
260 replacementprice
=> $replacement_amount,
261 itype
=> $item_type->itemtype
266 C4
::Circulation
::AddIssue
( $patron->unblessed, $item->barcode );
268 # Simulate item marked as lost
269 $item->itemlost(1)->store;
270 C4
::Circulation
::LostItem
( $item->itemnumber, 1 );
272 my $processing_fee_lines = Koha
::Account
::Lines
->search(
274 borrowernumber
=> $patron->id,
275 itemnumber
=> $item->itemnumber,
276 debit_type_code
=> 'PROCESSING'
279 is
( $processing_fee_lines->count,
280 1, 'Only one processing fee produced' );
281 my $processing_fee_line = $processing_fee_lines->next;
282 is
( $processing_fee_line->amount + 0,
284 'The right PROCESSING amount is generated' );
285 is
( $processing_fee_line->amountoutstanding + 0,
287 'The right PROCESSING amountoutstanding is generated' );
289 my $lost_fee_lines = Koha
::Account
::Lines
->search(
291 borrowernumber
=> $patron->id,
292 itemnumber
=> $item->itemnumber,
293 debit_type_code
=> 'LOST'
296 is
( $lost_fee_lines->count, 1, 'Only one lost item fee produced' );
297 my $lost_fee_line = $lost_fee_lines->next;
298 is
( $lost_fee_line->amount + 0,
299 $replacement_amount, 'The right LOST amount is generated' );
300 is
( $lost_fee_line->amountoutstanding + 0,
302 'The right LOST amountountstanding is generated' );
304 my $account = $patron->account;
305 my $debts = $account->outstanding_debits;
308 my $credit = $account->add_credit(
310 amount
=> $account->balance,
316 { debits
=> [ $debts->as_list ], offset_type
=> 'Payment' } );
318 # Simulate item marked as found
319 $item->itemlost(0)->store;
320 is
( $item->{_refunded
}, 1, 'Refund triggered' );
322 my $credit_return = Koha
::Account
::Lines
->search(
324 itemnumber
=> $item->itemnumber,
325 credit_type_code
=> 'LOST_FOUND'
330 ok
( $credit_return, 'An account line of type LOST_FOUND is added' );
331 is
( $credit_return->amount + 0,
333 'The account line of type LOST_FOUND has an amount of -99' );
335 $credit_return->amountoutstanding + 0,
337 'The account line of type LOST_FOUND has an amountoutstanding of -99'
340 $lost_fee_line->discard_changes;
341 is
( $lost_fee_line->amountoutstanding + 0,
342 0, 'Lost fee has no outstanding amount' );
343 is
( $lost_fee_line->debit_type_code,
344 'LOST', 'Lost fee now still has account type of LOST' );
345 is
( $lost_fee_line->status, 'FOUND',
346 "Lost fee now has account status of FOUND" );
348 is
( $patron->account->balance, -99,
349 'The patron balance is -99, a credit that equals the lost fee payment'
353 subtest
'Test without payment or write off' => sub {
357 my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
359 my $item = $builder->build_sample_item(
361 biblionumber
=> $biblio->biblionumber,
362 library
=> $library->branchcode,
363 replacementprice
=> 23.00,
364 replacementprice
=> $replacement_amount,
365 itype
=> $item_type->itemtype
370 C4
::Circulation
::AddIssue
( $patron->unblessed, $item->barcode );
372 # Simulate item marked as lost
373 $item->itemlost(3)->store;
374 C4
::Circulation
::LostItem
( $item->itemnumber, 1 );
376 my $processing_fee_lines = Koha
::Account
::Lines
->search(
378 borrowernumber
=> $patron->id,
379 itemnumber
=> $item->itemnumber,
380 debit_type_code
=> 'PROCESSING'
383 is
( $processing_fee_lines->count,
384 1, 'Only one processing fee produced' );
385 my $processing_fee_line = $processing_fee_lines->next;
386 is
( $processing_fee_line->amount + 0,
388 'The right PROCESSING amount is generated' );
389 is
( $processing_fee_line->amountoutstanding + 0,
391 'The right PROCESSING amountoutstanding is generated' );
393 my $lost_fee_lines = Koha
::Account
::Lines
->search(
395 borrowernumber
=> $patron->id,
396 itemnumber
=> $item->itemnumber,
397 debit_type_code
=> 'LOST'
400 is
( $lost_fee_lines->count, 1, 'Only one lost item fee produced' );
401 my $lost_fee_line = $lost_fee_lines->next;
402 is
( $lost_fee_line->amount + 0,
403 $replacement_amount, 'The right LOST amount is generated' );
404 is
( $lost_fee_line->amountoutstanding + 0,
406 'The right LOST amountountstanding is generated' );
408 # Simulate item marked as found
409 $item->itemlost(0)->store;
410 is
( $item->{_refunded
}, 1, 'Refund triggered' );
412 my $credit_return = Koha
::Account
::Lines
->search(
414 itemnumber
=> $item->itemnumber,
415 credit_type_code
=> 'LOST_FOUND'
420 ok
( $credit_return, 'An account line of type LOST_FOUND is added' );
421 is
( $credit_return->amount + 0,
423 'The account line of type LOST_FOUND has an amount of -99' );
425 $credit_return->amountoutstanding + 0,
427 'The account line of type LOST_FOUND has an amountoutstanding of 0'
430 $lost_fee_line->discard_changes;
431 is
( $lost_fee_line->amountoutstanding + 0,
432 0, 'Lost fee has no outstanding amount' );
433 is
( $lost_fee_line->debit_type_code,
434 'LOST', 'Lost fee now still has account type of LOST' );
435 is
( $lost_fee_line->status, 'FOUND',
436 "Lost fee now has account status of FOUND" );
438 is
( $patron->account->balance,
439 20, 'The patron balance is 20, still owes the processing fee' );
443 'Test with partial payement and write off, and remaining debt' =>
448 my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
449 my $item = $builder->build_sample_item(
451 biblionumber
=> $biblio->biblionumber,
452 library
=> $library->branchcode,
453 replacementprice
=> $replacement_amount,
454 itype
=> $item_type->itemtype
459 C4
::Circulation
::AddIssue
( $patron->unblessed, $item->barcode );
461 # Simulate item marked as lost
462 $item->itemlost(1)->store;
463 C4
::Circulation
::LostItem
( $item->itemnumber, 1 );
465 my $processing_fee_lines = Koha
::Account
::Lines
->search(
467 borrowernumber
=> $patron->id,
468 itemnumber
=> $item->itemnumber,
469 debit_type_code
=> 'PROCESSING'
472 is
( $processing_fee_lines->count,
473 1, 'Only one processing fee produced' );
474 my $processing_fee_line = $processing_fee_lines->next;
475 is
( $processing_fee_line->amount + 0,
477 'The right PROCESSING amount is generated' );
478 is
( $processing_fee_line->amountoutstanding + 0,
480 'The right PROCESSING amountoutstanding is generated' );
482 my $lost_fee_lines = Koha
::Account
::Lines
->search(
484 borrowernumber
=> $patron->id,
485 itemnumber
=> $item->itemnumber,
486 debit_type_code
=> 'LOST'
489 is
( $lost_fee_lines->count, 1, 'Only one lost item fee produced' );
490 my $lost_fee_line = $lost_fee_lines->next;
491 is
( $lost_fee_line->amount + 0,
492 $replacement_amount, 'The right LOST amount is generated' );
493 is
( $lost_fee_line->amountoutstanding + 0,
495 'The right LOST amountountstanding is generated' );
497 my $account = $patron->account;
500 $processfee_amount + $replacement_amount,
501 'Balance is PROCESSING + L'
505 my $payment_amount = 27;
506 my $payment = $account->add_credit(
508 amount
=> $payment_amount,
515 { debits
=> [$lost_fee_line], offset_type
=> 'Payment' } );
517 # Partially write off fee
518 my $write_off_amount = 25;
519 my $write_off = $account->add_credit(
521 amount
=> $write_off_amount,
527 { debits
=> [$lost_fee_line], offset_type
=> 'Writeoff' } );
532 $replacement_amount -
535 'Payment and write off applied'
538 # Store the amountoutstanding value
539 $lost_fee_line->discard_changes;
540 my $outstanding = $lost_fee_line->amountoutstanding;
542 # Simulate item marked as found
543 $item->itemlost(0)->store;
544 is
( $item->{_refunded
}, 1, 'Refund triggered' );
546 my $credit_return = Koha
::Account
::Lines
->search(
548 itemnumber
=> $item->itemnumber,
549 credit_type_code
=> 'LOST_FOUND'
554 ok
( $credit_return, 'An account line of type LOST_FOUND is added' );
558 $processfee_amount - $payment_amount,
559 'Balance is PROCESSING - PAYMENT (LOST_FOUND)'
562 $lost_fee_line->discard_changes;
563 is
( $lost_fee_line->amountoutstanding + 0,
564 0, 'Lost fee has no outstanding amount' );
565 is
( $lost_fee_line->debit_type_code,
566 'LOST', 'Lost fee now still has account type of LOST' );
567 is
( $lost_fee_line->status, 'FOUND',
568 "Lost fee now has account status of FOUND" );
571 $credit_return->amount + 0,
572 ( $payment_amount + $outstanding ) * -1,
573 'The account line of type LOST_FOUND has an amount equal to the payment + outstanding'
576 $credit_return->amountoutstanding + 0,
577 $payment_amount * -1,
578 'The account line of type LOST_FOUND has an amountoutstanding equal to the payment'
583 $processfee_amount - $payment_amount,
584 'The patron balance is the difference between the PROCESSING and the credit'
588 subtest
'Partial payment, existing debits and AccountAutoReconcile' =>
593 my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
594 my $barcode = 'KD123456793';
595 my $replacement_amount = 100;
596 my $processfee_amount = 20;
598 my $item_type = $builder->build_object(
600 class => 'Koha::ItemTypes',
604 defaultreplacecost
=> undef,
606 rentalcharge_daily
=> 0,
610 my $item = Koha
::Item
->new(
612 biblionumber
=> $biblio->biblionumber,
613 homebranch
=> $library->branchcode,
614 holdingbranch
=> $library->branchcode,
616 replacementprice
=> $replacement_amount,
617 itype
=> $item_type->itemtype
622 C4
::Circulation
::AddIssue
( $patron->unblessed, $barcode );
624 # Simulate item marked as lost
625 $item->itemlost(1)->store;
626 C4
::Circulation
::LostItem
( $item->itemnumber, 1 );
628 my $lost_fee_lines = Koha
::Account
::Lines
->search(
630 borrowernumber
=> $patron->id,
631 itemnumber
=> $item->itemnumber,
632 debit_type_code
=> 'LOST'
635 is
( $lost_fee_lines->count, 1, 'Only one lost item fee produced' );
636 my $lost_fee_line = $lost_fee_lines->next;
637 is
( $lost_fee_line->amount + 0,
638 $replacement_amount, 'The right LOST amount is generated' );
639 is
( $lost_fee_line->amountoutstanding + 0,
641 'The right LOST amountountstanding is generated' );
643 my $account = $patron->account;
644 is
( $account->balance, $replacement_amount, 'Balance is L' );
647 my $payment_amount = 27;
648 my $payment = $account->add_credit(
650 amount
=> $payment_amount,
656 { debits
=> [$lost_fee_line], offset_type
=> 'Payment' } );
660 $replacement_amount - $payment_amount,
664 my $manual_debit_amount = 80;
667 amount
=> $manual_debit_amount,
675 $manual_debit_amount + $replacement_amount - $payment_amount,
676 'Manual debit applied'
679 t
::lib
::Mocks
::mock_preference
( 'AccountAutoReconcile', 1 );
681 # Simulate item marked as found
682 $item->itemlost(0)->store;
683 is
( $item->{_refunded
}, 1, 'Refund triggered' );
685 my $credit_return = Koha
::Account
::Lines
->search(
687 itemnumber
=> $item->itemnumber,
688 credit_type_code
=> 'LOST_FOUND'
693 ok
( $credit_return, 'An account line of type LOST_FOUND is added' );
697 $manual_debit_amount - $payment_amount,
698 'Balance is PROCESSING - payment (LOST_FOUND)'
701 my $manual_debit = Koha
::Account
::Lines
->search(
703 borrowernumber
=> $patron->id,
704 debit_type_code
=> 'OVERDUE',
705 status
=> 'UNRETURNED'
709 $manual_debit->amountoutstanding + 0,
710 $manual_debit_amount - $payment_amount,
711 'reconcile_balance was called'
715 subtest
'Patron deleted' => sub {
718 my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
719 my $barcode = 'KD123456794';
720 my $replacement_amount = 100;
721 my $processfee_amount = 20;
723 my $item_type = $builder->build_object(
725 class => 'Koha::ItemTypes',
729 defaultreplacecost
=> undef,
731 rentalcharge_daily
=> 0,
735 my $item = Koha
::Item
->new(
737 biblionumber
=> $biblio->biblionumber,
738 homebranch
=> $library->branchcode,
739 holdingbranch
=> $library->branchcode,
741 replacementprice
=> $replacement_amount,
742 itype
=> $item_type->itemtype
747 C4
::Circulation
::AddIssue
( $patron->unblessed, $barcode );
749 # Simulate item marked as lost
750 $item->itemlost(1)->store;
751 C4
::Circulation
::LostItem
( $item->itemnumber, 1 );
756 # Simulate item marked as found
757 $item->itemlost(0)->store;
758 is
( $item->{_refunded
}, undef, 'No refund triggered' );
762 subtest
'Continue when userenv is not set' => sub {
765 my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
766 my $barcode = 'KD123456795';
767 my $replacement_amount = 100;
768 my $processfee_amount = 20;
770 my $item_type = $builder->build_object(
772 class => 'Koha::ItemTypes',
776 defaultreplacecost
=> undef,
778 rentalcharge_daily
=> 0,
782 my $item = $builder->build_sample_item(
784 biblionumber
=> $biblio->biblionumber,
785 homebranch
=> $library->branchcode,
786 holdingbranch
=> $library->branchcode,
788 replacementprice
=> $replacement_amount,
789 itype
=> $item_type->itemtype
794 C4
::Circulation
::AddIssue
( $patron->unblessed, $barcode );
796 # Simulate item marked as lost
797 $item->itemlost(1)->store;
798 C4
::Circulation
::LostItem
( $item->itemnumber, 1 );
801 C4
::Context
->_new_userenv(undef);
803 # Simluate item marked as found
804 $item->itemlost(0)->store;
805 is
( $item->{_refunded
}, 1, 'No refund triggered' );
811 subtest
'get_transfer' => sub {
814 my $transfer = $new_item_1->get_transfer();
815 is
( $transfer, undef, 'Koha::Item->get_transfer should return undef if the item is not in transit' );
817 my $library_to = $builder->build( { source
=> 'Branch' } );
819 C4
::Circulation
::transferbook
({
820 from_branch
=> $new_item_1->holdingbranch,
821 to_branch
=> $library_to->{branchcode
},
822 barcode
=> $new_item_1->barcode,
825 $transfer = $new_item_1->get_transfer();
826 is
( ref($transfer), 'Koha::Item::Transfer', 'Koha::Item->get_transfer should return a Koha::Item::Transfers object' );
828 is
( $transfer->itemnumber, $new_item_1->itemnumber, 'Koha::Item->get_transfer should return a valid Koha::Item::Transfers object' );
831 subtest
'holds' => sub {
834 my $biblio = $builder->build_sample_biblio();
835 my $item = $builder->build_sample_item({
836 biblionumber
=> $biblio->biblionumber,
838 is
($item->holds->count, 0, "Nothing returned if no holds");
839 my $hold1 = $builder->build({ source
=> 'Reserve', value
=> { itemnumber
=>$item->itemnumber, found
=> 'T' }});
840 my $hold2 = $builder->build({ source
=> 'Reserve', value
=> { itemnumber
=>$item->itemnumber, found
=> 'W' }});
841 my $hold3 = $builder->build({ source
=> 'Reserve', value
=> { itemnumber
=>$item->itemnumber, found
=> 'W' }});
843 is
($item->holds()->count,3,"Three holds found");
844 is
($item->holds({found
=> 'W'})->count,2,"Two waiting holds found");
845 is_deeply
($item->holds({found
=> 'T'})->next->unblessed,$hold1,"Found transit holds matches the hold");
846 is
($item->holds({found
=> undef})->count, 0,"Nothing returned if no matching holds");
849 subtest
'biblio' => sub {
852 my $biblio = $retrieved_item_1->biblio;
853 is
( ref( $biblio ), 'Koha::Biblio', 'Koha::Item->biblio should return a Koha::Biblio' );
854 is
( $biblio->biblionumber, $retrieved_item_1->biblionumber, 'Koha::Item->biblio should return the correct biblio' );
857 subtest
'biblioitem' => sub {
860 my $biblioitem = $retrieved_item_1->biblioitem;
861 is
( ref( $biblioitem ), 'Koha::Biblioitem', 'Koha::Item->biblioitem should return a Koha::Biblioitem' );
862 is
( $biblioitem->biblionumber, $retrieved_item_1->biblionumber, 'Koha::Item->biblioitem should return the correct biblioitem' );
866 t
::lib
::Mocks
::mock_userenv
({ branchcode
=> $library->{branchcode
} });
867 subtest
'checkout' => sub {
869 my $item = Koha
::Items
->find( $new_item_1->itemnumber );
871 my $checkout = $item->checkout;
872 is
( $checkout, undef, 'Koha::Item->checkout should return undef if there is no current checkout on this item' );
875 my $patron = $builder->build({ source
=> 'Borrower' });
876 C4
::Circulation
::AddIssue
( $patron, $item->barcode );
877 $checkout = $retrieved_item_1->checkout;
878 is
( ref( $checkout ), 'Koha::Checkout', 'Koha::Item->checkout should return a Koha::Checkout' );
879 is
( $checkout->itemnumber, $item->itemnumber, 'Koha::Item->checkout should return the correct checkout' );
880 is
( $checkout->borrowernumber, $patron->{borrowernumber
}, 'Koha::Item->checkout should return the correct checkout' );
883 C4
::Circulation
::AddReturn
( $item->barcode );
885 # There is no more checkout on this item, making sure it will not return old checkouts
886 $checkout = $item->checkout;
887 is
( $checkout, undef, 'Koha::Item->checkout should return undef if there is no *current* checkout on this item' );
890 subtest
'can_be_transferred' => sub {
893 t
::lib
::Mocks
::mock_preference
('UseBranchTransferLimits', 1);
894 t
::lib
::Mocks
::mock_preference
('BranchTransferLimitsType', 'itemtype');
896 my $biblio = $builder->build_sample_biblio();
897 my $library1 = $builder->build_object( { class => 'Koha::Libraries' } );
898 my $library2 = $builder->build_object( { class => 'Koha::Libraries' } );
899 my $item = $builder->build_sample_item({
900 biblionumber
=> $biblio->biblionumber,
901 homebranch
=> $library1->branchcode,
902 holdingbranch
=> $library1->branchcode,
905 is
(Koha
::Item
::Transfer
::Limits
->search({
906 fromBranch
=> $library1->branchcode,
907 toBranch
=> $library2->branchcode,
908 })->count, 0, 'There are no transfer limits between libraries.');
909 ok
($item->can_be_transferred({ to
=> $library2 }),
910 'Item can be transferred between libraries.');
912 my $limit = Koha
::Item
::Transfer
::Limit
->new({
913 fromBranch
=> $library1->branchcode,
914 toBranch
=> $library2->branchcode,
915 itemtype
=> $item->effective_itemtype,
917 is
(Koha
::Item
::Transfer
::Limits
->search({
918 fromBranch
=> $library1->branchcode,
919 toBranch
=> $library2->branchcode,
920 })->count, 1, 'Given we have added a transfer limit,');
921 is
($item->can_be_transferred({ to
=> $library2 }), 0,
922 'Item can no longer be transferred between libraries.');
923 is
($item->can_be_transferred({ to
=> $library2, from
=> $library1 }), 0,
924 'We get the same result also if we pass the from-library parameter.');
927 # Reset nb_of_items prior to testing delete
928 $nb_of_items = Koha
::Items
->search->count;
931 $retrieved_item_1->delete;
932 is
( Koha
::Items
->search->count, $nb_of_items - 1, 'Delete should have deleted the item' );
934 $schema->storage->txn_rollback;