From 70938a6f11a938c7048ec93c45cc42796c18ea49 Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Mon, 7 Mar 2022 16:50:16 +0100 Subject: [PATCH] Bug 32030: ERM - Periods Signed-off-by: Jonathan Field Signed-off-by: Martin Renvoize Signed-off-by: Kyle M Hall Signed-off-by: Tomas Cohen Arazi --- Koha/ERM/Agreement.pm | 15 +++ Koha/ERM/Agreement/Period.pm | 44 ++++++++ Koha/ERM/Agreement/Periods.pm | 53 +++++++++ erm/agreements.pl | 104 ++++++++++++------ .../prog/en/modules/erm/agreements.tt | 92 +++++++++++++++- 5 files changed, 272 insertions(+), 36 deletions(-) create mode 100644 Koha/ERM/Agreement/Period.pm create mode 100644 Koha/ERM/Agreement/Periods.pm diff --git a/Koha/ERM/Agreement.pm b/Koha/ERM/Agreement.pm index d17cd7ccf8..bfa687657b 100644 --- a/Koha/ERM/Agreement.pm +++ b/Koha/ERM/Agreement.pm @@ -21,6 +21,8 @@ use Koha::Database; use base qw(Koha::Object); +use Koha::ERM::Agreement::Periods; + =head1 NAME Koha::ERM::Agreement - Koha ErmAgreement Object class @@ -31,6 +33,19 @@ Koha::ERM::Agreement - Koha ErmAgreement Object class =cut +=head3 periods + +Returns the periods for this agreement + +=cut + +sub periods { + my ( $self ) = @_; + + my $periods_rs = $self->_result->erm_agreement_periods; + return Koha::ERM::Agreement::Periods->_new_from_dbic($periods_rs); +} + =head2 Internal methods =head3 _type diff --git a/Koha/ERM/Agreement/Period.pm b/Koha/ERM/Agreement/Period.pm new file mode 100644 index 0000000000..cee585773c --- /dev/null +++ b/Koha/ERM/Agreement/Period.pm @@ -0,0 +1,44 @@ +package Koha::ERM::Agreement::Period; + +# 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 Koha::Database; + +use base qw(Koha::Object); + +=head1 NAME + +Koha::ERM::Agreement::Period - Koha Agreement Period Object class + +=head1 API + +=head2 Class Methods + +=cut + +=head2 Internal methods + +=head3 _type + +=cut + +sub _type { + return 'ErmAgreementPeriod'; +} + +1; diff --git a/Koha/ERM/Agreement/Periods.pm b/Koha/ERM/Agreement/Periods.pm new file mode 100644 index 0000000000..eb35b9a739 --- /dev/null +++ b/Koha/ERM/Agreement/Periods.pm @@ -0,0 +1,53 @@ +package Koha::ERM::Agreement::Periods; + +# 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 Koha::Database; + +use Koha::ERM::Agreement::Period; + +use base qw(Koha::Objects); + +=head1 NAME + +Koha::ERM::Agreement::Periods- Koha Agreement Period Object set class + +=head1 API + +=head2 Class Methods + +=cut + +=head3 type + +=cut + +sub _type { + return 'ErmAgreementPeriod'; +} + +=head3 object_class + +=cut + +sub object_class { + return 'Koha::ERM::Agreement::Period'; +} + +1; diff --git a/erm/agreements.pl b/erm/agreements.pl index 87c682249e..432b950009 100755 --- a/erm/agreements.pl +++ b/erm/agreements.pl @@ -21,6 +21,7 @@ use C4::Context; use C4::Auth qw( get_template_and_user ); use C4::Output qw( output_html_with_http_headers ); +use Koha::DateUtils qw( dt_from_string ); use Koha::Acquisition::Booksellers; use Koha::ERM::Agreements; @@ -57,46 +58,79 @@ elsif ( $op eq 'add_validate' ) { my $renewal_priority = $input->param('renewal_priority'); my $license_info = $input->param('license_info'); - if ($agreement_id) { - my $agreement = Koha::ERM::Agreements->find($agreement_id); - $agreement->vendor_id($vendor_id); - $agreement->name($name); - $agreement->description($description); - $agreement->status($status); - $agreement->closure_reason($closure_reason); - $agreement->is_perpetual($is_perpetual); - $agreement->renewal_priority($renewal_priority); - $agreement->license_info($license_info); - - eval { $agreement->store; }; - if ($@) { - push @messages, { type => 'error', code => 'error_on_update' }; + my $schema = Koha::Database->new->schema; + $schema->txn_do(sub{ + my ( $stored, $agreement ); + if ($agreement_id) { + $agreement = Koha::ERM::Agreements->find($agreement_id); + $agreement->vendor_id($vendor_id); + $agreement->name($name); + $agreement->description($description); + $agreement->status($status); + $agreement->closure_reason($closure_reason); + $agreement->is_perpetual($is_perpetual); + $agreement->renewal_priority($renewal_priority); + $agreement->license_info($license_info); + + eval { $agreement->store; }; + if ($@) { + push @messages, { type => 'error', code => 'error_on_update' }; + } + else { + $stored = 1; + push @messages, { type => 'message', code => 'success_on_update' }; + } } else { - push @messages, { type => 'message', code => 'success_on_update' }; - } - } - else { - my $agreement = Koha::ERM::Agreement->new( - { - vendor_id => $vendor_id, - name => $name, - description => $description, - status => $status, - closure_reason => $closure_reason, - is_perpetual => $is_perpetual, - renewal_priority => $renewal_priority, - license_info => $license_info, + $agreement = Koha::ERM::Agreement->new( + { + vendor_id => $vendor_id, + name => $name, + description => $description, + status => $status, + closure_reason => $closure_reason, + is_perpetual => $is_perpetual, + renewal_priority => $renewal_priority, + license_info => $license_info, + } + ); + eval { $agreement->store; }; + if ($@) { + push @messages, { type => 'error', code => 'error_on_insert' }; + } + else { + $stored = 1; + push @messages, { type => 'message', code => 'success_on_insert' }; } - ); - eval { $agreement->store; }; - if ($@) { - push @messages, { type => 'error', code => 'error_on_insert' }; } - else { - push @messages, { type => 'message', code => 'success_on_insert' }; + + if ( $stored ) { + if ( $agreement_id ) { + $agreement->periods->delete; + } + for my $unique_id ( $input->multi_param('period_unique_id') ) { + my $started_on = $input->param( 'started_on_' . $unique_id ); + next unless $started_on; + my $ended_on = $input->param( 'ended_on_' . $unique_id ); + my $cancellation_deadline = $input->param( 'cancellation_deadline_' . $unique_id ); + my $notes = $input->param( 'notes_' . $unique_id ); + + $started_on = dt_from_string($started_on); + $ended_on &&= dt_from_string($ended_on); + $cancellation_deadline &&= dt_from_string($cancellation_deadline); + + Koha::ERM::Agreement::Period->new( + { + agreement_id => $agreement->agreement_id, + started_on => $started_on, + ended_on => $ended_on, + cancellation_deadline => $cancellation_deadline, + notes => $notes, + } + )->store; + } } - } + }); $op = 'list'; } elsif ( $op eq 'delete_confirm' ) { diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/erm/agreements.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/erm/agreements.tt index 2458563a60..9505b3684a 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/erm/agreements.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/erm/agreements.tt @@ -1,9 +1,10 @@ [% USE raw %] [% USE To %] [% USE Asset %] -[% SET footerjs = 1 %] +[% USE KohaDates %] [% USE TablesSettings %] [% USE AuthorisedValues %] +[% SET footerjs = 1 %] [% INCLUDE 'doc-head-open.inc' %] [% IF op =='add_form' %] @@ -176,6 +177,50 @@ </ol> </fieldset> +[% BLOCK agreement_period %] + <fieldset class="agreement_period"> + <legend> + Agreement period <span class="period_count">[% id | html %]</span> + <a href="#" class="remove_period"><i class="fa fa-trash"></i> Remove this period</a> + </legend> + <input type="hidden" name="period_unique_id" value="[% id | html %]" /> + <ol> + <li> + <label for="started_on" class="required">Start date: </label> + <input type="text" id="started_on_[% id | html %]" class="started_on" name="started_on_[% id | html %]" value="[% p.started_on | $KohaDates %]" class="flatpickr" data-date_to="ended_on_[% id | html %]" /> + <span class="required">Required</span> + <div class="hint">[% INCLUDE 'date-format.inc' %]</div> + </li> + <li> + <label for="ended_on">End date: </label> + <input type="text" id="ended_on_[% id | html %]" class="ended_on" name="ended_on_[% id | html %]" value="[% p.ended_on | $KohaDates %]" class="flatpickr" /> + <div class="hint">[% INCLUDE 'date-format.inc' %]</div> + </li> + <li> + <label>Cancellation deadline: </label> + <input type="text" class="cancellation_deadline" name="cancellation_deadline_[% id | html %]" value="[% p.cancellation_deadline | $KohaDates %]" class="flatpickr" /> + <div class="hint">[% INCLUDE 'date-format.inc' %]</div> + </li> + <li> + <label>Notes: </label> + <input type="text" class="notes" name="notes_[% id | html %]" value="[% p.notes | html %]" /> + </li> + </ol> + </fieldset> +[% END %] + + <fieldset class="rows" id="agreement_periods"> + <legend>Periods</legend> + [% IF agreement.periods.count %] + [% FOR p IN agreement.periods %] + [% PROCESS agreement_period period => p, id => loop.count %] + [% END %] + [% ELSE %] + [% PROCESS agreement_period id => 1 %] + [% END %] + <button class="add_new_period" type="button" class="btn btn-primary"><i class="fa fa-plus" aria-hidden="true"></i>Add new period</button> + </fieldset> + <fieldset class="action"> <input type="submit" value="Submit" /> <a class="cancel" href="/cgi-bin/koha/erm/agreements.pl">Cancel</a> @@ -273,6 +318,7 @@ [% MACRO jsinclude BLOCK %] [% Asset.js("js/erm-menu.js") | $raw %] + [% INCLUDE 'calendar.inc' %] [% INCLUDE 'datatables.inc' %] [% INCLUDE 'columns_settings.inc' %] <script> @@ -380,7 +426,51 @@ ] }, columns_settings, 1); + $(".add_new_period").on("click", function(e){ + e.preventDefault(); + let new_period_block = $("fieldset.agreement_period:first").clone(1); + new_period_block.find("input").val(""); + $(new_period_block).insertBefore(this); + update_period_count(); + }); + $(".remove_period").on("click", function(e){ + e.preventDefault(); + $(this).parent().parent().remove(); + update_period_count(); + }); + update_period_count(); }); + + function update_period_count(){ + $("fieldset.agreement_period").each(function(i, period){ + let id = i + 1; + let remove_period_link = $(this).find(".remove_period"); + if ( id == 1 ) { + $(remove_period_link).hide(); + } else { + $(remove_period_link).show(); + } + $(period).find(".period_count").text(id); + $(period).find("input[name='period_unique_id']").val(id); + + let ended_on_input = $(period).find("input.ended_on"); + $(ended_on_input).attr("id", "ended_on_" + id); + $(ended_on_input).attr("name", "ended_on_" + id); + $(ended_on_input).flatpickr(); + + let started_on_input = $(period).find("input.started_on"); + $(started_on_input).attr("name", "started_on_" + id); + $(started_on_input).data("date_to", "ended_on_" + id); + $(started_on_input).flatpickr(); + + let cancellation_deadline_input = $(period).find("input.cancellation_deadline"); + $(cancellation_deadline_input).attr("name", "cancellation_deadline_" + id); + $(cancellation_deadline_input).flatpickr(); + + $(period).find(".notes").attr("name", "notes_" + id); + }); + } + </script> [% END %] [% INCLUDE 'intranet-bottom.inc' %] -- 2.39.5