@@ -, +, @@ orders --- C4/Acquisition.pm | 2 +- Koha/Acquisition/Orders.pm | 23 +++++- acqui/addorder.pl | 3 + acqui/basket.pl | 3 +- acqui/lateorders-export.pl | 2 +- acqui/moddeliverydate.pl | 83 ++++++++++++++++++++++ acqui/neworderempty.pl | 3 +- ...15348-add_aqorders.estimated_delivery_date.perl | 9 +++ installer/data/mysql/kohastructure.sql | 1 + .../intranet-tmpl/prog/en/modules/acqui/basket.tt | 4 ++ .../prog/en/modules/acqui/lateorders.tt | 65 +++++++++++++++-- .../prog/en/modules/acqui/moddeliverydate.tt | 45 ++++++++++++ .../prog/en/modules/acqui/neworderempty.tt | 7 ++ t/db_dependent/Koha/Acquisition/Order.t | 34 ++++++++- 14 files changed, 270 insertions(+), 14 deletions(-) create mode 100755 acqui/moddeliverydate.pl create mode 100644 installer/data/mysql/atomicupdate/bug_15348-add_aqorders.estimated_delivery_date.perl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/acqui/moddeliverydate.tt --- a/C4/Acquisition.pm +++ a/C4/Acquisition.pm @@ -1244,7 +1244,7 @@ sub GetOrder { aqbooksellers.name AS supplier, aqbooksellers.id AS supplierid, biblioitems.publishercode AS publisher, - ADDDATE(aqbasket.closedate, INTERVAL aqbooksellers.deliverytime DAY) AS estimateddeliverydate, + ADDDATE(aqbasket.closedate, INTERVAL aqbooksellers.deliverytime DAY) AS calculateddeliverydate, DATE(aqbasket.closedate) AS orderdate, aqorders.quantity - COALESCE(aqorders.quantityreceived,0) AS quantity_to_receive, (aqorders.quantity - COALESCE(aqorders.quantityreceived,0)) * aqorders.rrp AS subtotal, --- a/Koha/Acquisition/Orders.pm +++ a/Koha/Acquisition/Orders.pm @@ -70,17 +70,22 @@ sub filter_by_lates { my @delivery_time_conditions; my $date_add = "DATE_ADD(basketno.closedate, INTERVAL COALESCE(booksellerid.deliverytime, booksellerid.deliverytime, 0) day)"; + my @estimated_delivery_time_conditions; if ( defined $estimated_from or defined $estimated_to ) { push @delivery_time_conditions, \[ "$date_add IS NOT NULL" ]; + push @estimated_delivery_time_conditions, \[ "estimated_delivery_date IS NOT NULL" ]; } if ( defined $estimated_from ) { push @delivery_time_conditions, \[ "$date_add >= ?", $dtf->format_date($estimated_from) ]; + push @estimated_delivery_time_conditions, \[ "estimated_delivery_date >= ?", $dtf->format_date($estimated_from) ]; } if ( defined $estimated_to ) { push @delivery_time_conditions, \[ "$date_add <= ?", $dtf->format_date($estimated_to) ]; + push @estimated_delivery_time_conditions, \[ "estimated_delivery_date <= ?", $dtf->format_date($estimated_to) ]; } if ( defined $estimated_from and not defined $estimated_to ) { push @delivery_time_conditions, \[ "$date_add <= ?", $dtf->format_date(dt_from_string) ]; + push @estimated_delivery_time_conditions, \[ "estimated_delivery_date <= ?", $dtf->format_date(dt_from_string) ]; } $self->search( @@ -111,7 +116,15 @@ sub filter_by_lates { # ( $branchcode ? ('borrower.branchcode')) # FIXME branch is not a filter we may not need to implement this - ( @delivery_time_conditions ? ( -and => \@delivery_time_conditions ) : ()), + ( ( @delivery_time_conditions and @estimated_delivery_time_conditions ) ? + ( -or => + [ + -and => \@delivery_time_conditions, + -and => \@estimated_delivery_time_conditions + ] + ) + : () + ), ( C4::Context->preference('IndependentBranches') && !C4::Context->IsSuperLibrarian @@ -123,8 +136,12 @@ sub filter_by_lates { }, { - '+select' => [\"DATE_ADD(basketno.closedate, INTERVAL COALESCE(booksellerid.deliverytime, booksellerid.deliverytime, 0) day)"], - '+as' => ['estimated_delivery_date'], + '+select' => [ + \"DATE_ADD(basketno.closedate, INTERVAL COALESCE(booksellerid.deliverytime, booksellerid.deliverytime, 0) day)", + ], + '+as' => [qw/ + calculated_estimated_delivery_date + /], join => { 'basketno' => 'booksellerid' }, prefetch => {'basketno' => 'booksellerid'}, } --- a/acqui/addorder.pl +++ a/acqui/addorder.pl @@ -132,6 +132,7 @@ use Koha::Acquisition::Currencies; use Koha::Acquisition::Orders; use Koha::Acquisition::Baskets; use C4::Barcodes; +use Koha::DateUtils; ### "-------------------- addorder.pl ----------" @@ -293,6 +294,8 @@ if ( $basket->{is_standing} || $orderinfo->{quantity} ne '0' ) { } ); + $orderinfo->{estimated_delivery_date} = $orderinfo->{estimated_delivery_date} ? dt_from_string($orderinfo->{estimated_delivery_date}) : undef; + # if we already have $ordernumber, then it's an ordermodif my $order = Koha::Acquisition::Order->new($orderinfo); if ( $orderinfo->{ordernumber} ) { --- a/acqui/basket.pl +++ a/acqui/basket.pl @@ -501,12 +501,13 @@ sub get_order_infos { $line{order_object} = $order; } - my $suggestion = GetSuggestionInfoFromBiblionumber($line{biblionumber}); $line{suggestionid} = $$suggestion{suggestionid}; $line{surnamesuggestedby} = $$suggestion{surnamesuggestedby}; $line{firstnamesuggestedby} = $$suggestion{firstnamesuggestedby}; + $line{estimated_delivery_date} = $order->{estimated_delivery_date}; + foreach my $key (qw(transferred_from transferred_to)) { if ($line{$key}) { my $order = GetOrder($line{$key}); --- a/acqui/lateorders-export.pl +++ a/acqui/lateorders-export.pl @@ -44,7 +44,7 @@ unless ( $csv_profile_id ) { push @orders, { orderdate => $order->{orderdate}, latesince => $order->{latesince}, - estimateddeliverydate => $order->{estimateddeliverydate}, + estimateddeliverydate => $order->{estimated_delivery_date} ? $order->{estimated_delivery_date} : $order->{calculateddeliverydate}, supplier => $order->{supplier}, supplierid => $order->{supplierid}, title => $order->{title}, --- a/acqui/moddeliverydate.pl +++ a/acqui/moddeliverydate.pl @@ -0,0 +1,83 @@ +#!/usr/bin/perl + +# Copyright 2021 Aleisha Amohia +# +# 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 . + +=head1 NAME + +moddeliverydate.pl + +=head1 DESCRIPTION + +Modify just the estimated delivery date of an individual order when +its basket is closed. + +=cut + +use Modern::Perl; + +use CGI qw ( -utf8 ); +use C4::Auth; +use C4::Output; +use C4::Acquisition; + +use Koha::Acquisition::Booksellers; +use Koha::DateUtils; + +my $input = CGI->new; +my ($template, $loggedinuser, $cookie, $flags) = get_template_and_user( { + template_name => 'acqui/moddeliverydate.tt', + query => $input, + type => 'intranet', + flagsrequired => { 'acquisition' => '*' }, + debug => 1, +} ); + +my $op = $input->param('op'); +my $ordernumber = $input->param('ordernumber'); +my $referrer = $input->param('referrer') || $input->referer(); +my $order = GetOrder($ordernumber); +my $basket = GetBasket($order->{basketno}); +my $bookseller = Koha::Acquisition::Booksellers->find( $basket->{booksellerid} ); + +if($op and $op eq 'save') { + my $estimated_delivery_date = $input->param('estimated_delivery_date'); + $order->{'estimated_delivery_date'} = dt_from_string( $estimated_delivery_date ); + ModOrder($order); + print $input->redirect($referrer); + exit; +} else { + $template->param( + estimated_delivery_date => $order->{'estimated_delivery_date'} + ); +} + +if($op) { + $template->param($op => 1); +} + +$template->param( + basketname => $basket->{'basketname'}, + basketno => $order->{basketno}, + booksellerid => $bookseller->id, + booksellername => $bookseller->name, + ordernumber => $ordernumber, + referrer => $referrer, +); + + +output_html_with_http_headers $input, $cookie, $template->output; --- a/acqui/neworderempty.pl +++ a/acqui/neworderempty.pl @@ -476,7 +476,8 @@ $template->param( acqcreate => $basketobj->effective_create_items eq "ordering" ? 1 : "", users_ids => join(':', @order_user_ids), users => \@order_users, - (uc(C4::Context->preference("marcflavour"))) => 1 + (uc(C4::Context->preference("marcflavour"))) => 1, + estimated_delivery_date => $data->{estimated_delivery_date}, ); output_html_with_http_headers $input, $cookie, $template->output; --- a/installer/data/mysql/atomicupdate/bug_15348-add_aqorders.estimated_delivery_date.perl +++ a/installer/data/mysql/atomicupdate/bug_15348-add_aqorders.estimated_delivery_date.perl @@ -0,0 +1,9 @@ +use Date::Calc qw( Add_Delta_Days ); +$DBversion = 'XXX'; +if( CheckVersion( $DBversion ) ) { + unless( column_exists( 'aqorders', 'estimated_delivery_date' ) ) { + $dbh->do(q{ ALTER TABLE aqorders ADD estimated_delivery_date date default null AFTER suppliers_report }); + + NewVersion( $DBversion, 15348, "Add new column aqorders.estimated_delivery_date" ); + } +} --- a/installer/data/mysql/kohastructure.sql +++ a/installer/data/mysql/kohastructure.sql @@ -671,6 +671,7 @@ CREATE TABLE `aqorders` ( `suppliers_reference_number` varchar(35) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Suppliers unique edifact quote ref', `suppliers_reference_qualifier` varchar(3) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Type of number above usually ''QLI''', `suppliers_report` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'reports received from suppliers', + `estimated_delivery_date` date default null, PRIMARY KEY (`ordernumber`), KEY `basketno` (`basketno`), KEY `biblionumber` (`biblionumber`), --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt @@ -434,6 +434,7 @@ GST Fund Supplier report + Estimated delivery date [% IF ( active ) %] [% UNLESS ( closedate ) %] Modify @@ -461,6 +462,7 @@ [% foot_loo.tax_value | $Price %]     + [% foot_loo.estimated_delivery_date | $KohaDates | html %] [% IF ( active ) %] [% UNLESS ( closedate ) %]   @@ -486,6 +488,7 @@ [% total_tax_value | $Price %]     + [% estimated_delivery_date | $KohaDates | html %] [% IF ( active ) %] [% UNLESS ( closedate ) %]   @@ -570,6 +573,7 @@ [% books_loo.tax_value | $Price %] [% books_loo.budget_name | html %] [% books_loo.suppliers_report | html %] + [% books_loo.estimated_delivery_date | $KohaDates | html %] [% IF ( active ) %] [% UNLESS ( closedate ) %] --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/lateorders.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/lateorders.tt @@ -102,9 +102,18 @@ [% lateorder.basket.closedate | $KohaDates %] ([% lateorder.basket.late_since_days | html %] days) - [% SET estimated_delivery_date = lateorder.get_column('estimated_delivery_date') %] + [% IF lateorder.get_column('estimated_delivery_date') %] + [% SET estimated_delivery_date = lateorder.get_column('estimated_delivery_date') %] + [% ELSIF lateorder.get_column('calculated_estimated_delivery_date') %] + [% SET estimated_delivery_date = lateorder.get_column('calculated_estimated_delivery_date') %] + [% END %] - [% estimated_delivery_date | $KohaDates %] +

+ [% estimated_delivery_date | $KohaDates %] + + Edit + +

[% lateorder.basket.bookseller.name | html %] @@ -190,7 +199,7 @@ - Total + Total [% total_quantity | html %] [% total | $Price %]   @@ -271,7 +280,7 @@ @@ -284,6 +293,30 @@ + + + [% MACRO jsinclude BLOCK %] [% Asset.js("js/acquisitions-menu.js") | $raw %] [% INCLUDE 'datatables.inc' %] @@ -355,7 +388,7 @@ var modalTitle = $(this).attr("title") + " (order number " + ordernumber + ")"; var note_text = $( "#" + note_type + "-note-" + ordernumber ).html(); $("#noteEditor .modal-title").text(modalTitle); - $("#ordernumber").val( ordernumber ); + $("#notes_ordernumber").val( ordernumber ); $("#ordernotes").html( note_text ); $("#type").val( note_type ); $("#noteEditor").modal("show"); @@ -366,9 +399,29 @@ $("#noteEditorLabel").html(""); $("#noteEditor .modal-title").text(""); $("#ordernotes").html( "" ); - $("#ordernumber").val(""); + $("#notes_ordernumber").val(""); $("#type").val(""); }); + + $("#estimated_delivery_date").datepicker(); + + $(".edit_delivery_date").on("click", function(e) { + e.preventDefault(); + var ordernumber = $(this).data("ordernumber"); + var modalTitle = $(this).attr("title") + " (order number " + ordernumber + ")"; + var date_text = $( "#delivery_date_" + ordernumber ).html(); + $("#dateEditor .modal-title").text(modalTitle); + $("#date_ordernumber").val(ordernumber); + $("#estimated_delivery_date").html( date_text ); + $("#dateEditor").modal("show"); + }); + + $("#dateEditor").on('hidden.bs.modal', function (e) { + $("#dateEditorLabel").html(""); + $("#dateEditor .modal-title").text(""); + $("#estimated_delivery_date").html( "" ); + $("#date_ordernumber").val(""); + }); }); [% END %] --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/moddeliverydate.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/moddeliverydate.tt @@ -0,0 +1,45 @@ +[% SET footerjs = 1 %] +[% INCLUDE 'doc-head-open.inc' %] +Koha › Acquisition › + Change estimated delivery date + +[% INCLUDE 'doc-head-close.inc' %] + + + +[% INCLUDE 'header.inc' %] + + + +
+
+
+ +

Change estimated delivery date

+
+
+ + +
[% INCLUDE 'date-format.inc' %]
+
+ + + +
+ + Cancel +
+
+
+
+ +[% MACRO jsinclude BLOCK %] + [% INCLUDE 'calendar.inc' %] + +[% END %] + +[% INCLUDE 'intranet-bottom.inc' %] --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/neworderempty.tt @@ -477,6 +477,11 @@ +
  • + + +
    [% INCLUDE 'date-format.inc' %]
    +
  • The 2 following fields are available for your own usage. They can be useful for statistical purposes
    @@ -676,6 +681,8 @@ getAuthValueDropbox( 'sort2', sort2_authcat, destination_sort2, sort2 ); }); $("#budget_id").change(); + + $("#estimated_delivery_date").datepicker(); }); function UserSearchPopup(f) { --- a/t/db_dependent/Koha/Acquisition/Order.t +++ a/t/db_dependent/Koha/Acquisition/Order.t @@ -389,7 +389,7 @@ subtest 'claim*' => sub { }; subtest 'filter_by_late' => sub { - plan tests => 16; + plan tests => 17; $schema->storage->txn_begin; my $now = dt_from_string; @@ -415,6 +415,7 @@ subtest 'filter_by_late' => sub { basketno => $basket_1->basketno, datereceived => undef, datecancellationprinted => undef, + estimated_delivery_date => undef, } } ); @@ -434,6 +435,7 @@ subtest 'filter_by_late' => sub { basketno => $basket_2->basketno, datereceived => undef, datecancellationprinted => undef, + estimated_delivery_date => undef, } } ); @@ -453,6 +455,7 @@ subtest 'filter_by_late' => sub { basketno => $basket_3->basketno, datereceived => undef, datecancellationprinted => undef, + estimated_delivery_date => undef, } } ); @@ -472,6 +475,7 @@ subtest 'filter_by_late' => sub { basketno => $basket_4->basketno, datereceived => undef, datecancellationprinted => undef, + estimated_delivery_date => undef, } } ); @@ -539,6 +543,34 @@ subtest 'filter_by_late' => sub { ); is( $late_orders->count, 1 ); + my $basket_5 = $builder->build_object( # closed today + { + class => 'Koha::Acquisition::Baskets', + value => { + booksellerid => $bookseller->id, + closedate => $now, + } + } + ); + my $order_5 = $builder->build_object( + { + class => 'Koha::Acquisition::Orders', + value => { + basketno => $basket_4->basketno, + datereceived => undef, + datecancellationprinted => undef, + estimated_delivery_date => $now->clone->subtract( days => 2 ), + } + } + ); + $late_orders = $orders->filter_by_lates( + { + estimated_from => $now->clone->subtract( days => 3 ), + estimated_to => $now->clone->subtract( days => 2 ) + } + ); + is( $late_orders->count, 1 ); + $schema->storage->txn_rollback; }; --