Bugzilla – Attachment 142879 Details for
Bug 24606
Allow storing item values as a template for creating new items
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 24606: Implement item templates
Bug-24606-Implement-item-templates.patch (text/plain), 15.36 KB, created by
Katrin Fischer
on 2022-11-01 14:36:43 UTC
(
hide
)
Description:
Bug 24606: Implement item templates
Filename:
MIME Type:
Creator:
Katrin Fischer
Created:
2022-11-01 14:36:43 UTC
Size:
15.36 KB
patch
obsolete
>From e7a7a73ca1d978da19c540c65a85f9c21f0fa68d Mon Sep 17 00:00:00 2001 >From: Kyle Hall <kyle@bywatersolutions.com> >Date: Thu, 29 Sep 2022 09:06:28 -0400 >Subject: [PATCH] Bug 24606: Implement item templates > >This patch set implements item editor templates for community Koha. > >Test Plan: >1) Apply this patch set >2) Run updatedatabase.pl >3) Restart all the things! >4) prove t/db_dependent/Koha/Item/Template* >5) As a non superlibrarian, enter the item editor >6) Set some item fields, save as a new template using the buttom and > form below the editor. >7) Test loading a template without remembering for the session >8) Test loading a template while remembering for the session >9) Test deleting a template >10) Test updating a template >11) Create one or more shared templates >12) Log in as another non superlibrarian without the new permission manage_item_editor_templates, > verify you cannot edit/delete templates shared to you >13) Enable the new permission manage_item_editor_templates, > verify you can now edit and delete templates shared to you > >Signed-off-by: David Nind <david@davidnind.com> > >Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de> >--- > cataloguing/additem.pl | 127 ++++++++++++++---- > .../en/includes/str/cataloging_additem.inc | 1 + > .../prog/en/modules/cataloguing/additem.tt | 67 +++++++++ > .../prog/js/cataloging_additem.js | 40 ++++++ > 4 files changed, 210 insertions(+), 25 deletions(-) > >diff --git a/cataloguing/additem.pl b/cataloguing/additem.pl >index 4617cb54db..0a17b538ce 100755 >--- a/cataloguing/additem.pl >+++ b/cataloguing/additem.pl >@@ -22,38 +22,34 @@ > use Modern::Perl; > > use CGI qw ( -utf8 ); >+ > use C4::Auth qw( get_template_and_user haspermission ); >-use C4::Output qw( output_and_exit_if_error output_and_exit output_html_with_http_headers ); >-use C4::Biblio qw( >- GetFrameworkCode >- GetMarcFromKohaField >- GetMarcStructure >- IsMarcStructureInternal >- ModBiblio >-); >-use C4::Context; >-use C4::Circulation qw( barcodedecode LostItem ); >-use C4::Barcodes; > use C4::Barcodes::ValueBuilder; >+use C4::Barcodes; >+use C4::Biblio qw( GetFrameworkCode GetMarcFromKohaField GetMarcStructure IsMarcStructureInternal ModBiblio ); >+use C4::Circulation qw( barcodedecode LostItem ); >+use C4::Context; >+use C4::Members; >+use C4::Output qw( output_and_exit_if_error output_and_exit output_html_with_http_headers ); >+use C4::Search qw( enabled_staff_search_views ); > use Koha::Biblios; >-use Koha::Items; >+use Koha::Item::Templates; > use Koha::ItemTypes; > use Koha::Items; >+use Koha::Items; > use Koha::Libraries; > use Koha::Patrons; > use Koha::SearchEngine::Indexer; >-use C4::Search qw( enabled_staff_search_views ); >-use Storable qw( freeze thaw ); >-use URI::Escape qw( uri_escape_utf8 ); >-use C4::Members; > use Koha::UI::Form::Builder::Item; > >-use MARC::File::XML; >-use URI::Escape qw( uri_escape_utf8 ); > use Encode qw( encode_utf8 ); >-use MIME::Base64 qw( decode_base64url encode_base64url ); >-use List::Util qw( first ); > use List::MoreUtils qw( any uniq ); >+use List::Util qw( first ); >+use MARC::File::XML; >+use MIME::Base64 qw( decode_base64url encode_base64url ); >+use Storable qw( freeze thaw ); >+use URI::Escape qw( uri_escape_utf8 ); >+use URI::Escape qw( uri_escape_utf8 ); > > our $dbh = C4::Context->dbh; > >@@ -85,6 +81,14 @@ sub add_item_to_item_group { > )->store(); > } > >+sub get_item_from_template { >+ my ( $template_id ) = @_; >+ >+ my $template = Koha::Item::Templates->find($template_id); >+ >+ return $template->decoded_contents if $template; >+} >+ > sub get_item_from_cookie { > my ( $input ) = @_; > >@@ -174,12 +178,51 @@ my @errors; # store errors found while checking data BEFORE saving item. > # Getting last created item cookie > my $prefillitem = C4::Context->preference('PrefillItem'); > >+my $load_template_submit = $input->param('load_template_submit'); >+my $delete_template_submit = $input->param('delete_template_submit'); >+my $unload_template_submit = $input->param('unload_template_submit'); >+my $use_template_for_session = $input->param('use_template_for_session') || $input->cookie('ItemEditorSessionTemplateId'); >+my $template_id = $input->param('template_id') || $input->cookie('ItemEditorSessionTemplateId'); >+if ( $delete_template_submit ) { >+ my $t = Koha::Item::Templates->find($template_id); >+ $t->delete if $t && $t->borrowernumber eq $loggedinuser; >+ $template_id = undef; >+ $use_template_for_session = undef; >+} >+if ($load_template_submit || $unload_template_submit) { >+ $op = q{} if $template_id; >+ >+ $template_id = undef if !$input->param('template_id'); >+ $template_id = undef if $unload_template_submit; >+ >+ # Unset the cookie if either no template id as submitted, or "use for session" checkbox as unchecked >+ my $cookie_value = $input->param('use_template_for_session') && $template_id ? $template_id : q{}; >+ $use_template_for_session = $cookie_value; >+ >+ # Update the cookie >+ my $template_cookie = $input->cookie( >+ -name => 'ItemEditorSessionTemplateId', >+ -value => $cookie_value, >+ -HttpOnly => 1, >+ -expires => '', >+ -sameSite => 'Lax' >+ ); >+ >+ $cookie = [ $cookie, $template_cookie ]; >+} >+$template->param( >+ template_id => $template_id, >+ item_templates => Koha::Item::Templates->get_available($loggedinuser), >+ use_template_for_session => $use_template_for_session, >+); >+ > #------------------------------------------------------------------------------- > if ($op eq "additem") { > > my $add_submit = $input->param('add_submit'); > my $add_duplicate_submit = $input->param('add_duplicate_submit'); > my $add_multiple_copies_submit = $input->param('add_multiple_copies_submit'); >+ my $save_as_template_submit = $input->param('save_as_template_submit'); > my $number_of_copies = $input->param('number_of_copies'); > > my @columns = Koha::Items->columns; >@@ -225,8 +268,36 @@ if ($op eq "additem") { > > $item->barcode(barcodedecode($item->barcode)); > >+ if ($save_as_template_submit) { >+ my $template_name = $input->param('template_name'); >+ my $template_is_shared = $input->param('template_is_shared'); >+ my $replace_template_id = $input->param('replace_template_id'); >+ >+ if ($replace_template_id) { >+ my $template = Koha::Item::Templates->find($replace_template_id); >+ if ($template) { >+ $template->update( >+ { >+ id => $replace_template_id, >+ is_shared => $template_is_shared ? 1 : 0, >+ contents => $item->unblessed, >+ } >+ ); >+ } >+ } >+ else { >+ my $template = Koha::Item::Template->new( >+ { >+ name => $template_name, >+ borrowernumber => $loggedinuser, >+ is_shared => $template_is_shared ? 1 : 0, >+ contents => $item->unblessed, >+ } >+ )->store(); >+ } >+ } > # If we have to add or add & duplicate, we add the item >- if ( $add_submit || $add_duplicate_submit || $prefillitem) { >+ elsif ( $add_submit || $add_duplicate_submit || $prefillitem) { > > # check for item barcode # being unique > if ( defined $item->barcode >@@ -585,13 +656,19 @@ my @header_value_loop = map { > } sort keys %$subfieldcode_attribute_mappings; > > # Using last created item if it exists >-if ( $prefillitem >- && $op ne "additem" >+if ( >+ $op ne "additem" > && $op ne "edititem" > && $op ne "dupeitem" ) > { >- my $item_from_cookie = get_item_from_cookie($input); >- $current_item = $item_from_cookie if $item_from_cookie; >+ if ( $template_id ) { >+ my $item_from_template = get_item_from_template($template_id); >+ $current_item = $item_from_template if $item_from_template; >+ } >+ elsif ( $prefillitem ) { >+ my $item_from_cookie = get_item_from_cookie($input); >+ $current_item = $item_from_cookie if $item_from_cookie; >+ } > } > > if ( $current_item->{more_subfields_xml} ) { >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/str/cataloging_additem.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/str/cataloging_additem.inc >index 1a2009d6f1..c51447de9a 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/str/cataloging_additem.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/str/cataloging_additem.inc >@@ -20,6 +20,7 @@ > var MSG_CONFIRM_DELETE_ITEM = _("Are you sure you want to delete this item?"); > var MSG_CONFIRM_ADD_ITEM = _("Are you sure you want to add a new item? Any changes made on this page will be lost."); > var MSG_CONFIRM_SAVE = _("Are you sure you want to save?"); >+ var MSG_TEMPLATE_NAME_REQUIRED = _("Template name is required."); > var table_settings = [% TablesSettings.GetTableSettings( 'cataloguing', 'additem', 'itemst', 'json' ) | $raw %]; > </script> > <!-- / str/cataloging_additem.inc --> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt >index b80404a420..8e355b60e1 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/additem.tt >@@ -161,6 +161,44 @@ > [% ELSE %] > <h2 id="edititem">Edit item #[% itemnumber | html %][% IF ( barcode ) %] / Barcode [% barcode | html %][% END %]</h2> > [% END %] >+ >+ <div id="item-template-toolbar" class="btn-toolbar"> >+ <select name="template_id" id="template_id" class="select2" style="width: 20em"> >+ <option value="0" selected="selected">Do not use template</option> >+ <optgroup label="My templates"> >+ [% FOREACH t IN item_templates.owned %] >+ [% IF t.id == template_id %] >+ <option data-owner="1" value="[% t.id | html %]" selected="selected">[% t.name | html %][% IF t.is_shared %] (shared)[% END %]</option> >+ [% ELSE %] >+ <option data-owner="1" value="[% t.id | html %]">[% t.name | html %][% IF t.is_shared %] (shared)[% END %]</option> >+ [% END %] >+ [% END %] >+ </optgroup> >+ <optgroup label="Shared templates"> >+ [% FOREACH t IN item_templates.shared %] >+ [% IF t.id == template_id %] >+ <option data-owner="0" value="[% t.id | html %]" selected="selected">[% t.name | html %]</option> >+ [% ELSE %] >+ <option data-owner="0" value="[% t.id | html %]">[% t.name | html %]</option> >+ [% END %] >+ [% END %] >+ </optgroup> >+ </select> >+ <button type="submit" id="load_template_submit" name="load_template_submit" value="1"><i class="fa fa-wpforms"></i> Apply template</button> >+ <label for="use_template_for_session"> >+ [% IF use_template_for_session %] >+ <input type="checkbox" id="use_template_for_session" name="use_template_for_session" checked="checked"> >+ [% ELSE %] >+ <input type="checkbox" id="use_template_for_session" name="use_template_for_session"> >+ [% END %] >+ For session</label> >+ >+ <button type="submit" id="unload_template_submit" name="unload_template_submit" value="1"><i class="fa fa-eraser"></i> Clear template</button> >+ >+ <button type="submit" id="delete_template_submit" name="delete_template_submit" value="1" disabled><i class="fa fa-trash"></i> Delete template</button> >+ >+ </div> >+ > <fieldset class="rows"> > [% PROCESS subfields_for_item subfields => subfields %] > </fieldset> >@@ -217,6 +255,35 @@ > <div class="hint"><p>The barcode you enter will be incremented for each additional item.</p></div> > </fieldset> > >+ <span id="savetemplate"> >+ <input type="button" name="save_as_template" id="save_as_template" value="Save as template" /> >+ </span> >+ <fieldset id="save_as_template_span"> >+ <legend>Save template</legend> >+ <select name="replace_template_id" id="replace_template_id" class="select2" style="width: 20em"> >+ <option value="0" selected="selected">Save as new</option> >+ <optgroup label="Update existing"> >+ [% FOREACH t IN item_templates.owned %] >+ <option data-owner="1" value="[% t.id | html %]">[% t.name | html %][% IF t.is_shared %] (shared)[% END %]</option> >+ [% END %] >+ </optgroup> >+ </select> >+ >+ <span id="template_name_block"> >+ <label for="template_name" class="required">Template name: </label> >+ <input type="text" id="template_name" name="template_name" class="required"/> >+ <span class="required">Required</span> >+ </span> >+ >+ <label for="template_is_shared"> >+ <input type="checkbox" id="template_is_shared" name="template_is_shared"/> >+ Share template >+ </label> >+ >+ <input type="submit" id="save_as_template_submit" name="save_as_template_submit" value="Save" onclick="javascript:return CheckTemplateForm(this.form);" /> >+ <a href="#" id="cancel_save_as_template" class="cancel">Cancel</a> >+ </fieldset> >+ > [% ELSE %] > [% IF op != 'add_item' %] > <input type="hidden" name="itemnumber" value="[% itemnumber | html %]" /> >diff --git a/koha-tmpl/intranet-tmpl/prog/js/cataloging_additem.js b/koha-tmpl/intranet-tmpl/prog/js/cataloging_additem.js >index 1427f916a9..9bd660ad3b 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/cataloging_additem.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/cataloging_additem.js >@@ -69,6 +69,37 @@ $(document).ready(function(){ > multiCopyControl.toggle(); > }); > >+ var saveAsTemplateControl = $("#save_as_template_span"); >+ var saveTemplateBlock = $("#savetemplate"); >+ saveAsTemplateControl.hide(); >+ $("#save_as_template").on("click",function(e){ >+ e.preventDefault; >+ saveTemplateBlock.toggle(); >+ saveAsTemplateControl.toggle(); >+ $('#template_name').focus(); >+ }); >+ $("#cancel_save_as_template").on("click",function(e){ >+ e.preventDefault(); >+ saveTemplateBlock.toggle(); >+ saveAsTemplateControl.toggle(); >+ }); >+ >+ $("#template_id").on("change", function() { >+ if ( $(this).find(":selected").data("owner") ) { >+ $("#delete_template_submit").removeAttr("disabled"); >+ } else { >+ $("#delete_template_submit").attr("disabled", "disabled"); >+ } >+ }); >+ $("#template_id").change(); // Trigger to enable delete button if patron's template is in use >+ $("#replace_template_id").on("change", function() { >+ if ( $(this).find(":selected").val() > 0 ) { >+ $("#template_name_block").hide(); >+ } else { >+ $("#template_name_block").show(); >+ } >+ }); >+ > // Add new item to an item group > if ( has_item_groups ) { > $('#item-group-add-or-create-form-description-block').hide(); >@@ -98,6 +129,15 @@ $(document).ready(function(){ > }); > }); > >+function CheckTemplateForm(f) { >+ if ( $('#replace_template_id').val() == "0" && $('#template_name').val() == "" ) { >+ alert(MSG_TEMPLATE_NAME_REQUIRED); >+ return false; >+ } else { >+ return true; >+ } >+} >+ > function Check(f) { > var total_mandatory = CheckMandatorySubfields(f); > var total_important = CheckImportantSubfields(f); >-- >2.30.2
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 24606
:
141613
|
141614
|
141615
|
141616
|
141617
|
141717
|
141718
|
141719
|
141720
|
141721
|
141972
|
142003
|
142004
|
142005
|
142006
|
142007
|
142008
|
142833
|
142834
|
142835
|
142836
|
142837
|
142877
|
142878
|
142879
|
142880
|
142881
|
142882
|
142883
|
142884
|
142885
|
142886
|
142887
|
142888
|
143020
|
143569
|
143570
|
143571
|
143572
|
143573
|
143574
|
143575
|
143576
|
143577
|
143578
|
143579
|
143580
|
143581
|
143794
|
143795
|
143796
|
143989
|
143990
|
144161