Bugzilla – Attachment 105540 Details for
Bug 23019
Ability to create 'matching profiles' when importing records
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 23019: Add profiles to stage-import-batch and magnage-import-batch pages
Bug-23019-Add-profiles-to-stage-import-batch-and-m.patch (text/plain), 45.68 KB, created by
Agustín Moyano
on 2020-06-03 20:45:23 UTC
(
hide
)
Description:
Bug 23019: Add profiles to stage-import-batch and magnage-import-batch pages
Filename:
MIME Type:
Creator:
Agustín Moyano
Created:
2020-06-03 20:45:23 UTC
Size:
45.68 KB
patch
obsolete
>From 6fadcc2e836754ea8a5b6cd7fef8841c43deddac Mon Sep 17 00:00:00 2001 >From: Agustin Moyano <agustinmoyano@theke.io> >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. Create a profile and click on âStage for importâ >15. Go to Staged MARC management page >SUCCESS => Improt should have the name of the profile in profile column, and when you click on the file name, there should be the name of the profile in the details. > >16. prove t/db_dependent/ImportBatch.t t/db_dependent/api/v1/import_batch_profiles.t >17. 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/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 | 241 ++++++++++++ > tools/manage-marc-import.pl | 2 + > tools/stage-marc-import.pl | 7 + > 17 files changed, 1044 insertions(+), 4 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 2055a168f9..2f9dd252f5 100644 >--- a/C4/ImportBatch.pm >+++ b/C4/ImportBatch.pm >@@ -265,7 +265,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.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.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 >+# <http://www.gnu.org/licenses> >+ >+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..c0137f8265 >--- /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 >+# <http://www.gnu.org/licenses> >+ >+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 { >+ id => 'profile_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 >+# <http://www.gnu.org/licenses> >+ >+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 >+# <http://www.gnu.org/licenses> >+ >+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/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 <http://www.gnu.org/licenses>. >+ >+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..fde0393fdb >--- /dev/null >+++ b/api/v1/swagger/definitions/import-batch-profile.json >@@ -0,0 +1,53 @@ >+{ >+ "type": "object", >+ "properties": { >+ "id_profile": { >+ "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 @@ > <fieldset class="rows" id="staged-record-matching-rules"> > <ol> > <li><span class="label">File name:</span> [% file_name | html %]</li> >+ <li><span class="label">Profile:</span> [% IF (profile) %][% profile | html %][% ELSE %](none)[% END %]</li> > <li><span class="label">Comments:</span> [% IF ( comments ) %][% comments | html %][% ELSE %](none)[% END %]</li> > <li><span class="label">Type:</span> [% IF ( record_type == 'auth' ) %]Authority records[% ELSE %]Bibliographic records[% END %]</li> > <li><span class="label">Staged:</span> [% upload_timestamp | html %]</li> >@@ -326,6 +327,7 @@ > <tr> > <th>#</th> > <th>File name</th> >+ <th>Profile</th> > <th>Comments</th> > <th>Type</th> > <th>Status</th> >@@ -338,6 +340,7 @@ > <tr> > <td>[% batch_lis.import_batch_id | html %]</td> > <td><a href="[% batch_lis.script_name | url %]?import_batch_id=[% batch_lis.import_batch_id | uri %]">[% batch_lis.file_name | html %]</a></td> >+ <td>[% batch_lis.profile | html %]</td> > <td>[% batch_lis.comments | html %]</td> > <td>[% IF ( batch_lis.record_type == 'auth' ) %]Authority[% ELSE %]Bibliographic[% END %]</td> > <td> >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..0116984ae4 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 @@ > </div> > </form> > >+<fieldset class="rows" id="profile_fieldset"> >+ <legend>Profile settings</legend> >+ <ol> >+ <li> >+ <label for="profile">Pre fill values with profile</label> >+ <select name="profile" id="profile"> >+ <option value="">Do not use profile</option> >+ </select> >+ </li> >+ <li> >+ <label for="profile_name">Profile name</label> >+ <input type="text" id="profile_name" name="profile_name" /> >+ >+ </li> >+ </ol> >+ <fieldset class="action"> >+ <button id="add_profile" disabled>Add profile</button> >+ <button id="mod_profile" disabled>Update profile</button> >+ <button id="del_profile" disabled>Remove profile</button> >+ </fieldset> >+</fieldset> >+ > <form method="post" id="processfile" action="[% SCRIPT_NAME | html %]" enctype="multipart/form-data"> > [% IF basketno && booksellerid %] > <input type="hidden" name="basketno" id="basketno" value="[% basketno | html %]" /> > <input type="hidden" name="booksellerid" id="booksellerid" value="[% booksellerid | html %]" /> > [% END %] >+ <input type="hidden" name="profile_id" id="profile_id"/> > <fieldset class="rows"> > <input type="hidden" name="uploadedfileid" id="uploadedfileid" value="" /> > <input type="hidden" name="runinbackground" id="runinbackground" value="" /> >@@ -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,195 @@ > $("#mainformsubmit").on("click",function(){ > return CheckForm( document.getElementById("processfile")); > }); >+ getProfiles(); >+ $('#profile').change(function(){ >+ if(this.value=='') { >+ $("#mod_profile, #del_profile").prop("disabled",true); >+ $("#profile_id").val(""); >+ $("#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.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].profile_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.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.profile_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].profile_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 +465,7 @@ > $('#fileuploadbutton').hide(); > $("#fileuploadfailed").hide(); > $("#processfile").hide(); >+ $('#profile_fieldset').hide(); > $("#fileuploadstatus").show(); > $("#uploadedfileid").val(''); > xhr= AjaxUpload( $('#fileToUpload'), $('#fileuploadprogress'), 'temp=1', cbUpload ); >@@ -277,6 +491,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 +505,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 = $("<option/>"); >+ select.append(opt); >+ if(id && profile.profile_id == id) { >+ opt.prop('selected', true); >+ } >+ opt.attr("value", profile.profile_id); >+ opt.html(profile.name); >+ opt.data("profile", profile); >+ }); >+ }) >+ .then(function(){ >+ select.change(); >+ }); >+ } >+ >+ > </script> > [% END %] > >diff --git a/tools/manage-marc-import.pl b/tools/manage-marc-import.pl >index 6f9405d281..17b597dc0b 100755 >--- a/tools/manage-marc-import.pl >+++ b/tools/manage-marc-import.pl >@@ -217,6 +217,7 @@ sub import_batches_list { > comments => $batch->{'comments'}, > can_clean => ($batch->{'import_status'} ne 'cleaned') ? 1 : 0, > record_type => $batch->{'record_type'}, >+ profile => $batch->{'profile'}, > }; > } > $template->param(batch_list => \@list); >@@ -391,6 +392,7 @@ sub batch_info { > my ($template, $batch) = @_; > $template->param(batch_info => 1); > $template->param(file_name => $batch->{'file_name'}); >+ $template->param(profile => $batch->{'profile'}); > $template->param(comments => $batch->{'comments'}); > $template->param(import_status => $batch->{'import_status'}); > $template->param(upload_timestamp => $batch->{'upload_timestamp'}); >diff --git a/tools/stage-marc-import.pl b/tools/stage-marc-import.pl >index 78424bbc6f..b95c529120 100755 >--- a/tools/stage-marc-import.pl >+++ b/tools/stage-marc-import.pl >@@ -42,6 +42,7 @@ use Koha::UploadedFiles; > use C4::BackgroundJob; > use C4::MarcModificationTemplates; > use Koha::Plugins; >+use Koha::ImportBatches; > > my $input = new CGI; > >@@ -60,6 +61,7 @@ my $format = $input->param('format') || 'ISO2709'; > my $marc_modification_template = $input->param('marc_modification_template_id'); > my $basketno = $input->param('basketno'); > my $booksellerid = $input->param('booksellerid'); >+my $profile_id = $input->param('profile_id'); > > my ( $template, $loggedinuser, $cookie ) = get_template_and_user( > { >@@ -152,6 +154,11 @@ if ($completedJobID) { > 50, staging_progress_callback( $job, $dbh ) > ); > >+ if($profile_id) { >+ my $ibatch = Koha::ImportBatches->find($batch_id); >+ $ibatch->set({profile_id => $profile_id})->store; >+ } >+ > my $num_with_matches = 0; > my $checked_matches = 0; > my $matcher_failed = 0; >-- >2.25.0
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 23019
:
104972
|
104973
|
104974
|
104975
|
104976
|
105536
|
105537
|
105538
|
105539
|
105540
|
105541
|
105555
|
105600
|
105601
|
105602
|
105603
|
105604
|
106555
|
109265
|
109266
|
109637
|
112531
|
112532
|
112533
|
112534
|
112535
|
112536
|
112537
|
112715
|
112716
|
112717
|
112718
|
112719
|
112720
|
112721
|
112722
|
113276
|
113277
|
113311
|
113416
|
113421