From 2797d2f1d7b421f69ebb0f70db1d0b875c06ed8c Mon Sep 17 00:00:00 2001 From: Julian Maurice Date: Fri, 6 Apr 2012 16:57:12 +0200 Subject: [PATCH] [SIGNED-OFF] Bug 5349: Order line transfers Content-Type: text/plain; charset="utf-8" On basket.pl and parcel.pl there is a 'Transfer' link which allow you to transfer order lines from a basket to another. The link lead to a new page which allow you to search for a bookseller, then display this bookseller's baskets. Then you can pickup a basket and the transfer will be done. This add a message in new column aqorders.internalnotes which is displayed in basket.pl Signed-off-by: Marc Veron Note: Tested with different Vendors and Baskets, works as expected. Small glitch in ergonomy: The page where you can choose the new bookseller could better be a pop up like in Patrons->Guarantor information->Set to patron. Otherwise users could mistake and use the Vendors search at the top of the page (is active by default). If they do so they loose track of the transfer process. This could be fixed in a follow up - will sign off. --- C4/Acquisition.pm | 73 ++++++++++- acqui/transferorder.pl | 144 ++++++++++++++++++++ installer/data/mysql/kohastructure.sql | 1 + installer/data/mysql/updatedatabase.pl | 10 ++ .../intranet-tmpl/prog/en/modules/acqui/basket.tt | 6 + .../intranet-tmpl/prog/en/modules/acqui/parcel.tt | 9 +- .../prog/en/modules/acqui/transferorder.tt | 121 ++++++++++++++++ 7 files changed, 360 insertions(+), 4 deletions(-) create mode 100755 acqui/transferorder.pl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/acqui/transferorder.tt diff --git a/C4/Acquisition.pm b/C4/Acquisition.pm index e856059..cd244c9 100644 --- a/C4/Acquisition.pm +++ b/C4/Acquisition.pm @@ -55,7 +55,7 @@ BEGIN { &GetOrderNumber &GetLateOrders &GetOrderFromItemnumber &SearchOrder &GetHistory &GetRecentAcqui &ModReceiveOrder &ModOrderBiblioitemNumber - &GetCancelledOrders + &GetCancelledOrders &TransferOrder &NewOrderItem &ModOrderItem &ModItemOrder @@ -1334,6 +1334,77 @@ sub DelOrder { } +=head3 TransferOrder + + my $newordernumber = TransferOrder($ordernumber, $basketno); + +Transfer an order line to a basket. +Mark $ordernumber as cancelled with an internal note 'Cancelled and transfered +to BOOKSELLER on DATE' and create new order with internal note +'Transfered from BOOKSELLER on DATE'. +Move all attached items to the new order. +Received orders cannot be transfered. +Return the ordernumber of created order. + +=cut + +sub TransferOrder { + my ($ordernumber, $basketno) = @_; + + return unless $ordernumber or $basketno; + + my $order = GetOrder( $ordernumber ); + return if $order->{datereceived}; + + my $today = C4::Dates->new()->output("iso"); + my $query = qq{ + SELECT aqbooksellers.name + FROM aqorders + LEFT JOIN aqbasket ON aqorders.basketno = aqbasket.basketno + LEFT JOIN aqbooksellers ON aqbasket.booksellerid = aqbooksellers.id + WHERE aqorders.ordernumber = ? + }; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare($query); + $sth->execute($ordernumber); + my ($booksellerfromname) = $sth->fetchrow_array; + + $query = qq{ + SELECT aqbooksellers.name + FROM aqbasket + LEFT JOIN aqbooksellers ON aqbasket.booksellerid = aqbooksellers.id + WHERE aqbasket.basketno = ? + }; + $sth = $dbh->prepare($query); + $sth->execute($basketno); + my ($booksellertoname) = $sth->fetchrow_array; + + $query = qq{ + UPDATE aqorders + SET datecancellationprinted = CAST(NOW() AS date), + internalnotes = ? + WHERE ordernumber = ? + }; + $sth = $dbh->prepare($query); + $sth->execute("Cancelled and transfered to $booksellertoname on $today", $ordernumber); + + delete $order->{'ordernumber'}; + $order->{'basketno'} = $basketno; + $order->{'internalnotes'} = "Transfered from $booksellerfromname on $today"; + my $newordernumber; + (undef, $newordernumber) = NewOrder($order); + + $query = qq{ + UPDATE aqorders_items + SET ordernumber = ? + WHERE ordernumber = ? + }; + $sth = $dbh->prepare($query); + $sth->execute($newordernumber, $ordernumber); + + return $newordernumber; +} + =head2 FUNCTIONS ABOUT PARCELS =cut diff --git a/acqui/transferorder.pl b/acqui/transferorder.pl new file mode 100755 index 0000000..2946fcf --- /dev/null +++ b/acqui/transferorder.pl @@ -0,0 +1,144 @@ +#!/usr/bin/perl + +# Script to move an order from a bookseller to another + +# Copyright 2011 BibLibre SARL +# +# 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 2 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, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; +use CGI; + +use C4::Auth; +use C4::Output; +use C4::Context; +use C4::Acquisition; +use C4::Bookseller qw/GetBookSellerFromId GetBookSeller/; +use C4::Members; +use C4::Dates qw/format_date_in_iso/; +use Date::Calc qw/Today/; + +my $input = new CGI; +my ( $template, $loggedinuser, $cookie ) = get_template_and_user( + { template_name => "acqui/transferorder.tmpl", + query => $input, + type => "intranet", + authnotrequired => 1, + flagsrequired => { acquisition => 'order_manage' }, + debug => 1, + } +); + +my $dbh = C4::Context->dbh; + +my $bookselleridfrom = $input->param('bookselleridfrom'); +my $ordernumber = $input->param('ordernumber'); +my $bookselleridto = $input->param('bookselleridto'); +my $basketno = $input->param('basketno'); +my $op = $input->param('op'); +my $query = $input->param('query'); + +my $order = GetOrder($ordernumber); +if($order) { + my $basket = GetBasket($order->{basketno}); + $bookselleridfrom = $basket->{booksellerid} if $basket; +} + +my $booksellerfrom = GetBookSellerFromId($bookselleridfrom); +my $booksellerfromname; +if($booksellerfrom){ + $booksellerfromname = $booksellerfrom->{name}; +} +my $booksellerto = GetBookSellerFromId($bookselleridto); +my $booksellertoname; +if($booksellerto){ + $booksellertoname = $booksellerto->{name}; +} + +if( $basketno && $ordernumber) { + # Transfer order and exit + my $order = GetOrder( $ordernumber ); + my $basket = GetBasket($order->{basketno}); + my $booksellerfrom = GetBookSellerFromId($basket->{booksellerid}); + my $bookselleridfrom = $booksellerfrom->{id}; + + TransferOrder($ordernumber, $basketno); + + my $referrer = $input->param('referrer'); + print $input->redirect($referrer); + exit; +} elsif ( $bookselleridto && $ordernumber) { + # Show open baskets for this bookseller + my $order = GetOrder( $ordernumber ); + my $basketfrom = GetBasket( $order->{basketno} ); + my $booksellerfrom = GetBookSellerFromId( $basketfrom->{booksellerid} ); + $booksellerfromname = $booksellerfrom->{name}; + my $baskets = GetBasketsByBookseller( $bookselleridto ); + my $basketscount = scalar @$baskets; + my @basketsloop = (); + for( my $i = 0 ; $i < $basketscount ; $i++ ){ + my %line; + %line = %{ $baskets->[$i] }; + my $createdby = GetMember(borrowernumber => $line{authorisedby}); + $line{createdby} = "$createdby->{surname}, $createdby->{firstname}"; + push @basketsloop, \%line unless $line{closedate}; + } + $template->param( + show_baskets => 1, + basketsloop => \@basketsloop, + basketfromname => $basketfrom->{basketname}, + ); +} elsif ( $bookselleridfrom && !defined $ordernumber) { + # Show pending orders + my $pendingorders = GetPendingOrders($bookselleridfrom); + my $orderscount = scalar @$pendingorders; + my @ordersloop = (); + for( my $i = 0 ; $i < $orderscount ; $i++ ){ + my %line; + %line = %{ $pendingorders->[$i] }; + push @ordersloop, \%line; + } + $template->param( + ordersloop => \@ordersloop, + ); +} else { + # Search for booksellers to transfer from/to + $op = '' unless $op; + if( $op eq "do_search" ) { + my @booksellers = GetBookSeller($query); + $template->param( + query => $query, + do_search => 1, + booksellersloop => \@booksellers, + ); + } else { + $template->param( + search_form => 1, + ); + } +} + +$template->param( + bookselleridfrom => $bookselleridfrom, + booksellerfromname => $booksellerfromname, + bookselleridto => $bookselleridto, + booksellertoname => $booksellertoname, + ordernumber => $ordernumber, + basketno => $basketno, + referrer => $input->param('referrer') +); + +output_html_with_http_headers $input, $cookie, $template->output; diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 3137f38..17d4ba8 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -2728,6 +2728,7 @@ CREATE TABLE `aqorders` ( `cancelledby` varchar(10) default NULL, `datecancellationprinted` date default NULL, `notes` mediumtext, + internalnotes mediumtext DEFAULT NULL, `supplierreference` mediumtext, `purchaseordernumber` mediumtext, `subscription` tinyint(1) default NULL, diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index dbbdee3..311ee40 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -5308,6 +5308,16 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) { SetVersion ($DBversion); } +$DBversion = "XXX"; +if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { + $dbh->do(qq{ + ALTER TABLE aqorders + ADD COLUMN internalnotes MEDIUMTEXT DEFAULT NULL AFTER notes + }); + print "Upgrade to $DBversion done (Add internalnotes field in aqorders table)\n"; + SetVersion($DBversion); +} + =head1 FUNCTIONS =head2 TableExists($table) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt index dcd6ccb..19249d1 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/basket.tt @@ -312,6 +312,7 @@ [Add note] [% END %]

+

[% books_loo.internalnotes %]

[% books_loo.rrp %] [% books_loo.ecost %] @@ -322,6 +323,10 @@ [% UNLESS ( closedate ) %] Modify + [% UNLESS (books_loo.order_received) %] +
+ Transfer + [% END %] [% IF ( books_loo.left_holds_on_order ) %] @@ -393,6 +398,7 @@ [% IF ( order.publicationyear ) %], [% order.publicationyear %][% END %] [% IF ( books_loo.editionstatement ) %], [% books_loo.editionstatement %][% END %]

+

[% order.internalnotes %]

[% order.rrp %]

[% order.ecost %]

diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt index a5d3e1a..265c99e 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/parcel.tt @@ -106,9 +106,10 @@ + '' + order.ecost + '' + '' + order.ordertotal + '' + '' - + 'Receive /' - + 'Cancel' - + '').appendTo("table#pendingt"); + + 'Receive' + + '
' + + 'Transfer' + + '').appendTo("table#pendingt"); } // If nothing has been found, we tell the user so @@ -259,6 +260,8 @@ [% loop_order.ordertotal %] Receive +
+ Transfer diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/transferorder.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/transferorder.tt new file mode 100644 index 0000000..f694c1f --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/transferorder.tt @@ -0,0 +1,121 @@ +[% INCLUDE 'doc-head-open.inc' %] +Koha › Acquisitions › Transfer order +[% INCLUDE 'doc-head-close.inc' %] + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'acquisitions-search.inc' %] + + + +
+
+
+
+ [% IF ( show_baskets ) %] +

Baskets for [% booksellertoname %]

+ [% IF ( basketsloop ) %] + + + + + + + + + [% FOREACH basket IN basketsloop %] + + + + + + [% END %] + +
Basket (#)Created byDate 
[% basket.basketname %] (#[% basket.basketno %])[% basket.createdby %][% basket.creationdate %]Choose +
+ [% ELSE %] +

There is no open baskets for this supplier.

+ [% END %] + [% END %] + [% IF ( ordersloop ) %] +

Orders for [% booksellerfromname %]

+ + + + + + + + [% FOREACH ordersloo IN ordersloop %] + + + + + + [% END %] + +
OrderSummary 
[% ordersloo.ordernumber %] + [% ordersloo.title |html %] + [% IF ( ordersloo.author ) %] by [% ordersloo.author %][% END %] + [% IF ( ordersloo.isbn ) %] – [% ordersloo.isbn %][% END %] + [% IF ( ordersloo.publishercode ) %]
Publisher :[% ordersloo.publishercode %][% END %] +
Transfer
+ [% END %] + [% IF ( do_search ) %] + [% IF ( bookselleridfrom ) %] +

Choose a vendor to transfer to

+ [% ELSE %] +

Choose a vendor to transfer from

+ [% END %] + [% IF ( booksellersloop ) %] + + + + + + + [% FOREACH bookseller IN booksellersloop %] + + + + + [% END %] + +
Name 
[% bookseller.name %]Choose
+ [% ELSE %] +

No results found.

+ [% END %] + [% END %] + [% IF ( search_form ) %] + [% IF ( bookselleridfrom ) %] +

Search for a vendor to transfer to

+ [% ELSE %] +

Search for a vendor to transfer from

+ [% END %] +
+ + + [% IF ( ordernumber ) %] + + [% END %] + [% IF ( bookselleridfrom ) %] + + [% END %] + + + +
+ [% END %] +
+
+ +
+ [% INCLUDE 'acquisitions-menu.inc' %] +
+
+
+[% INCLUDE 'intranet-bottom.inc' %] -- 1.7.2.5