Bugzilla – Attachment 154179 Details for
Bug 30708
Creation of a new 'Preservation' module
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 30708: Duplicate/copy items to an opened train
Bug-30708-Duplicatecopy-items-to-an-opened-train.patch (text/plain), 14.39 KB, created by
Jonathan Druart
on 2023-08-03 08:23:03 UTC
(
hide
)
Description:
Bug 30708: Duplicate/copy items to an opened train
Filename:
MIME Type:
Creator:
Jonathan Druart
Created:
2023-08-03 08:23:03 UTC
Size:
14.39 KB
patch
obsolete
>From 7af5a85d00059815cf4c547dc4deada65fbd15a9 Mon Sep 17 00:00:00 2001 >From: Jonathan Druart <jonathan.druart@bugs.koha-community.org> >Date: Thu, 6 Apr 2023 17:00:21 +0200 >Subject: [PATCH] Bug 30708: Duplicate/copy items to an opened 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/Preservation/Train.pm | 21 +++-- > Koha/REST/V1/Preservation/Trains.pm | 92 +++++++++++++++++++ > api/v1/swagger/paths/preservation_trains.yaml | 75 +++++++++++++++ > api/v1/swagger/swagger.yaml | 2 + > .../components/Preservation/TrainsShow.vue | 38 +++----- > .../js/vue/fetch/preservation-api-client.js | 5 + > t/db_dependent/Koha/Preservation/Trains.t | 8 +- > 7 files changed, 206 insertions(+), 35 deletions(-) > >diff --git a/Koha/Preservation/Train.pm b/Koha/Preservation/Train.pm >index dadb1dd13d7..b87f0eb8788 100644 >--- a/Koha/Preservation/Train.pm >+++ b/Koha/Preservation/Train.pm >@@ -56,35 +56,42 @@ sub default_processing { > > Add item to this train > >-my $train_item = $train->add_item({item_id => $itemnumber, processing_id => $processing_id}); >-my $train_item = $train->add_item({barcode => $barcode, processing_id => $processing_id}); >+my $train_item = $train->add_item({item_id => $itemnumber, processing_id => $processing_id}, { skip_waiting_list_check => 0|1 }); >+my $train_item = $train->add_item({barcode => $barcode, processing_id => $processing_id, { skip_waiting_list_check => 0|1 }); >+ >+skip_waitin_list_check can be set to true if the item can be added to the train even if the item is not in the waiting list. > > =cut > > sub add_item { >- my ( $self, $train_item ) = @_; >+ my ( $self, $train_item, $params ) = @_; >+ >+ my $skip_waiting_list_check = $params->{skip_waiting_list_check} || 0; > > my $not_for_loan = C4::Context->preference('PreservationNotForLoanWaitingListIn'); > > my $key = exists $train_item->{item_id} ? 'itemnumber' : 'barcode'; > my $item = Koha::Items->find( { $key => $train_item->{item_id} || $train_item->{barcode} } ); > Koha::Exceptions::Preservation::ItemNotFound->throw unless $item; >- Koha::Exceptions::Preservation::ItemNotInWaitingList->throw if $item->notforloan != $not_for_loan; >+ >+ Koha::Exceptions::Preservation::ItemNotInWaitingList->throw >+ if !$skip_waiting_list_check && $item->notforloan != $not_for_loan; > > # 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 > my $max = $self->items->search->_resultset->get_column("user_train_item_id")->max || 0; >- my $train_item_rs = $self->_result->add_to_preservation_trains_items( >+ my $train_item_object = Koha::Preservation::Train::Item->new( > { >+ train_id => $self->train_id, > item_id => $item->itemnumber, > processing_id => $train_item->{processing_id} || $self->default_processing_id, > user_train_item_id => $max + 1, > added_on => \'NOW()', > } >- ); >+ )->store; > $item->notforloan( $self->not_for_loan )->store; >- return Koha::Preservation::Train::Item->_new_from_dbic($train_item_rs); >+ return $train_item_object->get_from_storage; > } > > =head3 add_items >diff --git a/Koha/REST/V1/Preservation/Trains.pm b/Koha/REST/V1/Preservation/Trains.pm >index 644a7a97215..cb70d2f74bd 100644 >--- a/Koha/REST/V1/Preservation/Trains.pm >+++ b/Koha/REST/V1/Preservation/Trains.pm >@@ -389,6 +389,98 @@ sub add_item { > }; > } > >+=head3 copy_item >+ >+=cut >+ >+sub copy_item { >+ my $c = shift->openapi->valid_input or return; >+ >+ my $train_id = $c->validation->param('train_id'); >+ my $train = Koha::Preservation::Trains->find( $train_id ); >+ >+ unless ($train) { >+ return $c->render( >+ status => 404, >+ openapi => { error => "Train not found" } >+ ); >+ } >+ >+ my $train_item_id = $c->validation->param('train_item_id'); >+ >+ my $train_item = Koha::Preservation::Train::Items->search({ train_item_id => $train_item_id, train_id => $train_id })->single; >+ >+ unless ($train_item) { >+ return $c->render( >+ status => 404, >+ openapi => { error => "Item not found" } >+ ); >+ } >+ >+ my $body = $c->validation->param('body'); >+ return try { >+ Koha::Database->new->schema->txn_do( >+ sub { >+ my $new_train_id = delete $body->{train_id}; >+ my $new_train = Koha::Preservation::Trains->find( $new_train_id ); >+ unless ($train) { >+ return $c->render( >+ status => 404, >+ openapi => { error => "Train not found" } >+ ); >+ } >+ my $new_train_item = $new_train->add_item( >+ { >+ item_id => $train_item->item_id, >+ processing_id => $train_item->processing_id >+ }, >+ { >+ skip_waiting_list_check => 1, >+ }, >+ ); >+ my $attributes = [ >+ map { >+ { >+ processing_attribute_id => $_->processing_attribute_id, >+ train_item_id => $new_train_item->train_item_id, >+ value => $_->value >+ } >+ } $train_item->attributes->as_list >+ ]; >+ $new_train_item->attributes($attributes); >+ return $c->render( status => 201, openapi => $train_item ); >+ } >+ ); >+ } >+ catch { >+ if ( blessed $_ ) { >+ if ( $_->isa('Koha::Exceptions::Preservation::MissingSettings') ) { >+ return $c->render( >+ status => 400, >+ openapi => { error => "MissingSettings", parameter => $_->parameter } >+ ); >+ } elsif ( $_->isa('Koha::Exceptions::Preservation::ItemNotFound') ) { >+ return $c->render( >+ status => 404, >+ openapi => { error => "Item not found" } >+ ); >+ } elsif ( $_->isa('Koha::Exceptions::Object::DuplicateID') ) { >+ return $c->render( >+ status => 409, >+ openapi => { error => $_->error, conflict => $_->duplicate_id } >+ ); >+ } elsif ( $_->isa('Koha::Exceptions::Preservation::ItemNotInWaitingList') ) { >+ return $c->render( >+ status => 400, >+ openapi => { error => 'Item not in waiting list' } >+ ); >+ } >+ } >+ >+ $c->unhandled_exception($_); >+ }; >+} >+ > =head3 update_item > > Controller function that handles updating an item from a train >diff --git a/api/v1/swagger/paths/preservation_trains.yaml b/api/v1/swagger/paths/preservation_trains.yaml >index e7fc5c90f83..dd4058e475a 100644 >--- a/api/v1/swagger/paths/preservation_trains.yaml >+++ b/api/v1/swagger/paths/preservation_trains.yaml >@@ -619,3 +619,78 @@ > x-koha-authorization: > permissions: > preservation: 1 >+ >+"/preservation/trains/{train_id}/items/{train_item_id}/copy": >+ post: >+ x-mojo-to: Preservation::Trains#copy_item >+ operationId: copyItemToAnotherTrain >+ tags: >+ - preservation_train >+ summary: Copy an item to an other train >+ consumes: >+ - application/json >+ produces: >+ - application/json >+ parameters: >+ - $ref: "../swagger.yaml#/parameters/preservation_train_id_pp" >+ - $ref: "../swagger.yaml#/parameters/preservation_train_item_id_pp" >+ - description: The train_id of the new train >+ in: body >+ name: body >+ required: true >+ schema: >+ type: object >+ responses: >+ 201: >+ description: A successfully copied item >+ schema: >+ type: object >+ 400: >+ description: Bad parameter >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ 401: >+ description: Authentication required >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ 403: >+ description: Access forbidden >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ 404: >+ description: Ressource not found >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ 409: >+ description: Conflict in creating resource >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ 413: >+ description: Payload too large >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ 500: >+ description: |- >+ Internal server error. Possible `error_code` attribute values: >+ * `internal_server_error` >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ 503: >+ description: Under maintenance >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ x-koha-authorization: >+ permissions: >+ preservation: 1 >+ description: |- >+ Internal server error. Possible `error_code` attribute values: >+ * `internal_server_error` >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ 503: >+ description: Under maintenance >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ x-koha-authorization: >+ permissions: >+ preservation: 1 >diff --git a/api/v1/swagger/swagger.yaml b/api/v1/swagger/swagger.yaml >index 4437f4e2d57..cc18bdf095b 100644 >--- a/api/v1/swagger/swagger.yaml >+++ b/api/v1/swagger/swagger.yaml >@@ -331,6 +331,8 @@ paths: > $ref: "./paths/preservation_trains.yaml#/~1preservation~1trains~1{train_id}~1items~1batch" > "/preservation/trains/{train_id}/items/{train_item_id}": > $ref: "./paths/preservation_trains.yaml#/~1preservation~1trains~1{train_id}~1items~1{train_item_id}" >+ "/preservation/trains/{train_id}/items/{train_item_id}/copy": >+ $ref: "./paths/preservation_trains.yaml#/~1preservation~1trains~1{train_id}~1items~1{train_item_id}~1copy" > /preservation/processings: > $ref: ./paths/preservation_processings.yaml#/~1preservation~1processings > "/preservation/processings/{processing_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 978b08986c3..6d522f88da3 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 >@@ -410,34 +410,18 @@ export default { > copyItem(event) { > event.preventDefault() > const client = APIClient.preservation >- let new_train_item = {} > client.train_items >- .get(this.train.train_id, this.train_item_id_to_copy) >- .then(train_item => { >- new_train_item = { >- attributes: train_item.attributes.map(attr => { >- return { >- processing_attribute_id: >- attr.processing_attribute_id, >- value: attr.value, >- } >- }), >- item_id: train_item.item_id, >- processing_id: train_item.processing_id, >- } >- }) >- .then(() => >- client.train_items >- .create(new_train_item, this.train_id_selected_for_copy) >- .then( >- success => { >- this.setMessage( >- this.$__("Item copied successfully.") >- ) >- this.show_modal = false >- }, >- error => {} >- ) >+ .copy( >+ this.train_id_selected_for_copy, >+ this.train.train_id, >+ this.train_item_id_to_copy >+ ) >+ .then( >+ success => { >+ this.setMessage(this.$__("Item copied successfully.")) >+ this.show_modal = false >+ }, >+ error => {} > ) > }, > build_datatable: function () { >diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/preservation-api-client.js b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/preservation-api-client.js >index 455a80be5e7..356adfac4b6 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/preservation-api-client.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/preservation-api-client.js >@@ -121,6 +121,11 @@ export class PreservationAPIClient extends HttpClient { > endpoint: "trains/" + train_id + "/items/batch", > body: train_items, > }), >+ copy: (new_train_id, train_id, id) => >+ this.post({ >+ endpoint: "trains/" + train_id + "/items/" + id + "/copy", >+ body: { train_id: new_train_id }, >+ }), > update: (train_item, train_id, id) => > this.put({ > endpoint: "trains/" + train_id + "/items/" + id, >diff --git a/t/db_dependent/Koha/Preservation/Trains.t b/t/db_dependent/Koha/Preservation/Trains.t >index 9fd1ea2c3ce..7bf7398ae4e 100755 >--- a/t/db_dependent/Koha/Preservation/Trains.t >+++ b/t/db_dependent/Koha/Preservation/Trains.t >@@ -52,7 +52,7 @@ subtest 'default_processing' => sub { > }; > > subtest 'add_items & items' => sub { >- plan tests => 9; >+ plan tests => 12; > > $schema->storage->txn_begin; > >@@ -98,5 +98,11 @@ subtest 'add_items & items' => sub { > is( $item_2->get_from_storage->notforloan, 0 ); > is( $item_3->get_from_storage->notforloan, $not_for_loan_train_in ); > >+ warning_is { >+ $train->add_item( { item_id => $item_2->itemnumber }, { skip_waiting_list_check => 1 } ); >+ } ''; >+ 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 ); >+ > $schema->storage->txn_rollback; > }; >-- >2.25.1
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 30708
:
134715
|
134716
|
134732
|
134733
|
134734
|
134736
|
134737
|
134738
|
134782
|
134783
|
134784
|
134785
|
152939
|
152940
|
152941
|
152942
|
152943
|
152944
|
152945
|
152946
|
152947
|
152948
|
152949
|
152950
|
152951
|
152952
|
152953
|
152954
|
152955
|
152956
|
152957
|
152958
|
152959
|
152960
|
152961
|
152962
|
152963
|
152964
|
152965
|
152966
|
152967
|
152968
|
152969
|
152970
|
153102
|
153576
|
154167
|
154168
|
154169
|
154170
|
154171
|
154172
|
154173
|
154174
|
154175
|
154176
|
154177
|
154178
|
154179
|
154180
|
154181
|
154182
|
154183
|
154184
|
154185
|
154186
|
154187
|
154188
|
154189
|
154190
|
154191
|
154192
|
154193
|
154194
|
154195
|
154196
|
154197
|
154198
|
154199
|
154200
|
154201
|
154202
|
154203
|
156592
|
156596
|
156597
|
156636
|
156637
|
156638
|
156639
|
156640
|
156641
|
156642
|
156643
|
156644
|
156645
|
156646
|
156647
|
156648
|
156649
|
156650
|
156651
|
156652
|
156653
|
156654
|
156655
|
156656
|
156657
|
156658
|
156659
|
156660
|
156661
|
156662
|
156663
|
156664
|
156665
|
156666
|
156667
|
156668
|
156669
|
156670
|
156671
|
156672
|
156673
|
156674
|
156675
|
157502
|
157503
|
157506
|
157508
|
157512
|
157514
|
157557