From 9a8a4389cf8d1431911ba999b974ea0292f20fc0 Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Fri, 7 Apr 2023 12:07:29 +0200 Subject: [PATCH] Bug 30708: Do not allow copy item to a train if the item already exists in a non-received train Content-Type: text/plain; charset=utf-8 Sponsored-by: BULAC - http://www.bulac.fr/ Signed-off-by: BULAC - http://www.bulac.fr/ Signed-off-by: Heather Hernandez Signed-off-by: Laurence Rault Signed-off-by: Marcel de Rooy --- Koha/Exceptions/Preservation.pm | 5 +++++ Koha/Preservation/Train.pm | 11 ++++++++++ Koha/REST/V1/Preservation/Trains.pm | 11 ++++++++++ .../components/Preservation/TrainsShow.vue | 12 +++++++++-- t/db_dependent/Koha/Preservation/Trains.t | 21 ++++++++++++++++++- 5 files changed, 57 insertions(+), 3 deletions(-) diff --git a/Koha/Exceptions/Preservation.pm b/Koha/Exceptions/Preservation.pm index 332a76536a..2224a9a233 100644 --- a/Koha/Exceptions/Preservation.pm +++ b/Koha/Exceptions/Preservation.pm @@ -33,6 +33,11 @@ use Exception::Class ( isa => 'Koha::Exceptions::Preservation', description => "Cannot add item to waiting list, it is already in a non-received train", }, + 'Koha::Exceptions::Preservation::ItemAlreadyInAnotherTrain' => { + isa => 'Koha::Exceptions::Preservation', + description => "Cannot add item to this train, it is already in an other non-received train", + fields => ['train_id'], + }, 'Koha::Exceptions::Preservation::ItemNotInWaitingList' => { isa => 'Koha::Exceptions::Preservation', description => "Cannot add item to train, it is not in the waiting list", diff --git a/Koha/Preservation/Train.pm b/Koha/Preservation/Train.pm index b87f0eb878..3622cb4461 100644 --- a/Koha/Preservation/Train.pm +++ b/Koha/Preservation/Train.pm @@ -77,6 +77,17 @@ sub add_item { Koha::Exceptions::Preservation::ItemNotInWaitingList->throw if !$skip_waiting_list_check && $item->notforloan != $not_for_loan; + my $already_in_train = Koha::Preservation::Train::Items->search( + { item_id => $train_item->{item_id}, 'train.received_on' => undef }, + { + join => 'train' + } + ); + if ( $already_in_train->count ) { + my $train_id = $already_in_train->next->train_id; + Koha::Exceptions::Preservation::ItemAlreadyInAnotherTrain->throw( train_id => $train_id ); + } + # FIXME We need a LOCK here # Not important for now as we have add_items # Note that there are several other places in Koha with this max+1 problem diff --git a/Koha/REST/V1/Preservation/Trains.pm b/Koha/REST/V1/Preservation/Trains.pm index cb70d2f74b..44075a1d7b 100644 --- a/Koha/REST/V1/Preservation/Trains.pm +++ b/Koha/REST/V1/Preservation/Trains.pm @@ -382,7 +382,13 @@ sub add_item { status => 400, openapi => { error => 'Item not in waiting list' } ); + } elsif ( $_->isa('Koha::Exceptions::Preservation::ItemAlreadyInAnotherTrain') ) { + return $c->render( + status => 409, + openapi => { error => 'Item already in a non-received train', train_id => $_->train_id } + ); } + } $c->unhandled_exception($_); @@ -474,6 +480,11 @@ sub copy_item { status => 400, openapi => { error => 'Item not in waiting list' } ); + } elsif ( $_->isa('Koha::Exceptions::Preservation::ItemAlreadyInAnotherTrain') ) { + return $c->render( + status => 409, + openapi => { error => 'Item already in a non-received train', train_id => $_->train_id } + ); } } diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Preservation/TrainsShow.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Preservation/TrainsShow.vue index 6d522f88da..db8096ff28 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Preservation/TrainsShow.vue +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Preservation/TrainsShow.vue @@ -197,7 +197,8 @@ export default { const AVStore = inject("AVStore") const { get_lib_from_av } = AVStore - const { setConfirmationDialog, setMessage } = inject("mainStore") + const { setConfirmationDialog, setMessage, setWarning } = + inject("mainStore") const table_id = "item_list" useDataTable(table_id) @@ -208,6 +209,7 @@ export default { table_id, setConfirmationDialog, setMessage, + setWarning, } }, data() { @@ -421,7 +423,13 @@ export default { this.setMessage(this.$__("Item copied successfully.")) this.show_modal = false }, - error => {} + error => { + this.setWarning( + this.$__( + "Item cannot be copied to a train, it is already in a non-received train." + ) + ) + } ) }, build_datatable: function () { diff --git a/t/db_dependent/Koha/Preservation/Trains.t b/t/db_dependent/Koha/Preservation/Trains.t index 7bf7398ae4..cd41e49d90 100755 --- a/t/db_dependent/Koha/Preservation/Trains.t +++ b/t/db_dependent/Koha/Preservation/Trains.t @@ -23,6 +23,7 @@ use Test::Warn; use Koha::Preservation::Trains; use Koha::Database; +use Koha::DateUtils qw( dt_from_string ); use t::lib::TestBuilder; use t::lib::Mocks; @@ -52,7 +53,7 @@ subtest 'default_processing' => sub { }; subtest 'add_items & items' => sub { - plan tests => 12; + plan tests => 13; $schema->storage->txn_begin; @@ -104,5 +105,23 @@ subtest 'add_items & items' => sub { is( $train->items->count, 3, 'the item has been added to the train' ); is( $item_2->get_from_storage->notforloan, $not_for_loan_train_in ); + my $another_train = $builder->build_object( + { + class => 'Koha::Preservation::Trains', + value => { + not_for_loan => $not_for_loan_train_in, + closed_on => undef, + sent_on => undef, + received_on => undef + } + } + ); + + $train->closed_on(dt_from_string)->store; + + throws_ok { + $another_train->add_item( { item_id => $item_1->itemnumber }, { skip_waiting_list_check => 1 }); + } 'Koha::Exceptions::Preservation::ItemAlreadyInAnotherTrain'; + $schema->storage->txn_rollback; }; -- 2.30.2