Bug 5349: add ability to transfer order lines from one basket to another
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 leads to a new page which allow you to search for a bookseller, then display this bookseller's baskets. Then you can pick a basket and the transfer will be done. Signed-off-by: Marc Veron <veron@veron.ch> Signed-off-by: Mathieu Saby <mathieu.saby@univ-rennes2.fr> Signed-off-by: sonia <koha@univ-lyon3.fr> Signed-off-by: Chris Cormack <chris@bigballofwax.co.nz> Signed-off-by: Galen Charlton <gmc@esilibrary.com>
This commit is contained in:
parent
6fcb6712fe
commit
12f62ba1db
|
|
@ -57,7 +57,7 @@ BEGIN {
|
|||
&GetLateOrders &GetOrderFromItemnumber
|
||||
&SearchOrder &GetHistory &GetRecentAcqui
|
||||
&ModReceiveOrder &CancelReceipt
|
||||
&GetCancelledOrders
|
||||
&GetCancelledOrders &TransferOrder
|
||||
&GetLastOrderNotReceivedFromSubscriptionid &GetLastOrderReceivedFromSubscriptionid
|
||||
&NewOrderItem &ModItemOrder
|
||||
|
||||
|
|
@ -1596,6 +1596,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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,145 @@
|
|||
#!/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;
|
||||
|
||||
|
|
@ -2911,6 +2911,7 @@ CREATE TABLE `aqorders` ( -- information related to the basket line items
|
|||
`cancelledby` varchar(10) default NULL, -- not used? always NULL
|
||||
`datecancellationprinted` date default NULL, -- the date the line item was deleted
|
||||
`notes` mediumtext, -- notes related to this order line
|
||||
internalnotes mediumtext DEFAULT NULL, -- used by Koha to store some informations, not editable by librarians
|
||||
`supplierreference` mediumtext, -- not used? always NULL
|
||||
`purchaseordernumber` mediumtext, -- not used? always NULL
|
||||
`basketno` int(11) default NULL, -- links this order line to a specific basket (aqbasket.basketno)
|
||||
|
|
|
|||
|
|
@ -7104,6 +7104,17 @@ if ( CheckVersion($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)
|
||||
|
|
|
|||
|
|
@ -348,6 +348,7 @@
|
|||
[% ELSE %]
|
||||
<p>[<a href="/cgi-bin/koha/acqui/modordernotes.pl?ordernumber=[% books_loo.ordernumber %]">Add note</a>]</p>
|
||||
[% END %]
|
||||
<p>[% books_loo.internalnotes %]</p>
|
||||
</td>
|
||||
<td class="number gste [% IF books_loo.rrpgste.search('^0') %]error[% END %]">[% books_loo.rrpgste %]</td>
|
||||
<td class="number gste [% IF books_loo.ecostgste.search('^0') %]error[% END %]">[% books_loo.ecostgste %]</td>
|
||||
|
|
@ -363,6 +364,10 @@
|
|||
[% UNLESS ( closedate ) %]
|
||||
<td>
|
||||
<a href="neworderempty.pl?ordernumber=[% books_loo.ordernumber %]&booksellerid=[% booksellerid %]&basketno=[% basketno %]">Modify</a>
|
||||
[% UNLESS (books_loo.order_received) %]
|
||||
<br />
|
||||
<a href="/cgi-bin/koha/acqui/transferorder.pl?ordernumber=[% books_loo.ordernumber %]&referrer=[% "/cgi-bin/koha/acqui/basket.pl?basketno=$basketno" | uri %]">Transfer</a>
|
||||
[% END %]
|
||||
</td>
|
||||
<td>
|
||||
[% IF ( books_loo.left_holds_on_order ) %]
|
||||
|
|
@ -435,6 +440,7 @@
|
|||
[% IF ( order.publicationyear ) %], [% order.publicationyear %][% END %]
|
||||
[% IF ( books_loo.editionstatement ) %], [% books_loo.editionstatement %][% END %]
|
||||
</p>
|
||||
<p>[% order.internalnotes %]</p>
|
||||
</td>
|
||||
<td class="number gste">[% order.rrpgste %]</td>
|
||||
<td class="number gste">[% order.ecostgste %]</td>
|
||||
|
|
|
|||
|
|
@ -215,6 +215,8 @@
|
|||
<td>[% loop_order.budget_name %]</td>
|
||||
<td>
|
||||
<a href="orderreceive.pl?ordernumber=[% loop_order.ordernumber %]&invoiceid=[% invoiceid %]">Receive</a>
|
||||
<br />
|
||||
<a href="/cgi-bin/koha/acqui/transferorder.pl?ordernumber=[% loop_order.ordernumber %]&referrer=[% "/cgi-bin/koha/acqui/parcel.pl?invoiceid=[% invoiceid %]" | uri %]">Transfer</a>
|
||||
</td>
|
||||
<td>
|
||||
[% IF ( loop_order.left_holds_on_order ) %]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,121 @@
|
|||
[% INCLUDE 'doc-head-open.inc' %]
|
||||
<title>Koha › Acquisitions › Transfer order</title>
|
||||
[% INCLUDE 'doc-head-close.inc' %]
|
||||
</head>
|
||||
<body>
|
||||
[% INCLUDE 'header.inc' %]
|
||||
[% INCLUDE 'acquisitions-search.inc' %]
|
||||
|
||||
<div id="breadcrumbs">
|
||||
<a href="/cgi-bin/koha/mainpage.pl">Home</a>
|
||||
› <a href="/cgi-bin/koha/acqui/acqui-home.pl">Acquisitions</a>
|
||||
› Transfer order
|
||||
</div>
|
||||
|
||||
<div id="doc3" class="yui-t2">
|
||||
<div id="bd">
|
||||
<div id="yui-main">
|
||||
<div class="yui-b">
|
||||
[% IF ( show_baskets ) %]
|
||||
<h1>Baskets for [% booksellertoname %]</h1>
|
||||
[% IF ( basketsloop ) %]
|
||||
<table>
|
||||
<thead>
|
||||
<th>Basket (#)</th>
|
||||
<th>Created by</th>
|
||||
<th>Date</th>
|
||||
<th> </th>
|
||||
</thead>
|
||||
<tbody>
|
||||
[% FOREACH basket IN basketsloop %]
|
||||
<tr>
|
||||
<td>[% basket.basketname %] (#[% basket.basketno %])</td>
|
||||
<td>[% basket.createdby %]</td>
|
||||
<td>[% basket.creationdate %]</td>
|
||||
<td><a href="transferorder.pl?basketno=[% basket.basketno %]&ordernumber=[% ordernumber %][% IF (referrer) %]&referrer=[% referrer | uri %][% END %]" onclick="return confirm('Do you want to transfer order [% ordernumber %] from basket [% basketfromname %] ([% booksellerfromname %]) to basket [% basket.basketname %] ([% booksellertoname %]) ?');">Choose</a>
|
||||
</tr>
|
||||
[% END %]
|
||||
</tbody>
|
||||
</table>
|
||||
[% ELSE %]
|
||||
<p>There is no open baskets for this supplier.</p>
|
||||
[% END %]
|
||||
[% END %]
|
||||
[% IF ( ordersloop ) %]
|
||||
<h1>Orders for [% booksellerfromname %]</h1>
|
||||
<table>
|
||||
<thead>
|
||||
<th>Order</th>
|
||||
<th>Summary</th>
|
||||
<th> </th>
|
||||
</thead>
|
||||
<tbody>
|
||||
[% FOREACH ordersloo IN ordersloop %]
|
||||
<tr>
|
||||
<td><a href="neworderempty.pl?ordernumber=[% ordersloo.ordernumber %]">[% ordersloo.ordernumber %]</a></td>
|
||||
<td>
|
||||
<a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% ordersloo.biblionumber %]">[% ordersloo.title |html %]</a>
|
||||
[% IF ( ordersloo.author ) %] by [% ordersloo.author %][% END %]
|
||||
[% IF ( ordersloo.isbn ) %] – [% ordersloo.isbn %][% END %]
|
||||
[% IF ( ordersloo.publishercode ) %]<br />Publisher :[% ordersloo.publishercode %][% END %]
|
||||
</td>
|
||||
<td><a href="transferorder.pl?bookselleridfrom=[% ordersloo.bookselleridfrom %]&ordernumber=[% ordersloo.ordernumber %][% IF (referrer) %]&referrer=[% referrer | uri %][% END %]">Transfer</a></td>
|
||||
</tr>
|
||||
[% END %]
|
||||
</tbody>
|
||||
</table>
|
||||
[% END %]
|
||||
[% IF ( do_search ) %]
|
||||
[% IF ( bookselleridfrom ) %]
|
||||
<h1>Choose a vendor to transfer to</h1>
|
||||
[% ELSE %]
|
||||
<h1>Choose a vendor to transfer from</h1>
|
||||
[% END %]
|
||||
[% IF ( booksellersloop ) %]
|
||||
<table>
|
||||
<thead>
|
||||
<th>Name</th>
|
||||
<th> </th>
|
||||
</thead>
|
||||
<tbody>
|
||||
[% FOREACH bookseller IN booksellersloop %]
|
||||
<tr>
|
||||
<td>[% bookseller.name %]</td>
|
||||
<td><a href="transferorder.pl?[% IF (bookselleridfrom) %]bookselleridto[% ELSE %]bookselleridfrom[% END %]=[% bookseller.id %][% IF (ordernumber) %]&ordernumber=[% ordernumber %][% END %][% IF (referrer) %]&referrer=[% referrer | uri %][% END %]">Choose</a></td>
|
||||
</tr>
|
||||
[% END %]
|
||||
</tbody>
|
||||
</table>
|
||||
[% ELSE %]
|
||||
<p>No results found.</p>
|
||||
[% END %]
|
||||
[% END %]
|
||||
[% IF ( search_form ) %]
|
||||
[% IF ( bookselleridfrom ) %]
|
||||
<h1>Search for a vendor to transfer to</h1>
|
||||
[% ELSE %]
|
||||
<h1>Search for a vendor to transfer from</h1>
|
||||
[% END %]
|
||||
<form method="get" action="transferorder.pl">
|
||||
<input type="hidden" name="op" value="do_search" />
|
||||
<input type="hidden" name="referrer" value="[% referrer %]" />
|
||||
[% IF ( ordernumber ) %]
|
||||
<input type="hidden" name="ordernumber" value="[% ordernumber %]" />
|
||||
[% END %]
|
||||
[% IF ( bookselleridfrom ) %]
|
||||
<input type="hidden" name="bookselleridfrom" value="[% bookselleridfrom %]" />
|
||||
[% END %]
|
||||
<label for="query">Vendor:</label>
|
||||
<input type="text" name="query" />
|
||||
<input type="submit" value="Search" />
|
||||
</form>
|
||||
[% END %]
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="yui-b">
|
||||
[% INCLUDE 'acquisitions-menu.inc' %]
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
[% INCLUDE 'intranet-bottom.inc' %]
|
||||
Loading…
Reference in New Issue