3 # Copyright 2017 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 => 13;
25 use t::lib::TestBuilder;
28 use C4::Circulation qw( AddIssue AddReturn );
32 use Koha::DateUtils qw(dt_from_string);
35 my $schema = Koha::Database->schema;
36 my $builder = t::lib::TestBuilder->new;
38 subtest 'basket() tests' => sub {
42 $schema->storage->txn_begin;
44 my $basket = $builder->build_object(
46 class => 'Koha::Acquisition::Baskets'
49 my $order = $builder->build_object(
51 class => 'Koha::Acquisition::Orders',
52 value => { basketno => $basket->basketno }
56 my $retrieved_basket = $order->basket;
57 is( ref($retrieved_basket), 'Koha::Acquisition::Basket',
58 'Type is correct for ->basket' );
59 is_deeply( $retrieved_basket->unblessed,
60 $basket->unblessed, "Correct basket found and updated" );
62 $schema->storage->txn_rollback;
65 subtest 'biblio() tests' => sub {
69 $schema->storage->txn_begin;
71 my $order = $builder->build_object(
73 class => 'Koha::Acquisition::Orders',
74 value => { biblionumber => undef }
78 is( $order->biblio, undef, 'If no linked biblio, undef is returned' );
80 # Add and link a biblio to the order
81 my $biblio = $builder->build_sample_biblio();
82 $order->set({ biblionumber => $biblio->biblionumber })->store->discard_changes;
84 my $THE_biblio = $order->biblio;
85 is( ref($THE_biblio), 'Koha::Biblio', 'Returns a Koha::Biblio object' );
86 is( $THE_biblio->biblionumber, $biblio->biblionumber, 'It is not cheating about the object' );
88 $order->biblio->delete;
89 $order = Koha::Acquisition::Orders->find($order->ordernumber);
90 ok( $order, 'The order is not deleted if the biblio is deleted' );
91 is( $order->biblio, undef, 'order.biblio is correctly set to NULL when the biblio is deleted' );
93 $schema->storage->txn_rollback;
96 subtest 'store' => sub {
99 $schema->storage->txn_begin;
100 my $o = $builder->build_object(
102 class => 'Koha::Acquisition::Orders'
106 subtest 'entrydate' => sub {
111 t::lib::Mocks::mock_preference( 'TimeFormat', '12hr' );
112 $order = Koha::Acquisition::Order->new(
114 basketno => $o->basketno,
115 biblionumber => $o->biblionumber,
116 budget_id => $o->budget_id,
120 $order->discard_changes;
121 like( $order->entrydate, qr|^\d{4}-\d{2}-\d{2}$| );
123 t::lib::Mocks::mock_preference( 'TimeFormat', '24hr' );
124 $order = Koha::Acquisition::Order->new(
126 basketno => $o->basketno,
127 biblionumber => $o->biblionumber,
128 budget_id => $o->budget_id,
132 $order->discard_changes;
133 like( $order->entrydate, qr|^\d{4}-\d{2}-\d{2}$| );
135 $schema->storage->txn_rollback;
138 subtest 'fund' => sub {
141 $schema->storage->txn_begin;
142 my $o = $builder->build_object(
144 class => 'Koha::Acquisition::Orders',
148 my $order = Koha::Acquisition::Orders->find( $o->ordernumber );
149 is( ref( $order->fund ),
150 'Koha::Acquisition::Fund',
151 '->fund should return a Koha::Acquisition::Fund object' );
152 $schema->storage->txn_rollback;
155 subtest 'invoice' => sub {
158 $schema->storage->txn_begin;
159 my $o = $builder->build_object(
161 class => 'Koha::Acquisition::Orders',
162 value => { cancellationreason => 'XXXXXXXX', invoiceid => undef }, # not received yet
166 my $order = Koha::Acquisition::Orders->find( $o->ordernumber );
167 is( $order->invoice, undef,
168 '->invoice should return undef if no invoice defined yet');
170 my $invoice = $builder->build_object(
172 class => 'Koha::Acquisition::Invoices',
176 $o->invoiceid( $invoice->invoiceid )->store;
177 $order = Koha::Acquisition::Orders->find( $o->ordernumber );
178 is( ref( $order->invoice ), 'Koha::Acquisition::Invoice',
179 '->invoice should return a Koha::Acquisition::Invoice object if an invoice is defined');
181 $schema->storage->txn_rollback;
184 subtest 'subscription' => sub {
187 $schema->storage->txn_begin;
188 my $o = $builder->build_object(
190 class => 'Koha::Acquisition::Orders',
191 value => { subscriptionid => undef }, # not linked to a subscription
195 my $order = Koha::Acquisition::Orders->find( $o->ordernumber );
196 is( $order->subscription, undef,
197 '->subscription should return undef if not created from a subscription');
199 $o = $builder->build_object(
201 class => 'Koha::Acquisition::Orders',
202 # Will be linked to a subscription by TestBuilder
206 $order = Koha::Acquisition::Orders->find( $o->ordernumber );
207 is( ref( $order->subscription ), 'Koha::Subscription',
208 '->subscription should return a Koha::Subscription object if created from a subscription');
210 $schema->storage->txn_rollback;
213 subtest 'duplicate_to | add_item' => sub {
216 $schema->storage->txn_begin;
218 my $item = $builder->build_sample_item;
219 my $order_no_sub = $builder->build_object(
221 class => 'Koha::Acquisition::Orders',
224 biblionumber => $item->biblionumber,
225 subscriptionid => undef, # not linked to a subscription
229 $order_no_sub->basket->create_items(undef)->store; # use syspref
230 $order_no_sub->add_item( $item->itemnumber );
232 $item = $builder->build_sample_item;
233 my $order_from_sub = $builder->build_object(
235 class => 'Koha::Acquisition::Orders',
238 biblionumber => $item->biblionumber,
239 # Will be linked to a subscription by TestBuilder
243 $order_from_sub->basket->create_items(undef)->store; # use syspref
244 $order_from_sub->add_item( $item->itemnumber );
246 my $basket_to = $builder->build_object(
247 { class => 'Koha::Acquisition::Baskets' });
249 subtest 'Create item on receiving' => sub {
252 t::lib::Mocks::mock_preference('AcqCreateItem', 'receiving');
254 my $duplicated_order = $order_no_sub->duplicate_to($basket_to);
255 is( $duplicated_order->items->count, 0,
256 'Items should not be copied if the original order did not create items on ordering'
259 $duplicated_order = $order_from_sub->duplicate_to($basket_to);
260 is( $duplicated_order->items->count, 0,
261 'Items should not be copied if the original order is created from a subscription'
265 subtest 'Create item on ordering' => sub {
268 t::lib::Mocks::mock_preference('AcqCreateItem', 'ordering');
270 my $duplicated_order = $order_no_sub->duplicate_to($basket_to);
271 is( $duplicated_order->items->count, 1,
272 'Items should be copied if items are created on ordering'
275 $duplicated_order = $order_from_sub->duplicate_to($basket_to);
276 is( $duplicated_order->items->count, 0,
277 'Items should never be copied if the original order is created from a subscription'
281 subtest 'Regression tests' => sub {
284 my $duplicated_order = $order_no_sub->duplicate_to($basket_to);
285 is($duplicated_order->invoiceid, undef, "invoiceid should be set to null for a new duplicated order");
288 $schema->storage->txn_rollback;
291 subtest 'current_item_level_holds() tests' => sub {
295 $schema->storage->txn_begin;
297 my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
298 my $biblio = $builder->build_sample_biblio();
299 my $item_1 = $builder->build_sample_item( { biblionumber => $biblio->biblionumber } );
300 my $item_2 = $builder->build_sample_item( { biblionumber => $biblio->biblionumber } );
301 my $item_3 = $builder->build_sample_item( { biblionumber => $biblio->biblionumber } );
303 C4::Reserves::AddReserve(
305 branchcode => $patron->branchcode,
306 borrowernumber => $patron->borrowernumber,
307 biblionumber => $biblio->biblionumber,
308 reservation_date => dt_from_string->add( days => -2 ),
309 itemnumber => $item_1->itemnumber,
312 C4::Reserves::AddReserve(
314 branchcode => $patron->branchcode,
315 borrowernumber => $patron->borrowernumber,
316 biblionumber => $biblio->biblionumber,
317 reservation_date => dt_from_string->add( days => -2 ),
318 itemnumber => $item_2->itemnumber,
321 # Add a hold in the future
322 C4::Reserves::AddReserve(
324 branchcode => $patron->branchcode,
325 borrowernumber => $patron->borrowernumber,
326 biblionumber => $biblio->biblionumber,
327 reservation_date => dt_from_string->add( days => 2 ),
328 itemnumber => $item_3->itemnumber,
332 # Add an order with no biblionumber
333 my $order = $builder->build_object(
335 class => 'Koha::Acquisition::Orders',
337 biblionumber => undef
342 my $holds = $order->current_item_level_holds;
344 is( ref($holds), 'Koha::Holds', 'Koha::Holds iterator returned if no linked biblio' );
345 is( $holds->count, 0, 'Count is 0 if no linked biblio' );
347 $order->set({ biblionumber => $biblio->biblionumber })->store->discard_changes;
349 $holds = $order->current_item_level_holds;
351 is( ref($holds), 'Koha::Holds', 'Koha::Holds iterator returned if no linked items' );
352 is( $holds->count, 0, 'Count is 0 if no linked items' );
354 $order->add_item( $item_2->itemnumber );
355 $order->add_item( $item_3->itemnumber );
357 $holds = $order->current_item_level_holds;
358 is( $holds->count, 1, 'Only current (not future) holds are returned');
360 $schema->storage->txn_rollback;
363 subtest 'claim*' => sub {
366 $schema->storage->txn_begin;
367 my $order = $builder->build_object(
369 class => 'Koha::Acquisition::Orders',
373 my $now = dt_from_string;
374 is( $order->claims->count, 0, 'No claim yet, ->claims should return an empty set');
375 is( $order->claims_count, 0, 'No claim yet, ->claims_count should return 0');
376 is( $order->claimed_date, undef, 'No claim yet, ->claimed_date should return undef');
378 my $claim_1 = $order->claim;
379 my $claim_2 = $order->claim;
381 $claim_1->claimed_on($now->clone->subtract(days => 1))->store;
382 $claim_2->claimed_on($now)->store;
384 is( $order->claims->count, 2, '->claims should return the correct number of claims');
385 is( $order->claims_count, 2, '->claims_count should return the correct number of claims');
386 is( dt_from_string($order->claimed_date), $now, '->claimed_date should return the date of the last claim');
388 $schema->storage->txn_rollback;
391 subtest 'filter_by_late' => sub {
394 $schema->storage->txn_begin;
395 my $now = dt_from_string;
396 my $bookseller = $builder->build_object(
398 class => 'Koha::Acquisition::Booksellers',
399 value => { deliverytime => 2 }
402 my $basket_1 = $builder->build_object(
404 class => 'Koha::Acquisition::Baskets',
406 booksellerid => $bookseller->id,
411 my $order_1 = $builder->build_object(
413 class => 'Koha::Acquisition::Orders',
415 basketno => $basket_1->basketno,
416 datereceived => undef,
417 datecancellationprinted => undef,
418 estimated_delivery_date => undef,
419 orderstatus => 'ordered',
423 my $basket_2 = $builder->build_object( # expected tomorrow
425 class => 'Koha::Acquisition::Baskets',
427 booksellerid => $bookseller->id,
428 closedate => $now->clone->subtract( days => 1 ),
432 my $order_2 = $builder->build_object(
434 class => 'Koha::Acquisition::Orders',
436 basketno => $basket_2->basketno,
437 datereceived => undef,
438 datecancellationprinted => undef,
439 estimated_delivery_date => undef,
440 orderstatus => 'ordered',
444 my $basket_3 = $builder->build_object( # expected yesterday (1 day)
446 class => 'Koha::Acquisition::Baskets',
448 booksellerid => $bookseller->id,
449 closedate => $now->clone->subtract( days => 3 ),
453 my $order_3 = $builder->build_object(
455 class => 'Koha::Acquisition::Orders',
457 basketno => $basket_3->basketno,
458 datereceived => undef,
459 datecancellationprinted => undef,
460 estimated_delivery_date => undef,
461 orderstatus => 'ordered',
465 my $basket_4 = $builder->build_object( # expected 3 days ago
467 class => 'Koha::Acquisition::Baskets',
469 booksellerid => $bookseller->id,
470 closedate => $now->clone->subtract( days => 5 ),
474 my $order_4 = $builder->build_object(
476 class => 'Koha::Acquisition::Orders',
478 basketno => $basket_4->basketno,
479 datereceived => undef,
480 datecancellationprinted => undef,
481 estimated_delivery_date => undef,
482 orderstatus => 'ordered',
486 my $order_42 = $builder->build_object(
488 class => 'Koha::Acquisition::Orders',
490 basketno => $basket_4->basketno,
491 datereceived => undef,
492 datecancellationprinted => undef,
493 estimated_delivery_date => undef,
494 orderstatus => 'complete',
499 my $orders = Koha::Acquisition::Orders->search(
503 $order_1->ordernumber, $order_2->ordernumber,
504 $order_3->ordernumber, $order_4->ordernumber,
510 my $late_orders = $orders->filter_by_lates;
511 is( $late_orders->count, 3 );
513 $late_orders = $orders->filter_by_lates( { delay => 0 } );
514 is( $late_orders->count, 3 );
516 $late_orders = $orders->filter_by_lates( { delay => 1 } );
517 is( $late_orders->count, 3 );
519 $late_orders = $orders->filter_by_lates( { delay => 3 } );
520 is( $late_orders->count, 2 );
522 $late_orders = $orders->filter_by_lates( { delay => 4 } );
523 is( $late_orders->count, 1 );
525 $late_orders = $orders->filter_by_lates( { delay => 5 } );
526 is( $late_orders->count, 1 );
528 $late_orders = $orders->filter_by_lates( { delay => 6 } );
529 is( $late_orders->count, 0 );
531 $late_orders = $orders->filter_by_lates(
532 { estimated_from => $now->clone->subtract( days => 6 ) } );
533 is( $late_orders->count, 2 );
534 is( $late_orders->next->ordernumber, $order_3->ordernumber );
536 $late_orders = $orders->filter_by_lates(
537 { estimated_from => $now->clone->subtract( days => 5 ) } );
538 is( $late_orders->count, 2 );
539 is( $late_orders->next->ordernumber, $order_3->ordernumber );
541 $late_orders = $orders->filter_by_lates(
542 { estimated_from => $now->clone->subtract( days => 4 ) } );
543 is( $late_orders->count, 2 );
544 is( $late_orders->next->ordernumber, $order_3->ordernumber );
546 $late_orders = $orders->filter_by_lates(
547 { estimated_from => $now->clone->subtract( days => 3 ) } );
548 is( $late_orders->count, 2 );
550 $late_orders = $orders->filter_by_lates(
551 { estimated_from => $now->clone->subtract( days => 1 ) } );
552 is( $late_orders->count, 1 );
554 $late_orders = $orders->filter_by_lates(
556 estimated_from => $now->clone->subtract( days => 4 ),
557 estimated_to => $now->clone->subtract( days => 3 )
560 is( $late_orders->count, 1 );
562 my $basket_5 = $builder->build_object( # closed today
564 class => 'Koha::Acquisition::Baskets',
566 booksellerid => $bookseller->id,
571 my $order_5 = $builder->build_object(
573 class => 'Koha::Acquisition::Orders',
575 basketno => $basket_4->basketno,
576 datereceived => undef,
577 datecancellationprinted => undef,
578 estimated_delivery_date => $now->clone->subtract( days => 2 ),
582 $late_orders = $orders->filter_by_lates(
584 estimated_from => $now->clone->subtract( days => 3 ),
585 estimated_to => $now->clone->subtract( days => 2 )
588 is( $late_orders->count, 1 );
590 $schema->storage->txn_rollback;
593 subtest 'filter_by_current & filter_by_cancelled' => sub {
596 $schema->storage->txn_begin;
597 my $now = dt_from_string;
598 my $order_1 = $builder->build_object(
600 class => 'Koha::Acquisition::Orders',
602 datecancellationprinted => undef,
606 my $order_2 = $builder->build_object(
608 class => 'Koha::Acquisition::Orders',
610 datecancellationprinted => undef,
614 my $order_3 = $builder->build_object(
616 class => 'Koha::Acquisition::Orders',
618 datecancellationprinted => dt_from_string,
623 my $orders = Koha::Acquisition::Orders->search(
627 $order_1->ordernumber, $order_2->ordernumber,
628 $order_3->ordernumber,
634 is( $orders->filter_by_current->count, 2);
635 is( $orders->filter_by_cancelled->count, 1);
638 $schema->storage->txn_rollback;
641 subtest 'creator ()' => sub {
644 $schema->storage->txn_begin;
646 my $patron = $builder->build_object({ class => 'Koha::Patrons' });
647 my $order = $builder->build_object({ class => 'Koha::Acquisition::Orders', value => { created_by => $patron->borrowernumber } });
649 my $creator = $order->creator;
651 is($creator->borrowernumber, $patron->borrowernumber, 'Patron is order creator');
655 is( $order->get_from_storage->creator, undef );
657 $schema->storage->txn_rollback;
660 subtest 'cancel() tests' => sub {
664 $schema->storage->txn_begin;
666 my $reason = 'Some reason';
669 # * order with one item attached
670 # * the item is on loan
671 # * delete_biblio is passed
672 # => order is not cancelled
673 # => item in order is not removed
674 # => biblio in order is not removed
675 # => message about not being able to delete
677 my $item = $builder->build_sample_item;
678 my $biblio_id = $item->biblionumber;
679 my $order = $builder->build_object(
681 class => 'Koha::Acquisition::Orders',
683 orderstatus => 'new',
684 biblionumber => $item->biblionumber,
685 datecancellationprinted => undef,
686 cancellationreason => undef,
690 $order->add_item( $item->id );
692 my $patron = $builder->build_object(
694 class => 'Koha::Patrons',
695 value => { branchcode => $item->homebranch, flags => 1 }
698 t::lib::Mocks::mock_userenv({ patron => $patron });
700 # Add a checkout so deleting the item fails because od 'book_on_loan'
701 C4::Circulation::AddIssue( $patron->unblessed, $item->barcode );
703 my $result = $order->cancel({ reason => $reason });
704 # refresh the order object
705 $order->discard_changes;
707 is( $result, $order, 'self is returned' );
708 is( $order->orderstatus, 'cancelled', 'Order is not marked as cancelled' );
709 isnt( $order->datecancellationprinted, undef, 'datecancellationprinted is not undef' );
710 is( $order->cancellationreason, $reason, 'cancellationreason is set' );
711 is( ref(Koha::Items->find($item->id)), 'Koha::Item', 'The item is present' );
712 is( ref(Koha::Biblios->find($biblio_id)), 'Koha::Biblio', 'The biblio is present' );
713 my @messages = @{ $order->object_messages };
714 is( $messages[0]->message, 'error_delitem', 'An error message is attached to the order' );
717 # * order with one item attached
718 # * the item is no longer on loan
719 # * delete_biblio not passed
720 # => order is cancelled
721 # => item in order is removed
722 # => biblio remains untouched
724 C4::Circulation::AddReturn( $item->barcode );
726 $order = Koha::Acquisition::Orders->find($order->ordernumber);
727 $order->cancel({ reason => $reason })
730 is( $order->orderstatus, 'cancelled', 'Order is marked as cancelled' );
731 isnt( $order->datecancellationprinted, undef, 'datecancellationprinted is set' );
732 is( $order->cancellationreason, $reason, 'cancellationreason is undef' );
733 is( Koha::Items->find($item->id), undef, 'The item is no longer present' );
734 is( ref(Koha::Biblios->find($biblio_id)), 'Koha::Biblio', 'The biblio is present' );
735 @messages = @{ $order->object_messages };
736 is( scalar @messages, 0, 'No messages' );
739 # * order with one item attached
740 # * biblio has another item
741 # => order is cancelled
742 # => item in order is removed
743 # => the extra item remains untouched
744 # => biblio remains untouched
746 my $item_1 = $builder->build_sample_item;
747 $biblio_id = $item_1->biblionumber;
748 my $item_2 = $builder->build_sample_item({ biblionumber => $biblio_id });
749 $order = $builder->build_object(
751 class => 'Koha::Acquisition::Orders',
753 orderstatus => 'new',
754 biblionumber => $biblio_id,
755 datecancellationprinted => undef,
756 cancellationreason => undef,
760 $order->add_item( $item_1->id );
762 $order->cancel({ reason => $reason, delete_biblio => 1 })
765 is( $order->orderstatus, 'cancelled', 'Order is marked as cancelled' );
766 isnt( $order->datecancellationprinted, undef, 'datecancellationprinted is set' );
767 is( $order->cancellationreason, $reason, 'cancellationreason is undef' );
768 is( Koha::Items->find($item_1->id), undef, 'The item is no longer present' );
769 is( ref(Koha::Items->find($item_2->id)), 'Koha::Item', 'The item is still present' );
770 is( ref(Koha::Biblios->find($biblio_id)), 'Koha::Biblio', 'The biblio is still present' );
771 @messages = @{ $order->object_messages };
772 is( $messages[0]->message, 'error_delbiblio_items', 'Cannot delete biblio and it gets notified' );
775 # * order with one item attached
776 # * there's another order pointing to the biblio
777 # => order is cancelled
778 # => item in order is removed
779 # => biblio remains untouched
780 # => biblio delete error notified
782 $item = $builder->build_sample_item;
783 $biblio_id = $item->biblionumber;
784 $order = $builder->build_object(
786 class => 'Koha::Acquisition::Orders',
788 orderstatus => 'new',
789 biblionumber => $biblio_id,
790 datecancellationprinted => undef,
791 cancellationreason => undef,
795 $order->add_item( $item->id );
798 $builder->build_object(
800 class => 'Koha::Acquisition::Orders',
802 orderstatus => 'new',
803 biblionumber => $biblio_id,
804 datecancellationprinted => undef,
805 cancellationreason => undef,
810 $order->cancel({ reason => $reason, delete_biblio => 1 })
813 is( $order->orderstatus, 'cancelled', 'Order is marked as cancelled' );
814 isnt( $order->datecancellationprinted, undef, 'datecancellationprinted is set' );
815 is( $order->cancellationreason, $reason, 'cancellationreason is undef' );
816 is( Koha::Items->find($item->id), undef, 'The item is no longer present' );
817 is( ref(Koha::Biblios->find($biblio_id)), 'Koha::Biblio', 'The biblio is still present' );
818 @messages = @{ $order->object_messages };
819 is( $messages[0]->message, 'error_delbiblio_active_orders', 'Cannot delete biblio and it gets notified' );
822 # * order with one item attached
823 # * there's a subscription on the biblio
824 # => order is cancelled
825 # => item in order is removed
826 # => biblio remains untouched
827 # => biblio delete error notified
829 $item = $builder->build_sample_item;
830 $biblio_id = $item->biblionumber;
831 $order = $builder->build_object(
833 class => 'Koha::Acquisition::Orders',
835 orderstatus => 'new',
836 biblionumber => $biblio_id,
837 datecancellationprinted => undef,
838 cancellationreason => undef,
842 $order->add_item( $item->id );
845 $builder->build_object(
847 class => 'Koha::Subscriptions',
849 biblionumber => $biblio_id,
854 $order->cancel({ reason => $reason, delete_biblio => 1 })
857 is( $order->orderstatus, 'cancelled', 'Order is marked as cancelled' );
858 isnt( $order->datecancellationprinted, undef, 'datecancellationprinted is set' );
859 is( $order->cancellationreason, $reason, 'cancellationreason is undef' );
860 is( Koha::Items->find($item->id), undef, 'The item is no longer present' );
861 is( ref(Koha::Biblios->find($biblio_id)), 'Koha::Biblio', 'The biblio is still present' );
862 @messages = @{ $order->object_messages };
863 is( $messages[0]->message, 'error_delbiblio_subscriptions', 'Cannot delete biblio and it gets notified' );
866 # * order with one item attached
867 # * delete_biblio is passed
868 # => order is cancelled
869 # => item in order is removed
870 # => biblio in order is removed
872 $item = $builder->build_sample_item;
873 $biblio_id = $item->biblionumber;
874 $order = $builder->build_object(
876 class => 'Koha::Acquisition::Orders',
878 orderstatus => 'new',
879 biblionumber => $item->biblionumber,
880 datecancellationprinted => undef,
881 cancellationreason => undef,
885 $order->add_item( $item->id );
887 $order->cancel({ reason => $reason, delete_biblio => 1 })
890 is( $order->orderstatus, 'cancelled', 'Order is not marked as cancelled' );
891 isnt( $order->datecancellationprinted, undef, 'datecancellationprinted is not undef' );
892 is( $order->cancellationreason, $reason, 'cancellationreason is set' );
893 is( Koha::Items->find($item->id), undef, 'The item is not present' );
894 is( Koha::Biblios->find($biblio_id), undef, 'The biblio is not present' );
895 @messages = @{ $order->object_messages };
896 is( scalar @messages, 0, 'No errors' );
899 # * order made from a suggestion with same biblionumber
900 # => order is cancelled
901 # => suggestion status is changed to ACCEPTED
903 $item = $builder->build_sample_item;
904 $biblio_id = $item->biblionumber;
907 my $suggestion = $builder->build_object(
909 class => 'Koha::Suggestions',
911 biblionumber => $biblio_id,
912 suggesteddate => dt_from_string,
919 $order = $builder->build_object(
921 class => 'Koha::Acquisition::Orders',
923 orderstatus => 'new',
924 biblionumber => $biblio_id,
925 datecancellationprinted => undef,
926 cancellationreason => undef,
931 $order->cancel({ reason => $reason })
934 $suggestion = Koha::Suggestions->find( $suggestion->id );
936 is( $order->orderstatus, 'cancelled', 'Order is marked as cancelled' );
937 is( $suggestion->STATUS, 'ACCEPTED', 'Suggestion status is correctly reverted after order is cancelled' );
940 # * order with two items attached
941 # * one of the items is on loan
942 # => order is cancelled
943 # => item on loan is kept
944 # => the other item is removed
945 # => biblio remains untouched
946 # => biblio delete error notified
947 # => item delete error notified
949 $item_1 = $builder->build_sample_item;
950 $item_2 = $builder->build_sample_item({ biblionumber => $item_1->biblionumber });
951 my $item_3 = $builder->build_sample_item({ biblionumber => $item_1->biblionumber });
952 $biblio_id = $item_1->biblionumber;
953 $order = $builder->build_object(
955 class => 'Koha::Acquisition::Orders',
957 orderstatus => 'new',
958 biblionumber => $biblio_id,
959 datecancellationprinted => undef,
960 cancellationreason => undef,
964 $order->add_item( $item_1->id );
965 $order->add_item( $item_2->id );
966 $order->add_item( $item_3->id );
968 # Add a checkout so deleting the item fails because od 'book_on_loan'
969 C4::Circulation::AddIssue( $patron->unblessed, $item_2->barcode );
970 C4::Reserves::AddReserve(
972 branchcode => $item_3->holdingbranch,
973 borrowernumber => $patron->borrowernumber,
974 biblionumber => $biblio_id,
975 itemnumber => $item_3->id,
980 $order->cancel({ reason => $reason, delete_biblio => 1 })
983 is( $order->orderstatus, 'cancelled', 'Order is marked as cancelled' );
984 isnt( $order->datecancellationprinted, undef, 'datecancellationprinted is set' );
985 is( $order->cancellationreason, $reason, 'cancellationreason is undef' );
986 is( Koha::Items->find($item_1->id), undef, 'The item is no longer present' );
987 is( ref(Koha::Items->find($item_2->id)), 'Koha::Item', 'The on loan item is still present' );
988 is( ref(Koha::Biblios->find($biblio_id)), 'Koha::Biblio', 'The biblio is still present' );
989 @messages = @{ $order->object_messages };
990 is( $messages[0]->message, 'error_delitem', 'Cannot delete on loan item' );
991 is( $messages[0]->payload->{item}->id, $item_2->id, 'Cannot delete on loan item' );
992 is( $messages[0]->payload->{reason}, 'book_on_loan', 'Item on loan notified' );
993 is( $messages[1]->message, 'error_delitem', 'Cannot delete reserved and found item' );
994 is( $messages[1]->payload->{item}->id, $item_3->id, 'Cannot delete reserved and found item' );
995 is( $messages[1]->payload->{reason}, 'book_reserved', 'Item reserved notified' );
996 is( $messages[2]->message, 'error_delbiblio_items', 'Cannot delete on loan item' );
997 is( $messages[2]->payload->{biblio}->id, $biblio_id, 'The right biblio is attached' );
999 # Call ->store with biblionumber NULL (as ->cancel does)
1000 $item_1 = $builder->build_sample_item;
1001 $biblio_id = $item_1->biblionumber;
1002 $order= $builder->build_object({
1003 class => 'Koha::Acquisition::Orders',
1005 orderstatus => 'new',
1006 biblionumber => $biblio_id,
1007 datecancellationprinted => undef,
1008 cancellationreason => undef,
1012 biblionumber => undef,
1013 cancellationreason => $reason,
1014 datecancellationprinted => \'NOW()',
1015 orderstatus => 'cancelled',
1017 lives_ok { $order->set($columns)->store; } 'No croak on missing biblionumber when cancelling an order';
1018 throws_ok { $order->orderstatus('new')->store; } qr/Cannot insert order: Mandatory parameter biblionumber is missing/, 'Expected croak';
1020 $schema->storage->txn_rollback;