3 # Copyright PTFS Europe 2016
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>.
23 use DateTime::Duration;
25 use Koha::DateUtils qw( dt_from_string );
26 use Koha::Item::Transfer;
29 use t::lib::TestBuilder;
32 use Test::More tests => 9;
34 my $schema = Koha::Database->new->schema;
36 use_ok('Koha::StockRotationItems');
37 use_ok('Koha::StockRotationItem');
39 my $builder = t::lib::TestBuilder->new;
41 subtest 'Basic object tests' => sub {
45 $schema->storage->txn_begin;
47 my $itm = $builder->build_sample_item;
48 my $stage = $builder->build({ source => 'Stockrotationstage' });
50 my $item = $builder->build({
51 source => 'Stockrotationitem',
53 itemnumber_id => $itm->itemnumber,
54 stage_id => $stage->{stage_id},
58 my $sritem = Koha::StockRotationItems->find($item->{itemnumber_id});
61 'Koha::StockRotationItem',
62 "Correctly create and load a stock rotation item."
65 # Relationship to rota
66 isa_ok( $sritem->item, 'Koha::Item', "Fetched related item." );
67 is( $sritem->item->itemnumber, $itm->itemnumber, "Related rota OK." );
69 # Relationship to stage
70 isa_ok( $sritem->stage, 'Koha::StockRotationStage', "Fetched related stage." );
71 is( $sritem->stage->stage_id, $stage->{stage_id}, "Related stage OK." );
74 $schema->storage->txn_rollback;
77 subtest 'Tests for needs_repatriating' => sub {
81 $schema->storage->txn_begin;
83 # Setup a pristine stockrotation context.
84 my $sritem = $builder->build(
86 source => 'Stockrotationitem',
88 { itemnumber_id => $builder->build_sample_item->itemnumber }
91 my $dbitem = Koha::StockRotationItems->find($sritem->{itemnumber_id});
92 $dbitem->item->homebranch($dbitem->stage->branchcode_id);
93 $dbitem->item->holdingbranch($dbitem->stage->branchcode_id);
94 $dbitem->stage->position(1);
96 my $dbrota = $dbitem->stage->rota;
97 my $newstage = $builder->build({
98 source => 'Stockrotationstage',
100 rota_id => $dbrota->rota_id,
105 # - homebranch == holdingbranch [0]
107 $dbitem->needs_repatriating, 0,
108 "Homebranch == Holdingbranch."
111 my $branch = $builder->build({ source => 'Branch' });
112 $dbitem->item->holdingbranch($branch->{branchcode});
114 # - homebranch != holdingbranch [1]
116 $dbitem->needs_repatriating, 1,
117 "Homebranch != holdingbranch."
120 # Set to incorrect homebranch.
121 $dbitem->item->holdingbranch($dbitem->stage->branchcode_id);
122 $dbitem->item->homebranch($branch->{branchcode});
123 # - homebranch != stockrotationstage.branch & not in transit [1]
125 $dbitem->needs_repatriating, 1,
126 "Homebranch != StockRotationStage.Branchcode_id & not in transit."
129 # Set to in transit (by implication).
130 $dbitem->stage($newstage->{stage_id});
131 # - homebranch != stockrotaitonstage.branch & in transit [0]
133 $dbitem->needs_repatriating, 1,
134 "homebranch != stockrotaitonstage.branch & in transit."
137 $schema->storage->txn_rollback;
140 subtest "Tests for repatriate." => sub {
142 $schema->storage->txn_begin;
144 my $sritem_1 = $builder->build_object(
146 class => 'Koha::StockRotationItems',
148 itemnumber_id => $builder->build_sample_item->itemnumber
152 my $item_id = $sritem_1->item->itemnumber;
153 my $srstage_1 = $sritem_1->stage;
154 $sritem_1->discard_changes;
155 $sritem_1->stage->position(1);
156 $sritem_1->stage->duration(50);
157 my $branch = $builder->build({ source => 'Branch' });
158 $sritem_1->item->holdingbranch($branch->{branchcode});
160 # Test a straight up repatriate
161 ok($sritem_1->repatriate, "Repatriation done.");
162 my $intransfer = $sritem_1->item->get_transfer;
163 is($intransfer->frombranch, $branch->{branchcode}, "Origin correct.");
164 is($intransfer->tobranch, $sritem_1->stage->branchcode_id, "Target Correct.");
167 $intransfer->datearrived(dt_from_string())->store;
168 $sritem_1->item->holdingbranch($branch->{branchcode});
170 # Setup a conflicting manual transfer
171 my $item = Koha::Items->find($item_id);
172 $item->request_transfer({ to => $srstage_1->branchcode, reason => "Manual" });
173 $intransfer = $item->get_transfer;
174 is (ref($intransfer), 'Koha::Item::Transfer', "Conflicting transfer added");
175 is ($intransfer->reason, 'Manual', "Conflicting transfer reason is 'Manual'");
177 # Stockrotation should handle transfer clashes
178 is($sritem_1->repatriate, 0, "Repatriation skipped if transfer in progress.");
181 $intransfer->datearrived(dt_from_string())->store;
182 $sritem_1->item->holdingbranch($branch->{branchcode});
184 # Confirm that stockrotation ignores transfer limits
185 t::lib::Mocks::mock_preference('UseBranchTransferLimits', 1);
186 t::lib::Mocks::mock_preference('BranchTransferLimitsType', 'itemtype');
187 my $limit = Koha::Item::Transfer::Limit->new(
189 fromBranch => $branch->{branchcode},
190 toBranch => $srstage_1->branchcode_id,
191 itemtype => $sritem_1->item->effective_itemtype,
195 # Stockrotation should overrule transfer limits
196 ok($sritem_1->repatriate, "Repatriation done regardless of transfer limits.");
197 $intransfer = $sritem_1->item->get_transfer;
198 is($intransfer->frombranch, $branch->{branchcode}, "Origin correct.");
199 is($intransfer->tobranch, $sritem_1->stage->branchcode_id, "Target Correct.");
201 $schema->storage->txn_rollback;
204 subtest "Tests for needs_advancing." => sub {
206 $schema->storage->txn_begin;
208 # Test behaviour of item freshly added to rota.
209 my $sritem = $builder->build(
211 source => 'Stockrotationitem',
214 itemnumber_id => $builder->build_sample_item->itemnumber
218 my $dbitem = Koha::StockRotationItems->find($sritem->{itemnumber_id});
219 is($dbitem->needs_advancing, 1, "An item that is fresh will always need advancing.");
221 # Setup a pristine stockrotation context.
222 $sritem = $builder->build(
224 source => 'Stockrotationitem',
227 itemnumber_id => $builder->build_sample_item->itemnumber
231 $dbitem = Koha::StockRotationItems->find($sritem->{itemnumber_id});
232 $dbitem->item->homebranch($dbitem->stage->branchcode_id);
233 $dbitem->item->holdingbranch($dbitem->stage->branchcode_id);
234 $dbitem->stage->position(1);
235 $dbitem->stage->duration(50);
237 my $dbtransfer = Koha::Item::Transfer->new({
238 'itemnumber' => $dbitem->itemnumber_id,
239 'frombranch' => $dbitem->stage->branchcode_id,
240 'tobranch' => $dbitem->stage->branchcode_id,
241 'datesent' => dt_from_string(),
242 'datearrived' => undef,
243 'reason' => "StockrotationAdvance",
246 # Test item will not be advanced if in transit.
247 is($dbitem->needs_advancing, 0, "Not ready to advance: in transfer.");
248 # Test item will not be advanced if in transit even if fresh.
249 $dbitem->fresh(1)->store;
250 is($dbitem->needs_advancing, 0, "Not ready to advance: in transfer (fresh).");
251 $dbitem->fresh(0)->store;
253 # Test item will not be advanced if it has not spent enough time.
254 $dbtransfer->datearrived(dt_from_string())->store;
255 is($dbitem->needs_advancing, 0, "Not ready to advance: Not spent enough time.");
256 # Test item will be advanced if it has not spent enough time, but is fresh.
257 $dbitem->fresh(1)->store;
258 is($dbitem->needs_advancing, 1, "Advance: Not spent enough time, but fresh.");
259 $dbitem->fresh(0)->store;
261 # Test item will be advanced if it has spent enough time.
262 $dbtransfer->datesent( # Item was sent 100 days ago...
263 dt_from_string() - DateTime::Duration->new( days => 100 )
265 $dbtransfer->datearrived( # And arrived 75 days ago.
266 dt_from_string() - DateTime::Duration->new( days => 75 )
268 is($dbitem->needs_advancing, 1, "Ready to be advanced.");
270 warning_is {$dbitem->needs_advancing} "We have no historical branch transfer for item " . $dbitem->item->itemnumber . "; This should not have happened!", "Missing transfer is warned.";
272 $schema->storage->txn_rollback;
275 subtest "Tests for advance." => sub {
277 $schema->storage->txn_begin;
279 my $sritem_1 = $builder->build_object(
281 class => 'Koha::StockRotationItems',
284 itemnumber_id => $builder->build_sample_item->itemnumber
288 $sritem_1->discard_changes;
289 $sritem_1->item->holdingbranch($sritem_1->stage->branchcode_id);
290 my $item_id = $sritem_1->item->itemnumber;
291 my $srstage_1 = $sritem_1->stage;
292 $srstage_1->position(1)->duration(50)->store; # Configure stage.
294 $sritem_1->item->holdingbranch($srstage_1->branchcode_id)->store;
295 $sritem_1->item->homebranch($srstage_1->branchcode_id)->store;
297 is($sritem_1->stage->stage_id, $srstage_1->stage_id, "Stage sanity check.");
299 # Test if an item is fresh, always move to first stage.
300 is($sritem_1->fresh, 1, "Fresh is correct.");
302 is($sritem_1->stage->stage_id, $srstage_1->stage_id, "Stage is first stage after fresh advance.");
303 is($sritem_1->fresh, 0, "Fresh reset after advance.");
305 # Test cases of single stage
306 $srstage_1->rota->cyclical(1)->store; # Set Rota to cyclical.
307 ok($sritem_1->advance, "Single stage cyclical advance done.");
309 $sritem_1->discard_changes;
310 is($sritem_1->stage->stage_id, $srstage_1->stage_id, "Single stage cyclical stage OK.");
312 # Test with indemand advance
313 $sritem_1->indemand(1)->store;
314 ok($sritem_1->advance, "Indemand item advance done.");
316 $sritem_1->discard_changes;
317 is($sritem_1->indemand, 0, "Indemand OK.");
318 is($sritem_1->stage->stage_id, $srstage_1->stage_id, "Indemand item advance stage OK.");
321 my $srstage_2 = $builder->build_object({
322 class => 'Koha::StockRotationStages',
323 value => { duration => 50 }
325 $srstage_2->discard_changes;
326 $srstage_2->move_to_group($sritem_1->stage->rota_id);
327 $srstage_2->move_last;
329 # Test a straight up advance
330 ok($sritem_1->advance, "Advancement done.");
332 $sritem_1->discard_changes;
334 is($sritem_1->stage->stage_id, $srstage_2->stage_id, "Stage updated.");
336 $sritem_1->item->homebranch,
337 $srstage_2->branchcode_id,
338 "Item homebranch updated"
340 my $transfer_request = $sritem_1->item->get_transfer;
341 is($transfer_request->frombranch, $srstage_1->branchcode_id, "Origin correct.");
342 is($transfer_request->tobranch, $srstage_2->branchcode_id, "Target Correct.");
343 is($transfer_request->datesent, undef, "Transfer requested, but not sent.");
345 # Arrive at new branch
346 $transfer_request->datearrived(dt_from_string())->store;
347 $sritem_1->item->holdingbranch($srstage_2->branchcode_id)->store;
349 # Test a cyclical advance
350 ok($sritem_1->advance, "Cyclical advancement done.");
352 $sritem_1->discard_changes;
354 is($sritem_1->stage->stage_id, $srstage_1->stage_id, "Stage updated.");
356 $sritem_1->item->homebranch,
357 $srstage_1->branchcode_id,
358 "Item homebranch updated"
360 $transfer_request = $sritem_1->item->get_transfer;
361 is($transfer_request->frombranch, $srstage_2->branchcode_id, "Origin correct.");
362 is($transfer_request->tobranch, $srstage_1->branchcode_id, "Target correct.");
364 # Arrive at new branch
365 $transfer_request->datearrived(dt_from_string())->store;
366 $sritem_1->item->holdingbranch($srstage_1->branchcode_id)->store;
368 # Confirm that stockrotation ignores transfer limits
369 t::lib::Mocks::mock_preference('UseBranchTransferLimits', 1);
370 t::lib::Mocks::mock_preference('BranchTransferLimitsType', 'itemtype');
371 my $limit = Koha::Item::Transfer::Limit->new(
373 fromBranch => $srstage_1->branchcode_id,
374 toBranch => $srstage_2->branchcode_id,
375 itemtype => $sritem_1->item->effective_itemtype,
379 ok($sritem_1->advance, "Advancement overrules transfer limits.");
381 $sritem_1->discard_changes;
383 is($sritem_1->stage->stage_id, $srstage_2->stage_id, "Stage updated ignoring transfer limits.");
385 $sritem_1->item->homebranch,
386 $srstage_2->branchcode_id,
387 "Item homebranch updated ignoring transfer limits"
389 $transfer_request = $sritem_1->item->get_transfer;
390 is($transfer_request->frombranch, $srstage_1->branchcode_id, "Origin correct ignoring transfer limits.");
391 is($transfer_request->tobranch, $srstage_2->branchcode_id, "Target correct ignoring transfer limits.");
393 # Arrive at new branch
394 $transfer_request->datearrived(dt_from_string())->store;
395 $sritem_1->item->holdingbranch($srstage_2->branchcode_id)->store;
397 # Setup a conflicting manual transfer
398 my $item = Koha::Items->find($item_id);
399 $item->request_transfer({ to => $srstage_1->branchcode, reason => "Manual" });
400 $transfer_request = $item->get_transfer;
401 is (ref($transfer_request), 'Koha::Item::Transfer', "Conflicting transfer added");
402 is ($transfer_request->reason, 'Manual', "Conflicting transfer reason is 'Manual'");
404 # Advance item whilst conflicting manual transfer exists
405 ok($sritem_1->advance, "Advancement done.");
407 $sritem_1->discard_changes;
409 ## Refetch conflicted transfer
410 $transfer_request->discard_changes;
412 # Conflicted transfer should have been cancelled
413 isnt($transfer_request->datecancelled, undef, "Conflicting manual transfer was cancelled");
415 # StockRotationAdvance transfer added
416 $transfer_request = $sritem_1->item->get_transfer;
417 is($transfer_request->reason, 'StockrotationAdvance', "StockrotationAdvance transfer added");
418 is($transfer_request->frombranch, $srstage_2->branchcode_id, "Origin correct.");
419 is($transfer_request->tobranch, $srstage_1->branchcode_id, "Target correct.");
421 # Arrive at new branch
422 $transfer_request->datearrived(dt_from_string())->store;
423 $sritem_1->item->holdingbranch($srstage_1->branchcode_id)->store;
425 # Setup a conflicting reserve transfer
426 $item->request_transfer({ to => $srstage_2->branchcode, reason => "Reserve" });
427 $transfer_request = $item->get_transfer;
428 is (ref($transfer_request), 'Koha::Item::Transfer', "Conflicting transfer added");
429 is ($transfer_request->reason, 'Reserve', "Conflicting transfer reason is 'Reserve'");
431 # Advance item whilst conflicting reserve transfer exists
432 ok($sritem_1->advance, "Advancement done.");
434 $sritem_1->discard_changes;
436 ## Refetch conflicted transfer
437 $transfer_request->discard_changes;
439 # Conflicted transfer should not been cancelled
440 is($transfer_request->datecancelled, undef, "Conflicting reserve transfer was not cancelled");
442 # StockRotationAdvance transfer added
443 my $transfer_requests = Koha::Item::Transfers->search(
445 itemnumber => $sritem_1->item->itemnumber,
446 datearrived => undef,
447 datecancelled => undef
450 is($transfer_requests->count, '2', "StockrotationAdvance transfer queued");
452 # Arrive at new branch
453 $transfer_request->datearrived(dt_from_string())->store;
454 $sritem_1->item->holdingbranch($srstage_2->branchcode_id)->store;
456 # StockRotationAdvance transfer added
457 $transfer_request = $sritem_1->item->get_transfer;
458 is($transfer_request->reason, 'StockrotationAdvance', "StockrotationAdvance transfer remains after reserve is met");
459 is($transfer_request->frombranch, $srstage_1->branchcode_id, "Origin correct.");
460 is($transfer_request->tobranch, $srstage_2->branchcode_id, "Target correct.");
462 # Arrive at new branch
463 $transfer_request->datearrived(dt_from_string())->store;
464 $sritem_1->item->holdingbranch($srstage_2->branchcode_id)->store;
466 # Checked out item, advanced to next stage, checkedout from next stage
467 # transfer should be generated, but not initiated
468 my $issue = $builder->build_object({
469 class => 'Koha::Checkouts',
471 branchcode => $srstage_1->branchcode_id,
472 itemnumber => $sritem_1->item->itemnumber,
476 $sritem_1->item->holdingbranch($srstage_1->branchcode_id)->store;
477 ok($sritem_1->advance, "Advancement done.");
478 $transfer_request = $sritem_1->item->get_transfer;
479 is($transfer_request->frombranch, $srstage_1->branchcode_id, "Origin correct.");
480 is($transfer_request->tobranch, $srstage_1->branchcode_id, "Target correct.");
481 is($transfer_request->datesent, undef, "Transfer waiting to initiate until return.");
483 $issue->delete; #remove issue
484 $sritem_1->advance; #advance back to second stage
486 $transfer_request->datearrived(dt_from_string())->store;
487 $sritem_1->item->holdingbranch($srstage_2->branchcode_id)->store;
490 $srstage_1->rota->cyclical(0)->store; # Set Rota to non-cyclical.
492 my $srstage_3 = $builder->build_object({
493 class => 'Koha::StockRotationStages',
494 value => { duration => 50 }
496 $srstage_3->discard_changes;
497 $srstage_3->move_to_group($sritem_1->stage->rota_id);
498 $srstage_3->move_last;
500 # Advance again, to end of rota.
501 ok($sritem_1->advance, "Non-cyclical advance to last stage.");
503 # Arrive at new branch
504 $transfer_request->datearrived(dt_from_string())->store;
505 $sritem_1->item->holdingbranch($srstage_3->branchcode_id)->store;
507 # Advance again, Remove from rota.
508 ok($sritem_1->advance, "Non-cyclical advance.");
510 $sritem_1 = Koha::StockRotationItems->find({ itemnumber_id => $item_id });
511 is($sritem_1, undef, "StockRotationItem has been removed.");
512 $item = Koha::Items->find($item_id);
513 is($item->homebranch, $srstage_3->branchcode_id, "Item homebranch remains");
515 $schema->storage->txn_rollback;
518 subtest "Tests for investigate (singular)." => sub {
520 $schema->storage->txn_begin;
522 # Test brand new item's investigation ['initiation']
523 my $sritem = $builder->build(
525 source => 'Stockrotationitem',
528 itemnumber_id => $builder->build_sample_item->itemnumber
532 my $dbitem = Koha::StockRotationItems->find($sritem->{itemnumber_id});
533 is($dbitem->investigate->{reason}, 'initiation', "fresh item initiates.");
535 # Test brand new item at stagebranch ['initiation']
536 $sritem = $builder->build(
538 source => 'Stockrotationitem',
541 itemnumber_id => $builder->build_sample_item->itemnumber
545 $dbitem = Koha::StockRotationItems->find($sritem->{itemnumber_id});
546 $dbitem->item->homebranch($dbitem->stage->branchcode_id)->store;
547 $dbitem->item->holdingbranch($dbitem->stage->branchcode_id)->store;
548 is($dbitem->investigate->{reason}, 'initiation', "fresh item at stagebranch initiates.");
550 # Test item not at stagebranch with branchtransfer history ['repatriation']
551 $sritem = $builder->build(
553 source => 'Stockrotationitem',
556 itemnumber_id => $builder->build_sample_item->itemnumber
560 $dbitem = Koha::StockRotationItems->find($sritem->{itemnumber_id});
561 my $dbtransfer = Koha::Item::Transfer->new({
562 'itemnumber' => $dbitem->itemnumber_id,
563 'frombranch' => $dbitem->item->homebranch,
564 'tobranch' => $dbitem->item->homebranch,
565 'datesent' => dt_from_string(),
566 'datearrived' => dt_from_string(),
567 'reason' => "StockrotationAdvance",
569 is($dbitem->investigate->{reason}, 'repatriation', "older item repatriates.");
571 # Test item at stagebranch with branchtransfer history ['not-ready']
572 $sritem = $builder->build(
574 source => 'Stockrotationitem',
577 itemnumber_id => $builder->build_sample_item->itemnumber
581 $dbitem = Koha::StockRotationItems->find($sritem->{itemnumber_id});
582 $dbtransfer = Koha::Item::Transfer->new({
583 'itemnumber' => $dbitem->itemnumber_id,
584 'frombranch' => $dbitem->item->homebranch,
585 'tobranch' => $dbitem->stage->branchcode_id,
586 'datesent' => dt_from_string(),
587 'datearrived' => dt_from_string(),
588 'reason' => "StockrotationAdvance",
590 $dbitem->item->homebranch($dbitem->stage->branchcode_id)->store;
591 $dbitem->item->holdingbranch($dbitem->stage->branchcode_id)->store;
592 is($dbitem->investigate->{reason}, 'not-ready', "older item at stagebranch not-ready.");
594 # Test item due for advancement ['advancement']
595 $sritem = $builder->build(
597 source => 'Stockrotationitem',
600 itemnumber_id => $builder->build_sample_item->itemnumber
604 $dbitem = Koha::StockRotationItems->find($sritem->{itemnumber_id});
605 $dbitem->indemand(0)->store;
606 $dbitem->stage->duration(50)->store;
607 my $sent_duration = DateTime::Duration->new( days => 55);
608 my $arrived_duration = DateTime::Duration->new( days => 52);
609 $dbtransfer = Koha::Item::Transfer->new({
610 'itemnumber' => $dbitem->itemnumber_id,
611 'frombranch' => $dbitem->item->homebranch,
612 'tobranch' => $dbitem->stage->branchcode_id,
613 'datesent' => dt_from_string() - $sent_duration,
614 'datearrived' => dt_from_string() - $arrived_duration,
615 'reason' => "StockrotationAdvance",
617 $dbitem->item->homebranch($dbitem->stage->branchcode_id)->store;
618 $dbitem->item->holdingbranch($dbitem->stage->branchcode_id)->store;
619 is($dbitem->investigate->{reason}, 'advancement',
620 "Item ready for advancement.");
622 # Test item due for advancement but in-demand ['in-demand']
623 $sritem = $builder->build(
625 source => 'Stockrotationitem',
628 itemnumber_id => $builder->build_sample_item->itemnumber
632 $dbitem = Koha::StockRotationItems->find($sritem->{itemnumber_id});
633 $dbitem->indemand(1)->store;
634 $dbitem->stage->duration(50)->store;
635 $sent_duration = DateTime::Duration->new( days => 55);
636 $arrived_duration = DateTime::Duration->new( days => 52);
637 $dbtransfer = Koha::Item::Transfer->new({
638 'itemnumber' => $dbitem->itemnumber_id,
639 'frombranch' => $dbitem->item->homebranch,
640 'tobranch' => $dbitem->stage->branchcode_id,
641 'datesent' => dt_from_string() - $sent_duration,
642 'datearrived' => dt_from_string() - $arrived_duration,
643 'reason' => "StockrotationAdvance",
645 $dbitem->item->homebranch($dbitem->stage->branchcode_id)->store;
646 $dbitem->item->holdingbranch($dbitem->stage->branchcode_id)->store;
647 is($dbitem->investigate->{reason}, 'in-demand',
648 "Item advances, but in-demand.");
650 # Test item ready for advancement, but at wrong library ['repatriation']
651 $sritem = $builder->build(
653 source => 'Stockrotationitem',
656 itemnumber_id => $builder->build_sample_item->itemnumber
660 $dbitem = Koha::StockRotationItems->find($sritem->{itemnumber_id});
661 $dbitem->indemand(0)->store;
662 $dbitem->stage->duration(50)->store;
663 $sent_duration = DateTime::Duration->new( days => 55);
664 $arrived_duration = DateTime::Duration->new( days => 52);
665 $dbtransfer = Koha::Item::Transfer->new({
666 'itemnumber' => $dbitem->itemnumber_id,
667 'frombranch' => $dbitem->item->homebranch,
668 'tobranch' => $dbitem->stage->branchcode_id,
669 'datesent' => dt_from_string() - $sent_duration,
670 'datearrived' => dt_from_string() - $arrived_duration,
671 'reason' => "StockrotationAdvance",
673 is($dbitem->investigate->{reason}, 'repatriation',
674 "Item advances, but not at stage branch.");
676 $schema->storage->txn_rollback;
679 subtest "Tests for toggle_indemand" => sub {
681 $schema->storage->txn_begin;
683 my $sritem = $builder->build({
684 source => 'Stockrotationitem',
685 value => { 'fresh' => 0, 'indemand' => 0 }
687 my $dbitem = Koha::StockRotationItems->find($sritem->{itemnumber_id});
688 my $firstbranch = $dbitem->stage->branchcode_id;
689 $dbitem->item->holdingbranch($firstbranch)->store;
690 my $dbstage = $dbitem->stage;
691 $dbstage->position(1)->duration(50)->store; # Configure stage.
693 $dbitem->item->holdingbranch($firstbranch)->store;
694 $dbitem->item->homebranch($firstbranch)->store;
696 is($dbitem->stage->stage_id, $dbstage->stage_id, "Stage sanity check.");
698 # Test if an item is not in transfer, toggle always acts.
699 is($dbitem->indemand, 0, "Item not in transfer starts with indemand disabled.");
700 $dbitem->toggle_indemand;
701 is($dbitem->indemand, 1, "Item not in transfer toggled correctly first time.");
702 $dbitem->toggle_indemand;
703 is($dbitem->indemand, 0, "Item not in transfer toggled correctly second time.");
706 my $srstage = $builder->build({
707 source => 'Stockrotationstage',
708 value => { duration => 50 }
710 my $dbstage2 = Koha::StockRotationStages->find($srstage->{stage_id});
711 $dbstage2->move_to_group($dbitem->stage->rota_id);
712 $dbstage2->position(2)->store;
713 my $secondbranch = $dbstage2->branchcode_id;
715 # Test an item in transfer, toggle cancels transfer and resets indemand.
716 ok($dbitem->advance, "Advancement done.");
717 $dbitem->get_from_storage;
718 my $transfer = $dbitem->item->get_transfer;
719 is(ref($transfer), 'Koha::Item::Transfer', 'Item set to in transfer as expected');
720 is($transfer->frombranch, $firstbranch, 'Transfer from set correctly');
721 is($transfer->tobranch, $secondbranch, 'Transfer to set correctly');
722 is($transfer->datearrived, undef, 'Transfer datearrived not set');
723 $dbitem->toggle_indemand;
724 my $updated_transfer = $transfer->get_from_storage;
725 is($updated_transfer->frombranch, $firstbranch, 'Transfer from retained correctly');
726 is($updated_transfer->tobranch, $firstbranch, 'Transfer to updated correctly');
727 isnt($updated_transfer->datearrived, undef, 'Transfer datearrived set as expected');
728 is($dbitem->indemand, 0, "Item retains indemand as expected.");
729 is($dbitem->stage_id, $dbstage->id, 'Item stage reset as expected.');
730 is($dbitem->item->homebranch, $firstbranch, 'Item homebranch reset as expected.');
732 $schema->storage->txn_rollback;