From c485e5afbdcf14d93bf5404827fca8008ae6a20a Mon Sep 17 00:00:00 2001 From: Julian Maurice Date: Thu, 17 Nov 2022 14:14:35 +0100 Subject: [PATCH] Bug 33075: Add ability to mark an item as floating Test plan: 1. Run updatedatabase.pl, update_dbix_class_files.pl and restart koha 2. Go to "Admin > Koha to MARC mapping" and map items.floating to an item subfield 3. Create an item. 4. Make sure that your configuration allows to check out this item, and when returned to a different library the item should be transfered back to its home library. 5. Check out this item and return it in a different library. It should be transfered. Check in the item in its home library to complete the transfer. 6. Modify the item and in the "floating" subfield put a value different than "0" 7. Check out this item and return it in a different library. There should be no transfer. Item's holding library should be the library where it has been returned --- Koha/CirculationRules.pm | 2 + Koha/Item.pm | 3 +- .../data/mysql/atomicupdate/bug-XXXXX.pl | 22 +++++++++ installer/data/mysql/kohastructure.sql | 2 + .../Circulation/AddReturn/floating.t | 47 +++++++++++++++++++ t/db_dependent/Circulation/Branch.t | 10 +++- 6 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/bug-XXXXX.pl create mode 100644 t/db_dependent/Circulation/AddReturn/floating.t diff --git a/Koha/CirculationRules.pm b/Koha/CirculationRules.pm index f96df496fb..24345802d9 100644 --- a/Koha/CirculationRules.pm +++ b/Koha/CirculationRules.pm @@ -499,6 +499,8 @@ This searches branchitemrules in the following order: sub get_return_branch_policy { my ( $self, $item ) = @_; + return 'noreturn' if $item->floating; + my $pref = C4::Context->preference('CircControlReturnsBranch'); my $branchcode = diff --git a/Koha/Item.pm b/Koha/Item.pm index 89d1a948c4..3c3717ff5f 100644 --- a/Koha/Item.pm +++ b/Koha/Item.pm @@ -143,11 +143,12 @@ sub store { exists $updated_columns{itemlost} or exists $updated_columns{withdrawn} or exists $updated_columns{damaged} + or exists $updated_columns{floating} ) ? $self->get_from_storage : undef; # Update *_on fields if needed # FIXME: Why not for AddItem as well? - my @fields = qw( itemlost withdrawn damaged ); + my @fields = qw( itemlost withdrawn damaged floating ); for my $field (@fields) { # If the field is defined but empty or 0, we are diff --git a/installer/data/mysql/atomicupdate/bug-XXXXX.pl b/installer/data/mysql/atomicupdate/bug-XXXXX.pl new file mode 100644 index 0000000000..0ff6367005 --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug-XXXXX.pl @@ -0,0 +1,22 @@ +use Modern::Perl; + +return { + bug_number => "XXXXX", + description => "Add items.floating and items.floating_on", + up => sub { + my ($args) = @_; + my ($dbh, $out) = @$args{qw(dbh out)}; + + unless (column_exists('items', 'floating')) { + $dbh->do(q{ + ALTER TABLE `items` ADD COLUMN `floating` TINYINT NOT NULL DEFAULT 0 COMMENT 'if set, the item does not return to its homebranch after being returned (overrides circulation rules)' AFTER withdrawn_on + }); + } + + unless (column_exists('items', 'floating_on')) { + $dbh->do(q{ + ALTER TABLE `items` ADD COLUMN `floating_on` DATETIME NULL DEFAULT NULL COMMENT 'the date and time an item was last marked as floating, NULL if not floating' AFTER floating + }); + } + }, +}; diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 03d6cbebc9..8137edefeb 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -3600,6 +3600,8 @@ CREATE TABLE `items` ( `itemlost_on` datetime DEFAULT NULL COMMENT 'the date and time an item was last marked as lost, NULL if not lost', `withdrawn` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'authorized value defining this item as withdrawn (MARC21 952$0)', `withdrawn_on` datetime DEFAULT NULL COMMENT 'the date and time an item was last marked as withdrawn, NULL if not withdrawn', + `floating` TINYINT NOT NULL DEFAULT 0 COMMENT 'if set, the item does not return to its homebranch after being returned (overrides circulation rules)', + `floating_on` DATETIME NULL DEFAULT NULL COMMENT 'the date and time an item was last marked as floating, NULL if not floating', `itemcallnumber` varchar(255) DEFAULT NULL COMMENT 'call number for this item (MARC21 952$o)', `coded_location_qualifier` varchar(10) DEFAULT NULL COMMENT 'coded location qualifier(MARC21 952$f)', `issues` smallint(6) DEFAULT 0 COMMENT 'number of times this item has been checked out/issued', diff --git a/t/db_dependent/Circulation/AddReturn/floating.t b/t/db_dependent/Circulation/AddReturn/floating.t new file mode 100644 index 0000000000..c7c72d80e0 --- /dev/null +++ b/t/db_dependent/Circulation/AddReturn/floating.t @@ -0,0 +1,47 @@ +#!/usr/bin/perl + +use Modern::Perl; +use Test::More; + +use C4::Circulation; +use Koha::Database; + +use t::lib::TestBuilder; +use t::lib::Mocks; + +my $builder = t::lib::TestBuilder->new(); +my $schema = Koha::Database->schema; + +$schema->txn_begin(); + +my $biblio = $builder->build_sample_biblio(); +my $item = $builder->build_sample_item({ biblionumber => $biblio->biblionumber, floating => 1 }); +my $patron = $builder->build_object({ class => 'Koha::Patrons' }); +my $other_library = $builder->build_object({ class => 'Koha::Libraries' }); + +t::lib::Mocks::mock_userenv({ patron => $patron }); +t::lib::Mocks::mock_preference('CircControl', 'PickupLibrary'); +t::lib::Mocks::mock_preference('AllowReturnToBranch', 'anywhere'); + +Koha::CirculationRule->new( + { + branchcode => $patron->branchcode, + itemtype => $biblio->itemtype, + categorycode => $patron->categorycode, + rule_name => 'returnbranch', + rule_value => 'homebranch' + } +); + +C4::Circulation::AddIssue($patron->unblessed, $item->barcode); +my ($doreturn, $messages) = C4::Circulation::AddReturn($item->barcode, $other_library->branchcode); +$item->discard_changes; + +ok($doreturn, 'item is returned'); +ok(!exists $messages->{WasTransfered}, 'no transfer was done'); +is($item->holdingbranch, $other_library->branchcode, 'item holding branch was changed'); + +$schema->txn_rollback(); + +done_testing; + diff --git a/t/db_dependent/Circulation/Branch.t b/t/db_dependent/Circulation/Branch.t index 53e26d2d6a..de9594ecf0 100755 --- a/t/db_dependent/Circulation/Branch.t +++ b/t/db_dependent/Circulation/Branch.t @@ -332,7 +332,7 @@ t::lib::Mocks::mock_preference( 'item-level_itypes', 0 ); $schema->storage->txn_rollback; subtest "GetBranchItemRule() tests" => sub { - plan tests => 3; + plan tests => 5; $schema->storage->txn_begin; @@ -390,9 +390,17 @@ subtest "GetBranchItemRule() tests" => sub { t::lib::Mocks::mock_preference( 'CircControlReturnsBranch', 'ItemHomeLibrary' ); is( Koha::CirculationRules->get_return_branch_policy($item), 'homebranch' ); + $item->floating(1); + is( Koha::CirculationRules->get_return_branch_policy($item), 'noreturn' ); + $item->floating(0); + t::lib::Mocks::mock_preference( 'CircControlReturnsBranch', 'ItemHoldingLibrary' ); is( Koha::CirculationRules->get_return_branch_policy($item), 'holdingbranch' ); + $item->floating(1); + is( Koha::CirculationRules->get_return_branch_policy($item), 'noreturn' ); + $item->floating(0); + t::lib::Mocks::mock_preference( 'CircControlReturnsBranch', 'CheckInLibrary' ); is( Koha::CirculationRules->get_return_branch_policy($item), 'noreturn' ); -- 2.30.2