X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=C4%2FAcquisition.pm;h=f9c12d797d0f6c6538786f3342c8acda9519f99f;hb=df97814f3034a3d5015546c4eca21f08ae951e37;hp=e0853477bb05e06f07ddc774be48fab709c9d2b3;hpb=201af593f885ecb11c76d02baa6e27ef5e744e30;p=koha.git diff --git a/C4/Acquisition.pm b/C4/Acquisition.pm index e0853477bb..f9c12d797d 100644 --- a/C4/Acquisition.pm +++ b/C4/Acquisition.pm @@ -4,42 +4,45 @@ package C4::Acquisition; # # 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 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. +# 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. +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . -use strict; -use warnings; +use Modern::Perl; use Carp; use C4::Context; use C4::Debug; -use C4::Dates qw(format_date format_date_in_iso); -use MARC::Record; use C4::Suggestions; use C4::Biblio; +use C4::Contract; use C4::Debug; -use C4::SQLHelper qw(InsertInTable UpdateInTable); -use C4::Bookseller qw(GetBookSellerFromId); use C4::Templates qw(gettemplate); +use Koha::DateUtils qw( dt_from_string output_pref ); +use Koha::Acquisition::Order; +use Koha::Acquisition::Bookseller; +use Koha::Number::Price; +use Koha::Libraries; + +use C4::Koha; + +use MARC::Field; +use MARC::Record; use Time::localtime; -use HTML::Entities; -use vars qw($VERSION @ISA @EXPORT); +use vars qw(@ISA @EXPORT); BEGIN { - # set the version for version checking - $VERSION = 3.07.00.049; require Exporter; @ISA = qw(Exporter); @EXPORT = qw( @@ -56,16 +59,15 @@ BEGIN { &ModBasketgroup &NewBasketgroup &DelBasketgroup &GetBasketgroup &CloseBasketgroup &GetBasketgroups &ReOpenBasketgroup - &NewOrder &DelOrder &ModOrder &GetOrder &GetOrders &GetOrdersByBiblionumber + &DelOrder &ModOrder &GetOrder &GetOrders &GetOrdersByBiblionumber &GetLateOrders &GetOrderFromItemnumber &SearchOrders &GetHistory &GetRecentAcqui &ModReceiveOrder &CancelReceipt - &GetCancelledOrders &TransferOrder + &TransferOrder &GetLastOrderNotReceivedFromSubscriptionid &GetLastOrderReceivedFromSubscriptionid - &NewOrderItem &ModItemOrder + &ModItemOrder - &GetParcels &GetParcel - &GetContracts &GetContract + &GetParcels &GetInvoices &GetInvoice @@ -81,6 +83,12 @@ BEGIN { &AddClaim &GetBiblioCountByBasketno + + &GetOrderUsers + &ModOrderUsers + &NotifyOrderUsers + + &FillWithDefaultValues ); } @@ -177,8 +185,8 @@ sub GetBasket { =head3 NewBasket - $basket = &NewBasket( $booksellerid, $authorizedby, $basketname, - $basketnote, $basketbooksellernote, $basketcontractnumber, $deliveryplace, $billingplace ); + $basket = &NewBasket( $booksellerid, $authorizedby, $basketname, + $basketnote, $basketbooksellernote, $basketcontractnumber, $deliveryplace, $billingplace, $is_standing ); Create a new basket in aqbasket table @@ -197,7 +205,7 @@ The other parameters are optional, see ModBasketHeader for more info on them. sub NewBasket { my ( $booksellerid, $authorisedby, $basketname, $basketnote, $basketbooksellernote, $basketcontractnumber, $deliveryplace, - $billingplace ) = @_; + $billingplace, $is_standing ) = @_; my $dbh = C4::Context->dbh; my $query = 'INSERT INTO aqbasket (creationdate,booksellerid,authorisedby) ' @@ -209,7 +217,7 @@ sub NewBasket { $basketnote ||= q{}; $basketbooksellernote ||= q{}; ModBasketHeader( $basket, $basketname, $basketnote, $basketbooksellernote, - $basketcontractnumber, $booksellerid, $deliveryplace, $billingplace ); + $basketcontractnumber, $booksellerid, $deliveryplace, $billingplace, $is_standing ); return $basket; } @@ -226,24 +234,11 @@ close a basket (becomes unmodifiable, except for receives) sub CloseBasket { my ($basketno) = @_; my $dbh = C4::Context->dbh; - my $query = " - UPDATE aqbasket - SET closedate=now() - WHERE basketno=? - "; - my $sth = $dbh->prepare($query); - $sth->execute($basketno); + $dbh->do('UPDATE aqbasket SET closedate=now() WHERE basketno=?', {}, $basketno ); - my @orders = GetOrders($basketno); - foreach my $order (@orders) { - $query = qq{ - UPDATE aqorders - SET orderstatus = 'ordered' - WHERE ordernumber = ?; - }; - $sth = $dbh->prepare($query); - $sth->execute($order->{'ordernumber'}); - } + $dbh->do( q{UPDATE aqorders SET orderstatus = 'ordered' WHERE basketno = ? AND orderstatus != 'complete'}, + {}, $basketno); + return; } =head3 ReopenBasket @@ -257,24 +252,15 @@ reopen a basket sub ReopenBasket { my ($basketno) = @_; my $dbh = C4::Context->dbh; - my $query = " - UPDATE aqbasket - SET closedate=NULL - WHERE basketno=? - "; - my $sth = $dbh->prepare($query); - $sth->execute($basketno); + $dbh->do( q{UPDATE aqbasket SET closedate=NULL WHERE basketno=?}, {}, $basketno ); - my @orders = GetOrders($basketno); - foreach my $order (@orders) { - $query = qq{ - UPDATE aqorders - SET orderstatus = 'new' - WHERE ordernumber = ?; - }; - $sth = $dbh->prepare($query); - $sth->execute($order->{'ordernumber'}); - } + $dbh->do( q{ + UPDATE aqorders + SET orderstatus = 'new' + WHERE basketno = ? + AND orderstatus != 'complete' + }, {}, $basketno); + return; } #------------------------------------------------------------# @@ -293,9 +279,11 @@ sub GetBasketAsCSV { my ($basketno, $cgi) = @_; my $basket = GetBasket($basketno); my @orders = GetOrders($basketno); - my $contract = GetContract($basket->{'contractnumber'}); + my $contract = GetContract({ + contractnumber => $basket->{'contractnumber'} + }); - my $template = C4::Templates::gettemplate("acqui/csv/basket.tmpl", "intranet", $cgi); + my $template = C4::Templates::gettemplate("acqui/csv/basket.tt", "intranet", $cgi); my @rows; foreach my $order (@orders) { @@ -310,12 +298,15 @@ sub GetBasketAsCSV { publicationyear => $bd->{'publicationyear'}, publishercode => $bd->{'publishercode'}, collectiontitle => $bd->{'collectiontitle'}, - notes => $order->{'notes'}, + notes => $order->{'order_vendornote'}, quantity => $order->{'quantity'}, rrp => $order->{'rrp'}, - deliveryplace => C4::Branch::GetBranchName( $basket->{'deliveryplace'} ), - billingplace => C4::Branch::GetBranchName( $basket->{'billingplace'} ), }; + for my $place ( qw( deliveryplace billingplace ) ) { + if ( my $library = Koha::Libraries->find( $row->{deliveryplace} ) ) { + $row->{$place} = $library->branchname + } + } foreach(qw( contractname author title publishercode collectiontitle notes deliveryplace billingplace @@ -340,29 +331,27 @@ sub GetBasketAsCSV { =head3 GetBasketGroupAsCSV -=over - -&GetBasketGroupAsCSV($basketgroupid); + &GetBasketGroupAsCSV($basketgroupid); Export a basket group as CSV $cgi parameter is needed for column name translation -=back - =cut sub GetBasketGroupAsCSV { my ($basketgroupid, $cgi) = @_; my $baskets = GetBasketsByBasketgroup($basketgroupid); - my $template = C4::Templates::gettemplate('acqui/csv/basketgroup.tmpl', 'intranet', $cgi); + my $template = C4::Templates::gettemplate('acqui/csv/basketgroup.tt', 'intranet', $cgi); my @rows; for my $basket (@$baskets) { - my @orders = GetOrders( $$basket{basketno} ); - my $contract = GetContract( $$basket{contractnumber} ); - my $bookseller = GetBookSellerFromId( $$basket{booksellerid} ); + my @orders = GetOrders( $basket->{basketno} ); + my $contract = GetContract({ + contractnumber => $basket->{contractnumber} + }); + my $bookseller = Koha::Acquisition::Bookseller->fetch({ id => $basket->{booksellerid} }); my $basketgroup = GetBasketgroup( $$basket{basketgroupid} ); foreach my $order (@orders) { @@ -381,18 +370,23 @@ sub GetBasketGroupAsCSV { rrp => $order->{rrp}, discount => $bookseller->{discount}, ecost => $order->{ecost}, - notes => $order->{notes}, + notes => $order->{order_vendornote}, entrydate => $order->{entrydate}, booksellername => $bookseller->{name}, bookselleraddress => $bookseller->{address1}, booksellerpostal => $bookseller->{postal}, contractnumber => $contract->{contractnumber}, contractname => $contract->{contractname}, - basketgroupdeliveryplace => C4::Branch::GetBranchName( $basketgroup->{deliveryplace} ), - basketgroupbillingplace => C4::Branch::GetBranchName( $basketgroup->{billingplace} ), - basketdeliveryplace => C4::Branch::GetBranchName( $basket->{deliveryplace} ), - basketbillingplace => C4::Branch::GetBranchName( $basket->{billingplace} ), + basketgroupdeliveryplace => $basketgroup->{deliveryplace}, + basketgroupbillingplace => $basketgroup->{billingplace}, + basketdeliveryplace => $basket->{deliveryplace}, + basketbillingplace => $basket->{billingplace}, }; + for my $place (qw( basketgroupdeliveryplace basketgroupbillingplace basketdeliveryplace basketbillingplace )) { + if ( my $library = Koha::Libraries->find( $row->{deliveryplace} ) ) { + $row->{$place} = $library->branchname; + } + } foreach(qw( basketname author title publishercode collectiontitle notes booksellername bookselleraddress booksellerpostal contractname @@ -544,21 +538,23 @@ Modifies a basket's header. =item C<$billingplace> is the "billingplace" field in the aqbasket table. +=item C<$is_standing> is the "is_standing" field in the aqbasket table. + =back =cut sub ModBasketHeader { - my ($basketno, $basketname, $note, $booksellernote, $contractnumber, $booksellerid, $deliveryplace, $billingplace) = @_; + my ($basketno, $basketname, $note, $booksellernote, $contractnumber, $booksellerid, $deliveryplace, $billingplace, $is_standing) = @_; my $query = qq{ UPDATE aqbasket - SET basketname=?, note=?, booksellernote=?, booksellerid=?, deliveryplace=?, billingplace=? + SET basketname=?, note=?, booksellernote=?, booksellerid=?, deliveryplace=?, billingplace=?, is_standing=? WHERE basketno=? }; my $dbh = C4::Context->dbh; my $sth = $dbh->prepare($query); - $sth->execute($basketname, $note, $booksellernote, $booksellerid, $deliveryplace, $billingplace, $basketno); + $sth->execute($basketname, $note, $booksellernote, $booksellerid, $deliveryplace, $billingplace, $is_standing, $basketno); if ( $contractnumber ) { my $query2 ="UPDATE aqbasket SET contractnumber=? WHERE basketno=?"; @@ -632,9 +628,12 @@ sub GetBasketsInfosByBookseller { return unless $supplierid; my $dbh = C4::Context->dbh; - my $query = qq{ + my $query = q{ SELECT aqbasket.*, SUM(aqorders.quantity) AS total_items, + SUM( + IF ( aqorders.orderstatus = 'cancelled', aqorders.quantity, 0 ) + ) AS total_items_cancelled, COUNT(DISTINCT aqorders.biblionumber) AS total_biblios, SUM( IF(aqorders.datereceived IS NULL @@ -645,14 +644,30 @@ sub GetBasketsInfosByBookseller { FROM aqbasket LEFT JOIN aqorders ON aqorders.basketno = aqbasket.basketno WHERE booksellerid = ?}; - if(!$allbaskets) { + + unless ( $allbaskets ) { $query.=" AND (closedate IS NULL OR (aqorders.quantity > aqorders.quantityreceived AND datecancellationprinted IS NULL))"; } $query.=" GROUP BY aqbasket.basketno"; my $sth = $dbh->prepare($query); $sth->execute($supplierid); - return $sth->fetchall_arrayref({}); + my $baskets = $sth->fetchall_arrayref({}); + + # Retrieve the number of biblios cancelled + my $cancelled_biblios = $dbh->selectall_hashref( q| + SELECT COUNT(DISTINCT(biblionumber)) AS total_biblios_cancelled, aqbasket.basketno + FROM aqbasket + LEFT JOIN aqorders ON aqorders.basketno = aqbasket.basketno + WHERE booksellerid = ? + AND aqorders.orderstatus = 'cancelled' + GROUP BY aqbasket.basketno + |, 'basketno', {}, $supplierid ); + map { + $_->{total_biblios_cancelled} = $cancelled_biblios->{$_->{basketno}}{total_biblios_cancelled} || 0 + } @$baskets; + + return $baskets; } =head3 GetBasketUsers @@ -1012,47 +1027,80 @@ sub GetBasketgroups { =head3 GetOrders - @orders = &GetOrders($basketnumber, $orderby); + @orders = &GetOrders( $basketno, { orderby => 'biblio.title', cancelled => 0|1 } ); Looks up the pending (non-cancelled) orders with the given basket -number. If C<$booksellerID> is non-empty, only orders from that seller -are returned. +number. -return : -C<&basket> returns a two-element array. C<@orders> is an array of -references-to-hash, whose keys are the fields from the aqorders, -biblio, and biblioitems tables in the Koha database. +If cancelled is set, only cancelled orders will be returned. =cut sub GetOrders { - my ( $basketno, $orderby ) = @_; + my ( $basketno, $params ) = @_; + + return () unless $basketno; + + my $orderby = $params->{orderby}; + my $cancelled = $params->{cancelled} || 0; + my $dbh = C4::Context->dbh; - my $query =" + my $query = q| SELECT biblio.*,biblioitems.*, aqorders.*, aqbudgets.*, - biblio.title, + |; + $query .= $cancelled + ? q| + aqorders_transfers.ordernumber_to AS transferred_to, + aqorders_transfers.timestamp AS transferred_to_timestamp + | + : q| aqorders_transfers.ordernumber_from AS transferred_from, aqorders_transfers.timestamp AS transferred_from_timestamp + |; + $query .= q| FROM aqorders LEFT JOIN aqbudgets ON aqbudgets.budget_id = aqorders.budget_id LEFT JOIN biblio ON biblio.biblionumber = aqorders.biblionumber LEFT JOIN biblioitems ON biblioitems.biblionumber =biblio.biblionumber + |; + $query .= $cancelled + ? q| + LEFT JOIN aqorders_transfers ON aqorders_transfers.ordernumber_from = aqorders.ordernumber + | + : q| LEFT JOIN aqorders_transfers ON aqorders_transfers.ordernumber_to = aqorders.ordernumber + + |; + $query .= q| WHERE basketno=? + |; + + if ($cancelled) { + $orderby ||= q|biblioitems.publishercode, biblio.title|; + $query .= q| + AND (datecancellationprinted IS NOT NULL + AND datecancellationprinted <> '0000-00-00') + |; + } + else { + $orderby ||= + q|aqorders.datecancellationprinted desc, aqorders.timestamp desc|; + $query .= q| AND (datecancellationprinted IS NULL OR datecancellationprinted='0000-00-00') - "; + |; + } - $orderby = "biblioitems.publishercode,biblio.title" unless $orderby; $query .= " ORDER BY $orderby"; - my $result_set = + my $orders = $dbh->selectall_arrayref( $query, { Slice => {} }, $basketno ); - return @{$result_set}; + return @{$orders}; } #------------------------------------------------------------# + =head3 GetOrdersByBiblionumber @orders = &GetOrdersByBiblionumber($biblionumber); @@ -1101,6 +1149,8 @@ C<$order> are fields from the biblio, biblioitems, aqorders tables of the Koha d sub GetOrder { my ($ordernumber) = @_; + return unless $ordernumber; + my $dbh = C4::Context->dbh; my $query = qq{SELECT aqorders.*, @@ -1197,102 +1247,13 @@ sub GetLastOrderReceivedFromSubscriptionid { LIMIT 1 |; my $result_set = - $dbh->selectall_arrayref( $query, { Slice => {} }, $subscriptionid ); + $dbh->selectall_arrayref( $query, { Slice => {} }, $subscriptionid, $subscriptionid ); # result_set assumed to contain 1 match return $result_set->[0]; } - -#------------------------------------------------------------# - -=head3 NewOrder - - &NewOrder(\%hashref); - -Adds a new order to the database. Any argument that isn't described -below is the new value of the field with the same name in the aqorders -table of the Koha database. - -=over - -=item $hashref->{'basketno'} is the basketno foreign key in aqorders, it is mandatory - -=item $hashref->{'ordernumber'} is a "minimum order number." - -=item $hashref->{'budgetdate'} is effectively ignored. -If it's undef (anything false) or the string 'now', the current day is used. -Else, the upcoming July 1st is used. - -=item $hashref->{'subscription'} may be either "yes", or anything else for "no". - -=item $hashref->{'uncertainprice'} may be 0 for "the price is known" or 1 for "the price is uncertain" - -=item defaults entrydate to Now - -The following keys are used: "biblionumber", "title", "basketno", "quantity", "notes", "rrp", "ecost", "gstrate", "unitprice", "subscription", "sort1", "sort2", "booksellerinvoicenumber", "listprice", "budgetdate", "purchaseordernumber", "branchcode", "booksellerinvoicenumber", "budget_id". - -=back - -=cut - -sub NewOrder { - my $orderinfo = shift; - - my $dbh = C4::Context->dbh; - my @params; - - - # if these parameters are missing, we can't continue - for my $key (qw/basketno quantity biblionumber budget_id/) { - croak "Mandatory parameter $key missing" unless $orderinfo->{$key}; - } - - if ( defined $orderinfo->{subscription} && $orderinfo->{'subscription'} eq 'yes' ) { - $orderinfo->{'subscription'} = 1; - } else { - $orderinfo->{'subscription'} = 0; - } - $orderinfo->{'entrydate'} ||= C4::Dates->new()->output("iso"); - if (!$orderinfo->{quantityreceived}) { - $orderinfo->{quantityreceived} = 0; - } - - my $ordernumber=InsertInTable("aqorders",$orderinfo); - if (not $orderinfo->{parent_ordernumber}) { - my $sth = $dbh->prepare(" - UPDATE aqorders - SET parent_ordernumber = ordernumber - WHERE ordernumber = ? - "); - $sth->execute($ordernumber); - } - return ( $orderinfo->{'basketno'}, $ordernumber ); -} - - - -#------------------------------------------------------------# - -=head3 NewOrderItem - - &NewOrderItem(); - -=cut - -sub NewOrderItem { - my ($itemnumber, $ordernumber) = @_; - my $dbh = C4::Context->dbh; - my $query = qq| - INSERT INTO aqorders_items - (itemnumber, ordernumber) - VALUES (?,?) |; - - my $sth = $dbh->prepare($query); - $sth->execute( $itemnumber, $ordernumber); -} - #------------------------------------------------------------# =head3 ModOrder @@ -1309,8 +1270,7 @@ table of the Koha database. sub ModOrder { my $orderinfo = shift; - die "Ordernumber is required" if $orderinfo->{'ordernumber'} eq '' ; - die "Biblionumber is required" if $orderinfo->{'biblionumber'} eq ''; + die "Ordernumber is required" if $orderinfo->{'ordernumber'} eq ''; my $dbh = C4::Context->dbh; my @params; @@ -1368,57 +1328,25 @@ sub ModItemOrder { return $sth->execute($ordernumber, $itemnumber); } -#------------------------------------------------------------# - -=head3 GetCancelledOrders - - my @orders = GetCancelledOrders($basketno, $orderby); - -Returns cancelled orders for a basket - -=cut - -sub GetCancelledOrders { - my ( $basketno, $orderby ) = @_; - - return () unless $basketno; - - my $dbh = C4::Context->dbh; - my $query = " - SELECT - biblio.*, - biblioitems.*, - aqorders.*, - aqbudgets.*, - aqorders_transfers.ordernumber_to AS transferred_to, - aqorders_transfers.timestamp AS transferred_to_timestamp - FROM aqorders - LEFT JOIN aqbudgets ON aqbudgets.budget_id = aqorders.budget_id - LEFT JOIN biblio ON biblio.biblionumber = aqorders.biblionumber - LEFT JOIN biblioitems ON biblioitems.biblionumber = biblio.biblionumber - LEFT JOIN aqorders_transfers ON aqorders_transfers.ordernumber_from = aqorders.ordernumber - WHERE basketno = ? - AND (datecancellationprinted IS NOT NULL - AND datecancellationprinted <> '0000-00-00') - "; - - $orderby = "aqorders.datecancellationprinted desc, aqorders.timestamp desc" - unless $orderby; - $query .= " ORDER BY $orderby"; - my $sth = $dbh->prepare($query); - $sth->execute($basketno); - my $results = $sth->fetchall_arrayref( {} ); - - return @$results; -} - - #------------------------------------------------------------# =head3 ModReceiveOrder - &ModReceiveOrder($biblionumber, $ordernumber, $quantityreceived, $user, - $cost, $ecost, $invoiceid, rrp, budget_id, datereceived, \@received_itemnumbers); + &ModReceiveOrder({ + biblionumber => $biblionumber, + ordernumber => $ordernumber, + quantityreceived => $quantityreceived, + user => $user, + cost => $cost, + ecost => $ecost, + invoiceid => $invoiceid, + rrp => $rrp, + budget_id => $budget_id, + datereceived => $datereceived, + received_itemnumbers => \@received_itemnumbers, + order_internalnote => $order_internalnote, + order_vendornote => $order_vendornote, + }); Updates an order, to reflect the fact that it was received, at least in part. All arguments not mentioned below update the fields with the @@ -1433,14 +1361,29 @@ C<$ordernumber>. sub ModReceiveOrder { - my ( - $biblionumber, $ordernumber, $quantrec, $user, $cost, $ecost, - $invoiceid, $rrp, $budget_id, $datereceived, $received_items - ) - = @_; + my ( $params ) = @_; + my $biblionumber = $params->{biblionumber}; + my $ordernumber = $params->{ordernumber}; + my $quantrec = $params->{quantityreceived}; + my $user = $params->{user}; + my $cost = $params->{cost}; + my $ecost = $params->{ecost}; + my $invoiceid = $params->{invoiceid}; + my $rrp = $params->{rrp}; + my $budget_id = $params->{budget_id}; + my $datereceived = $params->{datereceived}; + my $received_items = $params->{received_items}; + my $order_internalnote = $params->{order_internalnote}; + my $order_vendornote = $params->{order_vendornote}; my $dbh = C4::Context->dbh; - $datereceived = C4::Dates->output('iso') unless $datereceived; + $datereceived = output_pref( + { + dt => ( $datereceived ? dt_from_string( $datereceived ) : dt_from_string ), + dateformat => 'iso', + dateonly => 1, + } + ); my $suggestionid = GetSuggestionFromBiblionumber( $biblionumber ); if ($suggestionid) { ModSuggestion( {suggestionid=>$suggestionid, @@ -1450,7 +1393,7 @@ sub ModReceiveOrder { } my $result_set = $dbh->selectall_arrayref( -q{SELECT * FROM aqorders WHERE biblionumber=? AND aqorders.ordernumber=?}, +q{SELECT *, aqbasket.is_standing FROM aqorders LEFT JOIN aqbasket USING (basketno) WHERE biblionumber=? AND aqorders.ordernumber=?}, { Slice => {} }, $biblionumber, $ordernumber ); @@ -1458,19 +1401,26 @@ q{SELECT * FROM aqorders WHERE biblionumber=? AND aqorders.ordernumber=?}, my $order = $result_set->[0]; my $new_ordernumber = $ordernumber; - if ( $order->{quantity} > $quantrec ) { + if ( $order->{is_standing} || $order->{quantity} > $quantrec ) { # Split order line in two parts: the first is the original order line # without received items (the quantity is decreased), # the second part is a new order line with quantity=quantityrec # (entirely received) - my $sth=$dbh->prepare(" + my $query = q| UPDATE aqorders SET quantity = ?, - orderstatus = 'partial' - WHERE ordernumber = ? - "); + orderstatus = 'partial'|; + $query .= q|, order_internalnote = ?| if defined $order_internalnote; + $query .= q|, order_vendornote = ?| if defined $order_vendornote; + $query .= q| WHERE ordernumber = ?|; + my $sth = $dbh->prepare($query); - $sth->execute($order->{quantity} - $quantrec, $ordernumber); + $sth->execute( + ( $order->{is_standing} ? 1 : ( $order->{quantity} - $quantrec ) ), + ( defined $order_internalnote ? $order_internalnote : () ), + ( defined $order_vendornote ? $order_vendornote : () ), + $ordernumber + ); delete $order->{'ordernumber'}; $order->{'budget_id'} = ( $budget_id || $order->{'budget_id'} ); @@ -1482,8 +1432,7 @@ q{SELECT * FROM aqorders WHERE biblionumber=? AND aqorders.ordernumber=?}, $order->{'rrp'} = $rrp; $order->{ecost} = $ecost; $order->{'orderstatus'} = 'complete'; - my $basketno; - ( $basketno, $new_ordernumber ) = NewOrder($order); + $new_ordernumber = Koha::Acquisition::Order->new($order)->insert->{ordernumber}; if ($received_items) { foreach my $itemnumber (@$received_items) { @@ -1491,11 +1440,31 @@ q{SELECT * FROM aqorders WHERE biblionumber=? AND aqorders.ordernumber=?}, } } } else { - my $sth=$dbh->prepare("update aqorders - set quantityreceived=?,datereceived=?,invoiceid=?, - unitprice=?,rrp=?,ecost=?,budget_id=?,orderstatus='complete' - where biblionumber=? and ordernumber=?"); - $sth->execute($quantrec,$datereceived,$invoiceid,$cost,$rrp,$ecost,$budget_id,$biblionumber,$ordernumber); + my $query = q| + update aqorders + set quantityreceived=?,datereceived=?,invoiceid=?, + unitprice=?,rrp=?,ecost=?,budget_id=?,orderstatus='complete'|; + $query .= q|, order_internalnote = ?| if defined $order_internalnote; + $query .= q|, order_vendornote = ?| if defined $order_vendornote; + $query .= q| where biblionumber=? and ordernumber=?|; + my $sth = $dbh->prepare( $query ); + $sth->execute( + $quantrec, + $datereceived, + $invoiceid, + $cost, + $rrp, + $ecost, + ( $budget_id ? $budget_id : $order->{budget_id} ), + ( defined $order_internalnote ? $order_internalnote : () ), + ( defined $order_vendornote ? $order_vendornote : () ), + $biblionumber, + $ordernumber + ); + + # All items have been received, sent a notification to users + NotifyOrderUsers( $ordernumber ); + } return ($datereceived, $new_ordernumber); } @@ -1536,6 +1505,8 @@ sub CancelReceipt { my $parent_ordernumber = $order->{'parent_ordernumber'}; + my @itemnumbers = GetItemnumbersFromOrder( $ordernumber ); + if($parent_ordernumber == $ordernumber || not $parent_ordernumber) { # The order line has no parent, just mark it as not received $query = qq{ @@ -1548,6 +1519,7 @@ sub CancelReceipt { }; $sth = $dbh->prepare($query); $sth->execute(0, undef, undef, $ordernumber); + _cancel_items_receipt( $ordernumber ); } else { # The order line has a parent, increase parent quantity and delete # the order line. @@ -1584,25 +1556,7 @@ sub CancelReceipt { " receipt"; return; } - if(C4::Context->preference('AcqCreateItem') eq 'receiving') { - # Remove items that were created at receipt - $query = qq{ - DELETE FROM items, aqorders_items - USING items, aqorders_items - WHERE items.itemnumber = ? AND aqorders_items.itemnumber = ? - }; - $sth = $dbh->prepare($query); - my @itemnumbers = GetItemnumbersFromOrder($ordernumber); - foreach my $itemnumber (@itemnumbers) { - $sth->execute($itemnumber, $itemnumber); - } - } else { - # Update items - my @itemnumbers = GetItemnumbersFromOrder($ordernumber); - foreach my $itemnumber (@itemnumbers) { - ModItemOrder($itemnumber, $parent_ordernumber); - } - } + _cancel_items_receipt( $ordernumber, $parent_ordernumber ); # Delete order line $query = qq{ DELETE FROM aqorders @@ -1613,9 +1567,53 @@ sub CancelReceipt { } + if(C4::Context->preference('AcqCreateItem') eq 'ordering') { + my @affects = split q{\|}, C4::Context->preference("AcqItemSetSubfieldsWhenReceiptIsCancelled"); + if ( @affects ) { + for my $in ( @itemnumbers ) { + my $biblionumber = C4::Biblio::GetBiblionumberFromItemnumber( $in ); + my $frameworkcode = GetFrameworkCode($biblionumber); + my ( $itemfield ) = GetMarcFromKohaField( 'items.itemnumber', $frameworkcode ); + my $item = C4::Items::GetMarcItem( $biblionumber, $in ); + for my $affect ( @affects ) { + my ( $sf, $v ) = split q{=}, $affect, 2; + foreach ( $item->field($itemfield) ) { + $_->update( $sf => $v ); + } + } + C4::Items::ModItemFromMarc( $item, $biblionumber, $in ); + } + } + } + return $parent_ordernumber; } +sub _cancel_items_receipt { + my ( $ordernumber, $parent_ordernumber ) = @_; + $parent_ordernumber ||= $ordernumber; + + my @itemnumbers = GetItemnumbersFromOrder($ordernumber); + if(C4::Context->preference('AcqCreateItem') eq 'receiving') { + # Remove items that were created at receipt + my $query = qq{ + DELETE FROM items, aqorders_items + USING items, aqorders_items + WHERE items.itemnumber = ? AND aqorders_items.itemnumber = ? + }; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare($query); + foreach my $itemnumber (@itemnumbers) { + $sth->execute($itemnumber, $itemnumber); + } + } else { + # Update items + foreach my $itemnumber (@itemnumbers) { + ModItemOrder($itemnumber, $parent_ordernumber); + } + } +} + #------------------------------------------------------------# =head3 SearchOrders @@ -1629,12 +1627,14 @@ sub CancelReceipt { basketno => $basketno, owner => $owner, pending => $pending + ordered => $ordered }); Searches for orders. C<$owner> Finds order for the logged in user. C<$pending> Finds pending orders. Ignores completed and cancelled orders. +C<$ordered> Finds orders to receive only (status 'ordered' or 'partial'). C<@results> is an array of references-to-hash with the keys are fields @@ -1653,6 +1653,9 @@ sub SearchOrders { my $basketgroupname = $params->{basketgroupname}; my $owner = $params->{owner}; my $pending = $params->{pending}; + my $ordered = $params->{ordered}; + my $biblionumber = $params->{biblionumber}; + my $budget_id = $params->{budget_id}; my $dbh = C4::Context->dbh; my @args = (); @@ -1663,6 +1666,8 @@ sub SearchOrders { biblio.*, biblioitems.isbn, biblioitems.biblioitemnumber, + aqbasket.authorisedby, + aqbasket.booksellerid, aqbasket.closedate, aqbasket.creationdate, aqbasket.basketname, @@ -1675,12 +1680,33 @@ sub SearchOrders { LEFT JOIN borrowers ON aqbasket.authorisedby=borrowers.borrowernumber LEFT JOIN biblio ON aqorders.biblionumber=biblio.biblionumber LEFT JOIN biblioitems ON biblioitems.biblionumber=biblio.biblionumber - WHERE (datecancellationprinted is NULL) }; + # If we search on ordernumber, we retrieve the transferred order if a transfer has been done. + $query .= q{ + LEFT JOIN aqorders_transfers ON aqorders_transfers.ordernumber_to = aqorders.ordernumber + } if $ordernumber; + $query .= q{ - AND (quantity > quantityreceived OR quantityreceived is NULL) - } if $pending; + WHERE (datecancellationprinted is NULL) + }; + + if ( $pending or $ordered ) { + $query .= q{ + AND ( + ( aqbasket.is_standing AND aqorders.orderstatus IN ( "new", "ordered", "partial" ) ) + OR ( + ( quantity > quantityreceived OR quantityreceived is NULL ) + }; + + if ( $ordered ) { + $query .= q{ AND aqorders.orderstatus IN ( "ordered", "partial" )}; + } + $query .= q{ + ) + ) + }; + } my $userenv = C4::Context->userenv; if ( C4::Context->preference("IndependentBranches") ) { @@ -1696,8 +1722,12 @@ sub SearchOrders { } if ( $ordernumber ) { - $query .= ' AND (aqorders.ordernumber=?)'; - push @args, $ordernumber; + $query .= ' AND ( aqorders.ordernumber = ? OR aqorders_transfers.ordernumber_from = ? ) '; + push @args, ( $ordernumber, $ordernumber ); + } + if ( $biblionumber ) { + $query .= 'AND aqorders.biblionumber = ?'; + push @args, $biblionumber; } if( $search ) { $query .= ' AND (biblio.title LIKE ? OR biblio.author LIKE ? OR biblioitems.isbn LIKE ?)'; @@ -1729,6 +1759,11 @@ sub SearchOrders { push @args, $userenv->{'number'}; } + if ( $budget_id ) { + $query .= ' AND aqorders.budget_id = ?'; + push @args, $budget_id; + } + $query .= ' ORDER BY aqbasket.basketno'; my $sth = $dbh->prepare($query); @@ -1749,20 +1784,53 @@ cancelled. =cut sub DelOrder { - my ( $bibnum, $ordernumber ) = @_; + my ( $bibnum, $ordernumber, $delete_biblio, $reason ) = @_; + + my $error; my $dbh = C4::Context->dbh; my $query = " UPDATE aqorders SET datecancellationprinted=now(), orderstatus='cancelled' - WHERE biblionumber=? AND ordernumber=? + "; + if($reason) { + $query .= ", cancellationreason = ? "; + } + $query .= " + WHERE biblionumber=? AND ordernumber=? "; my $sth = $dbh->prepare($query); - $sth->execute( $bibnum, $ordernumber ); + if($reason) { + $sth->execute($reason, $bibnum, $ordernumber); + } else { + $sth->execute( $bibnum, $ordernumber ); + } + $sth->finish; + my @itemnumbers = GetItemnumbersFromOrder( $ordernumber ); foreach my $itemnumber (@itemnumbers){ - C4::Items::DelItem( $dbh, $bibnum, $itemnumber ); + my $delcheck = C4::Items::DelItemCheck( $bibnum, $itemnumber ); + + if($delcheck != 1) { + $error->{'delitem'} = 1; + } } - return; + + if($delete_biblio) { + # We get the number of remaining items + my $itemcount = C4::Items::GetItemsCount($bibnum); + + # If there are no items left, + if ( $itemcount == 0 ) { + # We delete the record + my $delcheck = DelBiblio($bibnum); + + if($delcheck) { + $error->{'delbiblio'} = 1; + } + } + } + + return $error; } =head3 TransferOrder @@ -1770,11 +1838,11 @@ sub DelOrder { my $newordernumber = TransferOrder($ordernumber, $basketno); Transfer an order line to a basket. -Mark $ordernumber as cancelled with an internal note 'Cancelled and transfered +Mark $ordernumber as cancelled with an internal note 'Cancelled and transferred to BOOKSELLER on DATE' and create new order with internal note -'Transfered from BOOKSELLER on DATE'. +'Transferred from BOOKSELLER on DATE'. Move all attached items to the new order. -Received orders cannot be transfered. +Received orders cannot be transferred. Return the ordernumber of created order. =cut @@ -1794,17 +1862,17 @@ sub TransferOrder { $query = q{ UPDATE aqorders - SET datecancellationprinted = CAST(NOW() AS date) + SET datecancellationprinted = CAST(NOW() AS date), orderstatus = ? WHERE ordernumber = ? }; $sth = $dbh->prepare($query); - $rv = $sth->execute($ordernumber); + $rv = $sth->execute('cancelled', $ordernumber); delete $order->{'ordernumber'}; delete $order->{parent_ordernumber}; $order->{'basketno'} = $basketno; - my $newordernumber; - (undef, $newordernumber) = NewOrder($order); + + my $newordernumber = Koha::Acquisition::Order->new($order)->insert->{ordernumber}; $query = q{ UPDATE aqorders_items @@ -1826,77 +1894,6 @@ sub TransferOrder { =head2 FUNCTIONS ABOUT PARCELS -=cut - -#------------------------------------------------------------# - -=head3 GetParcel - - @results = &GetParcel($booksellerid, $code, $date); - -Looks up all of the received items from the supplier with the given -bookseller ID at the given date, for the given code (bookseller Invoice number). Ignores cancelled and completed orders. - -C<@results> is an array of references-to-hash. The keys of each element are fields from -the aqorders, biblio, and biblioitems tables of the Koha database. - -C<@results> is sorted alphabetically by book title. - -=cut - -sub GetParcel { - #gets all orders from a certain supplier, orders them alphabetically - my ( $supplierid, $code, $datereceived ) = @_; - my $dbh = C4::Context->dbh; - my @results = (); - $code .= '%' - if $code; # add % if we search on a given code (otherwise, let him empty) - my $strsth =" - SELECT authorisedby, - creationdate, - aqbasket.basketno, - closedate,surname, - firstname, - aqorders.biblionumber, - aqorders.ordernumber, - aqorders.parent_ordernumber, - aqorders.quantity, - aqorders.quantityreceived, - aqorders.unitprice, - aqorders.listprice, - aqorders.rrp, - aqorders.ecost, - aqorders.gstrate, - biblio.title - FROM aqorders - LEFT JOIN aqbasket ON aqbasket.basketno=aqorders.basketno - LEFT JOIN borrowers ON aqbasket.authorisedby=borrowers.borrowernumber - LEFT JOIN biblio ON aqorders.biblionumber=biblio.biblionumber - LEFT JOIN aqinvoices ON aqorders.invoiceid = aqinvoices.invoiceid - WHERE - aqbasket.booksellerid = ? - AND aqinvoices.invoicenumber LIKE ? - AND aqorders.datereceived = ? "; - - my @query_params = ( $supplierid, $code, $datereceived ); - if ( C4::Context->preference("IndependentBranches") ) { - unless ( C4::Context->IsSuperLibrarian() ) { - $strsth .= " and (borrowers.branchcode = ? - or borrowers.branchcode = '')"; - push @query_params, C4::Context->userenv->{branch}; - } - } - $strsth .= " ORDER BY aqbasket.basketno"; - my $result_set = $dbh->selectall_arrayref( - $strsth, - { Slice => {} }, - @query_params); - - return @{$result_set}; -} - -#------------------------------------------------------------# - =head3 GetParcels $results = &GetParcels($bookseller, $order, $code, $datefrom, $dateto); @@ -2013,6 +2010,9 @@ sub GetLateOrders { SELECT aqbasket.basketno, aqorders.ordernumber, DATE(aqbasket.closedate) AS orderdate, + aqbasket.basketname AS basketname, + aqbasket.basketgroupid AS basketgroupid, + aqbasketgroups.name AS basketgroupname, aqorders.rrp AS unitpricesupplier, aqorders.ecost AS unitpricelib, aqorders.claims_count AS claims_count, @@ -2033,6 +2033,7 @@ sub GetLateOrders { LEFT JOIN aqbudgets ON aqorders.budget_id = aqbudgets.budget_id, aqbasket LEFT JOIN borrowers ON aqbasket.authorisedby = borrowers.borrowernumber LEFT JOIN aqbooksellers ON aqbasket.booksellerid = aqbooksellers.id + LEFT JOIN aqbasketgroups ON aqbasket.basketgroupid = aqbasketgroups.id WHERE aqorders.basketno = aqbasket.basketno AND ( datereceived = '' OR datereceived IS NULL @@ -2104,8 +2105,6 @@ sub GetLateOrders { $sth->execute(@query_params); my @results; while (my $data = $sth->fetchrow_hashref) { - $data->{orderdate} = format_date($data->{orderdate}); - $data->{claimed_date} = format_date($data->{claimed_date}); push @results, $data; } return @results; @@ -2115,7 +2114,7 @@ sub GetLateOrders { =head3 GetHistory - (\@order_loop, $total_qty, $total_price, $total_qtyreceived) = GetHistory( %params ); + \@order_loop = GetHistory( %params ); Retreives some acquisition history information @@ -2155,9 +2154,6 @@ returns: 'quantityreceived' => undef, 'title' => 'The Adventures of Huckleberry Finn' } - $total_qty is the sum of all of the quantities in $order_loop - $total_price is the cost of each in $order_loop times the quantity - $total_qtyreceived is the sum of all of the quantityreceived entries in $order_loop =cut @@ -2179,6 +2175,9 @@ sub GetHistory { my $orderstatus = $params{orderstatus}; my $biblionumber = $params{biblionumber}; my $get_canceled_order = $params{get_canceled_order} || 0; + my $ordernumber = $params{ordernumber}; + my $search_children_too = $params{search_children_too} || 0; + my $created_by = $params{created_by} || []; my @order_loop; my $total_qty = 0; @@ -2195,6 +2194,8 @@ sub GetHistory { aqorders.basketno, aqbasket.basketname, aqbasket.basketgroupid, + aqbasket.authorisedby, + concat( borrowers.firstname,' ',borrowers.surname) AS authorisedbyname, aqbasketgroups.name as groupname, aqbooksellers.name, aqbasket.creationdate, @@ -2223,12 +2224,9 @@ sub GetHistory { LEFT JOIN aqinvoices ON aqorders.invoiceid = aqinvoices.invoiceid LEFT JOIN deletedbiblio ON deletedbiblio.biblionumber=aqorders.biblionumber LEFT JOIN deletedbiblioitems ON deletedbiblioitems.biblionumber=aqorders.biblionumber + LEFT JOIN borrowers ON aqbasket.authorisedby=borrowers.borrowernumber "; - if ( C4::Context->preference("IndependentBranches") ) { - $query .= " LEFT JOIN borrowers ON aqbasket.authorisedby=borrowers.borrowernumber"; - } - $query .= " WHERE 1 "; unless ($get_canceled_order or (defined $orderstatus and $orderstatus eq 'cancelled')) { @@ -2306,6 +2304,22 @@ sub GetHistory { push @query_params, "%$basketgroupname%"; } + if ($ordernumber) { + $query .= " AND (aqorders.ordernumber = ? "; + push @query_params, $ordernumber; + if ($search_children_too) { + $query .= " OR aqorders.parent_ordernumber = ? "; + push @query_params, $ordernumber; + } + $query .= ") "; + } + + if ( @$created_by ) { + $query .= ' AND aqbasket.authorisedby IN ( ' . join( ',', ('?') x @$created_by ) . ')'; + push @query_params, @$created_by; + } + + if ( C4::Context->preference("IndependentBranches") ) { unless ( C4::Context->IsSuperLibrarian() ) { $query .= " AND (borrowers.branchcode = ? OR borrowers.branchcode ='' ) "; @@ -2313,18 +2327,8 @@ sub GetHistory { } } $query .= " ORDER BY id"; - my $sth = $dbh->prepare($query); - $sth->execute( @query_params ); - my $cnt = 1; - while ( my $line = $sth->fetchrow_hashref ) { - $line->{count} = $cnt++; - $line->{toggle} = 1 if $cnt % 2; - push @order_loop, $line; - $total_qty += ( $line->{quantity} ) ? $line->{quantity} : 0; - $total_qtyreceived += ( $line->{quantityreceived} ) ? $line->{quantityreceived} : 0; - $total_price += ( $line->{quantity} and $line->{ecost} ) ? $line->{quantity} * $line->{ecost} : 0; - } - return \@order_loop, $total_qty, $total_price, $total_qtyreceived; + + return $dbh->selectall_arrayref( $query, { Slice => {} }, @query_params ); } =head2 GetRecentAcqui @@ -2350,82 +2354,14 @@ sub GetRecentAcqui { return $results; } -=head3 GetContracts - - $contractlist = &GetContracts($booksellerid, $activeonly); - -Looks up the contracts that belong to a bookseller - -Returns a list of contracts - -=over - -=item C<$booksellerid> is the "id" field in the "aqbooksellers" table. - -=item C<$activeonly> if exists get only contracts that are still active. - -=back - -=cut - -sub GetContracts { - my ( $booksellerid, $activeonly ) = @_; - my $dbh = C4::Context->dbh; - my $query; - if (! $activeonly) { - $query = " - SELECT * - FROM aqcontract - WHERE booksellerid=? - "; - } else { - $query = "SELECT * - FROM aqcontract - WHERE booksellerid=? - AND contractenddate >= CURDATE( )"; - } - my $result_set = - $dbh->selectall_arrayref( $query, { Slice => {} }, $booksellerid ); - return @{$result_set}; -} - #------------------------------------------------------------# -=head3 GetContract - - $contract = &GetContract($contractID); - -Looks up the contract that has PRIMKEY (contractnumber) value $contractID - -Returns a contract - -=cut - -sub GetContract { - my ( $contractno ) = @_; - my $dbh = C4::Context->dbh; - my $query = " - SELECT * - FROM aqcontract - WHERE contractnumber=? - "; - - my $sth = $dbh->prepare($query); - $sth->execute( $contractno ); - my $result = $sth->fetchrow_hashref; - return $result; -} - =head3 AddClaim -=over - -&AddClaim($ordernumber); + &AddClaim($ordernumber); Add a claim for an order -=back - =cut sub AddClaim { @@ -2486,6 +2422,13 @@ sub GetInvoices { NULL ) ) AS receivedbiblios, + COUNT( + DISTINCT IF( + aqorders.subscriptionid IS NOT NULL, + aqorders.subscriptionid, + NULL + ) + ) AS is_linked_to_subscriptions, SUM(aqorders.quantityreceived) AS receiveditems FROM aqinvoices LEFT JOIN aqbooksellers ON aqbooksellers.id = aqinvoices.booksellerid @@ -2551,6 +2494,10 @@ sub GetInvoices { push @bind_strs, " borrowers.branchcode = ? "; push @bind_args, $args{branchcode}; } + if($args{message_id}) { + push @bind_strs, " aqinvoices.message_id = ? "; + push @bind_args, $args{message_id}; + } $query .= " WHERE " . join(" AND ", @bind_strs) if @bind_strs; $query .= " GROUP BY aqinvoices.invoiceid "; @@ -2630,10 +2577,19 @@ sub GetInvoiceDetails { my $invoice = $sth->fetchrow_hashref; $query = q{ - SELECT aqorders.*, biblio.*, aqbasket.basketname + SELECT aqorders.*, + biblio.*, + biblio.copyrightdate, + biblioitems.publishercode, + biblioitems.publicationyear, + aqbasket.basketname, + aqbasketgroups.id AS basketgroupid, + aqbasketgroups.name AS basketgroupname FROM aqorders LEFT JOIN aqbasket ON aqorders.basketno = aqbasket.basketno + LEFT JOIN aqbasketgroups ON aqbasket.basketgroupid = aqbasketgroups.id LEFT JOIN biblio ON aqorders.biblionumber = biblio.biblionumber + LEFT JOIN biblioitems ON aqorders.biblionumber = biblioitems.biblionumber WHERE invoiceid = ? }; $sth = $dbh->prepare($query); @@ -2666,7 +2622,7 @@ sub AddInvoice { return unless(%invoice and $invoice{invoicenumber}); my @columns = qw(invoicenumber booksellerid shipmentdate billingdate - closedate shipmentcost shipmentcost_budgetid); + closedate shipmentcost shipmentcost_budgetid message_id); my @set_strs; my @set_args; @@ -2767,7 +2723,7 @@ sub CloseInvoice { Reopen an invoice -Equivalent to ModInvoice(invoiceid => $invoiceid, closedate => C4::Dates->new()->output('iso')) +Equivalent to ModInvoice(invoiceid => $invoiceid, closedate => output_pref({ dt=>dt_from_string, dateonly=>1, otputpref=>'iso' })) =cut @@ -2869,6 +2825,222 @@ sub GetBiblioCountByBasketno { return $sth->fetchrow; } +# This is *not* the good way to calcul prices +# But it's how it works at the moment into Koha +# This will be fixed later. +# Note this subroutine should be moved to Koha::Acquisition::Order +# Will do when a DBIC decision will be taken. +sub populate_order_with_prices { + my ($params) = @_; + + my $order = $params->{order}; + my $booksellerid = $params->{booksellerid}; + return unless $booksellerid; + + my $bookseller = Koha::Acquisition::Bookseller->fetch({ id => $booksellerid }); + + my $receiving = $params->{receiving}; + my $ordering = $params->{ordering}; + my $discount = $order->{discount}; + $discount /= 100 if $discount > 1; + + $order->{rrp} = Koha::Number::Price->new( $order->{rrp} )->round; + $order->{ecost} = Koha::Number::Price->new( $order->{ecost} )->round; + if ($ordering) { + if ( $bookseller->{listincgst} ) { + $order->{rrpgsti} = $order->{rrp}; + $order->{rrpgste} = Koha::Number::Price->new( + $order->{rrpgsti} / ( 1 + $order->{gstrate} ) )->round; + $order->{ecostgsti} = $order->{ecost}; + $order->{ecostgste} = Koha::Number::Price->new( + $order->{ecost} / ( 1 + $order->{gstrate} ) )->round; + $order->{gstvalue} = Koha::Number::Price->new( + ( $order->{ecostgsti} - $order->{ecostgste} ) * + $order->{quantity} )->round; + $order->{totalgste} = $order->{ecostgste} * $order->{quantity}; + $order->{totalgsti} = $order->{ecostgsti} * $order->{quantity}; + } + else { + $order->{rrpgste} = $order->{rrp}; + $order->{rrpgsti} = Koha::Number::Price->new( + $order->{rrp} * ( 1 + $order->{gstrate} ) )->round; + $order->{ecostgste} = $order->{ecost}; + $order->{ecostgsti} = Koha::Number::Price->new( + $order->{ecost} * ( 1 + $order->{gstrate} ) )->round; + $order->{gstvalue} = Koha::Number::Price->new( + ( $order->{ecostgsti} - $order->{ecostgste} ) * + $order->{quantity} )->round; + $order->{totalgste} = $order->{ecostgste} * $order->{quantity}; + $order->{totalgsti} = $order->{ecostgsti} * $order->{quantity}; + } + } + + if ($receiving) { + if ( $bookseller->{listincgst} ) { + $order->{unitpricegsti} = Koha::Number::Price->new( $order->{unitprice} )->round; + $order->{unitpricegste} = Koha::Number::Price->new( + $order->{unitpricegsti} / ( 1 + $order->{gstrate} ) )->round; + } + else { + $order->{unitpricegste} = Koha::Number::Price->new( $order->{unitprice} )->round; + $order->{unitpricegsti} = Koha::Number::Price->new( + $order->{unitpricegste} * ( 1 + $order->{gstrate} ) )->round; + } + $order->{gstvalue} = Koha::Number::Price->new( + ( $order->{unitpricegsti} - $order->{unitpricegste} ) + * $order->{quantityreceived} )->round; + + $order->{totalgste} = $order->{unitpricegste} * $order->{quantity}; + $order->{totalgsti} = $order->{unitpricegsti} * $order->{quantity}; + } + + return $order; +} + +=head3 GetOrderUsers + + $order_users_ids = &GetOrderUsers($ordernumber); + +Returns a list of all borrowernumbers that are in order users list + +=cut + +sub GetOrderUsers { + my ($ordernumber) = @_; + + return unless $ordernumber; + + my $query = q| + SELECT borrowernumber + FROM aqorder_users + WHERE ordernumber = ? + |; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare($query); + $sth->execute($ordernumber); + my $results = $sth->fetchall_arrayref( {} ); + + my @borrowernumbers; + foreach (@$results) { + push @borrowernumbers, $_->{'borrowernumber'}; + } + + return @borrowernumbers; +} + +=head3 ModOrderUsers + + my @order_users_ids = (1, 2, 3); + &ModOrderUsers($ordernumber, @basketusers_ids); + +Delete all users from order users list, and add users in C<@order_users_ids> +to this users list. + +=cut + +sub ModOrderUsers { + my ( $ordernumber, @order_users_ids ) = @_; + + return unless $ordernumber; + + my $dbh = C4::Context->dbh; + my $query = q| + DELETE FROM aqorder_users + WHERE ordernumber = ? + |; + my $sth = $dbh->prepare($query); + $sth->execute($ordernumber); + + $query = q| + INSERT INTO aqorder_users (ordernumber, borrowernumber) + VALUES (?, ?) + |; + $sth = $dbh->prepare($query); + foreach my $order_user_id (@order_users_ids) { + $sth->execute( $ordernumber, $order_user_id ); + } +} + +sub NotifyOrderUsers { + my ($ordernumber) = @_; + + my @borrowernumbers = GetOrderUsers($ordernumber); + return unless @borrowernumbers; + + my $order = GetOrder( $ordernumber ); + for my $borrowernumber (@borrowernumbers) { + my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber ); + my $library = Koha::Libraries->find( $borrower->{branchcode} )->unblessed; + my $biblio = C4::Biblio::GetBiblio( $order->{biblionumber} ); + my $letter = C4::Letters::GetPreparedLetter( + module => 'acquisition', + letter_code => 'ACQ_NOTIF_ON_RECEIV', + branchcode => $library->{branchcode}, + tables => { + 'branches' => $library, + 'borrowers' => $borrower, + 'biblio' => $biblio, + 'aqorders' => $order, + }, + ); + if ( $letter ) { + C4::Letters::EnqueueLetter( + { + letter => $letter, + borrowernumber => $borrowernumber, + LibraryName => C4::Context->preference("LibraryName"), + message_transport_type => 'email', + } + ) or warn "can't enqueue letter $letter"; + } + } +} + +=head3 FillWithDefaultValues + +FillWithDefaultValues( $marc_record ); + +This will update the record with default value defined in the ACQ framework. +For all existing fields, if a default value exists and there are no subfield, it will be created. +If the field does not exist, it will be created too. + +=cut + +sub FillWithDefaultValues { + my ($record) = @_; + my $tagslib = C4::Biblio::GetMarcStructure( 1, 'ACQ' ); + if ($tagslib) { + my ($itemfield) = + C4::Biblio::GetMarcFromKohaField( 'items.itemnumber', '' ); + for my $tag ( sort keys %$tagslib ) { + next unless $tag; + next if $tag == $itemfield; + for my $subfield ( sort keys %{ $tagslib->{$tag} } ) { + next if IsMarcStructureInternal($tagslib->{$tag}{$subfield}); + my $defaultvalue = $tagslib->{$tag}{$subfield}{defaultvalue}; + if ( defined $defaultvalue and $defaultvalue ne '' ) { + my @fields = $record->field($tag); + if (@fields) { + for my $field (@fields) { + unless ( defined $field->subfield($subfield) ) { + $field->add_subfields( + $subfield => $defaultvalue ); + } + } + } + else { + $record->insert_fields_ordered( + MARC::Field->new( + $tag, '', '', $subfield => $defaultvalue + ) + ); + } + } + } + } + } +} + 1; __END__