Bug 15006: Introduce client_timeout in SIPconfig.xml
[srvgit] / C4 / Acquisition.pm
index a14ffe7..c091f89 100644 (file)
@@ -4,42 +4,46 @@ package C4::Acquisition;
 #
 # This file is part of Koha.
 #
 #
 # 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 <http://www.gnu.org/licenses>.
 
 
 
 
-use strict;
-use warnings;
+use Modern::Perl;
 use Carp;
 use C4::Context;
 use C4::Debug;
 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::Suggestions;
 use C4::Biblio;
+use C4::Contract;
 use C4::Debug;
 use C4::Debug;
-use C4::SQLHelper qw(InsertInTable UpdateInTable);
-use C4::Bookseller qw(GetBookSellerFromId);
 use C4::Templates qw(gettemplate);
 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 Time::localtime;
 use HTML::Entities;
 
-use vars qw($VERSION @ISA @EXPORT);
+use vars qw(@ISA @EXPORT);
 
 BEGIN {
 
 BEGIN {
-    # set the version for version checking
-    $VERSION = 3.07.00.049;
     require Exporter;
     @ISA    = qw(Exporter);
     @EXPORT = qw(
     require Exporter;
     @ISA    = qw(Exporter);
     @EXPORT = qw(
@@ -56,16 +60,15 @@ BEGIN {
         &ModBasketgroup &NewBasketgroup &DelBasketgroup &GetBasketgroup &CloseBasketgroup
         &GetBasketgroups &ReOpenBasketgroup
 
         &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
         &GetLateOrders &GetOrderFromItemnumber
         &SearchOrders &GetHistory &GetRecentAcqui
         &ModReceiveOrder &CancelReceipt
-        &GetCancelledOrders &TransferOrder
+        &TransferOrder
         &GetLastOrderNotReceivedFromSubscriptionid &GetLastOrderReceivedFromSubscriptionid
         &GetLastOrderNotReceivedFromSubscriptionid &GetLastOrderReceivedFromSubscriptionid
-        &NewOrderItem &ModItemOrder
+        &ModItemOrder
 
 
-        &GetParcels &GetParcel
-        &GetContracts &GetContract
+        &GetParcels
 
         &GetInvoices
         &GetInvoice
 
         &GetInvoices
         &GetInvoice
@@ -81,6 +84,12 @@ BEGIN {
 
         &AddClaim
         &GetBiblioCountByBasketno
 
         &AddClaim
         &GetBiblioCountByBasketno
+
+        &GetOrderUsers
+        &ModOrderUsers
+        &NotifyOrderUsers
+
+        &FillWithDefaultValues
     );
 }
 
     );
 }
 
@@ -177,8 +186,8 @@ sub GetBasket {
 
 =head3 NewBasket
 
 
 =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
 
 
 Create a new basket in aqbasket table
 
@@ -197,7 +206,7 @@ The other parameters are optional, see ModBasketHeader for more info on them.
 sub NewBasket {
     my ( $booksellerid, $authorisedby, $basketname, $basketnote,
         $basketbooksellernote, $basketcontractnumber, $deliveryplace,
 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) '
     my $dbh = C4::Context->dbh;
     my $query =
         'INSERT INTO aqbasket (creationdate,booksellerid,authorisedby) '
@@ -209,7 +218,7 @@ sub NewBasket {
     $basketnote           ||= q{};
     $basketbooksellernote ||= q{};
     ModBasketHeader( $basket, $basketname, $basketnote, $basketbooksellernote,
     $basketnote           ||= q{};
     $basketbooksellernote ||= q{};
     ModBasketHeader( $basket, $basketname, $basketnote, $basketbooksellernote,
-        $basketcontractnumber, $booksellerid, $deliveryplace, $billingplace );
+        $basketcontractnumber, $booksellerid, $deliveryplace, $billingplace, $is_standing );
     return $basket;
 }
 
     return $basket;
 }
 
@@ -226,24 +235,11 @@ close a basket (becomes unmodifiable, except for receives)
 sub CloseBasket {
     my ($basketno) = @_;
     my $dbh        = C4::Context->dbh;
 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
 }
 
 =head3 ReopenBasket
@@ -257,24 +253,15 @@ reopen a basket
 sub ReopenBasket {
     my ($basketno) = @_;
     my $dbh        = C4::Context->dbh;
 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 +280,11 @@ sub GetBasketAsCSV {
     my ($basketno, $cgi) = @_;
     my $basket = GetBasket($basketno);
     my @orders = GetOrders($basketno);
     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) {
 
     my @rows;
     foreach my $order (@orders) {
@@ -310,7 +299,7 @@ sub GetBasketAsCSV {
             publicationyear => $bd->{'publicationyear'},
             publishercode => $bd->{'publishercode'},
             collectiontitle => $bd->{'collectiontitle'},
             publicationyear => $bd->{'publicationyear'},
             publishercode => $bd->{'publishercode'},
             collectiontitle => $bd->{'collectiontitle'},
-            notes => $order->{'order_internalnote'},
+            notes => $order->{'order_vendornote'},
             quantity => $order->{'quantity'},
             rrp => $order->{'rrp'},
             deliveryplace => C4::Branch::GetBranchName( $basket->{'deliveryplace'} ),
             quantity => $order->{'quantity'},
             rrp => $order->{'rrp'},
             deliveryplace => C4::Branch::GetBranchName( $basket->{'deliveryplace'} ),
@@ -340,29 +329,27 @@ sub GetBasketAsCSV {
 
 =head3 GetBasketGroupAsCSV
 
 
 =head3 GetBasketGroupAsCSV
 
-=over
-
-&GetBasketGroupAsCSV($basketgroupid);
+  &GetBasketGroupAsCSV($basketgroupid);
 
 Export a basket group as CSV
 
 $cgi parameter is needed for column name translation
 
 
 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);
 
 =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 @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) {
         my $basketgroup = GetBasketgroup( $$basket{basketgroupid} );
 
         foreach my $order (@orders) {
@@ -381,7 +368,7 @@ sub GetBasketGroupAsCSV {
                 rrp => $order->{rrp},
                 discount => $bookseller->{discount},
                 ecost => $order->{ecost},
                 rrp => $order->{rrp},
                 discount => $bookseller->{discount},
                 ecost => $order->{ecost},
-                notes => $order->{order_internalnote},
+                notes => $order->{order_vendornote},
                 entrydate => $order->{entrydate},
                 booksellername => $bookseller->{name},
                 bookselleraddress => $bookseller->{address1},
                 entrydate => $order->{entrydate},
                 booksellername => $bookseller->{name},
                 bookselleraddress => $bookseller->{address1},
@@ -544,21 +531,23 @@ Modifies a basket's header.
 
 =item C<$billingplace> is the "billingplace" field in the aqbasket table.
 
 
 =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 {
 =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
     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);
         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=?";
 
     if ( $contractnumber ) {
         my $query2 ="UPDATE aqbasket SET contractnumber=? WHERE basketno=?";
@@ -1031,48 +1020,80 @@ sub GetBasketgroups {
 
 =head3 GetOrders
 
 
 =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
 
 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 {
 
 =cut
 
 sub GetOrders {
-    my ( $basketno, $orderby ) = @_;
+    my ( $basketno, $params ) = @_;
+
     return () unless $basketno;
     return () unless $basketno;
+
+    my $orderby = $params->{orderby};
+    my $cancelled = $params->{cancelled} || 0;
+
     my $dbh   = C4::Context->dbh;
     my $dbh   = C4::Context->dbh;
-    my $query  ="
+    my $query = q|
         SELECT biblio.*,biblioitems.*,
                 aqorders.*,
                 aqbudgets.*,
         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
                 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
         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
             LEFT JOIN aqorders_transfers ON aqorders_transfers.ordernumber_to = aqorders.ordernumber
+
+    |;
+    $query .= q|
         WHERE   basketno=?
         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')
             AND (datecancellationprinted IS NULL OR datecancellationprinted='0000-00-00')
-    ";
+        |;
+    }
 
 
-    $orderby = "biblioitems.publishercode,biblio.title" unless $orderby;
     $query .= " ORDER BY $orderby";
     $query .= " ORDER BY $orderby";
-    my $result_set =
+    my $orders =
       $dbh->selectall_arrayref( $query, { Slice => {} }, $basketno );
       $dbh->selectall_arrayref( $query, { Slice => {} }, $basketno );
-    return @{$result_set};
+    return @{$orders};
 
 }
 
 #------------------------------------------------------------#
 
 }
 
 #------------------------------------------------------------#
+
 =head3 GetOrdersByBiblionumber
 
   @orders = &GetOrdersByBiblionumber($biblionumber);
 =head3 GetOrdersByBiblionumber
 
   @orders = &GetOrdersByBiblionumber($biblionumber);
@@ -1226,95 +1247,6 @@ sub GetLastOrderReceivedFromSubscriptionid {
 
 }
 
 
 }
 
-
-#------------------------------------------------------------#
-
-=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", "order_vendornote", "order_internalnote", "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
 #------------------------------------------------------------#
 
 =head3 ModOrder
@@ -1392,51 +1324,6 @@ sub ModItemOrder {
 
 #------------------------------------------------------------#
 
 
 #------------------------------------------------------------#
 
-=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({
 =head3 ModReceiveOrder
 
   &ModReceiveOrder({
@@ -1484,7 +1371,13 @@ sub ModReceiveOrder {
     my $order_vendornote = $params->{order_vendornote};
 
     my $dbh = C4::Context->dbh;
     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,
     my $suggestionid = GetSuggestionFromBiblionumber( $biblionumber );
     if ($suggestionid) {
         ModSuggestion( {suggestionid=>$suggestionid,
@@ -1494,7 +1387,7 @@ sub ModReceiveOrder {
     }
 
     my $result_set = $dbh->selectall_arrayref(
     }
 
     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
     );
 
         { Slice => {} }, $biblionumber, $ordernumber
     );
 
@@ -1502,7 +1395,7 @@ q{SELECT * FROM aqorders WHERE biblionumber=? AND aqorders.ordernumber=?},
     my $order = $result_set->[0];
 
     my $new_ordernumber = $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
         # 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
@@ -1517,7 +1410,7 @@ q{SELECT * FROM aqorders WHERE biblionumber=? AND aqorders.ordernumber=?},
         my $sth = $dbh->prepare($query);
 
         $sth->execute(
         my $sth = $dbh->prepare($query);
 
         $sth->execute(
-            $order->{quantity} - $quantrec,
+            ( $order->{is_standing} ? 1 : ( $order->{quantity} - $quantrec ) ),
             ( defined $order_internalnote ? $order_internalnote : () ),
             ( defined $order_vendornote ? $order_vendornote : () ),
             $ordernumber
             ( defined $order_internalnote ? $order_internalnote : () ),
             ( defined $order_vendornote ? $order_vendornote : () ),
             $ordernumber
@@ -1533,8 +1426,7 @@ q{SELECT * FROM aqorders WHERE biblionumber=? AND aqorders.ordernumber=?},
         $order->{'rrp'} = $rrp;
         $order->{ecost} = $ecost;
         $order->{'orderstatus'} = 'complete';
         $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) {
 
         if ($received_items) {
             foreach my $itemnumber (@$received_items) {
@@ -1557,12 +1449,16 @@ q{SELECT * FROM aqorders WHERE biblionumber=? AND aqorders.ordernumber=?},
             $cost,
             $rrp,
             $ecost,
             $cost,
             $rrp,
             $ecost,
-            $budget_id,
+            ( $budget_id ? $budget_id : $order->{budget_id} ),
             ( defined $order_internalnote ? $order_internalnote : () ),
             ( defined $order_vendornote ? $order_vendornote : () ),
             $biblionumber,
             $ordernumber
         );
             ( 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);
 }
     }
     return ($datereceived, $new_ordernumber);
 }
@@ -1603,6 +1499,8 @@ sub CancelReceipt {
 
     my $parent_ordernumber = $order->{'parent_ordernumber'};
 
 
     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{
     if($parent_ordernumber == $ordernumber || not $parent_ordernumber) {
         # The order line has no parent, just mark it as not received
         $query = qq{
@@ -1615,6 +1513,7 @@ sub CancelReceipt {
         };
         $sth = $dbh->prepare($query);
         $sth->execute(0, undef, undef, $ordernumber);
         };
         $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.
     } else {
         # The order line has a parent, increase parent quantity and delete
         # the order line.
@@ -1651,25 +1550,7 @@ sub CancelReceipt {
                 " receipt";
             return;
         }
                 " 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
         # Delete order line
         $query = qq{
             DELETE FROM aqorders
@@ -1680,9 +1561,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;
 }
 
     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
 #------------------------------------------------------------#
 
 =head3 SearchOrders
@@ -1723,6 +1648,8 @@ sub SearchOrders {
     my $owner = $params->{owner};
     my $pending = $params->{pending};
     my $ordered = $params->{ordered};
     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 = ();
 
     my $dbh = C4::Context->dbh;
     my @args = ();
@@ -1749,7 +1676,7 @@ sub SearchOrders {
             LEFT JOIN biblioitems ON biblioitems.biblionumber=biblio.biblionumber
     };
 
             LEFT JOIN biblioitems ON biblioitems.biblionumber=biblio.biblionumber
     };
 
-    # If we search on ordernumber, we retrieve the transfered order if a transfer has been done.
+    # 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{
             LEFT JOIN aqorders_transfers ON aqorders_transfers.ordernumber_to = aqorders.ordernumber
     } if $ordernumber;
@@ -1759,10 +1686,20 @@ sub SearchOrders {
     };
 
     if ( $pending or $ordered ) {
     };
 
     if ( $pending or $ordered ) {
-        $query .= q{ AND (quantity > quantityreceived OR quantityreceived is NULL)};
-    }
-    if ( $ordered ) {
-        $query .= q{ AND aqorders.orderstatus IN ( "ordered", "partial" )};
+        $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;
     }
 
     my $userenv = C4::Context->userenv;
@@ -1782,6 +1719,10 @@ sub SearchOrders {
         $query .= ' AND ( aqorders.ordernumber = ? OR aqorders_transfers.ordernumber_from = ? ) ';
         push @args, ( $ordernumber, $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 ?)';
         push @args, ("%$search%","%$search%","%$search%");
     if( $search ) {
         $query .= ' AND (biblio.title LIKE ? OR biblio.author LIKE ? OR biblioitems.isbn LIKE ?)';
         push @args, ("%$search%","%$search%","%$search%");
@@ -1812,6 +1753,11 @@ sub SearchOrders {
         push @args, $userenv->{'number'};
     }
 
         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);
     $query .= ' ORDER BY aqbasket.basketno';
 
     my $sth = $dbh->prepare($query);
@@ -1832,20 +1778,53 @@ cancelled.
 =cut
 
 sub DelOrder {
 =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'
     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);
     ";
     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){
     my @itemnumbers = GetItemnumbersFromOrder( $ordernumber );
     foreach my $itemnumber (@itemnumbers){
-        C4::Items::DelItem( $dbh, $bibnum, $itemnumber );
+        my $delcheck = C4::Items::DelItemCheck( $dbh, $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
 }
 
 =head3 TransferOrder
@@ -1853,11 +1832,11 @@ sub DelOrder {
     my $newordernumber = TransferOrder($ordernumber, $basketno);
 
 Transfer an order line to a basket.
     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
 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.
 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
 Return the ordernumber of created order.
 
 =cut
@@ -1877,17 +1856,17 @@ sub TransferOrder {
 
     $query = q{
         UPDATE aqorders
 
     $query = q{
         UPDATE aqorders
-        SET datecancellationprinted = CAST(NOW() AS date)
+        SET datecancellationprinted = CAST(NOW() AS date), orderstatus = ?
         WHERE ordernumber = ?
     };
     $sth = $dbh->prepare($query);
         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;
 
     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
 
     $query = q{
         UPDATE aqorders_items
@@ -1909,77 +1888,6 @@ sub TransferOrder {
 
 =head2 FUNCTIONS ABOUT PARCELS
 
 
 =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);
 =head3 GetParcels
 
   $results = &GetParcels($bookseller, $order, $code, $datefrom, $dateto);
@@ -2200,7 +2108,7 @@ sub GetLateOrders {
 
 =head3 GetHistory
 
 
 =head3 GetHistory
 
-  (\@order_loop, $total_qty, $total_price, $total_qtyreceived) = GetHistory( %params );
+  \@order_loop = GetHistory( %params );
 
 Retreives some acquisition history information
 
 
 Retreives some acquisition history information
 
@@ -2240,9 +2148,6 @@ returns:
                 'quantityreceived' => undef,
                 'title'            => 'The Adventures of Huckleberry Finn'
             }
                 '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
 
 
 =cut
 
@@ -2266,6 +2171,7 @@ sub GetHistory {
     my $get_canceled_order = $params{get_canceled_order} || 0;
     my $ordernumber = $params{ordernumber};
     my $search_children_too = $params{search_children_too} || 0;
     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;
 
     my @order_loop;
     my $total_qty         = 0;
@@ -2282,6 +2188,8 @@ sub GetHistory {
             aqorders.basketno,
             aqbasket.basketname,
             aqbasket.basketgroupid,
             aqorders.basketno,
             aqbasket.basketname,
             aqbasket.basketgroupid,
+            aqbasket.authorisedby,
+            concat( borrowers.firstname,' ',borrowers.surname) AS authorisedbyname,
             aqbasketgroups.name as groupname,
             aqbooksellers.name,
             aqbasket.creationdate,
             aqbasketgroups.name as groupname,
             aqbooksellers.name,
             aqbasket.creationdate,
@@ -2310,12 +2218,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 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')) {
     $query .= " WHERE 1 ";
 
     unless ($get_canceled_order or (defined $orderstatus and $orderstatus eq 'cancelled')) {
@@ -2403,6 +2308,11 @@ sub GetHistory {
         $query .= ") ";
     }
 
         $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() ) {
 
     if ( C4::Context->preference("IndependentBranches") ) {
         unless ( C4::Context->IsSuperLibrarian() ) {
@@ -2411,18 +2321,8 @@ sub GetHistory {
         }
     }
     $query .= " ORDER BY id";
         }
     }
     $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
 }
 
 =head2 GetRecentAcqui
@@ -2448,82 +2348,14 @@ sub GetRecentAcqui {
     return $results;
 }
 
     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
 
 =head3 AddClaim
 
-=over
-
-&AddClaim($ordernumber);
+  &AddClaim($ordernumber);
 
 Add a claim for an order
 
 
 Add a claim for an order
 
-=back
-
 =cut
 
 sub AddClaim {
 =cut
 
 sub AddClaim {
@@ -2656,6 +2488,10 @@ sub GetInvoices {
         push @bind_strs, " borrowers.branchcode = ? ";
         push @bind_args, $args{branchcode};
     }
         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 ";
 
     $query .= " WHERE " . join(" AND ", @bind_strs) if @bind_strs;
     $query .= " GROUP BY aqinvoices.invoiceid ";
@@ -2735,10 +2571,19 @@ sub GetInvoiceDetails {
     my $invoice = $sth->fetchrow_hashref;
 
     $query = q{
     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
         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 biblio ON aqorders.biblionumber = biblio.biblionumber
+          LEFT JOIN biblioitems ON aqorders.biblionumber = biblioitems.biblionumber
         WHERE invoiceid = ?
     };
     $sth = $dbh->prepare($query);
         WHERE invoiceid = ?
     };
     $sth = $dbh->prepare($query);
@@ -2771,7 +2616,7 @@ sub AddInvoice {
     return unless(%invoice and $invoice{invoicenumber});
 
     my @columns = qw(invoicenumber booksellerid shipmentdate billingdate
     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;
 
     my @set_strs;
     my @set_args;
@@ -2872,7 +2717,7 @@ sub CloseInvoice {
 
 Reopen an invoice
 
 
 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
 
 
 =cut
 
@@ -2974,6 +2819,222 @@ sub GetBiblioCountByBasketno {
     return $sth->fetchrow;
 }
 
     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__
 
 1;
 __END__