From 18023171d7dafd6024833eea2dfc96a684fe43f8 Mon Sep 17 00:00:00 2001 From: Agustin Moyano Date: Fri, 15 May 2020 11:09:49 -0300 Subject: [PATCH] Bug 23019: Add profiles to stage-import-batch and magnage-import-batch pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds the logic and the needed UI elements to be able to pre-load an import profile. It also displays which profile was used to stage an import in staged import manager. To test: 1. Apply all patches 2. Updatedatabase 3. Go to Stage MARC records for Import tool in admin, and upload a file with MARC records. CHECK => after uploading, there is a fieldset with the legend “Profile settings” => inside the fieldset there is a select labeled “Pre fill values with profile”. The only value it has is “Do not use profile”. 4. Change some settings, and set “profile 1” as profile name and click on “Add profile” SUCCESS => The select now has the new profile selected 5. Change profile select to “Do not use profile” SUCCESS => Default values are now displayed in the form 6. Reload the page and upload the file again SUCCESS => the select still has the profile recently added 7. Select the profile, change some parameter in the form and set the profile name to “profile 2”, and click add profile SUCCESS => there are two profiles now, and if you toggle between them, the parameter changes 8. Select profile 1, change one parameter and click on update profile SUCCESS => if you toggle that profile with the other, the new parameter of the value is shown when you select profile 1 9. Select profile 2, change some parameter and click Add profile (leaving the name as profile 2) SUCCESS => the page complains there is another profile with the same name, and asks if you want to replace it. 10. Click on accept SUCCESS => profile 2 now has the new value in the parameter 11. Select profile 2 and change the name to profile 1 SUCCESS => the page complains there is another profile with that name, and asks if you want to replace it 12. Click on accept SUCCESS => in profile select there is only one profile called profile 1 that has the values of profile 2 13. Select profile 1 and click remove profile SUCCESS => there is no profile in profile select. 14. prove t/db_dependent/ImportBatch.t t/db_dependent/api/v1/import_batch_profiles.t 15. Sign off --- C4/ImportBatch.pm | 10 +- Koha/ImportBatch.pm | 41 ++ Koha/ImportBatchProfile.pm | 54 +++ Koha/ImportBatchProfiles.pm | 51 +++ Koha/ImportBatches.pm | 51 +++ Koha/REST/V1.pm | 2 +- Koha/REST/V1/ImportBatchProfiles.pm | 145 +++++++ api/v1/swagger/definitions.json | 6 + .../definitions/import-batch-profile.json | 53 +++ .../definitions/import-batch-profiles.json | 6 + api/v1/swagger/parameters.json | 3 + .../parameters/import-batch-profile.json | 9 + api/v1/swagger/paths.json | 6 + .../swagger/paths/import-batch-profiles.json | 360 ++++++++++++++++++ .../en/modules/tools/manage-marc-import.tt | 3 + .../en/modules/tools/stage-marc-import.tt | 240 ++++++++++++ tools/manage-marc-import.pl | 2 + tools/stage-marc-import.pl | 7 + 18 files changed, 1044 insertions(+), 5 deletions(-) create mode 100644 Koha/ImportBatch.pm create mode 100644 Koha/ImportBatchProfile.pm create mode 100644 Koha/ImportBatchProfiles.pm create mode 100644 Koha/ImportBatches.pm create mode 100644 Koha/REST/V1/ImportBatchProfiles.pm create mode 100644 api/v1/swagger/definitions/import-batch-profile.json create mode 100644 api/v1/swagger/definitions/import-batch-profiles.json create mode 100644 api/v1/swagger/parameters/import-batch-profile.json create mode 100644 api/v1/swagger/paths/import-batch-profiles.json diff --git a/C4/ImportBatch.pm b/C4/ImportBatch.pm index 739f9f6786..a35bc7215f 100644 --- a/C4/ImportBatch.pm +++ b/C4/ImportBatch.pm @@ -267,7 +267,7 @@ sub GetImportBatch { my ($batch_id) = @_; my $dbh = C4::Context->dbh; - my $sth = $dbh->prepare_cached("SELECT * FROM import_batches WHERE import_batch_id = ?"); + my $sth = $dbh->prepare_cached("SELECT b.*, p.name as profile FROM import_batches b LEFT JOIN import_batches_profile p ON p.profile_id = b.profile_id WHERE import_batch_id = ?"); $sth->bind_param(1, $batch_id); $sth->execute(); my $result = $sth->fetchrow_hashref; @@ -1023,9 +1023,11 @@ sub GetImportBatchRangeDesc { my ($offset, $results_per_group) = @_; my $dbh = C4::Context->dbh; - my $query = "SELECT * FROM import_batches - WHERE batch_type IN ('batch', 'webservice') - ORDER BY import_batch_id DESC"; + my $query = "SELECT b.*, p.name as profile FROM import_batches b + LEFT JOIN import_batches_profile p + ON b.profile_id = p.profile_id + WHERE b.batch_type IN ('batch', 'webservice') + ORDER BY b.import_batch_id DESC"; my @params; if ($results_per_group){ $query .= " LIMIT ?"; diff --git a/Koha/ImportBatch.pm b/Koha/ImportBatch.pm new file mode 100644 index 0000000000..e30389c133 --- /dev/null +++ b/Koha/ImportBatch.pm @@ -0,0 +1,41 @@ +package Koha::ImportBatch; + +# This file is part of Koha. +# +# Copyright 2020 Koha Development Team +# +# Koha is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 +# of the License, or (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General +# Public License along with Koha; if not, see +# + +use Modern::Perl; + +use base qw(Koha::Object); + +=head1 NAME + +Koha::ImportBatch - Koha ImportBatch Object class + +=head1 API + +=head2 Class Methods + +=head3 _type + +=cut + +sub _type { + return 'ImportBatch'; +} + +1; \ No newline at end of file diff --git a/Koha/ImportBatchProfile.pm b/Koha/ImportBatchProfile.pm new file mode 100644 index 0000000000..5626fa9dba --- /dev/null +++ b/Koha/ImportBatchProfile.pm @@ -0,0 +1,54 @@ +package Koha::ImportBatchProfile; + +# This file is part of Koha. +# +# Copyright 2020 Koha Development Team +# +# Koha is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 +# of the License, or (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General +# Public License along with Koha; if not, see +# + +use Modern::Perl; + +use base qw(Koha::Object); + +=head1 NAME + +Koha::ImportBatchProfile - Koha ImportBatchProfile Object class + +=head1 API + +=head2 Class Methods + +=head3 to_api_mapping + +This method returns the mapping for representing a Koha::ImportBatchProfile object +on the API. + +=cut + +sub to_api_mapping { + return { + profile_id => 'id' + }; +} + +=head3 _type + +=cut + +sub _type { + return 'ImportBatchesProfile'; +} + +1; \ No newline at end of file diff --git a/Koha/ImportBatchProfiles.pm b/Koha/ImportBatchProfiles.pm new file mode 100644 index 0000000000..46800f1c59 --- /dev/null +++ b/Koha/ImportBatchProfiles.pm @@ -0,0 +1,51 @@ +package Koha::ImportBatchProfiles; + +# This file is part of Koha. +# +# Copyright 2020 Koha Development Team +# +# Koha is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 +# of the License, or (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General +# Public License along with Koha; if not, see +# + +use Modern::Perl; + +use base qw(Koha::Objects); + +use Koha::ImportBatchProfile; + +=head1 NAME + +Koha::ImportBatchProfiles - Koha ImportBatchProfiles Object class + +=head1 API + +=head2 Class Methods + +=head3 _type + +=cut + +sub _type { + return 'ImportBatchesProfile'; +} + +=head3 object_class + +=cut + +sub object_class { + return 'Koha::ImportBatchProfile'; +} + +1; \ No newline at end of file diff --git a/Koha/ImportBatches.pm b/Koha/ImportBatches.pm new file mode 100644 index 0000000000..0c6002d58f --- /dev/null +++ b/Koha/ImportBatches.pm @@ -0,0 +1,51 @@ +package Koha::ImportBatches; + +# This file is part of Koha. +# +# Copyright 2020 Koha Development Team +# +# Koha is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 +# of the License, or (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General +# Public License along with Koha; if not, see +# + +use Modern::Perl; + +use base qw(Koha::Objects); + +use Koha::ImportBatch; + +=head1 NAME + +Koha::ImportBatches - Koha ImportBatches Object class + +=head1 API + +=head2 Class Methods + +=head3 _type + +=cut + +sub _type { + return 'ImportBatch'; +} + +=head3 object_class + +=cut + +sub object_class { + return 'Koha::ImportBatch'; +} + +1; \ No newline at end of file diff --git a/Koha/REST/V1.pm b/Koha/REST/V1.pm index 680b52cd67..12d51192f1 100644 --- a/Koha/REST/V1.pm +++ b/Koha/REST/V1.pm @@ -40,7 +40,7 @@ Overloaded Mojolicious->startup method. It is called at application startup. sub startup { my $self = shift; - $self->log( Koha::Logger->get({ interface => 'api' }) ); + #$self->log( Koha::Logger->get({ interface => 'api' }) ); $self->hook( before_dispatch => sub { diff --git a/Koha/REST/V1/ImportBatchProfiles.pm b/Koha/REST/V1/ImportBatchProfiles.pm new file mode 100644 index 0000000000..1533ef8a60 --- /dev/null +++ b/Koha/REST/V1/ImportBatchProfiles.pm @@ -0,0 +1,145 @@ +package Koha::REST::V1::ImportBatchProfiles; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . + +use Modern::Perl; + +use Mojo::Base 'Mojolicious::Controller'; + +use Koha::ImportBatchProfiles; +use Koha::ImportBatchProfile; + +use Try::Tiny; + +=head1 NAME + +Koha::REST::V1::ImportBatchProfiles - Koha REST API for handling profiles for import batches (V1) + +=head1 API + +=head2 Methods + +=cut + +=head3 list + +Method that handles listing Koha::ImportBatchProfile objects + +=cut + +sub list { + my $c = shift->openapi->valid_input or return; + + return try { + my $profiles_set = Koha::ImportBatchProfiles->new; + my $profiles = $c->objects->search( $profiles_set ); + return $c->render( + status => 200, + openapi => $profiles + ); + } + catch { + $c->unhandled_exception($_); + }; +} + +=head3 add + +Method that handles adding a new Koha::ImportBatchProfile object + +=cut + +sub add { + my $c = shift->openapi->valid_input or return; + + my $body = $c->validation->param('body'); + + $body = + + return try { + my $profile = Koha::ImportBatchProfile->new_from_api( $body )->store; + return $c->render( + status => 201, + openapi => $profile->to_api + ); + } + catch { + $c->unhandled_exception($_); + }; +} + +=head3 edit + +Method that handles modifying a Koha::Hold object + +=cut + +sub edit { + my $c = shift->openapi->valid_input or return; + + return try { + my $profile_id = $c->validation->param('profile_id'); + my $profile = Koha::ImportBatchProfiles->find( $profile_id ); + unless ($profile) { + return $c->render( status => 404, + openapi => {error => "Import batch profile not found"} ); + } + + my $body = $c->req->json; + + $profile->set_from_api($body)->store; + + return $c->render( + status => 200, + openapi => $profile->to_api + ); + } + catch { + $c->unhandled_exception($_); + }; +} + +=head3 delete + +Method that handles deleting a Koha::ImportBatchProfile object + +=cut + +sub delete { + my $c = shift->openapi->valid_input or return; + + my $profile_id = $c->validation->param('profile_id'); + my $profile = Koha::ImportBatchProfiles->find( $profile_id ); + + unless ($profile) { + return $c->render( status => 404, + openapi => {error => "Import batch profile not found"} ); + } + + return try { + $profile->delete; + + return $c->render( + status => 204, + openapi => q{} + ); + } + catch { + $c->unhandled_exception($_); + }; +} + +1; \ No newline at end of file diff --git a/api/v1/swagger/definitions.json b/api/v1/swagger/definitions.json index 716e8703b6..04b26fc558 100644 --- a/api/v1/swagger/definitions.json +++ b/api/v1/swagger/definitions.json @@ -38,6 +38,12 @@ "ill_backend": { "$ref": "definitions/ill_backend.json" }, + "import-batch-profile": { + "$ref": "definitions/import-batch-profile.json" + }, + "import-batch-profiles": { + "$ref": "definitions/import-batch-profiles.json" + }, "library": { "$ref": "definitions/library.json" }, diff --git a/api/v1/swagger/definitions/import-batch-profile.json b/api/v1/swagger/definitions/import-batch-profile.json new file mode 100644 index 0000000000..a0412c7649 --- /dev/null +++ b/api/v1/swagger/definitions/import-batch-profile.json @@ -0,0 +1,53 @@ +{ + "type": "object", + "properties": { + "id": { + "type": "integer", + "description": "Internal profile identifier" + }, + "name": { + "description": "name of this profile", + "type": "string" + }, + "matcher_id": { + "description": "the id of the match rule used (matchpoints.matcher_id)", + "type": ["integer", "null"] + }, + "template_id": { + "description": "the id of the marc modification template", + "type": ["integer", "null"] + }, + "overlay_action": { + "description": "how to handle duplicate records", + "type": ["string", "null"] + }, + "nomatch_action": { + "description": "how to handle records where no match is found", + "type": ["string", "null"] + }, + "item_action": { + "description": "what to do with item records", + "type": ["string", "null"] + }, + "parse_items": { + "description": "should items be parsed", + "type": ["boolean", "null"] + }, + "record_type": { + "description": "type of record in the batch", + "type": ["string", "null"] + }, + "encoding": { + "description": "file encoding", + "type": ["string", "null"] + }, + "format": { + "description": "marc format", + "type": ["string", "null"] + }, + "comments": { + "description": "any comments added when the file was uploaded", + "type": ["string", "null"] + } + } +} \ No newline at end of file diff --git a/api/v1/swagger/definitions/import-batch-profiles.json b/api/v1/swagger/definitions/import-batch-profiles.json new file mode 100644 index 0000000000..8237f5c39c --- /dev/null +++ b/api/v1/swagger/definitions/import-batch-profiles.json @@ -0,0 +1,6 @@ +{ + "type": "array", + "items": { + "$ref": "import-batch-profile.json" + } + } \ No newline at end of file diff --git a/api/v1/swagger/parameters.json b/api/v1/swagger/parameters.json index cab2d53b47..aa0c4fe4b7 100644 --- a/api/v1/swagger/parameters.json +++ b/api/v1/swagger/parameters.json @@ -11,6 +11,9 @@ "patron_id_qp": { "$ref": "parameters/patron.json#/patron_id_qp" }, + "profile_id_pp": { + "$ref": "parameters/import-batch-profile.json#/profile_id_pp" + }, "city_id_pp": { "$ref": "parameters/city.json#/city_id_pp" }, diff --git a/api/v1/swagger/parameters/import-batch-profile.json b/api/v1/swagger/parameters/import-batch-profile.json new file mode 100644 index 0000000000..3a0804045a --- /dev/null +++ b/api/v1/swagger/parameters/import-batch-profile.json @@ -0,0 +1,9 @@ +{ + "profile_id_pp": { + "name": "profile_id", + "in": "path", + "description": "Internal profile identifier", + "required": true, + "type": "integer" + } +} \ No newline at end of file diff --git a/api/v1/swagger/paths.json b/api/v1/swagger/paths.json index 8f1af595ce..fd7b19b14d 100644 --- a/api/v1/swagger/paths.json +++ b/api/v1/swagger/paths.json @@ -104,6 +104,12 @@ "/illrequests": { "$ref": "paths/illrequests.json#/~1illrequests" }, + "/import-batch-profiles": { + "$ref": "paths/import-batch-profiles.json#/~1import-batch-profiles" + }, + "/import-batch-profiles/{profile_id}": { + "$ref": "paths/import-batch-profiles.json#/~1import-batch-profiles~1{profile_id}" + }, "/rotas/{rota_id}/stages/{stage_id}/position": { "$ref": "paths/rotas.json#/~1rotas~1{rota_id}~1stages~1{stage_id}~1position" }, diff --git a/api/v1/swagger/paths/import-batch-profiles.json b/api/v1/swagger/paths/import-batch-profiles.json new file mode 100644 index 0000000000..0500f36dfe --- /dev/null +++ b/api/v1/swagger/paths/import-batch-profiles.json @@ -0,0 +1,360 @@ +{ + "/import-batch-profiles": { + "get": { + "x-mojo-to": "ImportBatchProfiles#list", + "operationId": "listImportBatchProfiles", + "tags": [ + "ImportBatchProfiles" + ], + "parameters": [ + { + "name": "name", + "in": "query", + "description": "Search on profile's name", + "required": false, + "type": "string" + }, + { + "$ref": "../parameters.json#/match" + }, + { + "$ref": "../parameters.json#/order_by" + }, + { + "$ref": "../parameters.json#/page" + }, + { + "$ref": "../parameters.json#/per_page" + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "A list of import batch profiles", + "schema": { + "$ref": "../definitions.json#/import-batch-profiles" + } + }, + "401": { + "description": "Authentication required", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "403": { + "description": "Access forbidden", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "500": { + "description": "Internal server error", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "503": { + "description": "Under maintenance", + "schema": { + "$ref": "../definitions.json#/error" + } + } + }, + "x-koha-authorization": { + "permissions": { + "catalogue": "1" + } + } + }, + "post": { + "x-mojo-to": "ImportBatchProfiles#add", + "operationId": "addImportBatchProfiles", + "tags": [ + "ImportBatchProfiles" + ], + "parameters": [ + { + "name": "body", + "in": "body", + "description": "A JSON object containing a import batch profile", + "required": true, + "schema": { + "type": "object", + "properties": { + "name": { + "description": "name of this profile", + "type": "string" + }, + "matcher_id": { + "description": "the id of the match rule used (matchpoints.matcher_id)", + "type": ["integer", "null"] + }, + "template_id": { + "description": "the id of the marc modification template", + "type": ["integer", "null"] + }, + "overlay_action": { + "description": "how to handle duplicate records", + "type": ["string", "null"] + }, + "nomatch_action": { + "description": "how to handle records where no match is found", + "type": ["string", "null"] + }, + "item_action": { + "description": "what to do with item records", + "type": ["string", "null"] + }, + "parse_items": { + "description": "should items be parsed", + "type": ["boolean", "null"] + }, + "record_type": { + "description": "type of record in the batch", + "type": ["string", "null"] + }, + "encoding": { + "description": "file encoding", + "type": ["string", "null"] + }, + "format": { + "description": "marc format", + "type": ["string", "null"] + }, + "comments": { + "description": "any comments added when the file was uploaded", + "type": ["string", "null"] + } + } + } + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "responses": { + "201": { + "description": "Created Profile", + "schema": { + "$ref": "../definitions.json#/import-batch-profile" + } + }, + "400": { + "description": "Missing or wrong parameters", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "401": { + "description": "Authentication required", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "403": { + "description": "Hold not allowed", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "404": { + "description": "Borrower not found", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "500": { + "description": "Internal server error", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "503": { + "description": "Under maintenance", + "schema": { + "$ref": "../definitions.json#/error" + } + } + }, + "x-koha-authorization": { + "permissions": { + "catalogue": "1" + } + } + } + }, + "/import-batch-profiles/{profile_id}": { + "put": { + "x-mojo-to": "ImportBatchProfiles#edit", + "operationId": "editImportBatchProfiles", + "tags": [ + "ImportBatchProfiles" + ], + "parameters": [ + { + "$ref": "../parameters.json#/profile_id_pp" + }, + { + "name": "body", + "in": "body", + "description": "A JSON object containing a import batch profile", + "required": true, + "schema": { + "type": "object", + "properties": { + "name": { + "description": "name of this profile", + "type": "string" + }, + "matcher_id": { + "description": "the id of the match rule used (matchpoints.matcher_id)", + "type": ["integer", "null"] + }, + "template_id": { + "description": "the id of the marc modification template", + "type": ["integer", "null"] + }, + "overlay_action": { + "description": "how to handle duplicate records", + "type": ["string", "null"] + }, + "nomatch_action": { + "description": "how to handle records where no match is found", + "type": ["string", "null"] + }, + "item_action": { + "description": "what to do with item records", + "type": ["string", "null"] + }, + "parse_items": { + "description": "should items be parsed", + "type": ["boolean", "null"] + }, + "record_type": { + "description": "type of record in the batch", + "type": ["string", "null"] + }, + "encoding": { + "description": "file encoding", + "type": ["string", "null"] + }, + "format": { + "description": "marc format", + "type": ["string", "null"] + }, + "comments": { + "description": "any comments added when the file was uploaded", + "type": ["string", "null"] + } + } + } + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "responses": { + "200": { + "description": "Updated profile", + "schema": { + "$ref": "../definitions.json#/import-batch-profile" + } + }, + "400": { + "description": "Missing or wrong parameters", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "401": { + "description": "Authentication required", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "403": { + "description": "Hold not allowed", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "404": { + "description": "Borrower not found", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "500": { + "description": "Internal server error", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "503": { + "description": "Under maintenance", + "schema": { + "$ref": "../definitions.json#/error" + } + } + }, + "x-koha-authorization": { + "permissions": { + "catalogue": "1" + } + } + }, + "delete": { + "x-mojo-to": "ImportBatchProfiles#delete", + "operationId": "deleteImportBatchProfiles", + "tags": ["ImportBatchProfiles"], + "parameters": [{ + "$ref": "../parameters.json#/profile_id_pp" + } + ], + "produces": ["application/json"], + "responses": { + "204": { + "description": "Profile deleted" + }, + "401": { + "description": "Authentication required", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "403": { + "description": "Hold not allowed", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "404": { + "description": "Hold not found", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "500": { + "description": "Internal server error", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "503": { + "description": "Under maintenance", + "schema": { + "$ref": "../definitions.json#/error" + } + } + }, + "x-koha-authorization": { + "permissions": { + "catalogue": "1" + } + } + } + } +} \ No newline at end of file diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/manage-marc-import.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/manage-marc-import.tt index a3edfdf904..c2b9d89b44 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/manage-marc-import.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/manage-marc-import.tt @@ -105,6 +105,7 @@
  1. File name: [% file_name | html %]
  2. +
  3. Profile: [% IF (profile) %][% profile | html %][% ELSE %](none)[% END %]
  4. Comments: [% IF ( comments ) %][% comments | html %][% ELSE %](none)[% END %]
  5. Type: [% IF ( record_type == 'auth' ) %]Authority records[% ELSE %]Bibliographic records[% END %]
  6. Staged: [% upload_timestamp | html %]
  7. @@ -326,6 +327,7 @@ # File name + Profile Comments Type Status @@ -338,6 +340,7 @@ [% batch_lis.import_batch_id | html %] [% batch_lis.file_name | html %] + [% batch_lis.profile | html %] [% batch_lis.comments | html %] [% IF ( batch_lis.record_type == 'auth' ) %]Authority[% ELSE %]Bibliographic[% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tt index 9cffac5386..30ddb011cd 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tt @@ -95,11 +95,34 @@ +
    + Profile settings +
      +
    1. + + +
    2. +
    3. + + + +
    4. +
    +
    + + + +
    +
    +
    [% IF basketno && booksellerid %] [% END %] +
    @@ -220,6 +243,7 @@ var xhr; $(document).ready(function(){ $("#processfile").hide(); + $('#profile_fieldset').hide(); $("#record_type").change(function() { if ($(this).val() == 'auth') { $('#items').hide(); @@ -238,6 +262,194 @@ $("#mainformsubmit").on("click",function(){ return CheckForm( document.getElementById("processfile")); }); + getProfiles(); + $('#profile').change(function(){ + if(this.value=='') { + $("#mod_profile, #del_profile").prop("disabled",true); + $("#comments").val(""); + $("#record_type").val('biblio').change(); + $("#encoding").val('UTF-8').change(); + $("#format").val('ISO2709').change(); + $("#marc_modification_template_id").val("").change(); + $("#matcher").val("").change(); + $("#overlay_action").val('replace').change(); + $("#nomatch_action").val('create_new').change(); + $("#parse_itemsyes").prop("checked", true).change(); + $("#item_action").val('always_add').change(); + $("#profile_name").val('').keyup(); + } else { + const profile = $('option:selected', this).data('profile'); + $("#profile_id").val(profile.id); + $("#mod_profile, #del_profile").prop("disabled", null); + $("#comments").val(profile.comments); + $("#record_type").val(profile.record_type).change(); + $("#encoding").val(profile.encoding).change(); + $("#format").val(profile.format).change(); + $("#marc_modification_template_id").val(profile.template_id).change(); + $("#matcher").val(profile.matcher_id).change(); + $("#overlay_action").val(profile.overlay_action).change(); + $("#nomatch_action").val(profile.nomatch_action).change(); + $("input[name='parse_items'][value='"+(profile.parse_items?'1':'0')+"']").prop("checked", true).change(); + $("#item_action").val(profile.item_action).change(); + $("#profile_name").val(profile.name).keyup(); + } + }); + + $("#profile_name").keyup(function(){ + $("#add_profile").prop("disabled", this.value.trim()==''); + $("#mod_profile").prop("disabled", this.value.trim()=='' || !$("#profile").val()) + }); + + $("#add_profile").click(function() { + var name = $("#profile_name").val().trim(); + if(!name) { + alert(_("Profile must have a name")); + return; + } + + var profile = $("#profile option[value!='']") + .map(function() { + return $(this).data('profile'); + }) + .filter(function() { + return this.name == name; + }); + + if(profile.length) { + if(!confirm(_("There is another profile with this name.")+"\n\n"+_("Do you want to replace it?"))) { + return; + } + } + + new Promise(function(resolve, reject) { + + const params = { + comments: $("#comments").val() || null, + record_type: $("#record_type").val() || null, + encoding: $("#encoding").val() || null, + format: $("#format").val() || null, + template_id: $("#marc_modification_template_id").val() || null, + matcher_id: $("#matcher").val() || null, + overlay_action: $("#overlay_action").val() || null, + nomatch_action: $("#nomatch_action").val() || null, + parse_items: !!$("input[name='parse_items']:checked").val() || null, + item_action: $("#item_action").val() || null, + name: name + }; + + if(profile.length) { + $.ajax({ + url: "/api/v1/import-batch-profiles/"+profile[0].id, + method: "PUT", + data: JSON.stringify(params), + contentType: 'application/json' + }) + .done(resolve) + .fail(reject); + } else { + $.ajax({ + url: "/api/v1/import-batch-profiles/", + method: "POST", + data: JSON.stringify(params), + contentType: 'application/json' + }) + .done(resolve) + .fail(reject); + } + }) + .then(function(profile) { + return getProfiles(profile.id); + }) + .catch(function(error) { + alert(_("An error occurred")+"\n\n"+error); + }) + }); + + $("#mod_profile").click(function() { + var name = $("#profile_name").val().trim(); + var id = $("#profile").val(); + if(!id) return; + if(!name) { + alert(_("Profile must have a name")); + return; + } + var profile = $("#profile option[value!='']") + .map(function() { + return $(this).data('profile'); + }) + .filter(function() { + return this.name == name && this.id != id; + }); + + if(profile.length) { + if(!confirm(_("There is another profile with this name.")+"\n\n"+_("Do you want to replace it?"))) { + return; + } + } + new Promise(function(resolve, reject) { + if(!profile.length) return resolve(); + $.ajax({ + url: "/api/v1/import-batch-profiles/"+profile[0].id, + method: "DELETE" + }) + .done(resolve) + .fail(reject); + }) + .then(function(){ + const params = { + comments: $("#comments").val() || null, + record_type: $("#record_type").val() || null, + encoding: $("#encoding").val() || null, + format: $("#format").val() || null, + template_id: $("#marc_modification_template_id").val() || null, + matcher_id: $("#matcher").val() || null, + overlay_action: $("#overlay_action").val() || null, + nomatch_action: $("#nomatch_action").val() || null, + parse_items: !!$("input[name='parse_items']:checked").val() || null, + item_action: $("#item_action").val() || null, + name: name + }; + return new Promise(function(resolve, reject) { + $.ajax({ + url: "/api/v1/import-batch-profiles/"+id, + method: "PUT", + data: JSON.stringify(params), + contentType: 'application/json' + }) + .done(resolve) + .fail(reject); + }); + }) + .then(function() { + return getProfiles(id); + }) + .catch(function(error) { + alert(_("An error occurred")+"\n\n"+error.message); + }) + }); + + $("#del_profile").click(function() { + var id = $("#profile").val(); + if(!id) return; + if(!confirm(_("Are you sure you want to delete this profile?"))) { + return; + } + new Promise(function(resolve, reject) { + $.ajax({ + url: "/api/v1/import-batch-profiles/"+id, + method: "DELETE" + }) + .done(resolve) + .fail(reject); + }) + .then(function() { + return getProfiles(); + }) + .catch(function(error) { + alert(_("An error occurred")+"\n\n"+error); + }) + }); + }); function CheckForm(f) { if ($("#fileToUpload").value == '') { @@ -252,6 +464,7 @@ $('#fileuploadbutton').hide(); $("#fileuploadfailed").hide(); $("#processfile").hide(); + $('#profile_fieldset').hide(); $("#fileuploadstatus").show(); $("#uploadedfileid").val(''); xhr= AjaxUpload( $('#fileToUpload'), $('#fileuploadprogress'), 'temp=1', cbUpload ); @@ -277,6 +490,7 @@ $('#format').val('MARCXML'); } $("#processfile").show(); + $('#profile_fieldset').show(); } else { var errMsgs = [ _("Error code 0 not used"), _("File already exists"), _("Directory is not writeable"), _("Root directory for uploads not defined"), _("Temporary directory for uploads not defined") ]; var errCode = errors[$('#fileToUpload').prop('files')[0].name].code; @@ -290,6 +504,32 @@ ); } } + + function getProfiles(id) { + const select = $("#profile"); + $("option[value!='']", select).remove(); + return new Promise(function(resolve, reject) { + $.ajax("/api/v1/import-batch-profiles") + .then(resolve, reject); + }) + .then(function(profiles) { + profiles.forEach(function(profile) { + const opt = $("