From b178bf3ef5604b64cf6632df5426ea076d14425c Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Wed, 12 Apr 2023 15:20:12 +0200 Subject: [PATCH] Bug 33547: Add print slip Sponsored-by: BULAC - http://www.bulac.fr/ Signed-off-by: BULAC - http://www.bulac.fr/ --- C4/Letters.pm | 8 +- Koha/Preservation/Train/Item.pm | 12 +++ .../definitions/preservation_processing.yaml | 5 ++ api/v1/swagger/paths/preservation_trains.yaml | 1 + debian/templates/apache-shared-intranet.conf | 1 + .../data/mysql/atomicupdate/bug_33547.pl | 37 +++++++++ .../mysql/en/mandatory/sample_notices.yml | 22 ++++++ installer/data/mysql/kohastructure.sql | 1 + .../prog/en/modules/preservation/home.tt | 1 + .../prog/en/modules/tools/letter.tt | 7 ++ .../SettingsProcessingsFormAdd.vue | 15 ++++ .../Preservation/SettingsProcessingsShow.vue | 24 ++++++ .../components/Preservation/TrainsShow.vue | 34 ++++++++- .../js/vue/fetch/preservation-api-client.js | 2 +- preservation/home.pl | 5 ++ preservation/print_slip.pl | 75 +++++++++++++++++++ t/db_dependent/Koha/Preservation/Trains.t | 6 +- 17 files changed, 251 insertions(+), 5 deletions(-) create mode 100755 installer/data/mysql/atomicupdate/bug_33547.pl create mode 100755 preservation/print_slip.pl diff --git a/C4/Letters.pm b/C4/Letters.pm index 7100c4ea71b..00b256ac92d 100644 --- a/C4/Letters.pm +++ b/C4/Letters.pm @@ -1812,7 +1812,13 @@ sub _get_tt_params { singular => 'illrequest', plural => 'illrequests', pk => 'illrequest_id' - } + }, + preservation_train_items => { + module => 'Koha::Preservation::Train::Items', + singular => 'train_item', + plural => 'train_items', + pk => 'train_item_id' + }, }; foreach my $table ( keys %$tables ) { diff --git a/Koha/Preservation/Train/Item.pm b/Koha/Preservation/Train/Item.pm index 39cab4356ae..6089ae5d3bb 100644 --- a/Koha/Preservation/Train/Item.pm +++ b/Koha/Preservation/Train/Item.pm @@ -62,6 +62,18 @@ sub catalogue_item { return Koha::Item->_new_from_dbic($item_rs); } +=head3 train + +Return the train object for this item + +=cut + +sub train { + my ( $self ) = @_; + my $rs = $self->_result->train; + return Koha::Preservation::Train->_new_from_dbic($rs); +} + =head3 attributes Getter and setter for the attributes diff --git a/api/v1/swagger/definitions/preservation_processing.yaml b/api/v1/swagger/definitions/preservation_processing.yaml index 62ef2d8a9a2..4ae51d92572 100644 --- a/api/v1/swagger/definitions/preservation_processing.yaml +++ b/api/v1/swagger/definitions/preservation_processing.yaml @@ -8,6 +8,11 @@ properties: name: description: name of the processing type: string + letter_code: + description: Letter code of the letter to use for printing slips + type: + - string + - "null" attributes: description: attributes of the processing items: diff --git a/api/v1/swagger/paths/preservation_trains.yaml b/api/v1/swagger/paths/preservation_trains.yaml index a8563e8769d..c86cd888880 100644 --- a/api/v1/swagger/paths/preservation_trains.yaml +++ b/api/v1/swagger/paths/preservation_trains.yaml @@ -167,6 +167,7 @@ - items.attributes - items.attributes+strings - items.attributes.processing_attribute + - items.processing - default_processing - default_processing.attributes collectionFormat: csv diff --git a/debian/templates/apache-shared-intranet.conf b/debian/templates/apache-shared-intranet.conf index 75f495eb381..b4fe0ea2263 100644 --- a/debian/templates/apache-shared-intranet.conf +++ b/debian/templates/apache-shared-intranet.conf @@ -21,6 +21,7 @@ RewriteRule ^/issn/([^\/]*)/?$ /search?q=issn:$1 [PT] RewriteRule ^(.*)_[0-9]{2}\.[0-9]{7}\.(js|css)$ $1.$2 [L] RewriteRule ^/cgi-bin/koha/erm/.*$ /cgi-bin/koha/erm/erm.pl [PT] +RewriteCond %{REQUEST_URI} !^/cgi-bin/koha/preservation/.*.pl$ RewriteRule ^/cgi-bin/koha/preservation/.*$ /cgi-bin/koha/preservation/home.pl [PT] Alias "/api" "/usr/share/koha/api" diff --git a/installer/data/mysql/atomicupdate/bug_33547.pl b/installer/data/mysql/atomicupdate/bug_33547.pl new file mode 100755 index 00000000000..980153fe305 --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_33547.pl @@ -0,0 +1,37 @@ +use Modern::Perl; + +return { + bug_number => "33547", + description => "Add a new notice template 'PRES_TRAIN_ITEM'", + up => sub { + my ($args) = @_; + my ($dbh, $out) = @$args{qw(dbh out)}; + + unless ( column_exists('preservation_processings', 'letter_code') ) { + $dbh->do(q{ + ALTER TABLE preservation_processings + ADD COLUMN `letter_code` varchar(20) DEFAULT NULL COMMENT 'Foreign key to the letters table' AFTER `name` + }); + } + + my $notice_template = q{[%~ SET train = train_item.train ~%] +[%~ SET item = train_item.catalogue_item ~%] +Train name: [% train.name %] +Sent on: [% train.sent_on | $KohaDates %] + +[% train.default_processing.name %] + +Item number #[% train_item.user_train_item_id %] + +[% FOREACH item_attribute IN train_item.attributes %] + [% item_attribute.processing_attribute.name %]: [% item_attribute.value %] +[% END %]}; + + $dbh->do(q{ + INSERT IGNORE INTO letter + (module,code,branchcode,name,is_html,title,content,message_transport_type,lang) + VALUES + ('preservation','PRES_TRAIN_ITEM','','Train item slip',0,'Train item slip',?, 'print','default')}, undef, $notice_template); + say $out "Added new letter 'PRES_TRAIN_ITEM' (print)"; + }, +}; diff --git a/installer/data/mysql/en/mandatory/sample_notices.yml b/installer/data/mysql/en/mandatory/sample_notices.yml index 15adee50904..213e622ee25 100644 --- a/installer/data/mysql/en/mandatory/sample_notices.yml +++ b/installer/data/mysql/en/mandatory/sample_notices.yml @@ -2361,3 +2361,25 @@ tables: - "[% IF ( biblio.items.count > 0 ) %]
Items: [% END %]" - "
[% END %]" + + - module: preservation + code: PRES_TRAIN_ITEM + branchcode: "" + name: "Train item slip" + is_html: 0 + title: "Train item slip" + message_transport_type: print + lang: default + content: + - "[%~ SET train = train_item.train ~%]" + - "[%~ SET item = train_item.catalogue_item ~%]" + - "Train name: [% train.name %]" + - "Sent on: [% train.sent_on | $KohaDates %]" + - "" + - "[% train.default_processing.name %]" + - "" + - "Item number #[% train_item.user_train_item_id %]" + - "" + - "[% FOREACH item_attribute IN train_item.attributes %]" + - " [% item_attribute.processing_attribute.name %]: [% item_attribute.value %]" + - "[% END %]" diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 420695928ec..5d15b2ca0db 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -4776,6 +4776,7 @@ DROP TABLE IF EXISTS `preservation_processings`; CREATE TABLE `preservation_processings` ( `processing_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'primary key', `name` varchar(80) NOT NULL COMMENT 'name of the processing', + `letter_code` varchar(20) DEFAULT NULL COMMENT 'Foreign key to the letters table', PRIMARY KEY (`processing_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/preservation/home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/preservation/home.tt index 5740f51d5ec..0c3d01ebc6c 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/preservation/home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/preservation/home.tt @@ -33,6 +33,7 @@ const authorised_value_categories = [% To.json(AuthorisedValues.GetCategories()) | $raw %].map(c => c.category); const db_columns = [% To.json(db_columns) | $raw %]; const api_mappings = [% To.json(api_mappings) | $raw %]; + const notice_templates = [% To.json(notice_templates || []) | $raw %]; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt index 7ffbee6dd5a..38b4d3891ca 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/letter.tt @@ -155,6 +155,7 @@
  • Interlibrary loans
  • Order acquisition
  • Patrons
  • +
  • Preservation
  • Serials (new issue)
  • Suggestions
  • Point of sale
  • @@ -212,6 +213,7 @@ [% CASE 'reserves' %]Holds [% CASE 'ill' %]Interlibrary loans [% CASE 'members' %]Patrons + [% CASE 'preservation' %]Preservation [% CASE 'serial' %]Serials (new issue) [% CASE 'suggestions' %]Suggestions [% CASE 'pos' %]Point of sale @@ -376,6 +378,11 @@ [% ELSE %] [% END %] + [% IF ( module == "preservation" ) %] + + [% ELSE %] + + [% END %] [% IF ( module == "serial" ) %] [% ELSE %] diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Preservation/SettingsProcessingsFormAdd.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Preservation/SettingsProcessingsFormAdd.vue index 7ca15585e12..900a6075e37 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Preservation/SettingsProcessingsFormAdd.vue +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Preservation/SettingsProcessingsFormAdd.vue @@ -21,6 +21,20 @@ /> {{ $__("Required") }} +
  • + + +
  • @@ -199,6 +213,7 @@ export default { setWarning, authorised_value_categories, db_column_options, + notice_templates, } }, data() { diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Preservation/SettingsProcessingsShow.vue b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Preservation/SettingsProcessingsShow.vue index 25a34781f3e..c0f19fca51f 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/components/Preservation/SettingsProcessingsShow.vue +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/components/Preservation/SettingsProcessingsShow.vue @@ -21,6 +21,21 @@ {{ processing.name }} +
  • + + + {{ notice_template.name }} + + {{ $__("Edit this template") }} + +
  • @@ -74,14 +89,23 @@ export default { const { setConfirmationDialog, setMessage } = inject("mainStore") return { + notice_templates, setConfirmationDialog, setMessage, } }, + computed: { + notice_template() { + return this.notice_templates.find( + n => n.id == this.processing.letter_code + ) + }, + }, data() { return { processing: { processing_id: null, + letter_code: null, name: "", attributes: [], }, 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 01505688e69..7208e6cad1b 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 @@ -427,6 +427,13 @@ export default { } ) }, + printSlip(train_item_id) { + window.open( + "/cgi-bin/koha/preservation/print_slip.pl?train_item_id=" + + train_item_id, + "_blank" + ) + }, selectTrainForCopy(train_item_id) { this.show_modal = true this.train_item_id_to_copy = train_item_id @@ -459,6 +466,7 @@ export default { let item_table = this.item_table let removeItem = this.removeItem let editItem = this.editItem + let printSlip = this.printSlip let selectTrainForCopy = this.selectTrainForCopy let train = this.train @@ -471,8 +479,8 @@ export default { var api = new $.fn.dataTable.Api(settings) $.each($(this).find("td.actions"), function (index, e) { let tr = $(this).parent() - let train_item_id = api.row(tr).data() - .item.train_item_id + let train_item = api.row(tr).data().item + let train_item_id = train_item.train_item_id let editButton = createVNode( "a", @@ -537,6 +545,28 @@ export default { ) } + if (train_item.processing.letter_code !== null) { + let printButton = createVNode( + "a", + { + class: "btn btn-default btn-xs", + role: "button", + onClick: () => { + printSlip(train_item_id) + }, + }, + [ + createVNode("i", { + class: "fa fa-print", + "aria-hidden": "true", + }), + __("Print slip"), + ] + ) + buttons.push(" ") + buttons.push(printButton) + } + let n = createVNode("span", {}, buttons) render(n, e) }) 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 329a01455ce..bf41527238e 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 @@ -14,7 +14,7 @@ export class PreservationAPIClient extends HttpClient { endpoint: "trains/" + id, headers: { "x-koha-embed": - "default_processing,default_processing.attributes,items,items.attributes,items.attributes+strings,items.attributes.processing_attribute", + "default_processing,default_processing.attributes,items,items.attributes,items.attributes+strings,items.attributes.processing_attribute,items.processing", }, }), getAll: (query = {}) => diff --git a/preservation/home.pl b/preservation/home.pl index af66337c784..a13c48dedc8 100755 --- a/preservation/home.pl +++ b/preservation/home.pl @@ -22,6 +22,7 @@ use C4::Auth qw( get_template_and_user ); use C4::Output qw( output_html_with_http_headers ); use Koha::Database::Columns; +use Koha::Notice::Templates; my $query = CGI->new; my ( $template, $loggedinuser, $cookie, $userflags ) = get_template_and_user( @@ -47,6 +48,10 @@ $template->param( biblioitems => Koha::Biblioitem->to_api_mapping, biblio => Koha::Biblio->to_api_mapping, }, + notice_templates => + [ map { { id => $_->id, code => $_->code, name => $_->name } } + Koha::Notice::Templates->search( { module => 'preservation' } ) + ->as_list ], ); output_html_with_http_headers $query, $cookie, $template->output; diff --git a/preservation/print_slip.pl b/preservation/print_slip.pl new file mode 100755 index 00000000000..ec3687ba0f1 --- /dev/null +++ b/preservation/print_slip.pl @@ -0,0 +1,75 @@ +#!/usr/bin/perl + +# 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 CGI qw ( -utf8 ); +use C4::Context; +use C4::Auth qw( get_template_and_user ); +use C4::Output qw( output_and_exit_if_error output_and_exit output_html_with_http_headers ); +use C4::Letters; +use Koha::Patrons; +use Koha::Preservation::Train::Items; + +my $input = CGI->new; +my $train_item_id = $input->param('train_item_id'); + +my ( $template, $loggedinuser, $cookie ) = get_template_and_user( + { + template_name => "circ/printslip.tt", + query => $input, + type => "intranet", + flagsrequired => { preservation => '*' }, + } +); + +my $logged_in_user = Koha::Patrons->find($loggedinuser); +my $branch = C4::Context->userenv->{'branch'}; + +my $train_item = Koha::Preservation::Train::Items->find($train_item_id); + +unless ($train_item){ + print $input->redirect("/cgi-bin/koha/errors/404.pl"); + exit; +} + +my $train = $train_item->train; + +my $letter = C4::Letters::GetPreparedLetter( + module => 'preservation', + letter_code => $train_item->processing->letter_code, + branchcode => $branch, + lang => $logged_in_user->lang, + tables => { + preservation_train_items => $train_item_id, + }, + message_transport_type => 'print' +); + +my $slip = $letter->{content}; +my $is_html = $letter->{is_html}; + +$template->param( + slip => $slip, + plain => !$is_html, + caller => 'preservation', + stylesheet => C4::Context->preference("SlipCSS"), +); + +$template->param( IntranetSlipPrinterJS => C4::Context->preference('IntranetSlipPrinterJS' ) ); + +output_html_with_http_headers $input, $cookie, $template->output; diff --git a/t/db_dependent/Koha/Preservation/Trains.t b/t/db_dependent/Koha/Preservation/Trains.t index 7702875e94b..d881c5d89f4 100755 --- a/t/db_dependent/Koha/Preservation/Trains.t +++ b/t/db_dependent/Koha/Preservation/Trains.t @@ -53,7 +53,7 @@ subtest 'default_processing' => sub { }; subtest 'add_items & items' => sub { - plan tests => 14; + plan tests => 15; $schema->storage->txn_begin; @@ -99,6 +99,10 @@ 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 ); + is( ref( $item_train_1->train ), + 'Koha::Preservation::Train', + 'Train::Item->train returns a Koha::Preservation::Train object' ); + warning_is { $train->add_item( { item_id => $item_2->itemnumber }, { skip_waiting_list_check => 1 } ); } ''; -- 2.25.1