1 package C4
::Acquisition
;
3 # Copyright 2000-2002 Katipo Communications
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 2 of the License, or (at your option) any later
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License along
17 # with Koha; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 use C4
::Dates
qw(format_date format_date_in_iso);
31 use C4
::Bookseller
qw(GetBookSellerFromId);
32 use C4
::Templates
qw(gettemplate);
33 use Koha
::DateUtils
qw( dt_from_string output_pref );
34 use Koha
::Acquisition
::Order
;
39 use vars
qw($VERSION @ISA @EXPORT);
42 # set the version for version checking
43 $VERSION = 3.07.00.049;
47 &GetBasket &NewBasket &CloseBasket &ReopenBasket &DelBasket &ModBasket
48 &GetBasketAsCSV &GetBasketGroupAsCSV
49 &GetBasketsByBookseller &GetBasketsByBasketgroup
50 &GetBasketsInfosByBookseller
52 &GetBasketUsers &ModBasketUsers
57 &ModBasketgroup &NewBasketgroup &DelBasketgroup &GetBasketgroup &CloseBasketgroup
58 &GetBasketgroups &ReOpenBasketgroup
60 &DelOrder &ModOrder &GetOrder &GetOrders &GetOrdersByBiblionumber
61 &GetLateOrders &GetOrderFromItemnumber
62 &SearchOrders &GetHistory &GetRecentAcqui
63 &ModReceiveOrder &CancelReceipt
64 &GetCancelledOrders &TransferOrder
65 &GetLastOrderNotReceivedFromSubscriptionid &GetLastOrderReceivedFromSubscriptionid
68 &GetParcels &GetParcel
80 &GetItemnumbersFromOrder
83 &GetBiblioCountByBasketno
91 sub GetOrderFromItemnumber
{
92 my ($itemnumber) = @_;
93 my $dbh = C4
::Context
->dbh;
96 SELECT
* from aqorders LEFT JOIN aqorders_items
97 ON
( aqorders
.ordernumber
= aqorders_items
.ordernumber
)
98 WHERE itemnumber
= ?
|;
100 my $sth = $dbh->prepare($query);
104 $sth->execute($itemnumber);
106 my $order = $sth->fetchrow_hashref;
111 # Returns the itemnumber(s) associated with the ordernumber given in parameter
112 sub GetItemnumbersFromOrder
{
113 my ($ordernumber) = @_;
114 my $dbh = C4
::Context
->dbh;
115 my $query = "SELECT itemnumber FROM aqorders_items WHERE ordernumber=?";
116 my $sth = $dbh->prepare($query);
117 $sth->execute($ordernumber);
120 while (my $order = $sth->fetchrow_hashref) {
121 push @tab, $order->{'itemnumber'};
135 C4::Acquisition - Koha functions for dealing with orders and acquisitions
143 The functions in this module deal with acquisitions, managing book
144 orders, basket and parcels.
148 =head2 FUNCTIONS ABOUT BASKETS
152 $aqbasket = &GetBasket($basketnumber);
154 get all basket informations in aqbasket for a given basket
156 B<returns:> informations for a given basket returned as a hashref.
162 my $dbh = C4
::Context
->dbh;
165 concat( b.firstname,' ',b.surname) AS authorisedbyname
167 LEFT JOIN borrowers b ON aqbasket.authorisedby=b.borrowernumber
170 my $sth=$dbh->prepare($query);
171 $sth->execute($basketno);
172 my $basket = $sth->fetchrow_hashref;
176 #------------------------------------------------------------#
180 $basket = &NewBasket( $booksellerid, $authorizedby, $basketname,
181 $basketnote, $basketbooksellernote, $basketcontractnumber, $deliveryplace, $billingplace );
183 Create a new basket in aqbasket table
187 =item C<$booksellerid> is a foreign key in the aqbasket table
189 =item C<$authorizedby> is the username of who created the basket
193 The other parameters are optional, see ModBasketHeader for more info on them.
198 my ( $booksellerid, $authorisedby, $basketname, $basketnote,
199 $basketbooksellernote, $basketcontractnumber, $deliveryplace,
200 $billingplace ) = @_;
201 my $dbh = C4
::Context
->dbh;
203 'INSERT INTO aqbasket (creationdate,booksellerid,authorisedby) '
204 . 'VALUES (now(),?,?)';
205 $dbh->do( $query, {}, $booksellerid, $authorisedby );
207 my $basket = $dbh->{mysql_insertid
};
208 $basketname ||= q{}; # default to empty strings
210 $basketbooksellernote ||= q{};
211 ModBasketHeader
( $basket, $basketname, $basketnote, $basketbooksellernote,
212 $basketcontractnumber, $booksellerid, $deliveryplace, $billingplace );
216 #------------------------------------------------------------#
220 &CloseBasket($basketno);
222 close a basket (becomes unmodifiable, except for receives)
228 my $dbh = C4
::Context
->dbh;
234 my $sth = $dbh->prepare($query);
235 $sth->execute($basketno);
237 my @orders = GetOrders
($basketno);
238 foreach my $order (@orders) {
241 SET orderstatus
= 'ordered'
242 WHERE ordernumber
= ?
;
244 $sth = $dbh->prepare($query);
245 $sth->execute($order->{'ordernumber'});
251 &ReopenBasket($basketno);
259 my $dbh = C4
::Context
->dbh;
265 my $sth = $dbh->prepare($query);
266 $sth->execute($basketno);
268 my @orders = GetOrders
($basketno);
269 foreach my $order (@orders) {
272 SET orderstatus
= 'new'
273 WHERE ordernumber
= ?
;
275 $sth = $dbh->prepare($query);
276 $sth->execute($order->{'ordernumber'});
280 #------------------------------------------------------------#
282 =head3 GetBasketAsCSV
284 &GetBasketAsCSV($basketno);
286 Export a basket as CSV
288 $cgi parameter is needed for column name translation
293 my ($basketno, $cgi) = @_;
294 my $basket = GetBasket
($basketno);
295 my @orders = GetOrders
($basketno);
296 my $contract = GetContract
({
297 contractnumber
=> $basket->{'contractnumber'}
300 my $template = C4
::Templates
::gettemplate
("acqui/csv/basket.tt", "intranet", $cgi);
303 foreach my $order (@orders) {
304 my $bd = GetBiblioData
( $order->{'biblionumber'} );
306 contractname
=> $contract->{'contractname'},
307 ordernumber
=> $order->{'ordernumber'},
308 entrydate
=> $order->{'entrydate'},
309 isbn
=> $order->{'isbn'},
310 author
=> $bd->{'author'},
311 title
=> $bd->{'title'},
312 publicationyear
=> $bd->{'publicationyear'},
313 publishercode
=> $bd->{'publishercode'},
314 collectiontitle
=> $bd->{'collectiontitle'},
315 notes
=> $order->{'order_vendornote'},
316 quantity
=> $order->{'quantity'},
317 rrp
=> $order->{'rrp'},
318 deliveryplace
=> C4
::Branch
::GetBranchName
( $basket->{'deliveryplace'} ),
319 billingplace
=> C4
::Branch
::GetBranchName
( $basket->{'billingplace'} ),
322 contractname author title publishercode collectiontitle notes
323 deliveryplace billingplace
325 # Double the quotes to not be interpreted as a field end
326 $row->{$_} =~ s/"/""/g if $row->{$_};
332 if(defined $a->{publishercode
} and defined $b->{publishercode
}) {
333 $a->{publishercode
} cmp $b->{publishercode
};
337 $template->param(rows
=> \
@rows);
339 return $template->output;
343 =head3 GetBasketGroupAsCSV
347 &GetBasketGroupAsCSV($basketgroupid);
349 Export a basket group as CSV
351 $cgi parameter is needed for column name translation
357 sub GetBasketGroupAsCSV
{
358 my ($basketgroupid, $cgi) = @_;
359 my $baskets = GetBasketsByBasketgroup
($basketgroupid);
361 my $template = C4
::Templates
::gettemplate
('acqui/csv/basketgroup.tt', 'intranet', $cgi);
364 for my $basket (@
$baskets) {
365 my @orders = GetOrders
( $basket->{basketno
} );
366 my $contract = GetContract
({
367 contractnumber
=> $basket->{contractnumber
}
369 my $bookseller = GetBookSellerFromId
( $$basket{booksellerid
} );
370 my $basketgroup = GetBasketgroup
( $$basket{basketgroupid
} );
372 foreach my $order (@orders) {
373 my $bd = GetBiblioData
( $order->{'biblionumber'} );
375 clientnumber
=> $bookseller->{accountnumber
},
376 basketname
=> $basket->{basketname
},
377 ordernumber
=> $order->{ordernumber
},
378 author
=> $bd->{author
},
379 title
=> $bd->{title
},
380 publishercode
=> $bd->{publishercode
},
381 publicationyear
=> $bd->{publicationyear
},
382 collectiontitle
=> $bd->{collectiontitle
},
383 isbn
=> $order->{isbn
},
384 quantity
=> $order->{quantity
},
385 rrp
=> $order->{rrp
},
386 discount
=> $bookseller->{discount
},
387 ecost
=> $order->{ecost
},
388 notes
=> $order->{order_vendornote
},
389 entrydate
=> $order->{entrydate
},
390 booksellername
=> $bookseller->{name
},
391 bookselleraddress
=> $bookseller->{address1
},
392 booksellerpostal
=> $bookseller->{postal
},
393 contractnumber
=> $contract->{contractnumber
},
394 contractname
=> $contract->{contractname
},
395 basketgroupdeliveryplace
=> C4
::Branch
::GetBranchName
( $basketgroup->{deliveryplace
} ),
396 basketgroupbillingplace
=> C4
::Branch
::GetBranchName
( $basketgroup->{billingplace
} ),
397 basketdeliveryplace
=> C4
::Branch
::GetBranchName
( $basket->{deliveryplace
} ),
398 basketbillingplace
=> C4
::Branch
::GetBranchName
( $basket->{billingplace
} ),
401 basketname author title publishercode collectiontitle notes
402 booksellername bookselleraddress booksellerpostal contractname
403 basketgroupdeliveryplace basketgroupbillingplace
404 basketdeliveryplace basketbillingplace
406 # Double the quotes to not be interpreted as a field end
407 $row->{$_} =~ s/"/""/g if $row->{$_};
412 $template->param(rows
=> \
@rows);
414 return $template->output;
418 =head3 CloseBasketgroup
420 &CloseBasketgroup($basketgroupno);
426 sub CloseBasketgroup
{
427 my ($basketgroupno) = @_;
428 my $dbh = C4
::Context
->dbh;
429 my $sth = $dbh->prepare("
430 UPDATE aqbasketgroups
434 $sth->execute($basketgroupno);
437 #------------------------------------------------------------#
439 =head3 ReOpenBaskergroup($basketgroupno)
441 &ReOpenBaskergroup($basketgroupno);
447 sub ReOpenBasketgroup
{
448 my ($basketgroupno) = @_;
449 my $dbh = C4
::Context
->dbh;
450 my $sth = $dbh->prepare("
451 UPDATE aqbasketgroups
455 $sth->execute($basketgroupno);
458 #------------------------------------------------------------#
463 &DelBasket($basketno);
465 Deletes the basket that has basketno field $basketno in the aqbasket table.
469 =item C<$basketno> is the primary key of the basket in the aqbasket table.
476 my ( $basketno ) = @_;
477 my $query = "DELETE FROM aqbasket WHERE basketno=?";
478 my $dbh = C4
::Context
->dbh;
479 my $sth = $dbh->prepare($query);
480 $sth->execute($basketno);
484 #------------------------------------------------------------#
488 &ModBasket($basketinfo);
490 Modifies a basket, using a hashref $basketinfo for the relevant information, only $basketinfo->{'basketno'} is required.
494 =item C<$basketno> is the primary key of the basket in the aqbasket table.
501 my $basketinfo = shift;
502 my $query = "UPDATE aqbasket SET ";
504 foreach my $key (keys %$basketinfo){
505 if ($key ne 'basketno'){
506 $query .= "$key=?, ";
507 push(@params, $basketinfo->{$key} || undef );
510 # get rid of the "," at the end of $query
511 if (substr($query, length($query)-2) eq ', '){
516 $query .= "WHERE basketno=?";
517 push(@params, $basketinfo->{'basketno'});
518 my $dbh = C4
::Context
->dbh;
519 my $sth = $dbh->prepare($query);
520 $sth->execute(@params);
525 #------------------------------------------------------------#
527 =head3 ModBasketHeader
529 &ModBasketHeader($basketno, $basketname, $note, $booksellernote, $contractnumber, $booksellerid);
531 Modifies a basket's header.
535 =item C<$basketno> is the "basketno" field in the "aqbasket" table;
537 =item C<$basketname> is the "basketname" field in the "aqbasket" table;
539 =item C<$note> is the "note" field in the "aqbasket" table;
541 =item C<$booksellernote> is the "booksellernote" field in the "aqbasket" table;
543 =item C<$contractnumber> is the "contractnumber" (foreign) key in the "aqbasket" table.
545 =item C<$booksellerid> is the id (foreign) key in the "aqbooksellers" table for the vendor.
547 =item C<$deliveryplace> is the "deliveryplace" field in the aqbasket table.
549 =item C<$billingplace> is the "billingplace" field in the aqbasket table.
555 sub ModBasketHeader
{
556 my ($basketno, $basketname, $note, $booksellernote, $contractnumber, $booksellerid, $deliveryplace, $billingplace) = @_;
559 SET basketname
=?
, note
=?
, booksellernote
=?
, booksellerid
=?
, deliveryplace
=?
, billingplace
=?
563 my $dbh = C4
::Context
->dbh;
564 my $sth = $dbh->prepare($query);
565 $sth->execute($basketname, $note, $booksellernote, $booksellerid, $deliveryplace, $billingplace, $basketno);
567 if ( $contractnumber ) {
568 my $query2 ="UPDATE aqbasket SET contractnumber=? WHERE basketno=?";
569 my $sth2 = $dbh->prepare($query2);
570 $sth2->execute($contractnumber,$basketno);
575 #------------------------------------------------------------#
577 =head3 GetBasketsByBookseller
579 @results = &GetBasketsByBookseller($booksellerid, $extra);
581 Returns a list of hashes of all the baskets that belong to bookseller 'booksellerid'.
585 =item C<$booksellerid> is the 'id' field of the bookseller in the aqbooksellers table
587 =item C<$extra> is the extra sql parameters, can be
589 $extra->{groupby}: group baskets by column
590 ex. $extra->{groupby} = aqbasket.basketgroupid
591 $extra->{orderby}: order baskets by column
592 $extra->{limit}: limit number of results (can be helpful for pagination)
598 sub GetBasketsByBookseller
{
599 my ($booksellerid, $extra) = @_;
600 my $query = "SELECT * FROM aqbasket WHERE booksellerid=?";
602 if ($extra->{groupby
}) {
603 $query .= " GROUP by $extra->{groupby}";
605 if ($extra->{orderby
}){
606 $query .= " ORDER by $extra->{orderby}";
608 if ($extra->{limit
}){
609 $query .= " LIMIT $extra->{limit}";
612 my $dbh = C4
::Context
->dbh;
613 my $sth = $dbh->prepare($query);
614 $sth->execute($booksellerid);
615 return $sth->fetchall_arrayref({});
618 =head3 GetBasketsInfosByBookseller
620 my $baskets = GetBasketsInfosByBookseller($supplierid, $allbaskets);
622 The optional second parameter allbaskets is a boolean allowing you to
623 select all baskets from the supplier; by default only active baskets (open or
624 closed but still something to receive) are returned.
626 Returns in a arrayref of hashref all about booksellers baskets, plus:
627 total_biblios: Number of distinct biblios in basket
628 total_items: Number of items in basket
629 expected_items: Number of non-received items in basket
633 sub GetBasketsInfosByBookseller
{
634 my ($supplierid, $allbaskets) = @_;
636 return unless $supplierid;
638 my $dbh = C4
::Context
->dbh;
641 SUM(aqorders.quantity) AS total_items,
643 IF ( aqorders.orderstatus = 'cancelled', aqorders.quantity, 0 )
644 ) AS total_items_cancelled,
645 COUNT(DISTINCT aqorders.biblionumber) AS total_biblios,
647 IF(aqorders.datereceived IS NULL
648 AND aqorders.datecancellationprinted IS NULL
653 LEFT JOIN aqorders ON aqorders.basketno = aqbasket.basketno
654 WHERE booksellerid = ?};
656 unless ( $allbaskets ) {
657 $query.=" AND (closedate IS NULL OR (aqorders.quantity > aqorders.quantityreceived AND datecancellationprinted IS NULL))";
659 $query.=" GROUP BY aqbasket.basketno";
661 my $sth = $dbh->prepare($query);
662 $sth->execute($supplierid);
663 my $baskets = $sth->fetchall_arrayref({});
665 # Retrieve the number of biblios cancelled
666 my $cancelled_biblios = $dbh->selectall_hashref( q
|
667 SELECT COUNT
(DISTINCT
(biblionumber
)) AS total_biblios_cancelled
, aqbasket
.basketno
669 LEFT JOIN aqorders ON aqorders
.basketno
= aqbasket
.basketno
670 WHERE booksellerid
= ?
671 AND aqorders
.orderstatus
= 'cancelled'
672 GROUP BY aqbasket
.basketno
673 |, 'basketno', {}, $supplierid );
675 $_->{total_biblios_cancelled
} = $cancelled_biblios->{$_->{basketno
}}{total_biblios_cancelled
} || 0
681 =head3 GetBasketUsers
683 $basketusers_ids = &GetBasketUsers($basketno);
685 Returns a list of all borrowernumbers that are in basket users list
690 my $basketno = shift;
692 return unless $basketno;
695 SELECT borrowernumber
699 my $dbh = C4
::Context
->dbh;
700 my $sth = $dbh->prepare($query);
701 $sth->execute($basketno);
702 my $results = $sth->fetchall_arrayref( {} );
705 foreach (@
$results) {
706 push @borrowernumbers, $_->{'borrowernumber'};
709 return @borrowernumbers;
712 =head3 ModBasketUsers
714 my @basketusers_ids = (1, 2, 3);
715 &ModBasketUsers($basketno, @basketusers_ids);
717 Delete all users from basket users list, and add users in C<@basketusers_ids>
723 my ($basketno, @basketusers_ids) = @_;
725 return unless $basketno;
727 my $dbh = C4
::Context
->dbh;
729 DELETE FROM aqbasketusers
732 my $sth = $dbh->prepare($query);
733 $sth->execute($basketno);
736 INSERT INTO aqbasketusers
(basketno
, borrowernumber
)
739 $sth = $dbh->prepare($query);
740 foreach my $basketuser_id (@basketusers_ids) {
741 $sth->execute($basketno, $basketuser_id);
746 =head3 CanUserManageBasket
748 my $bool = CanUserManageBasket($borrower, $basket[, $userflags]);
749 my $bool = CanUserManageBasket($borrowernumber, $basketno[, $userflags]);
751 Check if a borrower can manage a basket, according to system preference
752 AcqViewBaskets, user permissions and basket properties (creator, users list,
755 First parameter can be either a borrowernumber or a hashref as returned by
756 C4::Members::GetMember.
758 Second parameter can be either a basketno or a hashref as returned by
759 C4::Acquisition::GetBasket.
761 The third parameter is optional. If given, it should be a hashref as returned
762 by C4::Auth::getuserflags. If not, getuserflags is called.
764 If user is authorised to manage basket, returns 1.
769 sub CanUserManageBasket
{
770 my ($borrower, $basket, $userflags) = @_;
772 if (!ref $borrower) {
773 $borrower = C4
::Members
::GetMember
(borrowernumber
=> $borrower);
776 $basket = GetBasket
($basket);
779 return 0 unless ($basket and $borrower);
781 my $borrowernumber = $borrower->{borrowernumber
};
782 my $basketno = $basket->{basketno
};
784 my $AcqViewBaskets = C4
::Context
->preference('AcqViewBaskets');
786 if (!defined $userflags) {
787 my $dbh = C4
::Context
->dbh;
788 my $sth = $dbh->prepare("SELECT flags FROM borrowers WHERE borrowernumber = ?");
789 $sth->execute($borrowernumber);
790 my ($flags) = $sth->fetchrow_array;
793 $userflags = C4
::Auth
::getuserflags
($flags, $borrower->{userid
}, $dbh);
796 unless ($userflags->{superlibrarian
}
797 || (ref $userflags->{acquisition
} && $userflags->{acquisition
}->{order_manage_all
})
798 || (!ref $userflags->{acquisition
} && $userflags->{acquisition
}))
800 if (not exists $userflags->{acquisition
}) {
804 if ( (ref $userflags->{acquisition
} && !$userflags->{acquisition
}->{order_manage
})
805 || (!ref $userflags->{acquisition
} && !$userflags->{acquisition
}) ) {
809 if ($AcqViewBaskets eq 'user'
810 && $basket->{authorisedby
} != $borrowernumber
811 && grep($borrowernumber, GetBasketUsers
($basketno)) == 0) {
815 if ($AcqViewBaskets eq 'branch' && defined $basket->{branch
}
816 && $basket->{branch
} ne $borrower->{branchcode
}) {
824 #------------------------------------------------------------#
826 =head3 GetBasketsByBasketgroup
828 $baskets = &GetBasketsByBasketgroup($basketgroupid);
830 Returns a reference to all baskets that belong to basketgroup $basketgroupid.
834 sub GetBasketsByBasketgroup
{
835 my $basketgroupid = shift;
837 SELECT
*, aqbasket
.booksellerid as booksellerid
839 LEFT JOIN aqcontract USING
(contractnumber
) WHERE basketgroupid
=?
841 my $dbh = C4
::Context
->dbh;
842 my $sth = $dbh->prepare($query);
843 $sth->execute($basketgroupid);
844 return $sth->fetchall_arrayref({});
847 #------------------------------------------------------------#
849 =head3 NewBasketgroup
851 $basketgroupid = NewBasketgroup(\%hashref);
853 Adds a basketgroup to the aqbasketgroups table, and add the initial baskets to it.
855 $hashref->{'booksellerid'} is the 'id' field of the bookseller in the aqbooksellers table,
857 $hashref->{'name'} is the 'name' field of the basketgroup in the aqbasketgroups table,
859 $hashref->{'basketlist'} is a list reference of the 'id's of the baskets that belong to this group,
861 $hashref->{'billingplace'} is the 'billingplace' field of the basketgroup in the aqbasketgroups table,
863 $hashref->{'deliveryplace'} is the 'deliveryplace' field of the basketgroup in the aqbasketgroups table,
865 $hashref->{'freedeliveryplace'} is the 'freedeliveryplace' field of the basketgroup in the aqbasketgroups table,
867 $hashref->{'deliverycomment'} is the 'deliverycomment' field of the basketgroup in the aqbasketgroups table,
869 $hashref->{'closed'} is the 'closed' field of the aqbasketgroups table, it is false if 0, true otherwise.
874 my $basketgroupinfo = shift;
875 die "booksellerid is required to create a basketgroup" unless $basketgroupinfo->{'booksellerid'};
876 my $query = "INSERT INTO aqbasketgroups (";
878 foreach my $field (qw(name billingplace deliveryplace freedeliveryplace deliverycomment closed)) {
879 if ( defined $basketgroupinfo->{$field} ) {
880 $query .= "$field, ";
881 push(@params, $basketgroupinfo->{$field});
884 $query .= "booksellerid) VALUES (";
889 push(@params, $basketgroupinfo->{'booksellerid'});
890 my $dbh = C4
::Context
->dbh;
891 my $sth = $dbh->prepare($query);
892 $sth->execute(@params);
893 my $basketgroupid = $dbh->{'mysql_insertid'};
894 if( $basketgroupinfo->{'basketlist'} ) {
895 foreach my $basketno (@
{$basketgroupinfo->{'basketlist'}}) {
896 my $query2 = "UPDATE aqbasket SET basketgroupid=? WHERE basketno=?";
897 my $sth2 = $dbh->prepare($query2);
898 $sth2->execute($basketgroupid, $basketno);
901 return $basketgroupid;
904 #------------------------------------------------------------#
906 =head3 ModBasketgroup
908 ModBasketgroup(\%hashref);
910 Modifies a basketgroup in the aqbasketgroups table, and add the baskets to it.
912 $hashref->{'id'} is the 'id' field of the basketgroup in the aqbasketgroup table, this parameter is mandatory,
914 $hashref->{'name'} is the 'name' field of the basketgroup in the aqbasketgroups table,
916 $hashref->{'basketlist'} is a list reference of the 'id's of the baskets that belong to this group,
918 $hashref->{'billingplace'} is the 'billingplace' field of the basketgroup in the aqbasketgroups table,
920 $hashref->{'deliveryplace'} is the 'deliveryplace' field of the basketgroup in the aqbasketgroups table,
922 $hashref->{'freedeliveryplace'} is the 'freedeliveryplace' field of the basketgroup in the aqbasketgroups table,
924 $hashref->{'deliverycomment'} is the 'deliverycomment' field of the basketgroup in the aqbasketgroups table,
926 $hashref->{'closed'} is the 'closed' field of the aqbasketgroups table, it is false if 0, true otherwise.
931 my $basketgroupinfo = shift;
932 die "basketgroup id is required to edit a basketgroup" unless $basketgroupinfo->{'id'};
933 my $dbh = C4
::Context
->dbh;
934 my $query = "UPDATE aqbasketgroups SET ";
936 foreach my $field (qw(name billingplace deliveryplace freedeliveryplace deliverycomment closed)) {
937 if ( defined $basketgroupinfo->{$field} ) {
938 $query .= "$field=?, ";
939 push(@params, $basketgroupinfo->{$field});
944 $query .= " WHERE id=?";
945 push(@params, $basketgroupinfo->{'id'});
946 my $sth = $dbh->prepare($query);
947 $sth->execute(@params);
949 $sth = $dbh->prepare('UPDATE aqbasket SET basketgroupid = NULL WHERE basketgroupid = ?');
950 $sth->execute($basketgroupinfo->{'id'});
952 if($basketgroupinfo->{'basketlist'} && @
{$basketgroupinfo->{'basketlist'}}){
953 $sth = $dbh->prepare("UPDATE aqbasket SET basketgroupid=? WHERE basketno=?");
954 foreach my $basketno (@
{$basketgroupinfo->{'basketlist'}}) {
955 $sth->execute($basketgroupinfo->{'id'}, $basketno);
961 #------------------------------------------------------------#
963 =head3 DelBasketgroup
965 DelBasketgroup($basketgroupid);
967 Deletes a basketgroup in the aqbasketgroups table, and removes the reference to it from the baskets,
971 =item C<$basketgroupid> is the 'id' field of the basket in the aqbasketgroup table
978 my $basketgroupid = shift;
979 die "basketgroup id is required to edit a basketgroup" unless $basketgroupid;
980 my $query = "DELETE FROM aqbasketgroups WHERE id=?";
981 my $dbh = C4
::Context
->dbh;
982 my $sth = $dbh->prepare($query);
983 $sth->execute($basketgroupid);
987 #------------------------------------------------------------#
990 =head2 FUNCTIONS ABOUT ORDERS
992 =head3 GetBasketgroup
994 $basketgroup = &GetBasketgroup($basketgroupid);
996 Returns a reference to the hash containing all information about the basketgroup.
1000 sub GetBasketgroup
{
1001 my $basketgroupid = shift;
1002 die "basketgroup id is required to edit a basketgroup" unless $basketgroupid;
1003 my $dbh = C4
::Context
->dbh;
1004 my $result_set = $dbh->selectall_arrayref(
1005 'SELECT * FROM aqbasketgroups WHERE id=?',
1009 return $result_set->[0]; # id is unique
1012 #------------------------------------------------------------#
1014 =head3 GetBasketgroups
1016 $basketgroups = &GetBasketgroups($booksellerid);
1018 Returns a reference to the array of all the basketgroups of bookseller $booksellerid.
1022 sub GetBasketgroups
{
1023 my $booksellerid = shift;
1024 die 'bookseller id is required to edit a basketgroup' unless $booksellerid;
1025 my $query = 'SELECT * FROM aqbasketgroups WHERE booksellerid=? ORDER BY id DESC';
1026 my $dbh = C4
::Context
->dbh;
1027 my $sth = $dbh->prepare($query);
1028 $sth->execute($booksellerid);
1029 return $sth->fetchall_arrayref({});
1032 #------------------------------------------------------------#
1034 =head2 FUNCTIONS ABOUT ORDERS
1038 @orders = &GetOrders($basketnumber, $orderby);
1040 Looks up the pending (non-cancelled) orders with the given basket
1041 number. If C<$booksellerID> is non-empty, only orders from that seller
1045 C<&basket> returns a two-element array. C<@orders> is an array of
1046 references-to-hash, whose keys are the fields from the aqorders,
1047 biblio, and biblioitems tables in the Koha database.
1052 my ( $basketno, $orderby ) = @_;
1053 return () unless $basketno;
1054 my $dbh = C4
::Context
->dbh;
1056 SELECT biblio.*,biblioitems.*,
1059 aqorders_transfers.ordernumber_from AS transferred_from,
1060 aqorders_transfers.timestamp AS transferred_from_timestamp
1062 LEFT JOIN aqbudgets ON aqbudgets.budget_id = aqorders.budget_id
1063 LEFT JOIN biblio ON biblio.biblionumber = aqorders.biblionumber
1064 LEFT JOIN biblioitems ON biblioitems.biblionumber =biblio.biblionumber
1065 LEFT JOIN aqorders_transfers ON aqorders_transfers.ordernumber_to = aqorders.ordernumber
1067 AND (datecancellationprinted IS NULL OR datecancellationprinted='0000-00-00')
1070 $orderby = "biblioitems.publishercode,biblio.title" unless $orderby;
1071 $query .= " ORDER BY $orderby";
1073 $dbh->selectall_arrayref( $query, { Slice
=> {} }, $basketno );
1074 return @
{$result_set};
1078 #------------------------------------------------------------#
1079 =head3 GetOrdersByBiblionumber
1081 @orders = &GetOrdersByBiblionumber($biblionumber);
1083 Looks up the orders with linked to a specific $biblionumber, including
1084 cancelled orders and received orders.
1087 C<@orders> is an array of references-to-hash, whose keys are the
1088 fields from the aqorders, biblio, and biblioitems tables in the Koha database.
1092 sub GetOrdersByBiblionumber
{
1093 my $biblionumber = shift;
1094 return unless $biblionumber;
1095 my $dbh = C4
::Context
->dbh;
1097 SELECT biblio.*,biblioitems.*,
1101 LEFT JOIN aqbudgets ON aqbudgets.budget_id = aqorders.budget_id
1102 LEFT JOIN biblio ON biblio.biblionumber = aqorders.biblionumber
1103 LEFT JOIN biblioitems ON biblioitems.biblionumber =biblio.biblionumber
1104 WHERE aqorders.biblionumber=?
1107 $dbh->selectall_arrayref( $query, { Slice
=> {} }, $biblionumber );
1108 return @
{$result_set};
1112 #------------------------------------------------------------#
1116 $order = &GetOrder($ordernumber);
1118 Looks up an order by order number.
1120 Returns a reference-to-hash describing the order. The keys of
1121 C<$order> are fields from the biblio, biblioitems, aqorders tables of the Koha database.
1126 my ($ordernumber) = @_;
1127 return unless $ordernumber;
1129 my $dbh = C4
::Context
->dbh;
1130 my $query = qq{SELECT
1134 aqbasket
.basketname
,
1135 borrowers
.branchcode
,
1136 biblioitems
.publicationyear
,
1137 biblio
.copyrightdate
,
1138 biblioitems
.editionstatement
,
1142 biblioitems
.publishercode
,
1143 aqorders
.rrp AS unitpricesupplier
,
1144 aqorders
.ecost AS unitpricelib
,
1145 aqorders
.claims_count AS claims_count
,
1146 aqorders
.claimed_date AS claimed_date
,
1147 aqbudgets
.budget_name AS budget
,
1148 aqbooksellers
.name AS supplier
,
1149 aqbooksellers
.id AS supplierid
,
1150 biblioitems
.publishercode AS publisher
,
1151 ADDDATE
(aqbasket
.closedate
, INTERVAL aqbooksellers
.deliverytime DAY
) AS estimateddeliverydate
,
1152 DATE
(aqbasket
.closedate
) AS orderdate
,
1153 aqorders
.quantity
- COALESCE
(aqorders
.quantityreceived
,0) AS quantity_to_receive
,
1154 (aqorders
.quantity
- COALESCE
(aqorders
.quantityreceived
,0)) * aqorders
.rrp AS subtotal
,
1155 DATEDIFF
(CURDATE
( ),closedate
) AS latesince
1156 FROM aqorders LEFT JOIN biblio ON biblio
.biblionumber
= aqorders
.biblionumber
1157 LEFT JOIN biblioitems ON biblioitems
.biblionumber
= biblio
.biblionumber
1158 LEFT JOIN aqbudgets ON aqorders
.budget_id
= aqbudgets
.budget_id
,
1159 aqbasket LEFT JOIN borrowers ON aqbasket
.authorisedby
= borrowers
.borrowernumber
1160 LEFT JOIN aqbooksellers ON aqbasket
.booksellerid
= aqbooksellers
.id
1161 WHERE aqorders
.basketno
= aqbasket
.basketno
1164 $dbh->selectall_arrayref( $query, { Slice
=> {} }, $ordernumber );
1166 # result_set assumed to contain 1 match
1167 return $result_set->[0];
1170 =head3 GetLastOrderNotReceivedFromSubscriptionid
1172 $order = &GetLastOrderNotReceivedFromSubscriptionid($subscriptionid);
1174 Returns a reference-to-hash describing the last order not received for a subscription.
1178 sub GetLastOrderNotReceivedFromSubscriptionid
{
1179 my ( $subscriptionid ) = @_;
1180 my $dbh = C4
::Context
->dbh;
1182 SELECT
* FROM aqorders
1183 LEFT JOIN subscription
1184 ON
( aqorders
.subscriptionid
= subscription
.subscriptionid
)
1185 WHERE aqorders
.subscriptionid
= ?
1186 AND aqorders
.datereceived IS NULL
1190 $dbh->selectall_arrayref( $query, { Slice
=> {} }, $subscriptionid );
1192 # result_set assumed to contain 1 match
1193 return $result_set->[0];
1196 =head3 GetLastOrderReceivedFromSubscriptionid
1198 $order = &GetLastOrderReceivedFromSubscriptionid($subscriptionid);
1200 Returns a reference-to-hash describing the last order received for a subscription.
1204 sub GetLastOrderReceivedFromSubscriptionid
{
1205 my ( $subscriptionid ) = @_;
1206 my $dbh = C4
::Context
->dbh;
1208 SELECT
* FROM aqorders
1209 LEFT JOIN subscription
1210 ON
( aqorders
.subscriptionid
= subscription
.subscriptionid
)
1211 WHERE aqorders
.subscriptionid
= ?
1212 AND aqorders
.datereceived
=
1214 SELECT MAX
( aqorders
.datereceived
)
1216 LEFT JOIN subscription
1217 ON
( aqorders
.subscriptionid
= subscription
.subscriptionid
)
1218 WHERE aqorders
.subscriptionid
= ?
1219 AND aqorders
.datereceived IS NOT NULL
1221 ORDER BY ordernumber DESC
1225 $dbh->selectall_arrayref( $query, { Slice
=> {} }, $subscriptionid, $subscriptionid );
1227 # result_set assumed to contain 1 match
1228 return $result_set->[0];
1232 #------------------------------------------------------------#
1236 &ModOrder(\%hashref);
1238 Modifies an existing order. Updates the order with order number
1239 $hashref->{'ordernumber'} and biblionumber $hashref->{'biblionumber'}. All
1240 other keys of the hash update the fields with the same name in the aqorders
1241 table of the Koha database.
1246 my $orderinfo = shift;
1248 die "Ordernumber is required" if $orderinfo->{'ordernumber'} eq '' ;
1249 die "Biblionumber is required" if $orderinfo->{'biblionumber'} eq '';
1251 my $dbh = C4
::Context
->dbh;
1254 # update uncertainprice to an integer, just in case (under FF, checked boxes have the value "ON" by default)
1255 $orderinfo->{uncertainprice
}=1 if $orderinfo->{uncertainprice
};
1257 # delete($orderinfo->{'branchcode'});
1258 # the hash contains a lot of entries not in aqorders, so get the columns ...
1259 my $sth = $dbh->prepare("SELECT * FROM aqorders LIMIT 1;");
1261 my $colnames = $sth->{NAME
};
1262 #FIXME Be careful. If aqorders would have columns with diacritics,
1263 #you should need to decode what you get back from NAME.
1264 #See report 10110 and guided_reports.pl
1265 my $query = "UPDATE aqorders SET ";
1267 foreach my $orderinfokey (grep(!/ordernumber/, keys %$orderinfo)){
1268 # ... and skip hash entries that are not in the aqorders table
1269 # FIXME : probably not the best way to do it (would be better to have a correct hash)
1270 next unless grep(/^$orderinfokey$/, @
$colnames);
1271 $query .= "$orderinfokey=?, ";
1272 push(@params, $orderinfo->{$orderinfokey});
1275 $query .= "timestamp=NOW() WHERE ordernumber=?";
1276 push(@params, $orderinfo->{'ordernumber'} );
1277 $sth = $dbh->prepare($query);
1278 $sth->execute(@params);
1282 #------------------------------------------------------------#
1286 ModItemOrder($itemnumber, $ordernumber);
1288 Modifies the ordernumber of an item in aqorders_items.
1293 my ($itemnumber, $ordernumber) = @_;
1295 return unless ($itemnumber and $ordernumber);
1297 my $dbh = C4
::Context
->dbh;
1299 UPDATE aqorders_items
1301 WHERE itemnumber
= ?
1303 my $sth = $dbh->prepare($query);
1304 return $sth->execute($ordernumber, $itemnumber);
1307 #------------------------------------------------------------#
1309 =head3 GetCancelledOrders
1311 my @orders = GetCancelledOrders($basketno, $orderby);
1313 Returns cancelled orders for a basket
1317 sub GetCancelledOrders
{
1318 my ( $basketno, $orderby ) = @_;
1320 return () unless $basketno;
1322 my $dbh = C4
::Context
->dbh;
1329 aqorders_transfers.ordernumber_to AS transferred_to,
1330 aqorders_transfers.timestamp AS transferred_to_timestamp
1332 LEFT JOIN aqbudgets ON aqbudgets.budget_id = aqorders.budget_id
1333 LEFT JOIN biblio ON biblio.biblionumber = aqorders.biblionumber
1334 LEFT JOIN biblioitems ON biblioitems.biblionumber = biblio.biblionumber
1335 LEFT JOIN aqorders_transfers ON aqorders_transfers.ordernumber_from = aqorders.ordernumber
1337 AND (datecancellationprinted IS NOT NULL
1338 AND datecancellationprinted <> '0000-00-00')
1341 $orderby = "aqorders.datecancellationprinted desc, aqorders.timestamp desc"
1343 $query .= " ORDER BY $orderby";
1344 my $sth = $dbh->prepare($query);
1345 $sth->execute($basketno);
1346 my $results = $sth->fetchall_arrayref( {} );
1352 #------------------------------------------------------------#
1354 =head3 ModReceiveOrder
1357 biblionumber => $biblionumber,
1358 ordernumber => $ordernumber,
1359 quantityreceived => $quantityreceived,
1363 invoiceid => $invoiceid,
1365 budget_id => $budget_id,
1366 datereceived => $datereceived,
1367 received_itemnumbers => \@received_itemnumbers,
1368 order_internalnote => $order_internalnote,
1369 order_vendornote => $order_vendornote,
1372 Updates an order, to reflect the fact that it was received, at least
1373 in part. All arguments not mentioned below update the fields with the
1374 same name in the aqorders table of the Koha database.
1376 If a partial order is received, splits the order into two.
1378 Updates the order with bibilionumber C<$biblionumber> and ordernumber
1384 sub ModReceiveOrder
{
1385 my ( $params ) = @_;
1386 my $biblionumber = $params->{biblionumber
};
1387 my $ordernumber = $params->{ordernumber
};
1388 my $quantrec = $params->{quantityreceived
};
1389 my $user = $params->{user
};
1390 my $cost = $params->{cost
};
1391 my $ecost = $params->{ecost
};
1392 my $invoiceid = $params->{invoiceid
};
1393 my $rrp = $params->{rrp
};
1394 my $budget_id = $params->{budget_id
};
1395 my $datereceived = $params->{datereceived
};
1396 my $received_items = $params->{received_items
};
1397 my $order_internalnote = $params->{order_internalnote
};
1398 my $order_vendornote = $params->{order_vendornote
};
1400 my $dbh = C4
::Context
->dbh;
1401 $datereceived = C4
::Dates
->output('iso') unless $datereceived;
1402 my $suggestionid = GetSuggestionFromBiblionumber
( $biblionumber );
1403 if ($suggestionid) {
1404 ModSuggestion
( {suggestionid
=>$suggestionid,
1405 STATUS
=>'AVAILABLE',
1406 biblionumber
=> $biblionumber}
1410 my $result_set = $dbh->selectall_arrayref(
1411 q{SELECT * FROM aqorders WHERE biblionumber=? AND aqorders.ordernumber=?},
1412 { Slice
=> {} }, $biblionumber, $ordernumber
1415 # we assume we have a unique order
1416 my $order = $result_set->[0];
1418 my $new_ordernumber = $ordernumber;
1419 if ( $order->{quantity
} > $quantrec ) {
1420 # Split order line in two parts: the first is the original order line
1421 # without received items (the quantity is decreased),
1422 # the second part is a new order line with quantity=quantityrec
1423 # (entirely received)
1427 orderstatus
= 'partial'|;
1428 $query .= q
|, order_internalnote
= ?
| if defined $order_internalnote;
1429 $query .= q
|, order_vendornote
= ?
| if defined $order_vendornote;
1430 $query .= q
| WHERE ordernumber
= ?
|;
1431 my $sth = $dbh->prepare($query);
1434 $order->{quantity
} - $quantrec,
1435 ( defined $order_internalnote ?
$order_internalnote : () ),
1436 ( defined $order_vendornote ?
$order_vendornote : () ),
1440 delete $order->{'ordernumber'};
1441 $order->{'budget_id'} = ( $budget_id || $order->{'budget_id'} );
1442 $order->{'quantity'} = $quantrec;
1443 $order->{'quantityreceived'} = $quantrec;
1444 $order->{'datereceived'} = $datereceived;
1445 $order->{'invoiceid'} = $invoiceid;
1446 $order->{'unitprice'} = $cost;
1447 $order->{'rrp'} = $rrp;
1448 $order->{ecost
} = $ecost;
1449 $order->{'orderstatus'} = 'complete';
1450 $new_ordernumber = Koha
::Acquisition
::Order
->new($order)->insert->{ordernumber
};
1452 if ($received_items) {
1453 foreach my $itemnumber (@
$received_items) {
1454 ModItemOrder
($itemnumber, $new_ordernumber);
1460 set quantityreceived
=?
,datereceived
=?
,invoiceid
=?
,
1461 unitprice
=?
,rrp
=?
,ecost
=?
,budget_id
=?
,orderstatus
='complete'|;
1462 $query .= q
|, order_internalnote
= ?
| if defined $order_internalnote;
1463 $query .= q
|, order_vendornote
= ?
| if defined $order_vendornote;
1464 $query .= q
| where biblionumber
=?
and ordernumber
=?
|;
1465 my $sth = $dbh->prepare( $query );
1474 ( defined $order_internalnote ?
$order_internalnote : () ),
1475 ( defined $order_vendornote ?
$order_vendornote : () ),
1480 return ($datereceived, $new_ordernumber);
1483 =head3 CancelReceipt
1485 my $parent_ordernumber = CancelReceipt($ordernumber);
1487 Cancel an order line receipt and update the parent order line, as if no
1489 If items are created at receipt (AcqCreateItem = receiving) then delete
1495 my $ordernumber = shift;
1497 return unless $ordernumber;
1499 my $dbh = C4
::Context
->dbh;
1501 SELECT datereceived
, parent_ordernumber
, quantity
1503 WHERE ordernumber
= ?
1505 my $sth = $dbh->prepare($query);
1506 $sth->execute($ordernumber);
1507 my $order = $sth->fetchrow_hashref;
1509 warn "CancelReceipt: order $ordernumber does not exist";
1512 unless($order->{'datereceived'}) {
1513 warn "CancelReceipt: order $ordernumber is not received";
1517 my $parent_ordernumber = $order->{'parent_ordernumber'};
1519 my @itemnumbers = GetItemnumbersFromOrder
( $ordernumber );
1521 if($parent_ordernumber == $ordernumber || not $parent_ordernumber) {
1522 # The order line has no parent, just mark it as not received
1525 SET quantityreceived
= ?
,
1528 orderstatus
= 'ordered'
1529 WHERE ordernumber
= ?
1531 $sth = $dbh->prepare($query);
1532 $sth->execute(0, undef, undef, $ordernumber);
1533 _cancel_items_receipt
( $ordernumber );
1535 # The order line has a parent, increase parent quantity and delete
1538 SELECT quantity
, datereceived
1540 WHERE ordernumber
= ?
1542 $sth = $dbh->prepare($query);
1543 $sth->execute($parent_ordernumber);
1544 my $parent_order = $sth->fetchrow_hashref;
1545 unless($parent_order) {
1546 warn "Parent order $parent_ordernumber does not exist.";
1549 if($parent_order->{'datereceived'}) {
1550 warn "CancelReceipt: parent order is received.".
1551 " Can't cancel receipt.";
1557 orderstatus
= 'ordered'
1558 WHERE ordernumber
= ?
1560 $sth = $dbh->prepare($query);
1561 my $rv = $sth->execute(
1562 $order->{'quantity'} + $parent_order->{'quantity'},
1566 warn "Cannot update parent order line, so do not cancel".
1570 _cancel_items_receipt
( $ordernumber, $parent_ordernumber );
1573 DELETE FROM aqorders
1574 WHERE ordernumber
= ?
1576 $sth = $dbh->prepare($query);
1577 $sth->execute($ordernumber);
1581 if(C4
::Context
->preference('AcqCreateItem') eq 'ordering') {
1582 my @affects = split q{\|}, C4
::Context
->preference("AcqItemSetSubfieldsWhenReceiptIsCancelled");
1584 for my $in ( @itemnumbers ) {
1585 my $biblionumber = C4
::Biblio
::GetBiblionumberFromItemnumber
( $in );
1586 my $frameworkcode = GetFrameworkCode
($biblionumber);
1587 my ( $itemfield ) = GetMarcFromKohaField
( 'items.itemnumber', $frameworkcode );
1588 my $item = C4
::Items
::GetMarcItem
( $biblionumber, $in );
1589 for my $affect ( @affects ) {
1590 my ( $sf, $v ) = split q{=}, $affect, 2;
1591 foreach ( $item->field($itemfield) ) {
1592 $_->update( $sf => $v );
1595 C4
::Items
::ModItemFromMarc
( $item, $biblionumber, $in );
1600 return $parent_ordernumber;
1603 sub _cancel_items_receipt
{
1604 my ( $ordernumber, $parent_ordernumber ) = @_;
1605 $parent_ordernumber ||= $ordernumber;
1607 my @itemnumbers = GetItemnumbersFromOrder
($ordernumber);
1608 if(C4
::Context
->preference('AcqCreateItem') eq 'receiving') {
1609 # Remove items that were created at receipt
1611 DELETE FROM items
, aqorders_items
1612 USING items
, aqorders_items
1613 WHERE items
.itemnumber
= ? AND aqorders_items
.itemnumber
= ?
1615 my $dbh = C4
::Context
->dbh;
1616 my $sth = $dbh->prepare($query);
1617 foreach my $itemnumber (@itemnumbers) {
1618 $sth->execute($itemnumber, $itemnumber);
1622 foreach my $itemnumber (@itemnumbers) {
1623 ModItemOrder
($itemnumber, $parent_ordernumber);
1628 #------------------------------------------------------------#
1632 @results = &SearchOrders({
1633 ordernumber => $ordernumber,
1635 biblionumber => $biblionumber,
1637 booksellerid => $booksellerid,
1638 basketno => $basketno,
1644 Searches for orders.
1646 C<$owner> Finds order for the logged in user.
1647 C<$pending> Finds pending orders. Ignores completed and cancelled orders.
1648 C<$ordered> Finds orders to receive only (status 'ordered' or 'partial').
1651 C<@results> is an array of references-to-hash with the keys are fields
1652 from aqorders, biblio, biblioitems and aqbasket tables.
1657 my ( $params ) = @_;
1658 my $ordernumber = $params->{ordernumber
};
1659 my $search = $params->{search
};
1660 my $ean = $params->{ean
};
1661 my $booksellerid = $params->{booksellerid
};
1662 my $basketno = $params->{basketno
};
1663 my $basketname = $params->{basketname
};
1664 my $basketgroupname = $params->{basketgroupname
};
1665 my $owner = $params->{owner
};
1666 my $pending = $params->{pending
};
1667 my $ordered = $params->{ordered
};
1668 my $biblionumber = $params->{biblionumber
};
1669 my $budget_id = $params->{budget_id
};
1671 my $dbh = C4
::Context
->dbh;
1674 SELECT aqbasket.basketno,
1676 borrowers.firstname,
1679 biblioitems.biblioitemnumber,
1680 aqbasket.authorisedby,
1681 aqbasket.booksellerid,
1683 aqbasket.creationdate,
1684 aqbasket.basketname,
1685 aqbasketgroups.id as basketgroupid,
1686 aqbasketgroups.name as basketgroupname,
1689 LEFT JOIN aqbasket ON aqorders.basketno = aqbasket.basketno
1690 LEFT JOIN aqbasketgroups ON aqbasket.basketgroupid = aqbasketgroups.id
1691 LEFT JOIN borrowers ON aqbasket.authorisedby=borrowers.borrowernumber
1692 LEFT JOIN biblio ON aqorders.biblionumber=biblio.biblionumber
1693 LEFT JOIN biblioitems ON biblioitems.biblionumber=biblio.biblionumber
1696 # If we search on ordernumber, we retrieve the transfered order if a transfer has been done.
1698 LEFT JOIN aqorders_transfers ON aqorders_transfers.ordernumber_to = aqorders.ordernumber
1702 WHERE (datecancellationprinted is NULL)
1705 if ( $pending or $ordered ) {
1706 $query .= q{ AND (quantity > quantityreceived OR quantityreceived is NULL)};
1709 $query .= q{ AND aqorders.orderstatus IN ( "ordered", "partial" )};
1712 my $userenv = C4
::Context
->userenv;
1713 if ( C4
::Context
->preference("IndependentBranches") ) {
1714 unless ( C4
::Context
->IsSuperLibrarian() ) {
1717 borrowers.branchcode = ?
1718 OR borrowers.branchcode = ''
1721 push @args, $userenv->{branch
};
1725 if ( $ordernumber ) {
1726 $query .= ' AND ( aqorders.ordernumber = ? OR aqorders_transfers.ordernumber_from = ? ) ';
1727 push @args, ( $ordernumber, $ordernumber );
1729 if ( $biblionumber ) {
1730 $query .= 'AND aqorders.biblionumber = ?';
1731 push @args, $biblionumber;
1734 $query .= ' AND (biblio.title LIKE ? OR biblio.author LIKE ? OR biblioitems.isbn LIKE ?)';
1735 push @args, ("%$search%","%$search%","%$search%");
1738 $query .= ' AND biblioitems.ean = ?';
1741 if ( $booksellerid ) {
1742 $query .= 'AND aqbasket.booksellerid = ?';
1743 push @args, $booksellerid;
1746 $query .= 'AND aqbasket.basketno = ?';
1747 push @args, $basketno;
1750 $query .= 'AND aqbasket.basketname LIKE ?';
1751 push @args, "%$basketname%";
1753 if( $basketgroupname ) {
1754 $query .= ' AND aqbasketgroups.name LIKE ?';
1755 push @args, "%$basketgroupname%";
1759 $query .= ' AND aqbasket.authorisedby=? ';
1760 push @args, $userenv->{'number'};
1764 $query .= ' AND aqorders.budget_id = ?';
1765 push @args, $budget_id;
1768 $query .= ' ORDER BY aqbasket.basketno';
1770 my $sth = $dbh->prepare($query);
1771 $sth->execute(@args);
1772 return $sth->fetchall_arrayref({});
1775 #------------------------------------------------------------#
1779 &DelOrder($biblionumber, $ordernumber);
1781 Cancel the order with the given order and biblio numbers. It does not
1782 delete any entries in the aqorders table, it merely marks them as
1788 my ( $bibnum, $ordernumber, $delete_biblio, $reason ) = @_;
1791 my $dbh = C4
::Context
->dbh;
1794 SET datecancellationprinted=now(), orderstatus='cancelled'
1797 $query .= ", cancellationreason = ? ";
1800 WHERE biblionumber=? AND ordernumber=?
1802 my $sth = $dbh->prepare($query);
1804 $sth->execute($reason, $bibnum, $ordernumber);
1806 $sth->execute( $bibnum, $ordernumber );
1810 my @itemnumbers = GetItemnumbersFromOrder
( $ordernumber );
1811 foreach my $itemnumber (@itemnumbers){
1812 my $delcheck = C4
::Items
::DelItemCheck
( $dbh, $bibnum, $itemnumber );
1814 if($delcheck != 1) {
1815 $error->{'delitem'} = 1;
1819 if($delete_biblio) {
1820 # We get the number of remaining items
1821 my $itemcount = C4
::Items
::GetItemsCount
($bibnum);
1823 # If there are no items left,
1824 if ( $itemcount == 0 ) {
1825 # We delete the record
1826 my $delcheck = DelBiblio
($bibnum);
1829 $error->{'delbiblio'} = 1;
1837 =head3 TransferOrder
1839 my $newordernumber = TransferOrder($ordernumber, $basketno);
1841 Transfer an order line to a basket.
1842 Mark $ordernumber as cancelled with an internal note 'Cancelled and transfered
1843 to BOOKSELLER on DATE' and create new order with internal note
1844 'Transfered from BOOKSELLER on DATE'.
1845 Move all attached items to the new order.
1846 Received orders cannot be transfered.
1847 Return the ordernumber of created order.
1852 my ($ordernumber, $basketno) = @_;
1854 return unless ($ordernumber and $basketno);
1856 my $order = GetOrder
( $ordernumber );
1857 return if $order->{datereceived
};
1858 my $basket = GetBasket
($basketno);
1859 return unless $basket;
1861 my $dbh = C4
::Context
->dbh;
1862 my ($query, $sth, $rv);
1866 SET datecancellationprinted = CAST(NOW() AS date)
1867 WHERE ordernumber = ?
1869 $sth = $dbh->prepare($query);
1870 $rv = $sth->execute($ordernumber);
1872 delete $order->{'ordernumber'};
1873 delete $order->{parent_ordernumber
};
1874 $order->{'basketno'} = $basketno;
1876 my $newordernumber = Koha
::Acquisition
::Order
->new($order)->insert->{ordernumber
};
1879 UPDATE aqorders_items
1881 WHERE ordernumber = ?
1883 $sth = $dbh->prepare($query);
1884 $sth->execute($newordernumber, $ordernumber);
1887 INSERT INTO aqorders_transfers (ordernumber_from, ordernumber_to)
1890 $sth = $dbh->prepare($query);
1891 $sth->execute($ordernumber, $newordernumber);
1893 return $newordernumber;
1896 =head2 FUNCTIONS ABOUT PARCELS
1900 #------------------------------------------------------------#
1904 @results = &GetParcel($booksellerid, $code, $date);
1906 Looks up all of the received items from the supplier with the given
1907 bookseller ID at the given date, for the given code (bookseller Invoice number). Ignores cancelled and completed orders.
1909 C<@results> is an array of references-to-hash. The keys of each element are fields from
1910 the aqorders, biblio, and biblioitems tables of the Koha database.
1912 C<@results> is sorted alphabetically by book title.
1917 #gets all orders from a certain supplier, orders them alphabetically
1918 my ( $supplierid, $code, $datereceived ) = @_;
1919 my $dbh = C4
::Context
->dbh;
1922 if $code; # add % if we search on a given code (otherwise, let him empty)
1924 SELECT authorisedby,
1929 aqorders.biblionumber,
1930 aqorders.ordernumber,
1931 aqorders.parent_ordernumber,
1933 aqorders.quantityreceived,
1941 LEFT JOIN aqbasket ON aqbasket.basketno=aqorders.basketno
1942 LEFT JOIN borrowers ON aqbasket.authorisedby=borrowers.borrowernumber
1943 LEFT JOIN biblio ON aqorders.biblionumber=biblio.biblionumber
1944 LEFT JOIN aqinvoices ON aqorders.invoiceid = aqinvoices.invoiceid
1946 aqbasket.booksellerid = ?
1947 AND aqinvoices.invoicenumber LIKE ?
1948 AND aqorders.datereceived = ? ";
1950 my @query_params = ( $supplierid, $code, $datereceived );
1951 if ( C4
::Context
->preference("IndependentBranches") ) {
1952 unless ( C4
::Context
->IsSuperLibrarian() ) {
1953 $strsth .= " and (borrowers.branchcode = ?
1954 or borrowers.branchcode = '')";
1955 push @query_params, C4
::Context
->userenv->{branch
};
1958 $strsth .= " ORDER BY aqbasket.basketno";
1959 my $result_set = $dbh->selectall_arrayref(
1964 return @
{$result_set};
1967 #------------------------------------------------------------#
1971 $results = &GetParcels($bookseller, $order, $code, $datefrom, $dateto);
1973 get a lists of parcels.
1980 is the bookseller this function has to get parcels.
1983 To know on what criteria the results list has to be ordered.
1986 is the booksellerinvoicenumber.
1988 =item $datefrom & $dateto
1989 to know on what date this function has to filter its search.
1994 a pointer on a hash list containing parcel informations as such :
2000 =item Last operation
2002 =item Number of biblio
2004 =item Number of items
2011 my ($bookseller,$order, $code, $datefrom, $dateto) = @_;
2012 my $dbh = C4
::Context
->dbh;
2013 my @query_params = ();
2015 SELECT aqinvoices.invoicenumber,
2016 datereceived,purchaseordernumber,
2017 count(DISTINCT biblionumber) AS biblio,
2018 sum(quantity) AS itemsexpected,
2019 sum(quantityreceived) AS itemsreceived
2020 FROM aqorders LEFT JOIN aqbasket ON aqbasket.basketno = aqorders.basketno
2021 LEFT JOIN aqinvoices ON aqorders.invoiceid = aqinvoices.invoiceid
2022 WHERE aqbasket.booksellerid = ? and datereceived IS NOT NULL
2024 push @query_params, $bookseller;
2026 if ( defined $code ) {
2027 $strsth .= ' and aqinvoices.invoicenumber like ? ';
2028 # add a % to the end of the code to allow stemming.
2029 push @query_params, "$code%";
2032 if ( defined $datefrom ) {
2033 $strsth .= ' and datereceived >= ? ';
2034 push @query_params, $datefrom;
2037 if ( defined $dateto ) {
2038 $strsth .= 'and datereceived <= ? ';
2039 push @query_params, $dateto;
2042 $strsth .= "group by aqinvoices.invoicenumber,datereceived ";
2044 # can't use a placeholder to place this column name.
2045 # but, we could probably be checking to make sure it is a column that will be fetched.
2046 $strsth .= "order by $order " if ($order);
2048 my $sth = $dbh->prepare($strsth);
2050 $sth->execute( @query_params );
2051 my $results = $sth->fetchall_arrayref({});
2055 #------------------------------------------------------------#
2057 =head3 GetLateOrders
2059 @results = &GetLateOrders;
2061 Searches for bookseller with late orders.
2064 the table of supplier with late issues. This table is full of hashref.
2070 my $supplierid = shift;
2072 my $estimateddeliverydatefrom = shift;
2073 my $estimateddeliverydateto = shift;
2075 my $dbh = C4
::Context
->dbh;
2077 #BEWARE, order of parenthesis and LEFT JOIN is important for speed
2078 my $dbdriver = C4
::Context
->config("db_scheme") || "mysql";
2080 my @query_params = ();
2082 SELECT aqbasket.basketno,
2083 aqorders.ordernumber,
2084 DATE(aqbasket.closedate) AS orderdate,
2085 aqbasket.basketname AS basketname,
2086 aqbasket.basketgroupid AS basketgroupid,
2087 aqbasketgroups.name AS basketgroupname,
2088 aqorders.rrp AS unitpricesupplier,
2089 aqorders.ecost AS unitpricelib,
2090 aqorders.claims_count AS claims_count,
2091 aqorders.claimed_date AS claimed_date,
2092 aqbudgets.budget_name AS budget,
2093 borrowers.branchcode AS branch,
2094 aqbooksellers.name AS supplier,
2095 aqbooksellers.id AS supplierid,
2096 biblio.author, biblio.title,
2097 biblioitems.publishercode AS publisher,
2098 biblioitems.publicationyear,
2099 ADDDATE(aqbasket.closedate, INTERVAL aqbooksellers.deliverytime DAY) AS estimateddeliverydate,
2103 aqorders LEFT JOIN biblio ON biblio.biblionumber = aqorders.biblionumber
2104 LEFT JOIN biblioitems ON biblioitems.biblionumber = biblio.biblionumber
2105 LEFT JOIN aqbudgets ON aqorders.budget_id = aqbudgets.budget_id,
2106 aqbasket LEFT JOIN borrowers ON aqbasket.authorisedby = borrowers.borrowernumber
2107 LEFT JOIN aqbooksellers ON aqbasket.booksellerid = aqbooksellers.id
2108 LEFT JOIN aqbasketgroups ON aqbasket.basketgroupid = aqbasketgroups.id
2109 WHERE aqorders.basketno = aqbasket.basketno
2110 AND ( datereceived = ''
2111 OR datereceived IS NULL
2112 OR aqorders.quantityreceived < aqorders.quantity
2114 AND aqbasket.closedate IS NOT NULL
2115 AND (aqorders.datecancellationprinted IS NULL OR aqorders.datecancellationprinted='0000-00-00')
2118 if ($dbdriver eq "mysql") {
2120 aqorders.quantity - COALESCE(aqorders.quantityreceived,0) AS quantity,
2121 (aqorders.quantity - COALESCE(aqorders.quantityreceived,0)) * aqorders.rrp AS subtotal,
2122 DATEDIFF(CAST(now() AS date),closedate) AS latesince
2124 if ( defined $delay ) {
2125 $from .= " AND (closedate <= DATE_SUB(CAST(now() AS date),INTERVAL ? DAY)) " ;
2126 push @query_params, $delay;
2129 HAVING quantity <> 0
2130 AND unitpricesupplier <> 0
2131 AND unitpricelib <> 0
2134 # FIXME: account for IFNULL as above
2136 aqorders.quantity AS quantity,
2137 aqorders.quantity * aqorders.rrp AS subtotal,
2138 (CAST(now() AS date) - closedate) AS latesince
2140 if ( defined $delay ) {
2141 $from .= " AND (closedate <= (CAST(now() AS date) -(INTERVAL ? DAY)) ";
2142 push @query_params, $delay;
2145 if (defined $supplierid) {
2146 $from .= ' AND aqbasket.booksellerid = ? ';
2147 push @query_params, $supplierid;
2149 if (defined $branch) {
2150 $from .= ' AND borrowers.branchcode LIKE ? ';
2151 push @query_params, $branch;
2154 if ( defined $estimateddeliverydatefrom or defined $estimateddeliverydateto ) {
2155 $from .= ' AND aqbooksellers.deliverytime IS NOT NULL ';
2157 if ( defined $estimateddeliverydatefrom ) {
2158 $from .= ' AND ADDDATE(aqbasket.closedate, INTERVAL aqbooksellers.deliverytime DAY) >= ?';
2159 push @query_params, $estimateddeliverydatefrom;
2161 if ( defined $estimateddeliverydateto ) {
2162 $from .= ' AND ADDDATE(aqbasket.closedate, INTERVAL aqbooksellers.deliverytime DAY) <= ?';
2163 push @query_params, $estimateddeliverydateto;
2165 if ( defined $estimateddeliverydatefrom and not defined $estimateddeliverydateto ) {
2166 $from .= ' AND ADDDATE(aqbasket.closedate, INTERVAL aqbooksellers.deliverytime DAY) <= CAST(now() AS date)';
2168 if (C4
::Context
->preference("IndependentBranches")
2169 && !C4
::Context
->IsSuperLibrarian() ) {
2170 $from .= ' AND borrowers.branchcode LIKE ? ';
2171 push @query_params, C4
::Context
->userenv->{branch
};
2173 $from .= " AND orderstatus <> 'cancelled' ";
2174 my $query = "$select $from $having\nORDER BY latesince, basketno, borrowers.branchcode, supplier";
2175 $debug and print STDERR
"GetLateOrders query: $query\nGetLateOrders args: " . join(" ",@query_params);
2176 my $sth = $dbh->prepare($query);
2177 $sth->execute(@query_params);
2179 while (my $data = $sth->fetchrow_hashref) {
2180 push @results, $data;
2185 #------------------------------------------------------------#
2189 (\@order_loop, $total_qty, $total_price, $total_qtyreceived) = GetHistory( %params );
2191 Retreives some acquisition history information
2201 basket - search both basket name and number
2202 booksellerinvoicenumber
2205 orderstatus (note that orderstatus '' will retrieve orders
2206 of any status except cancelled)
2208 get_canceled_order (if set to a true value, cancelled orders will
2212 $order_loop is a list of hashrefs that each look like this:
2214 'author' => 'Twain, Mark',
2216 'biblionumber' => '215',
2218 'creationdate' => 'MM/DD/YYYY',
2219 'datereceived' => undef,
2222 'invoicenumber' => undef,
2224 'ordernumber' => '1',
2226 'quantityreceived' => undef,
2227 'title' => 'The Adventures of Huckleberry Finn'
2229 $total_qty is the sum of all of the quantities in $order_loop
2230 $total_price is the cost of each in $order_loop times the quantity
2231 $total_qtyreceived is the sum of all of the quantityreceived entries in $order_loop
2236 # don't run the query if there are no parameters (list would be too long for sure !)
2237 croak
"No search params" unless @_;
2239 my $title = $params{title
};
2240 my $author = $params{author
};
2241 my $isbn = $params{isbn
};
2242 my $ean = $params{ean
};
2243 my $name = $params{name
};
2244 my $from_placed_on = $params{from_placed_on
};
2245 my $to_placed_on = $params{to_placed_on
};
2246 my $basket = $params{basket
};
2247 my $booksellerinvoicenumber = $params{booksellerinvoicenumber
};
2248 my $basketgroupname = $params{basketgroupname
};
2249 my $budget = $params{budget
};
2250 my $orderstatus = $params{orderstatus
};
2251 my $biblionumber = $params{biblionumber
};
2252 my $get_canceled_order = $params{get_canceled_order
} || 0;
2253 my $ordernumber = $params{ordernumber
};
2254 my $search_children_too = $params{search_children_too
} || 0;
2258 my $total_qtyreceived = 0;
2259 my $total_price = 0;
2261 my $dbh = C4
::Context
->dbh;
2264 COALESCE(biblio.title, deletedbiblio.title) AS title,
2265 COALESCE(biblio.author, deletedbiblio.author) AS author,
2266 COALESCE(biblioitems.isbn, deletedbiblioitems.isbn) AS isbn,
2267 COALESCE(biblioitems.ean, deletedbiblioitems.ean) AS ean,
2269 aqbasket.basketname,
2270 aqbasket.basketgroupid,
2271 aqbasketgroups.name as groupname,
2273 aqbasket.creationdate,
2274 aqorders.datereceived,
2276 aqorders.quantityreceived,
2278 aqorders.ordernumber,
2280 aqinvoices.invoicenumber,
2281 aqbooksellers.id as id,
2282 aqorders.biblionumber,
2283 aqorders.orderstatus,
2284 aqorders.parent_ordernumber,
2285 aqbudgets.budget_name
2287 $query .= ", aqbudgets.budget_id AS budget" if defined $budget;
2290 LEFT JOIN aqbasket ON aqorders.basketno=aqbasket.basketno
2291 LEFT JOIN aqbasketgroups ON aqbasket.basketgroupid=aqbasketgroups.id
2292 LEFT JOIN aqbooksellers ON aqbasket.booksellerid=aqbooksellers.id
2293 LEFT JOIN biblioitems ON biblioitems.biblionumber=aqorders.biblionumber
2294 LEFT JOIN biblio ON biblio.biblionumber=aqorders.biblionumber
2295 LEFT JOIN aqbudgets ON aqorders.budget_id=aqbudgets.budget_id
2296 LEFT JOIN aqinvoices ON aqorders.invoiceid = aqinvoices.invoiceid
2297 LEFT JOIN deletedbiblio ON deletedbiblio.biblionumber=aqorders.biblionumber
2298 LEFT JOIN deletedbiblioitems ON deletedbiblioitems.biblionumber=aqorders.biblionumber
2301 if ( C4
::Context
->preference("IndependentBranches") ) {
2302 $query .= " LEFT JOIN borrowers ON aqbasket.authorisedby=borrowers.borrowernumber";
2305 $query .= " WHERE 1 ";
2307 unless ($get_canceled_order or (defined $orderstatus and $orderstatus eq 'cancelled')) {
2308 $query .= " AND (datecancellationprinted is NULL or datecancellationprinted='0000-00-00') ";
2311 my @query_params = ();
2313 if ( $biblionumber ) {
2314 $query .= " AND biblio.biblionumber = ?";
2315 push @query_params, $biblionumber;
2319 $query .= " AND biblio.title LIKE ? ";
2320 $title =~ s/\s+/%/g;
2321 push @query_params, "%$title%";
2325 $query .= " AND biblio.author LIKE ? ";
2326 push @query_params, "%$author%";
2330 $query .= " AND biblioitems.isbn LIKE ? ";
2331 push @query_params, "%$isbn%";
2334 $query .= " AND biblioitems.ean = ? ";
2335 push @query_params, "$ean";
2338 $query .= " AND aqbooksellers.name LIKE ? ";
2339 push @query_params, "%$name%";
2343 $query .= " AND aqbudgets.budget_id = ? ";
2344 push @query_params, "$budget";
2347 if ( $from_placed_on ) {
2348 $query .= " AND creationdate >= ? ";
2349 push @query_params, $from_placed_on;
2352 if ( $to_placed_on ) {
2353 $query .= " AND creationdate <= ? ";
2354 push @query_params, $to_placed_on;
2357 if ( defined $orderstatus and $orderstatus ne '') {
2358 $query .= " AND aqorders.orderstatus = ? ";
2359 push @query_params, "$orderstatus";
2363 if ($basket =~ m/^\d+$/) {
2364 $query .= " AND aqorders.basketno = ? ";
2365 push @query_params, $basket;
2367 $query .= " AND aqbasket.basketname LIKE ? ";
2368 push @query_params, "%$basket%";
2372 if ($booksellerinvoicenumber) {
2373 $query .= " AND aqinvoices.invoicenumber LIKE ? ";
2374 push @query_params, "%$booksellerinvoicenumber%";
2377 if ($basketgroupname) {
2378 $query .= " AND aqbasketgroups.name LIKE ? ";
2379 push @query_params, "%$basketgroupname%";
2383 $query .= " AND (aqorders.ordernumber = ? ";
2384 push @query_params, $ordernumber;
2385 if ($search_children_too) {
2386 $query .= " OR aqorders.parent_ordernumber = ? ";
2387 push @query_params, $ordernumber;
2393 if ( C4
::Context
->preference("IndependentBranches") ) {
2394 unless ( C4
::Context
->IsSuperLibrarian() ) {
2395 $query .= " AND (borrowers.branchcode = ? OR borrowers.branchcode ='' ) ";
2396 push @query_params, C4
::Context
->userenv->{branch
};
2399 $query .= " ORDER BY id";
2400 my $sth = $dbh->prepare($query);
2401 $sth->execute( @query_params );
2403 while ( my $line = $sth->fetchrow_hashref ) {
2404 $line->{count
} = $cnt++;
2405 $line->{toggle
} = 1 if $cnt % 2;
2406 push @order_loop, $line;
2407 $total_qty += ( $line->{quantity
} ) ?
$line->{quantity
} : 0;
2408 $total_qtyreceived += ( $line->{quantityreceived
} ) ?
$line->{quantityreceived
} : 0;
2409 $total_price += ( $line->{quantity
} and $line->{ecost
} ) ?
$line->{quantity
} * $line->{ecost
} : 0;
2411 return \
@order_loop, $total_qty, $total_price, $total_qtyreceived;
2414 =head2 GetRecentAcqui
2416 $results = GetRecentAcqui($days);
2418 C<$results> is a ref to a table which containts hashref
2422 sub GetRecentAcqui
{
2424 my $dbh = C4
::Context
->dbh;
2428 ORDER BY timestamp DESC
2431 my $sth = $dbh->prepare($query);
2433 my $results = $sth->fetchall_arrayref({});
2437 #------------------------------------------------------------#
2443 &AddClaim($ordernumber);
2445 Add a claim for an order
2452 my ($ordernumber) = @_;
2453 my $dbh = C4
::Context
->dbh;
2456 claims_count = claims_count + 1,
2457 claimed_date = CURDATE()
2458 WHERE ordernumber = ?
2460 my $sth = $dbh->prepare($query);
2461 $sth->execute($ordernumber);
2466 my @invoices = GetInvoices(
2467 invoicenumber => $invoicenumber,
2468 supplierid => $supplierid,
2469 suppliername => $suppliername,
2470 shipmentdatefrom => $shipmentdatefrom, # ISO format
2471 shipmentdateto => $shipmentdateto, # ISO format
2472 billingdatefrom => $billingdatefrom, # ISO format
2473 billingdateto => $billingdateto, # ISO format
2474 isbneanissn => $isbn_or_ean_or_issn,
2477 publisher => $publisher,
2478 publicationyear => $publicationyear,
2479 branchcode => $branchcode,
2480 order_by => $order_by
2483 Return a list of invoices that match all given criteria.
2485 $order_by is "column_name (asc|desc)", where column_name is any of
2486 'invoicenumber', 'booksellerid', 'shipmentdate', 'billingdate', 'closedate',
2487 'shipmentcost', 'shipmentcost_budgetid'.
2489 asc is the default if omitted
2496 my @columns = qw(invoicenumber booksellerid shipmentdate billingdate
2497 closedate shipmentcost shipmentcost_budgetid);
2499 my $dbh = C4
::Context
->dbh;
2501 SELECT aqinvoices
.*, aqbooksellers
.name AS suppliername
,
2504 aqorders
.datereceived IS NOT NULL
,
2505 aqorders
.biblionumber
,
2508 ) AS receivedbiblios
,
2511 aqorders
.subscriptionid IS NOT NULL
,
2512 aqorders
.subscriptionid
,
2515 ) AS is_linked_to_subscriptions
,
2516 SUM
(aqorders
.quantityreceived
) AS receiveditems
2518 LEFT JOIN aqbooksellers ON aqbooksellers
.id
= aqinvoices
.booksellerid
2519 LEFT JOIN aqorders ON aqorders
.invoiceid
= aqinvoices
.invoiceid
2520 LEFT JOIN aqbasket ON aqbasket
.basketno
=aqorders
.basketno
2521 LEFT JOIN borrowers ON aqbasket
.authorisedby
=borrowers
.borrowernumber
2522 LEFT JOIN biblio ON aqorders
.biblionumber
= biblio
.biblionumber
2523 LEFT JOIN biblioitems ON biblio
.biblionumber
= biblioitems
.biblionumber
2524 LEFT JOIN subscription ON biblio
.biblionumber
= subscription
.biblionumber
2529 if($args{supplierid
}) {
2530 push @bind_strs, " aqinvoices.booksellerid = ? ";
2531 push @bind_args, $args{supplierid
};
2533 if($args{invoicenumber
}) {
2534 push @bind_strs, " aqinvoices.invoicenumber LIKE ? ";
2535 push @bind_args, "%$args{invoicenumber}%";
2537 if($args{suppliername
}) {
2538 push @bind_strs, " aqbooksellers.name LIKE ? ";
2539 push @bind_args, "%$args{suppliername}%";
2541 if($args{shipmentdatefrom
}) {
2542 push @bind_strs, " aqinvoices.shipmentdate >= ? ";
2543 push @bind_args, $args{shipmentdatefrom
};
2545 if($args{shipmentdateto
}) {
2546 push @bind_strs, " aqinvoices.shipmentdate <= ? ";
2547 push @bind_args, $args{shipmentdateto
};
2549 if($args{billingdatefrom
}) {
2550 push @bind_strs, " aqinvoices.billingdate >= ? ";
2551 push @bind_args, $args{billingdatefrom
};
2553 if($args{billingdateto
}) {
2554 push @bind_strs, " aqinvoices.billingdate <= ? ";
2555 push @bind_args, $args{billingdateto
};
2557 if($args{isbneanissn
}) {
2558 push @bind_strs, " (biblioitems.isbn LIKE CONCAT('%', ?, '%') OR biblioitems.ean LIKE CONCAT('%', ?, '%') OR biblioitems.issn LIKE CONCAT('%', ?, '%') ) ";
2559 push @bind_args, $args{isbneanissn
}, $args{isbneanissn
}, $args{isbneanissn
};
2562 push @bind_strs, " biblio.title LIKE CONCAT('%', ?, '%') ";
2563 push @bind_args, $args{title
};
2566 push @bind_strs, " biblio.author LIKE CONCAT('%', ?, '%') ";
2567 push @bind_args, $args{author
};
2569 if($args{publisher
}) {
2570 push @bind_strs, " biblioitems.publishercode LIKE CONCAT('%', ?, '%') ";
2571 push @bind_args, $args{publisher
};
2573 if($args{publicationyear
}) {
2574 push @bind_strs, " ((biblioitems.publicationyear LIKE CONCAT('%', ?, '%')) OR (biblio.copyrightdate LIKE CONCAT('%', ?, '%'))) ";
2575 push @bind_args, $args{publicationyear
}, $args{publicationyear
};
2577 if($args{branchcode
}) {
2578 push @bind_strs, " borrowers.branchcode = ? ";
2579 push @bind_args, $args{branchcode
};
2582 $query .= " WHERE " . join(" AND ", @bind_strs) if @bind_strs;
2583 $query .= " GROUP BY aqinvoices.invoiceid ";
2585 if($args{order_by
}) {
2586 my ($column, $direction) = split / /, $args{order_by
};
2587 if(grep /^$column$/, @columns) {
2588 $direction ||= 'ASC';
2589 $query .= " ORDER BY $column $direction";
2593 my $sth = $dbh->prepare($query);
2594 $sth->execute(@bind_args);
2596 my $results = $sth->fetchall_arrayref({});
2602 my $invoice = GetInvoice($invoiceid);
2604 Get informations about invoice with given $invoiceid
2606 Return a hash filled with aqinvoices.* fields
2611 my ($invoiceid) = @_;
2614 return unless $invoiceid;
2616 my $dbh = C4
::Context
->dbh;
2622 my $sth = $dbh->prepare($query);
2623 $sth->execute($invoiceid);
2625 $invoice = $sth->fetchrow_hashref;
2629 =head3 GetInvoiceDetails
2631 my $invoice = GetInvoiceDetails($invoiceid)
2633 Return informations about an invoice + the list of related order lines
2635 Orders informations are in $invoice->{orders} (array ref)
2639 sub GetInvoiceDetails
{
2640 my ($invoiceid) = @_;
2642 if ( !defined $invoiceid ) {
2643 carp
'GetInvoiceDetails called without an invoiceid';
2647 my $dbh = C4
::Context
->dbh;
2649 SELECT aqinvoices.*, aqbooksellers.name AS suppliername
2651 LEFT JOIN aqbooksellers ON aqinvoices.booksellerid = aqbooksellers.id
2654 my $sth = $dbh->prepare($query);
2655 $sth->execute($invoiceid);
2657 my $invoice = $sth->fetchrow_hashref;
2660 SELECT aqorders.*, biblio.*, aqbasket.basketname
2662 LEFT JOIN aqbasket ON aqorders.basketno = aqbasket.basketno
2663 LEFT JOIN biblio ON aqorders.biblionumber = biblio.biblionumber
2666 $sth = $dbh->prepare($query);
2667 $sth->execute($invoiceid);
2668 $invoice->{orders
} = $sth->fetchall_arrayref({});
2669 $invoice->{orders
} ||= []; # force an empty arrayref if fetchall_arrayref fails
2676 my $invoiceid = AddInvoice(
2677 invoicenumber => $invoicenumber,
2678 booksellerid => $booksellerid,
2679 shipmentdate => $shipmentdate,
2680 billingdate => $billingdate,
2681 closedate => $closedate,
2682 shipmentcost => $shipmentcost,
2683 shipmentcost_budgetid => $shipmentcost_budgetid
2686 Create a new invoice and return its id or undef if it fails.
2693 return unless(%invoice and $invoice{invoicenumber
});
2695 my @columns = qw(invoicenumber booksellerid shipmentdate billingdate
2696 closedate shipmentcost shipmentcost_budgetid);
2700 foreach my $key (keys %invoice) {
2701 if(0 < grep(/^$key$/, @columns)) {
2702 push @set_strs, "$key = ?";
2703 push @set_args, ($invoice{$key} || undef);
2709 my $dbh = C4
::Context
->dbh;
2710 my $query = "INSERT INTO aqinvoices SET ";
2711 $query .= join (",", @set_strs);
2712 my $sth = $dbh->prepare($query);
2713 $rv = $sth->execute(@set_args);
2715 $rv = $dbh->last_insert_id(undef, undef, 'aqinvoices', undef);
2724 invoiceid => $invoiceid, # Mandatory
2725 invoicenumber => $invoicenumber,
2726 booksellerid => $booksellerid,
2727 shipmentdate => $shipmentdate,
2728 billingdate => $billingdate,
2729 closedate => $closedate,
2730 shipmentcost => $shipmentcost,
2731 shipmentcost_budgetid => $shipmentcost_budgetid
2734 Modify an invoice, invoiceid is mandatory.
2736 Return undef if it fails.
2743 return unless(%invoice and $invoice{invoiceid
});
2745 my @columns = qw(invoicenumber booksellerid shipmentdate billingdate
2746 closedate shipmentcost shipmentcost_budgetid);
2750 foreach my $key (keys %invoice) {
2751 if(0 < grep(/^$key$/, @columns)) {
2752 push @set_strs, "$key = ?";
2753 push @set_args, ($invoice{$key} || undef);
2757 my $dbh = C4
::Context
->dbh;
2758 my $query = "UPDATE aqinvoices SET ";
2759 $query .= join(",", @set_strs);
2760 $query .= " WHERE invoiceid = ?";
2762 my $sth = $dbh->prepare($query);
2763 $sth->execute(@set_args, $invoice{invoiceid
});
2768 CloseInvoice($invoiceid);
2772 Equivalent to ModInvoice(invoiceid => $invoiceid, closedate => undef);
2777 my ($invoiceid) = @_;
2779 return unless $invoiceid;
2781 my $dbh = C4
::Context
->dbh;
2784 SET closedate
= CAST
(NOW
() AS DATE
)
2787 my $sth = $dbh->prepare($query);
2788 $sth->execute($invoiceid);
2791 =head3 ReopenInvoice
2793 ReopenInvoice($invoiceid);
2797 Equivalent to ModInvoice(invoiceid => $invoiceid, closedate => C4::Dates->new()->output('iso'))
2802 my ($invoiceid) = @_;
2804 return unless $invoiceid;
2806 my $dbh = C4
::Context
->dbh;
2809 SET closedate
= NULL
2812 my $sth = $dbh->prepare($query);
2813 $sth->execute($invoiceid);
2818 DelInvoice($invoiceid);
2820 Delete an invoice if there are no items attached to it.
2825 my ($invoiceid) = @_;
2827 return unless $invoiceid;
2829 my $dbh = C4
::Context
->dbh;
2835 my $sth = $dbh->prepare($query);
2836 $sth->execute($invoiceid);
2837 my $res = $sth->fetchrow_arrayref;
2838 if ( $res && $res->[0] == 0 ) {
2840 DELETE FROM aqinvoices
2843 my $sth = $dbh->prepare($query);
2844 return ( $sth->execute($invoiceid) > 0 );
2849 =head3 MergeInvoices
2851 MergeInvoices($invoiceid, \@sourceids);
2853 Merge the invoices identified by the IDs in \@sourceids into
2854 the invoice identified by $invoiceid.
2859 my ($invoiceid, $sourceids) = @_;
2861 return unless $invoiceid;
2862 foreach my $sourceid (@
$sourceids) {
2863 next if $sourceid == $invoiceid;
2864 my $source = GetInvoiceDetails
($sourceid);
2865 foreach my $order (@
{$source->{'orders'}}) {
2866 $order->{'invoiceid'} = $invoiceid;
2869 DelInvoice
($source->{'invoiceid'});
2874 =head3 GetBiblioCountByBasketno
2876 $biblio_count = &GetBiblioCountByBasketno($basketno);
2878 Looks up the biblio's count that has basketno value $basketno
2884 sub GetBiblioCountByBasketno
{
2885 my ($basketno) = @_;
2886 my $dbh = C4
::Context
->dbh;
2888 SELECT COUNT( DISTINCT( biblionumber ) )
2891 AND (datecancellationprinted IS NULL OR datecancellationprinted='0000-00-00')
2894 my $sth = $dbh->prepare($query);
2895 $sth->execute($basketno);
2896 return $sth->fetchrow;
2904 Koha Development Team <http://koha-community.org/>