From 03fca85a38c1acd969a38f8643d7c567e526986b Mon Sep 17 00:00:00 2001
From: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Date: Fri, 7 Apr 2023 12:34:10 +0200
Subject: [PATCH] Bug 30708: Do not allow adding new items to a closed train

Sponsored-by: BULAC - http://www.bulac.fr/
Signed-off-by: BULAC - http://www.bulac.fr/
Signed-off-by: Heather Hernandez <heather_hernandez@nps.gov>
Signed-off-by: Laurence Rault <laurence.rault@biblibre.com>
---
 Koha/Exceptions/Preservation.pm                |  5 +++++
 Koha/Preservation/Train.pm                     |  2 ++
 Koha/REST/V1/Preservation/Trains.pm            | 15 +++++++++++++--
 .../vue/components/Preservation/TrainsList.vue | 18 ++++++++++++------
 .../vue/components/Preservation/TrainsShow.vue |  9 +++++++++
 t/db_dependent/Koha/Preservation/Trains.t      |  9 +++++++--
 6 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/Koha/Exceptions/Preservation.pm b/Koha/Exceptions/Preservation.pm
index 2224a9a2335..56407656f4c 100644
--- a/Koha/Exceptions/Preservation.pm
+++ b/Koha/Exceptions/Preservation.pm
@@ -46,6 +46,11 @@ use Exception::Class (
         isa         => 'Koha::Exceptions::Preservation',
         description => "Cannot add item to train, the item does not exist",
     },
+    'Koha::Exceptions::Preservation::CannotAddItemToClosedTrain' => {
+        isa         => 'Koha::Exceptions::Preservation',
+        description => "Cannot add item to a closed train",
+    },
+
 );
 
 sub full_message {
diff --git a/Koha/Preservation/Train.pm b/Koha/Preservation/Train.pm
index 3622cb44615..7ecd7908b41 100644
--- a/Koha/Preservation/Train.pm
+++ b/Koha/Preservation/Train.pm
@@ -66,6 +66,8 @@ skip_waitin_list_check can be set to true if the item can be added to the train
 sub add_item {
     my ( $self, $train_item, $params ) = @_;
 
+    Koha::Exceptions::Preservation::CannotAddItemToClosedTrain->throw if $self->closed_on;
+
     my $skip_waiting_list_check = $params->{skip_waiting_list_check} || 0;
 
     my $not_for_loan = C4::Context->preference('PreservationNotForLoanWaitingListIn');
diff --git a/Koha/REST/V1/Preservation/Trains.pm b/Koha/REST/V1/Preservation/Trains.pm
index 44075a1d7bf..8c79bf4cfff 100644
--- a/Koha/REST/V1/Preservation/Trains.pm
+++ b/Koha/REST/V1/Preservation/Trains.pm
@@ -332,7 +332,7 @@ sub add_items {
 
 =head3 add_item
 
-Controller function that handles adding items in batch to a train
+Controller function that handles adding a new item to a train
 
 =cut
 
@@ -387,8 +387,12 @@ sub add_item {
                     status  => 409,
                     openapi => { error => 'Item already in a non-received train', train_id => $_->train_id }
                 );
+            } elsif ( $_->isa('Koha::Exceptions::Preservation::CannotAddItemToClosedTrain') ) {
+                return $c->render(
+                    status  => 400,
+                    openapi => { error => 'Cannot add item to a closed train' }
+                );
             }
-
         }
 
         $c->unhandled_exception($_);
@@ -397,6 +401,8 @@ sub add_item {
 
 =head3 copy_item
 
+Controller function that handles copying an item from a train to an other
+
 =cut
 
 sub copy_item {
@@ -485,6 +491,11 @@ sub copy_item {
                     status  => 409,
                     openapi => { error => 'Item already in a non-received train', train_id => $_->train_id }
                 );
+            } elsif ( $_->isa('Koha::Exceptions::Preservation::CannotAddItemToClosedTrain') ) {
+                return $c->render(
+                    status  => 400,
+                    openapi => { error => 'Cannot add item to a closed train' }
+                );
             }
         }
 
diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Preservation/TrainsList.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Preservation/TrainsList.vue
index d35304b4103..79c268c0f1d 100644
--- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Preservation/TrainsList.vue
+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Preservation/TrainsList.vue
@@ -64,7 +64,8 @@ export default {
     setup() {
         const AVStore = inject("AVStore")
         const { get_lib_from_av, map_av_dt_filter } = AVStore
-        const { setConfirmationDialog, setMessage } = inject("mainStore")
+        const { setConfirmationDialog, setMessage, setWarning } =
+            inject("mainStore")
         const table = ref()
         const filters = reactive({ status: "" })
         return {
@@ -72,6 +73,7 @@ export default {
             map_av_dt_filter,
             setConfirmationDialog,
             setMessage,
+            setWarning,
             table,
             filters,
         }
@@ -156,11 +158,15 @@ export default {
             )
         },
         doAddItems: function (train, dt, event) {
-            this.$router.push(
-                "/cgi-bin/koha/preservation/trains/" +
-                    train.train_id +
-                    "/items/add"
-            )
+            if (train.closed_on != null) {
+                this.setWarning(this.$__("Cannot add items to a closed train"))
+            } else {
+                this.$router.push(
+                    "/cgi-bin/koha/preservation/trains/" +
+                        train.train_id +
+                        "/items/add"
+                )
+            }
         },
         table_url() {
             let url = "/api/v1/preservation/trains"
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 db8096ff289..daea14636a5 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
@@ -49,11 +49,20 @@
     <div v-else id="trains_show">
         <div id="toolbar" class="btn-toolbar">
             <router-link
+                v-if="train.closed_on == null"
                 :to="`/cgi-bin/koha/preservation/trains/${train.train_id}/items/add`"
                 class="btn btn-default"
                 ><font-awesome-icon icon="plus" />
                 {{ $__("Add items") }}</router-link
             >
+            <span
+                v-else
+                class="btn btn-default"
+                disabled="disabled"
+                :title="$__('Cannot add items to a closed train')"
+            >
+                <font-awesome-icon icon="plus" /> {{ $__("Add items") }}
+            </span>
             <router-link
                 :to="`/cgi-bin/koha/preservation/trains/edit/${train.train_id}`"
                 class="btn btn-default"
diff --git a/t/db_dependent/Koha/Preservation/Trains.t b/t/db_dependent/Koha/Preservation/Trains.t
index cd41e49d90a..7702875e94b 100755
--- a/t/db_dependent/Koha/Preservation/Trains.t
+++ b/t/db_dependent/Koha/Preservation/Trains.t
@@ -53,7 +53,7 @@ subtest 'default_processing' => sub {
 };
 
 subtest 'add_items & items' => sub {
-    plan tests => 13;
+    plan tests => 14;
 
     $schema->storage->txn_begin;
 
@@ -120,8 +120,13 @@ subtest 'add_items & items' => sub {
     $train->closed_on(dt_from_string)->store;
 
     throws_ok {
-        $another_train->add_item( { item_id => $item_1->itemnumber }, { skip_waiting_list_check => 1 });
+        $another_train->add_item( { item_id => $item_1->itemnumber }, { skip_waiting_list_check => 1 } );
     } 'Koha::Exceptions::Preservation::ItemAlreadyInAnotherTrain';
 
+    my $item_4 = $builder->build_sample_item;
+    throws_ok {
+        $train->add_item( { item_id => $item_4->itemnumber } );
+    } 'Koha::Exceptions::Preservation::CannotAddItemToClosedTrain';
+
     $schema->storage->txn_rollback;
 };
-- 
2.25.1