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
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
29 use C4
::Templates
qw(gettemplate);
30 use Koha
::DateUtils
qw( dt_from_string output_pref );
31 use Koha
::Acquisition
::Booksellers
;
32 use Koha
::Acquisition
::Orders
;
36 use Koha
::Number
::Price
;
38 use Koha
::CsvProfiles
;
48 use vars
qw(@ISA @EXPORT);
54 &GetBasket &NewBasket &CloseBasket &ReopenBasket &DelBasket &ModBasket
55 &GetBasketAsCSV &GetBasketGroupAsCSV
56 &GetBasketsByBookseller &GetBasketsByBasketgroup
57 &GetBasketsInfosByBookseller
59 &GetBasketUsers &ModBasketUsers
64 &ModBasketgroup &NewBasketgroup &DelBasketgroup &GetBasketgroup &CloseBasketgroup
65 &GetBasketgroups &ReOpenBasketgroup
67 &DelOrder &ModOrder &GetOrder &GetOrders &GetOrdersByBiblionumber
68 &GetLateOrders &GetOrderFromItemnumber
69 &SearchOrders &GetHistory &GetRecentAcqui
70 &ModReceiveOrder &CancelReceipt
72 &GetLastOrderNotReceivedFromSubscriptionid &GetLastOrderReceivedFromSubscriptionid
88 &GetBiblioCountByBasketno
94 &FillWithDefaultValues
105 sub GetOrderFromItemnumber
{
106 my ($itemnumber) = @_;
107 my $dbh = C4
::Context
->dbh;
110 SELECT
* from aqorders LEFT JOIN aqorders_items
111 ON
( aqorders
.ordernumber
= aqorders_items
.ordernumber
)
112 WHERE itemnumber
= ?
|;
114 my $sth = $dbh->prepare($query);
118 $sth->execute($itemnumber);
120 my $order = $sth->fetchrow_hashref;
127 C4::Acquisition - Koha functions for dealing with orders and acquisitions
135 The functions in this module deal with acquisitions, managing book
136 orders, basket and parcels.
140 =head2 FUNCTIONS ABOUT BASKETS
144 $aqbasket = &GetBasket($basketnumber);
146 get all basket informations in aqbasket for a given basket
148 B<returns:> informations for a given basket returned as a hashref.
154 my $dbh = C4
::Context
->dbh;
157 concat( b.firstname,' ',b.surname) AS authorisedbyname
159 LEFT JOIN borrowers b ON aqbasket.authorisedby=b.borrowernumber
162 my $sth=$dbh->prepare($query);
163 $sth->execute($basketno);
164 my $basket = $sth->fetchrow_hashref;
168 #------------------------------------------------------------#
172 $basket = &NewBasket( $booksellerid, $authorizedby, $basketname,
173 $basketnote, $basketbooksellernote, $basketcontractnumber, $deliveryplace, $billingplace, $is_standing, $create_items );
175 Create a new basket in aqbasket table
179 =item C<$booksellerid> is a foreign key in the aqbasket table
181 =item C<$authorizedby> is the username of who created the basket
185 The other parameters are optional, see ModBasketHeader for more info on them.
190 my ( $booksellerid, $authorisedby, $basketname, $basketnote,
191 $basketbooksellernote, $basketcontractnumber, $deliveryplace,
192 $billingplace, $is_standing, $create_items ) = @_;
193 my $dbh = C4
::Context
->dbh;
195 'INSERT INTO aqbasket (creationdate,booksellerid,authorisedby) '
196 . 'VALUES (now(),?,?)';
197 $dbh->do( $query, {}, $booksellerid, $authorisedby );
199 my $basket = $dbh->{mysql_insertid
};
200 $basketname ||= q{}; # default to empty strings
202 $basketbooksellernote ||= q{};
203 ModBasketHeader
( $basket, $basketname, $basketnote, $basketbooksellernote,
204 $basketcontractnumber, $booksellerid, $deliveryplace, $billingplace, $is_standing, $create_items );
208 #------------------------------------------------------------#
212 &CloseBasket($basketno);
214 close a basket (becomes unmodifiable, except for receives)
220 my $dbh = C4
::Context
->dbh;
221 $dbh->do('UPDATE aqbasket SET closedate=now() WHERE basketno=?', {}, $basketno );
224 q{UPDATE aqorders SET orderstatus = 'ordered' WHERE basketno = ? AND orderstatus NOT IN ( 'complete', 'cancelled')},
232 &ReopenBasket($basketno);
240 my $dbh = C4
::Context
->dbh;
241 $dbh->do( q{UPDATE aqbasket SET closedate=NULL WHERE basketno=?}, {}, $basketno );
245 SET orderstatus = 'new'
247 AND orderstatus NOT IN ( 'complete', 'cancelled' )
252 #------------------------------------------------------------#
254 =head3 GetBasketAsCSV
256 &GetBasketAsCSV($basketno);
258 Export a basket as CSV
260 $cgi parameter is needed for column name translation
265 my ($basketno, $cgi, $csv_profile_id) = @_;
266 my $basket = GetBasket
($basketno);
267 my @orders = GetOrders
($basketno);
268 my $contract = GetContract
({
269 contractnumber
=> $basket->{'contractnumber'}
272 my $template = C4
::Templates
::gettemplate
("acqui/csv/basket.tt", "intranet", $cgi);
274 if ($csv_profile_id) {
275 my $csv_profile = Koha
::CsvProfiles
->find( $csv_profile_id );
276 Koha
::Exceptions
::ObjectNotFound
->throw( 'There is no valid csv profile given') unless $csv_profile;
278 my $csv = Text
::CSV_XS
->new({'quote_char'=>'"','escape_char'=>'"','sep_char'=>$csv_profile->csv_separator,'binary'=>1});
279 my $csv_profile_content = $csv_profile->content;
280 my ( @headers, @fields );
281 while ( $csv_profile_content =~ /
284 ([^\
|]*) # fieldname (table.row or row)
288 my $field = ($2 eq '') ?
$1 : $2;
290 $header =~ s/^\s+|\s+$//g; # Trim whitespaces
291 push @headers, $header;
293 $field =~ s/[^\.]*\.{1}//; # Remove the table name if exists.
294 $field =~ s/^\s+|\s+$//g; # Trim whitespaces
295 push @fields, $field;
297 for my $order (@orders) {
299 my $biblio = Koha
::Biblios
->find( $order->{biblionumber
} );
300 my $biblioitem = $biblio->biblioitem;
301 $order = { %$order, %{ $biblioitem->unblessed } };
303 $order = {%$order, %$contract};
305 $order = {%$order, %$basket, %{ $biblio->unblessed }};
306 for my $field (@fields) {
307 push @row, $order->{$field};
311 my $content = join( $csv_profile->csv_separator, @headers ) . "\n";
312 for my $row ( @rows ) {
313 $csv->combine(@
$row);
314 my $string = $csv->string;
315 $content .= $string . "\n";
320 foreach my $order (@orders) {
321 my $biblio = Koha
::Biblios
->find( $order->{biblionumber
} );
322 my $biblioitem = $biblio->biblioitem;
324 contractname
=> $contract->{'contractname'},
325 ordernumber
=> $order->{'ordernumber'},
326 entrydate
=> $order->{'entrydate'},
327 isbn
=> $order->{'isbn'},
328 author
=> $biblio->author,
329 title
=> $biblio->title,
330 publicationyear
=> $biblioitem->publicationyear,
331 publishercode
=> $biblioitem->publishercode,
332 collectiontitle
=> $biblioitem->collectiontitle,
333 notes
=> $order->{'order_vendornote'},
334 quantity
=> $order->{'quantity'},
335 rrp
=> $order->{'rrp'},
337 for my $place ( qw( deliveryplace billingplace ) ) {
338 if ( my $library = Koha
::Libraries
->find( $row->{deliveryplace
} ) ) {
339 $row->{$place} = $library->branchname
343 contractname author title publishercode collectiontitle notes
344 deliveryplace billingplace
346 # Double the quotes to not be interpreted as a field end
347 $row->{$_} =~ s/"/""/g if $row->{$_};
353 if(defined $a->{publishercode
} and defined $b->{publishercode
}) {
354 $a->{publishercode
} cmp $b->{publishercode
};
358 $template->param(rows
=> \
@rows);
360 return $template->output;
365 =head3 GetBasketGroupAsCSV
367 &GetBasketGroupAsCSV($basketgroupid);
369 Export a basket group as CSV
371 $cgi parameter is needed for column name translation
375 sub GetBasketGroupAsCSV
{
376 my ($basketgroupid, $cgi) = @_;
377 my $baskets = GetBasketsByBasketgroup
($basketgroupid);
379 my $template = C4
::Templates
::gettemplate
('acqui/csv/basketgroup.tt', 'intranet', $cgi);
382 for my $basket (@
$baskets) {
383 my @orders = GetOrders
( $basket->{basketno
} );
384 my $contract = GetContract
({
385 contractnumber
=> $basket->{contractnumber
}
387 my $bookseller = Koha
::Acquisition
::Booksellers
->find( $basket->{booksellerid
} );
388 my $basketgroup = GetBasketgroup
( $$basket{basketgroupid
} );
390 foreach my $order (@orders) {
391 my $biblio = Koha
::Biblios
->find( $order->{biblionumber
} );
392 my $biblioitem = $biblio->biblioitem;
394 clientnumber
=> $bookseller->accountnumber,
395 basketname
=> $basket->{basketname
},
396 ordernumber
=> $order->{ordernumber
},
397 author
=> $biblio->author,
398 title
=> $biblio->title,
399 publishercode
=> $biblioitem->publishercode,
400 publicationyear
=> $biblioitem->publicationyear,
401 collectiontitle
=> $biblioitem->collectiontitle,
402 isbn
=> $order->{isbn
},
403 quantity
=> $order->{quantity
},
404 rrp_tax_included
=> $order->{rrp_tax_included
},
405 rrp_tax_excluded
=> $order->{rrp_tax_excluded
},
406 discount
=> $bookseller->discount,
407 ecost_tax_included
=> $order->{ecost_tax_included
},
408 ecost_tax_excluded
=> $order->{ecost_tax_excluded
},
409 notes
=> $order->{order_vendornote
},
410 entrydate
=> $order->{entrydate
},
411 booksellername
=> $bookseller->name,
412 bookselleraddress
=> $bookseller->address1,
413 booksellerpostal
=> $bookseller->postal,
414 contractnumber
=> $contract->{contractnumber
},
415 contractname
=> $contract->{contractname
},
418 basketgroupdeliveryplace
=> $basketgroup->{deliveryplace
},
419 basketgroupbillingplace
=> $basketgroup->{billingplace
},
420 basketdeliveryplace
=> $basket->{deliveryplace
},
421 basketbillingplace
=> $basket->{billingplace
},
423 for my $place (qw( basketgroupdeliveryplace basketgroupbillingplace basketdeliveryplace basketbillingplace )) {
424 if ( my $library = Koha
::Libraries
->find( $temp->{$place} ) ) {
425 $row->{$place} = $library->branchname;
429 basketname author title publishercode collectiontitle notes
430 booksellername bookselleraddress booksellerpostal contractname
431 basketgroupdeliveryplace basketgroupbillingplace
432 basketdeliveryplace basketbillingplace
434 # Double the quotes to not be interpreted as a field end
435 $row->{$_} =~ s/"/""/g if $row->{$_};
440 $template->param(rows
=> \
@rows);
442 return $template->output;
446 =head3 CloseBasketgroup
448 &CloseBasketgroup($basketgroupno);
454 sub CloseBasketgroup
{
455 my ($basketgroupno) = @_;
456 my $dbh = C4
::Context
->dbh;
457 my $sth = $dbh->prepare("
458 UPDATE aqbasketgroups
462 $sth->execute($basketgroupno);
465 #------------------------------------------------------------#
467 =head3 ReOpenBaskergroup($basketgroupno)
469 &ReOpenBaskergroup($basketgroupno);
475 sub ReOpenBasketgroup
{
476 my ($basketgroupno) = @_;
477 my $dbh = C4
::Context
->dbh;
478 my $sth = $dbh->prepare("
479 UPDATE aqbasketgroups
483 $sth->execute($basketgroupno);
486 #------------------------------------------------------------#
491 &DelBasket($basketno);
493 Deletes the basket that has basketno field $basketno in the aqbasket table.
497 =item C<$basketno> is the primary key of the basket in the aqbasket table.
504 my ( $basketno ) = @_;
505 my $query = "DELETE FROM aqbasket WHERE basketno=?";
506 my $dbh = C4
::Context
->dbh;
507 my $sth = $dbh->prepare($query);
508 $sth->execute($basketno);
512 #------------------------------------------------------------#
516 &ModBasket($basketinfo);
518 Modifies a basket, using a hashref $basketinfo for the relevant information, only $basketinfo->{'basketno'} is required.
522 =item C<$basketno> is the primary key of the basket in the aqbasket table.
529 my $basketinfo = shift;
530 my $query = "UPDATE aqbasket SET ";
532 foreach my $key (keys %$basketinfo){
533 if ($key ne 'basketno'){
534 $query .= "$key=?, ";
535 push(@params, $basketinfo->{$key} || undef );
538 # get rid of the "," at the end of $query
539 if (substr($query, length($query)-2) eq ', '){
544 $query .= "WHERE basketno=?";
545 push(@params, $basketinfo->{'basketno'});
546 my $dbh = C4
::Context
->dbh;
547 my $sth = $dbh->prepare($query);
548 $sth->execute(@params);
553 #------------------------------------------------------------#
555 =head3 ModBasketHeader
557 &ModBasketHeader($basketno, $basketname, $note, $booksellernote, $contractnumber, $booksellerid);
559 Modifies a basket's header.
563 =item C<$basketno> is the "basketno" field in the "aqbasket" table;
565 =item C<$basketname> is the "basketname" field in the "aqbasket" table;
567 =item C<$note> is the "note" field in the "aqbasket" table;
569 =item C<$booksellernote> is the "booksellernote" field in the "aqbasket" table;
571 =item C<$contractnumber> is the "contractnumber" (foreign) key in the "aqbasket" table.
573 =item C<$booksellerid> is the id (foreign) key in the "aqbooksellers" table for the vendor.
575 =item C<$deliveryplace> is the "deliveryplace" field in the aqbasket table.
577 =item C<$billingplace> is the "billingplace" field in the aqbasket table.
579 =item C<$is_standing> is the "is_standing" field in the aqbasket table.
581 =item C<$create_items> should be set to 'ordering', 'receiving' or 'cataloguing' (or undef, in which
582 case the AcqCreateItem syspref takes precedence).
588 sub ModBasketHeader
{
589 my ($basketno, $basketname, $note, $booksellernote, $contractnumber, $booksellerid, $deliveryplace, $billingplace, $is_standing, $create_items) = @_;
594 SET basketname
=?
, note
=?
, booksellernote
=?
, booksellerid
=?
, deliveryplace
=?
, billingplace
=?
, is_standing
=?
, create_items
=?
598 my $dbh = C4
::Context
->dbh;
599 my $sth = $dbh->prepare($query);
600 $sth->execute($basketname, $note, $booksellernote, $booksellerid, $deliveryplace, $billingplace, $is_standing, $create_items || undef, $basketno);
602 if ( $contractnumber ) {
603 my $query2 ="UPDATE aqbasket SET contractnumber=? WHERE basketno=?";
604 my $sth2 = $dbh->prepare($query2);
605 $sth2->execute($contractnumber,$basketno);
610 #------------------------------------------------------------#
612 =head3 GetBasketsByBookseller
614 @results = &GetBasketsByBookseller($booksellerid, $extra);
616 Returns a list of hashes of all the baskets that belong to bookseller 'booksellerid'.
620 =item C<$booksellerid> is the 'id' field of the bookseller in the aqbooksellers table
622 =item C<$extra> is the extra sql parameters, can be
624 $extra->{groupby}: group baskets by column
625 ex. $extra->{groupby} = aqbasket.basketgroupid
626 $extra->{orderby}: order baskets by column
627 $extra->{limit}: limit number of results (can be helpful for pagination)
633 sub GetBasketsByBookseller
{
634 my ($booksellerid, $extra) = @_;
635 my $query = "SELECT * FROM aqbasket WHERE booksellerid=?";
637 if ($extra->{groupby
}) {
638 $query .= " GROUP by $extra->{groupby}";
640 if ($extra->{orderby
}){
641 $query .= " ORDER by $extra->{orderby}";
643 if ($extra->{limit
}){
644 $query .= " LIMIT $extra->{limit}";
647 my $dbh = C4
::Context
->dbh;
648 my $sth = $dbh->prepare($query);
649 $sth->execute($booksellerid);
650 return $sth->fetchall_arrayref({});
653 =head3 GetBasketsInfosByBookseller
655 my $baskets = GetBasketsInfosByBookseller($supplierid, $allbaskets);
657 The optional second parameter allbaskets is a boolean allowing you to
658 select all baskets from the supplier; by default only active baskets (open or
659 closed but still something to receive) are returned.
661 Returns in a arrayref of hashref all about booksellers baskets, plus:
662 total_biblios: Number of distinct biblios in basket
663 total_items: Number of items in basket
664 expected_items: Number of non-received items in basket
668 sub GetBasketsInfosByBookseller
{
669 my ($supplierid, $allbaskets) = @_;
671 return unless $supplierid;
673 my $dbh = C4
::Context
->dbh;
675 SELECT aqbasket.basketno, aqbasket.basketname, aqbasket.note, aqbasket.booksellernote, aqbasket.contractnumber, aqbasket.creationdate, aqbasket.closedate, aqbasket.booksellerid, aqbasket.authorisedby, aqbasket.booksellerinvoicenumber, aqbasket.basketgroupid, aqbasket.deliveryplace, aqbasket.billingplace, aqbasket.branch, aqbasket.is_standing, aqbasket.create_items,
676 SUM(aqorders.quantity) AS total_items,
678 IF ( aqorders.orderstatus = 'cancelled', aqorders.quantity, 0 )
679 ) AS total_items_cancelled,
680 COUNT(DISTINCT aqorders.biblionumber) AS total_biblios,
682 IF(aqorders.datereceived IS NULL
683 AND (aqorders.datecancellationprinted IS NULL OR aqorders.datecancellationprinted='0000-00-00')
688 LEFT JOIN aqorders ON aqorders.basketno = aqbasket.basketno
689 WHERE booksellerid = ?};
691 $query.=" GROUP BY aqbasket.basketno, aqbasket.basketname, aqbasket.note, aqbasket.booksellernote, aqbasket.contractnumber, aqbasket.creationdate, aqbasket.closedate, aqbasket.booksellerid, aqbasket.authorisedby, aqbasket.booksellerinvoicenumber, aqbasket.basketgroupid, aqbasket.deliveryplace, aqbasket.billingplace, aqbasket.branch, aqbasket.is_standing, aqbasket.create_items";
693 unless ( $allbaskets ) {
694 # Don't show the basket if it's NOT CLOSED or is FULLY RECEIVED
695 $query.=" HAVING (closedate IS NULL OR (
697 IF(aqorders.datereceived IS NULL
698 AND (aqorders.datecancellationprinted IS NULL OR aqorders.datecancellationprinted='0000-00-00')
704 my $sth = $dbh->prepare($query);
705 $sth->execute($supplierid);
706 my $baskets = $sth->fetchall_arrayref({});
708 # Retrieve the number of biblios cancelled
709 my $cancelled_biblios = $dbh->selectall_hashref( q
|
710 SELECT COUNT
(DISTINCT
(biblionumber
)) AS total_biblios_cancelled
, aqbasket
.basketno
712 LEFT JOIN aqorders ON aqorders
.basketno
= aqbasket
.basketno
713 WHERE booksellerid
= ?
714 AND aqorders
.orderstatus
= 'cancelled'
715 GROUP BY aqbasket
.basketno
716 |, 'basketno', {}, $supplierid );
718 $_->{total_biblios_cancelled
} = $cancelled_biblios->{$_->{basketno
}}{total_biblios_cancelled
} || 0
724 =head3 GetBasketUsers
726 $basketusers_ids = &GetBasketUsers($basketno);
728 Returns a list of all borrowernumbers that are in basket users list
733 my $basketno = shift;
735 return unless $basketno;
738 SELECT borrowernumber
742 my $dbh = C4
::Context
->dbh;
743 my $sth = $dbh->prepare($query);
744 $sth->execute($basketno);
745 my $results = $sth->fetchall_arrayref( {} );
748 foreach (@
$results) {
749 push @borrowernumbers, $_->{'borrowernumber'};
752 return @borrowernumbers;
755 =head3 ModBasketUsers
757 my @basketusers_ids = (1, 2, 3);
758 &ModBasketUsers($basketno, @basketusers_ids);
760 Delete all users from basket users list, and add users in C<@basketusers_ids>
766 my ($basketno, @basketusers_ids) = @_;
768 return unless $basketno;
770 my $dbh = C4
::Context
->dbh;
772 DELETE FROM aqbasketusers
775 my $sth = $dbh->prepare($query);
776 $sth->execute($basketno);
779 INSERT INTO aqbasketusers
(basketno
, borrowernumber
)
782 $sth = $dbh->prepare($query);
783 foreach my $basketuser_id (@basketusers_ids) {
784 $sth->execute($basketno, $basketuser_id);
789 =head3 CanUserManageBasket
791 my $bool = CanUserManageBasket($borrower, $basket[, $userflags]);
792 my $bool = CanUserManageBasket($borrowernumber, $basketno[, $userflags]);
794 Check if a borrower can manage a basket, according to system preference
795 AcqViewBaskets, user permissions and basket properties (creator, users list,
798 First parameter can be either a borrowernumber or a hashref as returned by
799 Koha::Patron->unblessed
801 Second parameter can be either a basketno or a hashref as returned by
802 C4::Acquisition::GetBasket.
804 The third parameter is optional. If given, it should be a hashref as returned
805 by C4::Auth::getuserflags. If not, getuserflags is called.
807 If user is authorised to manage basket, returns 1.
812 sub CanUserManageBasket
{
813 my ($borrower, $basket, $userflags) = @_;
815 if (!ref $borrower) {
816 # FIXME This needs to be replaced
817 # We should not accept both scalar and array
818 # Tests need to be updated
819 $borrower = Koha
::Patrons
->find( $borrower )->unblessed;
822 $basket = GetBasket
($basket);
825 return 0 unless ($basket and $borrower);
827 my $borrowernumber = $borrower->{borrowernumber
};
828 my $basketno = $basket->{basketno
};
830 my $AcqViewBaskets = C4
::Context
->preference('AcqViewBaskets');
832 if (!defined $userflags) {
833 my $dbh = C4
::Context
->dbh;
834 my $sth = $dbh->prepare("SELECT flags FROM borrowers WHERE borrowernumber = ?");
835 $sth->execute($borrowernumber);
836 my ($flags) = $sth->fetchrow_array;
839 $userflags = C4
::Auth
::getuserflags
($flags, $borrower->{userid
}, $dbh);
842 unless ($userflags->{superlibrarian
}
843 || (ref $userflags->{acquisition
} && $userflags->{acquisition
}->{order_manage_all
})
844 || (!ref $userflags->{acquisition
} && $userflags->{acquisition
}))
846 if (not exists $userflags->{acquisition
}) {
850 if ( (ref $userflags->{acquisition
} && !$userflags->{acquisition
}->{order_manage
})
851 || (!ref $userflags->{acquisition
} && !$userflags->{acquisition
}) ) {
855 if ($AcqViewBaskets eq 'user'
856 && $basket->{authorisedby
} != $borrowernumber
857 && ! grep { $borrowernumber eq $_ } GetBasketUsers
($basketno)) {
861 if ($AcqViewBaskets eq 'branch' && defined $basket->{branch
}
862 && $basket->{branch
} ne $borrower->{branchcode
}) {
870 #------------------------------------------------------------#
872 =head3 GetBasketsByBasketgroup
874 $baskets = &GetBasketsByBasketgroup($basketgroupid);
876 Returns a reference to all baskets that belong to basketgroup $basketgroupid.
880 sub GetBasketsByBasketgroup
{
881 my $basketgroupid = shift;
883 SELECT
*, aqbasket
.booksellerid as booksellerid
885 LEFT JOIN aqcontract USING
(contractnumber
) WHERE basketgroupid
=?
887 my $dbh = C4
::Context
->dbh;
888 my $sth = $dbh->prepare($query);
889 $sth->execute($basketgroupid);
890 return $sth->fetchall_arrayref({});
893 #------------------------------------------------------------#
895 =head3 NewBasketgroup
897 $basketgroupid = NewBasketgroup(\%hashref);
899 Adds a basketgroup to the aqbasketgroups table, and add the initial baskets to it.
901 $hashref->{'booksellerid'} is the 'id' field of the bookseller in the aqbooksellers table,
903 $hashref->{'name'} is the 'name' field of the basketgroup in the aqbasketgroups table,
905 $hashref->{'basketlist'} is a list reference of the 'id's of the baskets that belong to this group,
907 $hashref->{'billingplace'} is the 'billingplace' field of the basketgroup in the aqbasketgroups table,
909 $hashref->{'deliveryplace'} is the 'deliveryplace' field of the basketgroup in the aqbasketgroups table,
911 $hashref->{'freedeliveryplace'} is the 'freedeliveryplace' field of the basketgroup in the aqbasketgroups table,
913 $hashref->{'deliverycomment'} is the 'deliverycomment' field of the basketgroup in the aqbasketgroups table,
915 $hashref->{'closed'} is the 'closed' field of the aqbasketgroups table, it is false if 0, true otherwise.
920 my $basketgroupinfo = shift;
921 die "booksellerid is required to create a basketgroup" unless $basketgroupinfo->{'booksellerid'};
922 my $query = "INSERT INTO aqbasketgroups (";
924 foreach my $field (qw(name billingplace deliveryplace freedeliveryplace deliverycomment closed)) {
925 if ( defined $basketgroupinfo->{$field} ) {
926 $query .= "$field, ";
927 push(@params, $basketgroupinfo->{$field});
930 $query .= "booksellerid) VALUES (";
935 push(@params, $basketgroupinfo->{'booksellerid'});
936 my $dbh = C4
::Context
->dbh;
937 my $sth = $dbh->prepare($query);
938 $sth->execute(@params);
939 my $basketgroupid = $dbh->{'mysql_insertid'};
940 if( $basketgroupinfo->{'basketlist'} ) {
941 foreach my $basketno (@
{$basketgroupinfo->{'basketlist'}}) {
942 my $query2 = "UPDATE aqbasket SET basketgroupid=? WHERE basketno=?";
943 my $sth2 = $dbh->prepare($query2);
944 $sth2->execute($basketgroupid, $basketno);
947 return $basketgroupid;
950 #------------------------------------------------------------#
952 =head3 ModBasketgroup
954 ModBasketgroup(\%hashref);
956 Modifies a basketgroup in the aqbasketgroups table, and add the baskets to it.
958 $hashref->{'id'} is the 'id' field of the basketgroup in the aqbasketgroup table, this parameter is mandatory,
960 $hashref->{'name'} is the 'name' field of the basketgroup in the aqbasketgroups table,
962 $hashref->{'basketlist'} is a list reference of the 'id's of the baskets that belong to this group,
964 $hashref->{'billingplace'} is the 'billingplace' field of the basketgroup in the aqbasketgroups table,
966 $hashref->{'deliveryplace'} is the 'deliveryplace' field of the basketgroup in the aqbasketgroups table,
968 $hashref->{'freedeliveryplace'} is the 'freedeliveryplace' field of the basketgroup in the aqbasketgroups table,
970 $hashref->{'deliverycomment'} is the 'deliverycomment' field of the basketgroup in the aqbasketgroups table,
972 $hashref->{'closed'} is the 'closed' field of the aqbasketgroups table, it is false if 0, true otherwise.
977 my $basketgroupinfo = shift;
978 die "basketgroup id is required to edit a basketgroup" unless $basketgroupinfo->{'id'};
979 my $dbh = C4
::Context
->dbh;
980 my $query = "UPDATE aqbasketgroups SET ";
982 foreach my $field (qw(name billingplace deliveryplace freedeliveryplace deliverycomment closed)) {
983 if ( defined $basketgroupinfo->{$field} ) {
984 $query .= "$field=?, ";
985 push(@params, $basketgroupinfo->{$field});
990 $query .= " WHERE id=?";
991 push(@params, $basketgroupinfo->{'id'});
992 my $sth = $dbh->prepare($query);
993 $sth->execute(@params);
995 $sth = $dbh->prepare('UPDATE aqbasket SET basketgroupid = NULL WHERE basketgroupid = ?');
996 $sth->execute($basketgroupinfo->{'id'});
998 if($basketgroupinfo->{'basketlist'} && @
{$basketgroupinfo->{'basketlist'}}){
999 $sth = $dbh->prepare("UPDATE aqbasket SET basketgroupid=? WHERE basketno=?");
1000 foreach my $basketno (@
{$basketgroupinfo->{'basketlist'}}) {
1001 $sth->execute($basketgroupinfo->{'id'}, $basketno);
1007 #------------------------------------------------------------#
1009 =head3 DelBasketgroup
1011 DelBasketgroup($basketgroupid);
1013 Deletes a basketgroup in the aqbasketgroups table, and removes the reference to it from the baskets,
1017 =item C<$basketgroupid> is the 'id' field of the basket in the aqbasketgroup table
1023 sub DelBasketgroup
{
1024 my $basketgroupid = shift;
1025 die "basketgroup id is required to edit a basketgroup" unless $basketgroupid;
1026 my $query = "DELETE FROM aqbasketgroups WHERE id=?";
1027 my $dbh = C4
::Context
->dbh;
1028 my $sth = $dbh->prepare($query);
1029 $sth->execute($basketgroupid);
1033 #------------------------------------------------------------#
1036 =head2 FUNCTIONS ABOUT ORDERS
1038 =head3 GetBasketgroup
1040 $basketgroup = &GetBasketgroup($basketgroupid);
1042 Returns a reference to the hash containing all information about the basketgroup.
1046 sub GetBasketgroup
{
1047 my $basketgroupid = shift;
1048 die "basketgroup id is required to edit a basketgroup" unless $basketgroupid;
1049 my $dbh = C4
::Context
->dbh;
1050 my $result_set = $dbh->selectall_arrayref(
1051 'SELECT * FROM aqbasketgroups WHERE id=?',
1055 return $result_set->[0]; # id is unique
1058 #------------------------------------------------------------#
1060 =head3 GetBasketgroups
1062 $basketgroups = &GetBasketgroups($booksellerid);
1064 Returns a reference to the array of all the basketgroups of bookseller $booksellerid.
1068 sub GetBasketgroups
{
1069 my $booksellerid = shift;
1070 die 'bookseller id is required to edit a basketgroup' unless $booksellerid;
1071 my $query = 'SELECT * FROM aqbasketgroups WHERE booksellerid=? ORDER BY id DESC';
1072 my $dbh = C4
::Context
->dbh;
1073 my $sth = $dbh->prepare($query);
1074 $sth->execute($booksellerid);
1075 return $sth->fetchall_arrayref({});
1078 #------------------------------------------------------------#
1080 =head2 FUNCTIONS ABOUT ORDERS
1084 @orders = &GetOrders( $basketno, { orderby => 'biblio.title', cancelled => 0|1 } );
1086 Looks up the pending (non-cancelled) orders with the given basket
1089 If cancelled is set, only cancelled orders will be returned.
1094 my ( $basketno, $params ) = @_;
1096 return () unless $basketno;
1098 my $orderby = $params->{orderby
};
1099 my $cancelled = $params->{cancelled
} || 0;
1101 my $dbh = C4
::Context
->dbh;
1103 SELECT biblio
.*,biblioitems
.*,
1107 $query .= $cancelled
1109 aqorders_transfers
.ordernumber_to AS transferred_to
,
1110 aqorders_transfers
.timestamp AS transferred_to_timestamp
1113 aqorders_transfers
.ordernumber_from AS transferred_from
,
1114 aqorders_transfers
.timestamp AS transferred_from_timestamp
1118 LEFT JOIN aqbudgets ON aqbudgets
.budget_id
= aqorders
.budget_id
1119 LEFT JOIN biblio ON biblio
.biblionumber
= aqorders
.biblionumber
1120 LEFT JOIN biblioitems ON biblioitems
.biblionumber
=biblio
.biblionumber
1122 $query .= $cancelled
1124 LEFT JOIN aqorders_transfers ON aqorders_transfers
.ordernumber_from
= aqorders
.ordernumber
1127 LEFT JOIN aqorders_transfers ON aqorders_transfers
.ordernumber_to
= aqorders
.ordernumber
1135 $orderby ||= q
|biblioitems
.publishercode
, biblio
.title
|;
1137 AND
(datecancellationprinted IS NOT NULL
1138 AND datecancellationprinted
<> '0000-00-00')
1143 q
|aqorders
.datecancellationprinted desc
, aqorders
.timestamp desc
|;
1145 AND
(datecancellationprinted IS NULL OR datecancellationprinted
='0000-00-00')
1149 $query .= " ORDER BY $orderby";
1151 $dbh->selectall_arrayref( $query, { Slice
=> {} }, $basketno );
1156 #------------------------------------------------------------#
1158 =head3 GetOrdersByBiblionumber
1160 @orders = &GetOrdersByBiblionumber($biblionumber);
1162 Looks up the orders with linked to a specific $biblionumber, including
1163 cancelled orders and received orders.
1166 C<@orders> is an array of references-to-hash, whose keys are the
1167 fields from the aqorders, biblio, and biblioitems tables in the Koha database.
1171 sub GetOrdersByBiblionumber
{
1172 my $biblionumber = shift;
1173 return unless $biblionumber;
1174 my $dbh = C4
::Context
->dbh;
1176 SELECT biblio.*,biblioitems.*,
1180 LEFT JOIN aqbudgets ON aqbudgets.budget_id = aqorders.budget_id
1181 LEFT JOIN biblio ON biblio.biblionumber = aqorders.biblionumber
1182 LEFT JOIN biblioitems ON biblioitems.biblionumber =biblio.biblionumber
1183 WHERE aqorders.biblionumber=?
1186 $dbh->selectall_arrayref( $query, { Slice
=> {} }, $biblionumber );
1187 return @
{$result_set};
1191 #------------------------------------------------------------#
1195 $order = &GetOrder($ordernumber);
1197 Looks up an order by order number.
1199 Returns a reference-to-hash describing the order. The keys of
1200 C<$order> are fields from the biblio, biblioitems, aqorders tables of the Koha database.
1205 my ($ordernumber) = @_;
1206 return unless $ordernumber;
1208 my $dbh = C4
::Context
->dbh;
1209 my $query = qq{SELECT
1213 aqbasket
.basketname
,
1214 borrowers
.branchcode
,
1215 biblioitems
.publicationyear
,
1216 biblio
.copyrightdate
,
1217 biblioitems
.editionstatement
,
1221 biblioitems
.publishercode
,
1222 aqorders
.rrp AS unitpricesupplier
,
1223 aqorders
.ecost AS unitpricelib
,
1224 aqorders
.claims_count AS claims_count
,
1225 aqorders
.claimed_date AS claimed_date
,
1226 aqbudgets
.budget_name AS budget
,
1227 aqbooksellers
.name AS supplier
,
1228 aqbooksellers
.id AS supplierid
,
1229 biblioitems
.publishercode AS publisher
,
1230 ADDDATE
(aqbasket
.closedate
, INTERVAL aqbooksellers
.deliverytime DAY
) AS estimateddeliverydate
,
1231 DATE
(aqbasket
.closedate
) AS orderdate
,
1232 aqorders
.quantity
- COALESCE
(aqorders
.quantityreceived
,0) AS quantity_to_receive
,
1233 (aqorders
.quantity
- COALESCE
(aqorders
.quantityreceived
,0)) * aqorders
.rrp AS subtotal
,
1234 DATEDIFF
(CURDATE
( ),closedate
) AS latesince
1235 FROM aqorders LEFT JOIN biblio ON biblio
.biblionumber
= aqorders
.biblionumber
1236 LEFT JOIN biblioitems ON biblioitems
.biblionumber
= biblio
.biblionumber
1237 LEFT JOIN aqbudgets ON aqorders
.budget_id
= aqbudgets
.budget_id
,
1238 aqbasket LEFT JOIN borrowers ON aqbasket
.authorisedby
= borrowers
.borrowernumber
1239 LEFT JOIN aqbooksellers ON aqbasket
.booksellerid
= aqbooksellers
.id
1240 WHERE aqorders
.basketno
= aqbasket
.basketno
1243 $dbh->selectall_arrayref( $query, { Slice
=> {} }, $ordernumber );
1245 # result_set assumed to contain 1 match
1246 return $result_set->[0];
1249 =head3 GetLastOrderNotReceivedFromSubscriptionid
1251 $order = &GetLastOrderNotReceivedFromSubscriptionid($subscriptionid);
1253 Returns a reference-to-hash describing the last order not received for a subscription.
1257 sub GetLastOrderNotReceivedFromSubscriptionid
{
1258 my ( $subscriptionid ) = @_;
1259 my $dbh = C4
::Context
->dbh;
1261 SELECT
* FROM aqorders
1262 LEFT JOIN subscription
1263 ON
( aqorders
.subscriptionid
= subscription
.subscriptionid
)
1264 WHERE aqorders
.subscriptionid
= ?
1265 AND aqorders
.datereceived IS NULL
1269 $dbh->selectall_arrayref( $query, { Slice
=> {} }, $subscriptionid );
1271 # result_set assumed to contain 1 match
1272 return $result_set->[0];
1275 =head3 GetLastOrderReceivedFromSubscriptionid
1277 $order = &GetLastOrderReceivedFromSubscriptionid($subscriptionid);
1279 Returns a reference-to-hash describing the last order received for a subscription.
1283 sub GetLastOrderReceivedFromSubscriptionid
{
1284 my ( $subscriptionid ) = @_;
1285 my $dbh = C4
::Context
->dbh;
1287 SELECT
* FROM aqorders
1288 LEFT JOIN subscription
1289 ON
( aqorders
.subscriptionid
= subscription
.subscriptionid
)
1290 WHERE aqorders
.subscriptionid
= ?
1291 AND aqorders
.datereceived
=
1293 SELECT MAX
( aqorders
.datereceived
)
1295 LEFT JOIN subscription
1296 ON
( aqorders
.subscriptionid
= subscription
.subscriptionid
)
1297 WHERE aqorders
.subscriptionid
= ?
1298 AND aqorders
.datereceived IS NOT NULL
1300 ORDER BY ordernumber DESC
1304 $dbh->selectall_arrayref( $query, { Slice
=> {} }, $subscriptionid, $subscriptionid );
1306 # result_set assumed to contain 1 match
1307 return $result_set->[0];
1311 #------------------------------------------------------------#
1315 &ModOrder(\%hashref);
1317 Modifies an existing order. Updates the order with order number
1318 $hashref->{'ordernumber'} and biblionumber $hashref->{'biblionumber'}. All
1319 other keys of the hash update the fields with the same name in the aqorders
1320 table of the Koha database.
1325 my $orderinfo = shift;
1327 die "Ordernumber is required" if $orderinfo->{'ordernumber'} eq '';
1329 my $dbh = C4
::Context
->dbh;
1332 # update uncertainprice to an integer, just in case (under FF, checked boxes have the value "ON" by default)
1333 $orderinfo->{uncertainprice
}=1 if $orderinfo->{uncertainprice
};
1335 # delete($orderinfo->{'branchcode'});
1336 # the hash contains a lot of entries not in aqorders, so get the columns ...
1337 my $sth = $dbh->prepare("SELECT * FROM aqorders LIMIT 1;");
1339 my $colnames = $sth->{NAME
};
1340 #FIXME Be careful. If aqorders would have columns with diacritics,
1341 #you should need to decode what you get back from NAME.
1342 #See report 10110 and guided_reports.pl
1343 my $query = "UPDATE aqorders SET ";
1345 foreach my $orderinfokey (grep(!/ordernumber/, keys %$orderinfo)){
1346 # ... and skip hash entries that are not in the aqorders table
1347 # FIXME : probably not the best way to do it (would be better to have a correct hash)
1348 next unless grep(/^$orderinfokey$/, @
$colnames);
1349 $query .= "$orderinfokey=?, ";
1350 push(@params, $orderinfo->{$orderinfokey});
1353 $query .= "timestamp=NOW() WHERE ordernumber=?";
1354 push(@params, $orderinfo->{'ordernumber'} );
1355 $sth = $dbh->prepare($query);
1356 $sth->execute(@params);
1360 #------------------------------------------------------------#
1364 ModItemOrder($itemnumber, $ordernumber);
1366 Modifies the ordernumber of an item in aqorders_items.
1371 my ($itemnumber, $ordernumber) = @_;
1373 return unless ($itemnumber and $ordernumber);
1375 my $dbh = C4
::Context
->dbh;
1377 UPDATE aqorders_items
1379 WHERE itemnumber
= ?
1381 my $sth = $dbh->prepare($query);
1382 return $sth->execute($ordernumber, $itemnumber);
1385 #------------------------------------------------------------#
1387 =head3 ModReceiveOrder
1389 my ( $date_received, $new_ordernumber ) = ModReceiveOrder(
1391 biblionumber => $biblionumber,
1393 quantityreceived => $quantityreceived,
1395 invoice => $invoice,
1396 budget_id => $budget_id,
1397 received_itemnumbers => \@received_itemnumbers,
1398 order_internalnote => $order_internalnote,
1402 Updates an order, to reflect the fact that it was received, at least
1405 If a partial order is received, splits the order into two.
1407 Updates the order with biblionumber C<$biblionumber> and ordernumber
1408 C<$order->{ordernumber}>.
1413 sub ModReceiveOrder
{
1415 my $biblionumber = $params->{biblionumber
};
1416 my $order = { %{ $params->{order
} } }; # Copy the order, we don't want to modify it
1417 my $invoice = $params->{invoice
};
1418 my $quantrec = $params->{quantityreceived
};
1419 my $user = $params->{user
};
1420 my $budget_id = $params->{budget_id
};
1421 my $received_items = $params->{received_items
};
1423 my $dbh = C4
::Context
->dbh;
1424 my $datereceived = ( $invoice and $invoice->{datereceived
} ) ?
$invoice->{datereceived
} : dt_from_string
;
1425 my $suggestionid = GetSuggestionFromBiblionumber
( $biblionumber );
1426 if ($suggestionid) {
1427 ModSuggestion
( {suggestionid
=>$suggestionid,
1428 STATUS
=>'AVAILABLE',
1429 biblionumber
=> $biblionumber}
1433 my $result_set = $dbh->selectrow_arrayref(
1434 q{SELECT aqbasket.is_standing
1436 WHERE basketno=?},{ Slice
=> {} }, $order->{basketno
});
1437 my $is_standing = $result_set->[0]; # we assume we have a unique basket
1439 my $new_ordernumber = $order->{ordernumber
};
1440 if ( $is_standing || $order->{quantity
} > $quantrec ) {
1441 # Split order line in two parts: the first is the original order line
1442 # without received items (the quantity is decreased),
1443 # the second part is a new order line with quantity=quantityrec
1444 # (entirely received)
1448 orderstatus
= 'partial'|;
1449 $query .= q
| WHERE ordernumber
= ?
|;
1450 my $sth = $dbh->prepare($query);
1453 ( $is_standing ?
1 : ($order->{quantity
} - $quantrec) ),
1454 $order->{ordernumber
}
1457 if ( not $order->{subscriptionid
} && defined $order->{order_internalnote
} ) {
1458 $dbh->do(q
|UPDATE aqorders
1459 SET order_internalnote
= ?
|, {}, $order->{order_internalnote
});
1462 # Recalculate tax_value
1466 tax_value_on_ordering
= quantity
* | . get_rounding_sql
(q
|ecost_tax_excluded
|) . q
| * tax_rate_on_ordering
,
1467 tax_value_on_receiving
= quantity
* | . get_rounding_sql
(q
|unitprice_tax_excluded
|) . q
| * tax_rate_on_receiving
1468 WHERE ordernumber
= ?
1469 |, undef, $order->{ordernumber
});
1471 delete $order->{ordernumber
};
1472 $order->{budget_id
} = ( $budget_id || $order->{budget_id
} );
1473 $order->{quantity
} = $quantrec;
1474 $order->{quantityreceived
} = $quantrec;
1475 $order->{ecost_tax_excluded
} //= 0;
1476 $order->{tax_rate_on_ordering
} //= 0;
1477 $order->{unitprice_tax_excluded
} //= 0;
1478 $order->{tax_rate_on_receiving
} //= 0;
1479 $order->{tax_value_on_ordering
} = $order->{quantity
} * get_rounded_price
($order->{ecost_tax_excluded
}) * $order->{tax_rate_on_ordering
};
1480 $order->{tax_value_on_receiving
} = $order->{quantity
} * get_rounded_price
($order->{unitprice_tax_excluded
}) * $order->{tax_rate_on_receiving
};
1481 $order->{datereceived
} = $datereceived;
1482 $order->{invoiceid
} = $invoice->{invoiceid
};
1483 $order->{orderstatus
} = 'complete';
1484 $new_ordernumber = Koha
::Acquisition
::Order
->new($order)->store->ordernumber; # TODO What if the store fails?
1486 if ($received_items) {
1487 foreach my $itemnumber (@
$received_items) {
1488 ModItemOrder
($itemnumber, $new_ordernumber);
1494 SET quantityreceived
= ?
,
1498 orderstatus
= 'complete'
1502 , replacementprice
= ?
1503 | if defined $order->{replacementprice
};
1506 , unitprice
= ?
, unitprice_tax_included
= ?
, unitprice_tax_excluded
= ?
1507 | if defined $order->{unitprice
};
1510 ,tax_value_on_receiving
= ?
1511 | if defined $order->{tax_value_on_receiving
};
1514 ,tax_rate_on_receiving
= ?
1515 | if defined $order->{tax_rate_on_receiving
};
1518 , order_internalnote
= ?
1519 | if defined $order->{order_internalnote
};
1521 $query .= q
| where biblionumber
=?
and ordernumber
=?
|;
1523 my $sth = $dbh->prepare( $query );
1524 my @params = ( $quantrec, $datereceived, $invoice->{invoiceid
}, ( $budget_id ?
$budget_id : $order->{budget_id
} ) );
1526 if ( defined $order->{replacementprice
} ) {
1527 push @params, $order->{replacementprice
};
1530 if ( defined $order->{unitprice
} ) {
1531 push @params, $order->{unitprice
}, $order->{unitprice_tax_included
}, $order->{unitprice_tax_excluded
};
1534 if ( defined $order->{tax_value_on_receiving
} ) {
1535 push @params, $order->{tax_value_on_receiving
};
1538 if ( defined $order->{tax_rate_on_receiving
} ) {
1539 push @params, $order->{tax_rate_on_receiving
};
1542 if ( defined $order->{order_internalnote
} ) {
1543 push @params, $order->{order_internalnote
};
1546 push @params, ( $biblionumber, $order->{ordernumber
} );
1548 $sth->execute( @params );
1550 # All items have been received, sent a notification to users
1551 NotifyOrderUsers
( $order->{ordernumber
} );
1554 return ($datereceived, $new_ordernumber);
1557 =head3 CancelReceipt
1559 my $parent_ordernumber = CancelReceipt($ordernumber);
1561 Cancel an order line receipt and update the parent order line, as if no
1563 If items are created at receipt (AcqCreateItem = receiving) then delete
1569 my $ordernumber = shift;
1571 return unless $ordernumber;
1573 my $dbh = C4
::Context
->dbh;
1575 SELECT datereceived
, parent_ordernumber
, quantity
1577 WHERE ordernumber
= ?
1579 my $sth = $dbh->prepare($query);
1580 $sth->execute($ordernumber);
1581 my $order = $sth->fetchrow_hashref;
1583 warn "CancelReceipt: order $ordernumber does not exist";
1586 unless($order->{'datereceived'}) {
1587 warn "CancelReceipt: order $ordernumber is not received";
1591 my $parent_ordernumber = $order->{'parent_ordernumber'};
1593 my $order_obj = Koha
::Acquisition
::Orders
->find( $ordernumber ); # FIXME rewrite all this subroutine using this object
1594 my @itemnumbers = $order_obj->items->get_column('itemnumber');
1596 if($parent_ordernumber == $ordernumber || not $parent_ordernumber) {
1597 # The order line has no parent, just mark it as not received
1600 SET quantityreceived
= ?
,
1603 orderstatus
= 'ordered'
1604 WHERE ordernumber
= ?
1606 $sth = $dbh->prepare($query);
1607 $sth->execute(0, undef, undef, $ordernumber);
1608 _cancel_items_receipt
( $order_obj );
1610 # The order line has a parent, increase parent quantity and delete
1613 SELECT quantity
, datereceived
1615 WHERE ordernumber
= ?
1617 $sth = $dbh->prepare($query);
1618 $sth->execute($parent_ordernumber);
1619 my $parent_order = $sth->fetchrow_hashref;
1620 unless($parent_order) {
1621 warn "Parent order $parent_ordernumber does not exist.";
1624 if($parent_order->{'datereceived'}) {
1625 warn "CancelReceipt: parent order is received.".
1626 " Can't cancel receipt.";
1632 orderstatus
= 'ordered'
1633 WHERE ordernumber
= ?
1635 $sth = $dbh->prepare($query);
1636 my $rv = $sth->execute(
1637 $order->{'quantity'} + $parent_order->{'quantity'},
1641 warn "Cannot update parent order line, so do not cancel".
1646 # Recalculate tax_value
1650 tax_value_on_ordering
= quantity
* | . get_rounding_sql
(q
|ecost_tax_excluded
|) . q
| * tax_rate_on_ordering
,
1651 tax_value_on_receiving
= quantity
* | . get_rounding_sql
(q
|unitprice_tax_excluded
|) . q
| * tax_rate_on_receiving
1652 WHERE ordernumber
= ?
1653 |, undef, $parent_ordernumber);
1655 _cancel_items_receipt
( $order_obj, $parent_ordernumber );
1658 DELETE FROM aqorders
1659 WHERE ordernumber
= ?
1661 $sth = $dbh->prepare($query);
1662 $sth->execute($ordernumber);
1666 if( $order_obj->basket->effective_create_items eq 'ordering' ) {
1667 my @affects = split q{\|}, C4
::Context
->preference("AcqItemSetSubfieldsWhenReceiptIsCancelled");
1669 for my $in ( @itemnumbers ) {
1670 my $item = Koha
::Items
->find( $in ); # FIXME We do not need that, we already have Koha::Items from $order_obj->items
1671 my $biblio = $item->biblio;
1672 my ( $itemfield ) = GetMarcFromKohaField
( 'items.itemnumber', $biblio->frameworkcode );
1673 my $item_marc = C4
::Items
::GetMarcItem
( $biblio->biblionumber, $in );
1674 for my $affect ( @affects ) {
1675 my ( $sf, $v ) = split q{=}, $affect, 2;
1676 foreach ( $item_marc->field($itemfield) ) {
1677 $_->update( $sf => $v );
1680 C4
::Items
::ModItemFromMarc
( $item_marc, $biblio->biblionumber, $in );
1685 return $parent_ordernumber;
1688 sub _cancel_items_receipt
{
1689 my ( $order, $parent_ordernumber ) = @_;
1690 $parent_ordernumber ||= $order->ordernumber;
1692 my $items = $order->items;
1693 if ( $order->basket->effective_create_items eq 'receiving' ) {
1694 # Remove items that were created at receipt
1696 DELETE FROM items
, aqorders_items
1697 USING items
, aqorders_items
1698 WHERE items
.itemnumber
= ? AND aqorders_items
.itemnumber
= ?
1700 my $dbh = C4
::Context
->dbh;
1701 my $sth = $dbh->prepare($query);
1702 while ( my $item = $items->next ) {
1703 $sth->execute($item->itemnumber, $item->itemnumber);
1707 while ( my $item = $items->next ) {
1708 ModItemOrder
($item->itemnumber, $parent_ordernumber);
1713 #------------------------------------------------------------#
1717 @results = &SearchOrders({
1718 ordernumber => $ordernumber,
1721 booksellerid => $booksellerid,
1722 basketno => $basketno,
1723 basketname => $basketname,
1724 basketgroupname => $basketgroupname,
1728 biblionumber => $biblionumber,
1729 budget_id => $budget_id
1732 Searches for orders filtered by criteria.
1734 C<$ordernumber> Finds matching orders or transferred orders by ordernumber.
1735 C<$search> Finds orders matching %$search% in title, author, or isbn.
1736 C<$owner> Finds order for the logged in user.
1737 C<$pending> Finds pending orders. Ignores completed and cancelled orders.
1738 C<$ordered> Finds orders to receive only (status 'ordered' or 'partial').
1741 C<@results> is an array of references-to-hash with the keys are fields
1742 from aqorders, biblio, biblioitems and aqbasket tables.
1747 my ( $params ) = @_;
1748 my $ordernumber = $params->{ordernumber
};
1749 my $search = $params->{search
};
1750 my $ean = $params->{ean
};
1751 my $booksellerid = $params->{booksellerid
};
1752 my $basketno = $params->{basketno
};
1753 my $basketname = $params->{basketname
};
1754 my $basketgroupname = $params->{basketgroupname
};
1755 my $owner = $params->{owner
};
1756 my $pending = $params->{pending
};
1757 my $ordered = $params->{ordered
};
1758 my $biblionumber = $params->{biblionumber
};
1759 my $budget_id = $params->{budget_id
};
1761 my $dbh = C4
::Context
->dbh;
1764 SELECT aqbasket.basketno,
1766 borrowers.firstname,
1769 biblioitems.biblioitemnumber,
1770 biblioitems.publishercode,
1771 biblioitems.publicationyear,
1772 aqbasket.authorisedby,
1773 aqbasket.booksellerid,
1775 aqbasket.creationdate,
1776 aqbasket.basketname,
1777 aqbasketgroups.id as basketgroupid,
1778 aqbasketgroups.name as basketgroupname,
1781 LEFT JOIN aqbasket ON aqorders.basketno = aqbasket.basketno
1782 LEFT JOIN aqbasketgroups ON aqbasket.basketgroupid = aqbasketgroups.id
1783 LEFT JOIN borrowers ON aqbasket.authorisedby=borrowers.borrowernumber
1784 LEFT JOIN biblio ON aqorders.biblionumber=biblio.biblionumber
1785 LEFT JOIN biblioitems ON biblioitems.biblionumber=biblio.biblionumber
1788 # If we search on ordernumber, we retrieve the transferred order if a transfer has been done.
1790 LEFT JOIN aqorders_transfers ON aqorders_transfers.ordernumber_to = aqorders.ordernumber
1794 WHERE (datecancellationprinted is NULL)
1797 if ( $pending or $ordered ) {
1800 ( aqbasket.is_standing AND aqorders.orderstatus IN ( "new", "ordered", "partial" ) )
1802 ( quantity > quantityreceived OR quantityreceived is NULL )
1806 $query .= q{ AND aqorders.orderstatus IN ( "ordered", "partial" )};
1814 my $userenv = C4
::Context
->userenv;
1815 if ( C4
::Context
->preference("IndependentBranches") ) {
1816 unless ( C4
::Context
->IsSuperLibrarian() ) {
1819 borrowers.branchcode = ?
1820 OR borrowers.branchcode = ''
1823 push @args, $userenv->{branch
};
1827 if ( $ordernumber ) {
1828 $query .= ' AND ( aqorders.ordernumber = ? OR aqorders_transfers.ordernumber_from = ? ) ';
1829 push @args, ( $ordernumber, $ordernumber );
1831 if ( $biblionumber ) {
1832 $query .= 'AND aqorders.biblionumber = ?';
1833 push @args, $biblionumber;
1836 $query .= ' AND (biblio.title LIKE ? OR biblio.author LIKE ? OR biblioitems.isbn LIKE ?)';
1837 push @args, ("%$search%","%$search%","%$search%");
1840 $query .= ' AND biblioitems.ean = ?';
1843 if ( $booksellerid ) {
1844 $query .= 'AND aqbasket.booksellerid = ?';
1845 push @args, $booksellerid;
1848 $query .= 'AND aqbasket.basketno = ?';
1849 push @args, $basketno;
1852 $query .= 'AND aqbasket.basketname LIKE ?';
1853 push @args, "%$basketname%";
1855 if( $basketgroupname ) {
1856 $query .= ' AND aqbasketgroups.name LIKE ?';
1857 push @args, "%$basketgroupname%";
1861 $query .= ' AND aqbasket.authorisedby=? ';
1862 push @args, $userenv->{'number'};
1866 $query .= ' AND aqorders.budget_id = ?';
1867 push @args, $budget_id;
1870 $query .= ' ORDER BY aqbasket.basketno';
1872 my $sth = $dbh->prepare($query);
1873 $sth->execute(@args);
1874 return $sth->fetchall_arrayref({});
1877 #------------------------------------------------------------#
1881 &DelOrder($biblionumber, $ordernumber);
1883 Cancel the order with the given order and biblio numbers. It does not
1884 delete any entries in the aqorders table, it merely marks them as
1890 my ( $bibnum, $ordernumber, $delete_biblio, $reason ) = @_;
1893 my $dbh = C4
::Context
->dbh;
1896 SET datecancellationprinted=now(), orderstatus='cancelled'
1899 $query .= ", cancellationreason = ? ";
1902 WHERE biblionumber=? AND ordernumber=?
1904 my $sth = $dbh->prepare($query);
1906 $sth->execute($reason, $bibnum, $ordernumber);
1908 $sth->execute( $bibnum, $ordernumber );
1912 my $order = Koha
::Acquisition
::Orders
->find($ordernumber);
1913 my $items = $order->items;
1914 while ( my $item = $items->next ) { # Should be moved to Koha::Acquisition::Order->delete
1915 my $delcheck = C4
::Items
::DelItemCheck
( $bibnum, $item->itemnumber );
1917 if($delcheck != 1) {
1918 $error->{'delitem'} = 1;
1922 if($delete_biblio) {
1923 # We get the number of remaining items
1924 my $biblio = Koha
::Biblios
->find( $bibnum );
1925 my $itemcount = $biblio->items->count;
1927 # If there are no items left,
1928 if ( $itemcount == 0 ) {
1929 # We delete the record
1930 my $delcheck = DelBiblio
($bibnum);
1933 $error->{'delbiblio'} = 1;
1941 =head3 TransferOrder
1943 my $newordernumber = TransferOrder($ordernumber, $basketno);
1945 Transfer an order line to a basket.
1946 Mark $ordernumber as cancelled with an internal note 'Cancelled and transferred
1947 to BOOKSELLER on DATE' and create new order with internal note
1948 'Transferred from BOOKSELLER on DATE'.
1949 Move all attached items to the new order.
1950 Received orders cannot be transferred.
1951 Return the ordernumber of created order.
1956 my ($ordernumber, $basketno) = @_;
1958 return unless ($ordernumber and $basketno);
1960 my $order = Koha
::Acquisition
::Orders
->find( $ordernumber ) or return;
1961 return if $order->datereceived;
1963 $order = $order->unblessed;
1965 my $basket = GetBasket
($basketno);
1966 return unless $basket;
1968 my $dbh = C4
::Context
->dbh;
1969 my ($query, $sth, $rv);
1973 SET datecancellationprinted = CAST(NOW() AS date), orderstatus = ?
1974 WHERE ordernumber = ?
1976 $sth = $dbh->prepare($query);
1977 $rv = $sth->execute('cancelled', $ordernumber);
1979 delete $order->{'ordernumber'};
1980 delete $order->{parent_ordernumber
};
1981 $order->{'basketno'} = $basketno;
1983 my $newordernumber = Koha
::Acquisition
::Order
->new($order)->store->ordernumber;
1986 UPDATE aqorders_items
1988 WHERE ordernumber = ?
1990 $sth = $dbh->prepare($query);
1991 $sth->execute($newordernumber, $ordernumber);
1994 INSERT INTO aqorders_transfers (ordernumber_from, ordernumber_to)
1997 $sth = $dbh->prepare($query);
1998 $sth->execute($ordernumber, $newordernumber);
2000 return $newordernumber;
2003 =head3 get_rounding_sql
2005 $rounding_sql = get_rounding_sql($column_name);
2007 returns the correct SQL routine based on OrderPriceRounding system preference.
2011 sub get_rounding_sql
{
2012 my ( $round_string ) = @_;
2013 my $rounding_pref = C4
::Context
->preference('OrderPriceRounding') // q{};
2014 if ( $rounding_pref eq "nearest_cent" ) {
2015 return "CAST($round_string*100 AS SIGNED)/100";
2017 return $round_string;
2020 =head3 get_rounded_price
2022 $rounded_price = get_rounded_price( $price );
2024 returns a price rounded as specified in OrderPriceRounding system preference.
2028 sub get_rounded_price
{
2030 my $rounding_pref = C4
::Context
->preference('OrderPriceRounding') // q{};
2031 if( $rounding_pref eq 'nearest_cent' ) {
2032 return Koha
::Number
::Price
->new( $price )->round();
2038 =head2 FUNCTIONS ABOUT PARCELS
2042 $results = &GetParcels($bookseller, $order, $code, $datefrom, $dateto);
2044 get a lists of parcels.
2051 is the bookseller this function has to get parcels.
2054 To know on what criteria the results list has to be ordered.
2057 is the booksellerinvoicenumber.
2059 =item $datefrom & $dateto
2060 to know on what date this function has to filter its search.
2065 a pointer on a hash list containing parcel informations as such :
2071 =item Last operation
2073 =item Number of biblio
2075 =item Number of items
2082 my ($bookseller,$order, $code, $datefrom, $dateto) = @_;
2083 my $dbh = C4
::Context
->dbh;
2084 my @query_params = ();
2086 SELECT aqinvoices.invoicenumber,
2087 datereceived,purchaseordernumber,
2088 count(DISTINCT biblionumber) AS biblio,
2089 sum(quantity) AS itemsexpected,
2090 sum(quantityreceived) AS itemsreceived
2091 FROM aqorders LEFT JOIN aqbasket ON aqbasket.basketno = aqorders.basketno
2092 LEFT JOIN aqinvoices ON aqorders.invoiceid = aqinvoices.invoiceid
2093 WHERE aqbasket.booksellerid = ? and datereceived IS NOT NULL
2095 push @query_params, $bookseller;
2097 if ( defined $code ) {
2098 $strsth .= ' and aqinvoices.invoicenumber like ? ';
2099 # add a % to the end of the code to allow stemming.
2100 push @query_params, "$code%";
2103 if ( defined $datefrom ) {
2104 $strsth .= ' and datereceived >= ? ';
2105 push @query_params, $datefrom;
2108 if ( defined $dateto ) {
2109 $strsth .= 'and datereceived <= ? ';
2110 push @query_params, $dateto;
2113 $strsth .= "group by aqinvoices.invoicenumber,datereceived ";
2115 # can't use a placeholder to place this column name.
2116 # but, we could probably be checking to make sure it is a column that will be fetched.
2117 $strsth .= "order by $order " if ($order);
2119 my $sth = $dbh->prepare($strsth);
2121 $sth->execute( @query_params );
2122 my $results = $sth->fetchall_arrayref({});
2126 #------------------------------------------------------------#
2128 =head3 GetLateOrders
2130 @results = &GetLateOrders;
2132 Searches for bookseller with late orders.
2135 the table of supplier with late issues. This table is full of hashref.
2141 my $supplierid = shift;
2143 my $estimateddeliverydatefrom = shift;
2144 my $estimateddeliverydateto = shift;
2146 my $dbh = C4
::Context
->dbh;
2148 #BEWARE, order of parenthesis and LEFT JOIN is important for speed
2149 my $dbdriver = C4
::Context
->config("db_scheme") || "mysql";
2151 my @query_params = ();
2153 SELECT aqbasket.basketno,
2154 aqorders.ordernumber,
2155 DATE(aqbasket.closedate) AS orderdate,
2156 aqbasket.basketname AS basketname,
2157 aqbasket.basketgroupid AS basketgroupid,
2158 aqbasketgroups.name AS basketgroupname,
2159 aqorders.rrp AS unitpricesupplier,
2160 aqorders.ecost AS unitpricelib,
2161 aqorders.claims_count AS claims_count,
2162 aqorders.claimed_date AS claimed_date,
2163 aqbudgets.budget_name AS budget,
2164 borrowers.branchcode AS branch,
2165 aqbooksellers.name AS supplier,
2166 aqbooksellers.id AS supplierid,
2167 biblio.author, biblio.title,
2168 biblioitems.publishercode AS publisher,
2169 biblioitems.publicationyear,
2170 ADDDATE(aqbasket.closedate, INTERVAL aqbooksellers.deliverytime DAY) AS estimateddeliverydate,
2174 aqorders LEFT JOIN biblio ON biblio.biblionumber = aqorders.biblionumber
2175 LEFT JOIN biblioitems ON biblioitems.biblionumber = biblio.biblionumber
2176 LEFT JOIN aqbudgets ON aqorders.budget_id = aqbudgets.budget_id,
2177 aqbasket LEFT JOIN borrowers ON aqbasket.authorisedby = borrowers.borrowernumber
2178 LEFT JOIN aqbooksellers ON aqbasket.booksellerid = aqbooksellers.id
2179 LEFT JOIN aqbasketgroups ON aqbasket.basketgroupid = aqbasketgroups.id
2180 WHERE aqorders.basketno = aqbasket.basketno
2181 AND ( datereceived = ''
2182 OR datereceived IS NULL
2183 OR aqorders.quantityreceived < aqorders.quantity
2185 AND aqbasket.closedate IS NOT NULL
2186 AND (aqorders.datecancellationprinted IS NULL OR aqorders.datecancellationprinted='0000-00-00')
2188 if ($dbdriver eq "mysql") {
2190 aqorders.quantity - COALESCE(aqorders.quantityreceived,0) AS quantity,
2191 (aqorders.quantity - COALESCE(aqorders.quantityreceived,0)) * aqorders.rrp AS subtotal,
2192 DATEDIFF(CAST(now() AS date),closedate) AS latesince
2194 if ( defined $delay ) {
2195 $from .= " AND (closedate <= DATE_SUB(CAST(now() AS date),INTERVAL ? DAY)) " ;
2196 push @query_params, $delay;
2198 $from .= " AND aqorders.quantity - COALESCE(aqorders.quantityreceived,0) <> 0";
2200 # FIXME: account for IFNULL as above
2202 aqorders.quantity AS quantity,
2203 aqorders.quantity * aqorders.rrp AS subtotal,
2204 (CAST(now() AS date) - closedate) AS latesince
2206 if ( defined $delay ) {
2207 $from .= " AND (closedate <= (CAST(now() AS date) -(INTERVAL ? DAY)) ";
2208 push @query_params, $delay;
2210 $from .= " AND aqorders.quantity <> 0";
2212 if (defined $supplierid) {
2213 $from .= ' AND aqbasket.booksellerid = ? ';
2214 push @query_params, $supplierid;
2216 if (defined $branch) {
2217 $from .= ' AND borrowers.branchcode LIKE ? ';
2218 push @query_params, $branch;
2221 if ( defined $estimateddeliverydatefrom or defined $estimateddeliverydateto ) {
2222 $from .= ' AND aqbooksellers.deliverytime IS NOT NULL ';
2224 if ( defined $estimateddeliverydatefrom ) {
2225 $from .= ' AND ADDDATE(aqbasket.closedate, INTERVAL aqbooksellers.deliverytime DAY) >= ?';
2226 push @query_params, $estimateddeliverydatefrom;
2228 if ( defined $estimateddeliverydateto ) {
2229 $from .= ' AND ADDDATE(aqbasket.closedate, INTERVAL aqbooksellers.deliverytime DAY) <= ?';
2230 push @query_params, $estimateddeliverydateto;
2232 if ( defined $estimateddeliverydatefrom and not defined $estimateddeliverydateto ) {
2233 $from .= ' AND ADDDATE(aqbasket.closedate, INTERVAL aqbooksellers.deliverytime DAY) <= CAST(now() AS date)';
2235 if (C4
::Context
->preference("IndependentBranches")
2236 && !C4
::Context
->IsSuperLibrarian() ) {
2237 $from .= ' AND borrowers.branchcode LIKE ? ';
2238 push @query_params, C4
::Context
->userenv->{branch
};
2240 $from .= " AND orderstatus <> 'cancelled' ";
2241 my $query = "$select $from \nORDER BY latesince, basketno, borrowers.branchcode, supplier";
2242 $debug and print STDERR
"GetLateOrders query: $query\nGetLateOrders args: " . join(" ",@query_params);
2243 my $sth = $dbh->prepare($query);
2244 $sth->execute(@query_params);
2246 while (my $data = $sth->fetchrow_hashref) {
2247 push @results, $data;
2252 #------------------------------------------------------------#
2256 \@order_loop = GetHistory( %params );
2258 Retreives some acquisition history information
2268 basket - search both basket name and number
2269 booksellerinvoicenumber
2272 orderstatus (note that orderstatus '' will retrieve orders
2273 of any status except cancelled)
2275 get_canceled_order (if set to a true value, cancelled orders will
2279 $order_loop is a list of hashrefs that each look like this:
2281 'author' => 'Twain, Mark',
2283 'biblionumber' => '215',
2285 'creationdate' => 'MM/DD/YYYY',
2286 'datereceived' => undef,
2289 'invoicenumber' => undef,
2291 'ordernumber' => '1',
2293 'quantityreceived' => undef,
2294 'title' => 'The Adventures of Huckleberry Finn'
2300 # don't run the query if there are no parameters (list would be too long for sure !)
2301 croak
"No search params" unless @_;
2303 my $title = $params{title
};
2304 my $author = $params{author
};
2305 my $isbn = $params{isbn
};
2306 my $ean = $params{ean
};
2307 my $name = $params{name
};
2308 my $from_placed_on = $params{from_placed_on
};
2309 my $to_placed_on = $params{to_placed_on
};
2310 my $basket = $params{basket
};
2311 my $booksellerinvoicenumber = $params{booksellerinvoicenumber
};
2312 my $basketgroupname = $params{basketgroupname
};
2313 my $budget = $params{budget
};
2314 my $orderstatus = $params{orderstatus
};
2315 my $biblionumber = $params{biblionumber
};
2316 my $get_canceled_order = $params{get_canceled_order
} || 0;
2317 my $ordernumber = $params{ordernumber
};
2318 my $search_children_too = $params{search_children_too
} || 0;
2319 my $created_by = $params{created_by
} || [];
2320 my $ordernumbers = $params{ordernumbers
} || [];
2324 my $total_qtyreceived = 0;
2325 my $total_price = 0;
2327 #get variation of isbn
2331 if ( C4
::Context
->preference("SearchWithISBNVariations") ){
2332 @isbns = C4
::Koha
::GetVariationsOfISBN
( $isbn );
2333 foreach my $isb (@isbns){
2334 push @isbn_params, '?';
2339 push @isbn_params, '?';
2343 my $dbh = C4
::Context
->dbh;
2346 COALESCE(biblio.title, deletedbiblio.title) AS title,
2347 COALESCE(biblio.author, deletedbiblio.author) AS author,
2348 COALESCE(biblioitems.isbn, deletedbiblioitems.isbn) AS isbn,
2349 COALESCE(biblioitems.ean, deletedbiblioitems.ean) AS ean,
2351 aqbasket.basketname,
2352 aqbasket.basketgroupid,
2353 aqbasket.authorisedby,
2354 concat( borrowers.firstname,' ',borrowers.surname) AS authorisedbyname,
2355 aqbasketgroups.name as groupname,
2357 aqbasket.creationdate,
2358 aqorders.datereceived,
2360 aqorders.quantityreceived,
2362 aqorders.ordernumber,
2364 aqinvoices.invoicenumber,
2365 aqbooksellers.id as id,
2366 aqorders.biblionumber,
2367 aqorders.orderstatus,
2368 aqorders.parent_ordernumber,
2369 aqbudgets.budget_name
2371 $query .= ", aqbudgets.budget_id AS budget" if defined $budget;
2374 LEFT JOIN aqbasket ON aqorders.basketno=aqbasket.basketno
2375 LEFT JOIN aqbasketgroups ON aqbasket.basketgroupid=aqbasketgroups.id
2376 LEFT JOIN aqbooksellers ON aqbasket.booksellerid=aqbooksellers.id
2377 LEFT JOIN biblioitems ON biblioitems.biblionumber=aqorders.biblionumber
2378 LEFT JOIN biblio ON biblio.biblionumber=aqorders.biblionumber
2379 LEFT JOIN aqbudgets ON aqorders.budget_id=aqbudgets.budget_id
2380 LEFT JOIN aqinvoices ON aqorders.invoiceid = aqinvoices.invoiceid
2381 LEFT JOIN deletedbiblio ON deletedbiblio.biblionumber=aqorders.biblionumber
2382 LEFT JOIN deletedbiblioitems ON deletedbiblioitems.biblionumber=aqorders.biblionumber
2383 LEFT JOIN borrowers ON aqbasket.authorisedby=borrowers.borrowernumber
2386 $query .= " WHERE 1 ";
2388 unless ($get_canceled_order or (defined $orderstatus and $orderstatus eq 'cancelled')) {
2389 $query .= " AND (datecancellationprinted is NULL or datecancellationprinted='0000-00-00') ";
2392 my @query_params = ();
2394 if ( $biblionumber ) {
2395 $query .= " AND biblio.biblionumber = ?";
2396 push @query_params, $biblionumber;
2400 $query .= " AND biblio.title LIKE ? ";
2401 $title =~ s/\s+/%/g;
2402 push @query_params, "%$title%";
2406 $query .= " AND biblio.author LIKE ? ";
2407 push @query_params, "%$author%";
2411 $query .= " AND ( biblioitems.isbn LIKE " . join (" OR biblioitems.isbn LIKE ", @isbn_params ) . ")";
2412 foreach my $isb (@isbns){
2413 push @query_params, "%$isb%";
2418 $query .= " AND biblioitems.ean = ? ";
2419 push @query_params, "$ean";
2422 $query .= " AND aqbooksellers.name LIKE ? ";
2423 push @query_params, "%$name%";
2427 $query .= " AND aqbudgets.budget_id = ? ";
2428 push @query_params, "$budget";
2431 if ( $from_placed_on ) {
2432 $query .= " AND creationdate >= ? ";
2433 push @query_params, $from_placed_on;
2436 if ( $to_placed_on ) {
2437 $query .= " AND creationdate <= ? ";
2438 push @query_params, $to_placed_on;
2441 if ( defined $orderstatus and $orderstatus ne '') {
2442 $query .= " AND aqorders.orderstatus = ? ";
2443 push @query_params, "$orderstatus";
2447 if ($basket =~ m/^\d+$/) {
2448 $query .= " AND aqorders.basketno = ? ";
2449 push @query_params, $basket;
2451 $query .= " AND aqbasket.basketname LIKE ? ";
2452 push @query_params, "%$basket%";
2456 if ($booksellerinvoicenumber) {
2457 $query .= " AND aqinvoices.invoicenumber LIKE ? ";
2458 push @query_params, "%$booksellerinvoicenumber%";
2461 if ($basketgroupname) {
2462 $query .= " AND aqbasketgroups.name LIKE ? ";
2463 push @query_params, "%$basketgroupname%";
2467 $query .= " AND (aqorders.ordernumber = ? ";
2468 push @query_params, $ordernumber;
2469 if ($search_children_too) {
2470 $query .= " OR aqorders.parent_ordernumber = ? ";
2471 push @query_params, $ordernumber;
2476 if ( @
$created_by ) {
2477 $query .= ' AND aqbasket.authorisedby IN ( ' . join( ',', ('?') x @
$created_by ) . ')';
2478 push @query_params, @
$created_by;
2481 if ( @
$ordernumbers ) {
2482 $query .= ' AND (aqorders.ordernumber IN ( ' . join (',', ('?') x @
$ordernumbers ) . '))';
2483 push @query_params, @
$ordernumbers;
2486 if ( C4
::Context
->preference("IndependentBranches") ) {
2487 unless ( C4
::Context
->IsSuperLibrarian() ) {
2488 $query .= " AND (borrowers.branchcode = ? OR borrowers.branchcode ='' ) ";
2489 push @query_params, C4
::Context
->userenv->{branch
};
2492 $query .= " ORDER BY id";
2494 return $dbh->selectall_arrayref( $query, { Slice
=> {} }, @query_params );
2497 =head2 GetRecentAcqui
2499 $results = GetRecentAcqui($days);
2501 C<$results> is a ref to a table which contains hashref
2505 sub GetRecentAcqui
{
2507 my $dbh = C4
::Context
->dbh;
2511 ORDER BY timestamp DESC
2514 my $sth = $dbh->prepare($query);
2516 my $results = $sth->fetchall_arrayref({});
2520 #------------------------------------------------------------#
2524 &AddClaim($ordernumber);
2526 Add a claim for an order
2531 my ($ordernumber) = @_;
2532 my $dbh = C4
::Context
->dbh;
2535 claims_count = claims_count + 1,
2536 claimed_date = CURDATE()
2537 WHERE ordernumber = ?
2539 my $sth = $dbh->prepare($query);
2540 $sth->execute($ordernumber);
2545 my @invoices = GetInvoices(
2546 invoicenumber => $invoicenumber,
2547 supplierid => $supplierid,
2548 suppliername => $suppliername,
2549 shipmentdatefrom => $shipmentdatefrom, # ISO format
2550 shipmentdateto => $shipmentdateto, # ISO format
2551 billingdatefrom => $billingdatefrom, # ISO format
2552 billingdateto => $billingdateto, # ISO format
2553 isbneanissn => $isbn_or_ean_or_issn,
2556 publisher => $publisher,
2557 publicationyear => $publicationyear,
2558 branchcode => $branchcode,
2559 order_by => $order_by
2562 Return a list of invoices that match all given criteria.
2564 $order_by is "column_name (asc|desc)", where column_name is any of
2565 'invoicenumber', 'booksellerid', 'shipmentdate', 'billingdate', 'closedate',
2566 'shipmentcost', 'shipmentcost_budgetid'.
2568 asc is the default if omitted
2575 my @columns = qw(invoicenumber booksellerid shipmentdate billingdate
2576 closedate shipmentcost shipmentcost_budgetid);
2578 my $dbh = C4
::Context
->dbh;
2580 SELECT aqinvoices
.invoiceid
, aqinvoices
.invoicenumber
, aqinvoices
.booksellerid
, aqinvoices
.shipmentdate
, aqinvoices
.billingdate
, aqinvoices
.closedate
, aqinvoices
.shipmentcost
, aqinvoices
.shipmentcost_budgetid
, aqinvoices
.message_id
,
2581 aqbooksellers
.name AS suppliername
,
2584 aqorders
.datereceived IS NOT NULL
,
2585 aqorders
.biblionumber
,
2588 ) AS receivedbiblios
,
2591 aqorders
.subscriptionid IS NOT NULL
,
2592 aqorders
.subscriptionid
,
2595 ) AS is_linked_to_subscriptions
,
2596 SUM
(aqorders
.quantityreceived
) AS receiveditems
2598 LEFT JOIN aqbooksellers ON aqbooksellers
.id
= aqinvoices
.booksellerid
2599 LEFT JOIN aqorders ON aqorders
.invoiceid
= aqinvoices
.invoiceid
2600 LEFT JOIN aqbasket ON aqbasket
.basketno
=aqorders
.basketno
2601 LEFT JOIN borrowers ON aqbasket
.authorisedby
=borrowers
.borrowernumber
2602 LEFT JOIN biblio ON aqorders
.biblionumber
= biblio
.biblionumber
2603 LEFT JOIN biblioitems ON biblio
.biblionumber
= biblioitems
.biblionumber
2604 LEFT JOIN subscription ON biblio
.biblionumber
= subscription
.biblionumber
2609 if($args{supplierid
}) {
2610 push @bind_strs, " aqinvoices.booksellerid = ? ";
2611 push @bind_args, $args{supplierid
};
2613 if($args{invoicenumber
}) {
2614 push @bind_strs, " aqinvoices.invoicenumber LIKE ? ";
2615 push @bind_args, "%$args{invoicenumber}%";
2617 if($args{suppliername
}) {
2618 push @bind_strs, " aqbooksellers.name LIKE ? ";
2619 push @bind_args, "%$args{suppliername}%";
2621 if($args{shipmentdatefrom
}) {
2622 push @bind_strs, " aqinvoices.shipmentdate >= ? ";
2623 push @bind_args, $args{shipmentdatefrom
};
2625 if($args{shipmentdateto
}) {
2626 push @bind_strs, " aqinvoices.shipmentdate <= ? ";
2627 push @bind_args, $args{shipmentdateto
};
2629 if($args{billingdatefrom
}) {
2630 push @bind_strs, " aqinvoices.billingdate >= ? ";
2631 push @bind_args, $args{billingdatefrom
};
2633 if($args{billingdateto
}) {
2634 push @bind_strs, " aqinvoices.billingdate <= ? ";
2635 push @bind_args, $args{billingdateto
};
2637 if($args{isbneanissn
}) {
2638 push @bind_strs, " (biblioitems.isbn LIKE CONCAT('%', ?, '%') OR biblioitems.ean LIKE CONCAT('%', ?, '%') OR biblioitems.issn LIKE CONCAT('%', ?, '%') ) ";
2639 push @bind_args, $args{isbneanissn
}, $args{isbneanissn
}, $args{isbneanissn
};
2642 push @bind_strs, " biblio.title LIKE CONCAT('%', ?, '%') ";
2643 push @bind_args, $args{title
};
2646 push @bind_strs, " biblio.author LIKE CONCAT('%', ?, '%') ";
2647 push @bind_args, $args{author
};
2649 if($args{publisher
}) {
2650 push @bind_strs, " biblioitems.publishercode LIKE CONCAT('%', ?, '%') ";
2651 push @bind_args, $args{publisher
};
2653 if($args{publicationyear
}) {
2654 push @bind_strs, " ((biblioitems.publicationyear LIKE CONCAT('%', ?, '%')) OR (biblio.copyrightdate LIKE CONCAT('%', ?, '%'))) ";
2655 push @bind_args, $args{publicationyear
}, $args{publicationyear
};
2657 if($args{branchcode
}) {
2658 push @bind_strs, " borrowers.branchcode = ? ";
2659 push @bind_args, $args{branchcode
};
2661 if($args{message_id
}) {
2662 push @bind_strs, " aqinvoices.message_id = ? ";
2663 push @bind_args, $args{message_id
};
2666 $query .= " WHERE " . join(" AND ", @bind_strs) if @bind_strs;
2667 $query .= " GROUP BY aqinvoices.invoiceid, aqinvoices.invoicenumber, aqinvoices.booksellerid, aqinvoices.shipmentdate, aqinvoices.billingdate, aqinvoices.closedate, aqinvoices.shipmentcost, aqinvoices.shipmentcost_budgetid, aqinvoices.message_id, aqbooksellers.name";
2669 if($args{order_by
}) {
2670 my ($column, $direction) = split / /, $args{order_by
};
2671 if(grep /^$column$/, @columns) {
2672 $direction ||= 'ASC';
2673 $query .= " ORDER BY $column $direction";
2677 my $sth = $dbh->prepare($query);
2678 $sth->execute(@bind_args);
2680 my $results = $sth->fetchall_arrayref({});
2686 my $invoice = GetInvoice($invoiceid);
2688 Get informations about invoice with given $invoiceid
2690 Return a hash filled with aqinvoices.* fields
2695 my ($invoiceid) = @_;
2698 return unless $invoiceid;
2700 my $dbh = C4
::Context
->dbh;
2706 my $sth = $dbh->prepare($query);
2707 $sth->execute($invoiceid);
2709 $invoice = $sth->fetchrow_hashref;
2713 =head3 GetInvoiceDetails
2715 my $invoice = GetInvoiceDetails($invoiceid)
2717 Return informations about an invoice + the list of related order lines
2719 Orders informations are in $invoice->{orders} (array ref)
2723 sub GetInvoiceDetails
{
2724 my ($invoiceid) = @_;
2726 if ( !defined $invoiceid ) {
2727 carp
'GetInvoiceDetails called without an invoiceid';
2731 my $dbh = C4
::Context
->dbh;
2733 SELECT aqinvoices.*, aqbooksellers.name AS suppliername
2735 LEFT JOIN aqbooksellers ON aqinvoices.booksellerid = aqbooksellers.id
2738 my $sth = $dbh->prepare($query);
2739 $sth->execute($invoiceid);
2741 my $invoice = $sth->fetchrow_hashref;
2746 biblio.copyrightdate,
2748 biblioitems.publishercode,
2749 biblioitems.publicationyear,
2750 aqbasket.basketname,
2751 aqbasketgroups.id AS basketgroupid,
2752 aqbasketgroups.name AS basketgroupname
2754 LEFT JOIN aqbasket ON aqorders.basketno = aqbasket.basketno
2755 LEFT JOIN aqbasketgroups ON aqbasket.basketgroupid = aqbasketgroups.id
2756 LEFT JOIN biblio ON aqorders.biblionumber = biblio.biblionumber
2757 LEFT JOIN biblioitems ON aqorders.biblionumber = biblioitems.biblionumber
2760 $sth = $dbh->prepare($query);
2761 $sth->execute($invoiceid);
2762 $invoice->{orders
} = $sth->fetchall_arrayref({});
2763 $invoice->{orders
} ||= []; # force an empty arrayref if fetchall_arrayref fails
2770 my $invoiceid = AddInvoice(
2771 invoicenumber => $invoicenumber,
2772 booksellerid => $booksellerid,
2773 shipmentdate => $shipmentdate,
2774 billingdate => $billingdate,
2775 closedate => $closedate,
2776 shipmentcost => $shipmentcost,
2777 shipmentcost_budgetid => $shipmentcost_budgetid
2780 Create a new invoice and return its id or undef if it fails.
2787 return unless(%invoice and $invoice{invoicenumber
});
2789 my @columns = qw(invoicenumber booksellerid shipmentdate billingdate
2790 closedate shipmentcost shipmentcost_budgetid message_id);
2794 foreach my $key (keys %invoice) {
2795 if(0 < grep(/^$key$/, @columns)) {
2796 push @set_strs, "$key = ?";
2797 push @set_args, ($invoice{$key} || undef);
2803 my $dbh = C4
::Context
->dbh;
2804 my $query = "INSERT INTO aqinvoices SET ";
2805 $query .= join (",", @set_strs);
2806 my $sth = $dbh->prepare($query);
2807 $rv = $sth->execute(@set_args);
2809 $rv = $dbh->last_insert_id(undef, undef, 'aqinvoices', undef);
2818 invoiceid => $invoiceid, # Mandatory
2819 invoicenumber => $invoicenumber,
2820 booksellerid => $booksellerid,
2821 shipmentdate => $shipmentdate,
2822 billingdate => $billingdate,
2823 closedate => $closedate,
2824 shipmentcost => $shipmentcost,
2825 shipmentcost_budgetid => $shipmentcost_budgetid
2828 Modify an invoice, invoiceid is mandatory.
2830 Return undef if it fails.
2837 return unless(%invoice and $invoice{invoiceid
});
2839 my @columns = qw(invoicenumber booksellerid shipmentdate billingdate
2840 closedate shipmentcost shipmentcost_budgetid);
2844 foreach my $key (keys %invoice) {
2845 if(0 < grep(/^$key$/, @columns)) {
2846 push @set_strs, "$key = ?";
2847 push @set_args, ($invoice{$key} || undef);
2851 my $dbh = C4
::Context
->dbh;
2852 my $query = "UPDATE aqinvoices SET ";
2853 $query .= join(",", @set_strs);
2854 $query .= " WHERE invoiceid = ?";
2856 my $sth = $dbh->prepare($query);
2857 $sth->execute(@set_args, $invoice{invoiceid
});
2862 CloseInvoice($invoiceid);
2866 Equivalent to ModInvoice(invoiceid => $invoiceid, closedate => undef);
2871 my ($invoiceid) = @_;
2873 return unless $invoiceid;
2875 my $dbh = C4
::Context
->dbh;
2878 SET closedate
= CAST
(NOW
() AS DATE
)
2881 my $sth = $dbh->prepare($query);
2882 $sth->execute($invoiceid);
2885 =head3 ReopenInvoice
2887 ReopenInvoice($invoiceid);
2891 Equivalent to ModInvoice(invoiceid => $invoiceid, closedate => output_pref({ dt=>dt_from_string, dateonly=>1, otputpref=>'iso' }))
2896 my ($invoiceid) = @_;
2898 return unless $invoiceid;
2900 my $dbh = C4
::Context
->dbh;
2903 SET closedate
= NULL
2906 my $sth = $dbh->prepare($query);
2907 $sth->execute($invoiceid);
2912 DelInvoice($invoiceid);
2914 Delete an invoice if there are no items attached to it.
2919 my ($invoiceid) = @_;
2921 return unless $invoiceid;
2923 my $dbh = C4
::Context
->dbh;
2929 my $sth = $dbh->prepare($query);
2930 $sth->execute($invoiceid);
2931 my $res = $sth->fetchrow_arrayref;
2932 if ( $res && $res->[0] == 0 ) {
2934 DELETE FROM aqinvoices
2937 my $sth = $dbh->prepare($query);
2938 return ( $sth->execute($invoiceid) > 0 );
2943 =head3 MergeInvoices
2945 MergeInvoices($invoiceid, \@sourceids);
2947 Merge the invoices identified by the IDs in \@sourceids into
2948 the invoice identified by $invoiceid.
2953 my ($invoiceid, $sourceids) = @_;
2955 return unless $invoiceid;
2956 foreach my $sourceid (@
$sourceids) {
2957 next if $sourceid == $invoiceid;
2958 my $source = GetInvoiceDetails
($sourceid);
2959 foreach my $order (@
{$source->{'orders'}}) {
2960 $order->{'invoiceid'} = $invoiceid;
2963 DelInvoice
($source->{'invoiceid'});
2968 =head3 GetBiblioCountByBasketno
2970 $biblio_count = &GetBiblioCountByBasketno($basketno);
2972 Looks up the biblio's count that has basketno value $basketno
2978 sub GetBiblioCountByBasketno
{
2979 my ($basketno) = @_;
2980 my $dbh = C4
::Context
->dbh;
2982 SELECT COUNT( DISTINCT( biblionumber ) )
2985 AND (datecancellationprinted IS NULL OR datecancellationprinted='0000-00-00')
2988 my $sth = $dbh->prepare($query);
2989 $sth->execute($basketno);
2990 return $sth->fetchrow;
2993 =head3 populate_order_with_prices
2995 $order = populate_order_with_prices({
2996 order => $order #a hashref with the order values
2997 booksellerid => $booksellerid #FIXME - should obtain from order basket
2998 receiving => 1 # boolean representing order stage, should pass only this or ordering
2999 ordering => 1 # boolean representing order stage
3003 Sets calculated values for an order - all values are stored with pull precision regardless of rounding preference except fot
3004 tax value which is calculated on rounded values if requested
3006 For ordering the values set are:
3011 tax_value_on_ordering
3012 For receiving the value set are:
3013 unitprice_tax_included
3014 unitprice_tax_excluded
3015 tax_value_on_receiving
3017 Note: When receiving if the rounded value of the unitprice matches the rounded value of the ecost then then ecost (full precision) is used.
3019 Returns a hashref of the order
3021 FIXME: Move this to Koha::Acquisition::Order.pm
3025 sub populate_order_with_prices
{
3028 my $order = $params->{order
};
3029 my $booksellerid = $params->{booksellerid
};
3030 return unless $booksellerid;
3032 my $bookseller = Koha
::Acquisition
::Booksellers
->find( $booksellerid );
3034 my $receiving = $params->{receiving
};
3035 my $ordering = $params->{ordering
};
3036 my $discount = $order->{discount
};
3037 $discount /= 100 if $discount > 1;
3040 $order->{tax_rate_on_ordering
} //= $order->{tax_rate
};
3041 if ( $bookseller->listincgst ) {
3042 # The user entered the rrp tax included
3043 $order->{rrp_tax_included
} = $order->{rrp
};
3045 # rrp tax excluded = rrp tax included / ( 1 + tax rate )
3046 $order->{rrp_tax_excluded
} = $order->{rrp_tax_included
} / ( 1 + $order->{tax_rate_on_ordering
} );
3048 # ecost tax included = rrp tax included ( 1 - discount )
3049 $order->{ecost_tax_included
} = $order->{rrp_tax_included
} * ( 1 - $discount );
3051 # ecost tax excluded = rrp tax excluded * ( 1 - discount )
3052 $order->{ecost_tax_excluded
} = $order->{rrp_tax_excluded
} * ( 1 - $discount );
3054 # tax value = quantity * ecost tax excluded * tax rate
3055 $order->{tax_value_on_ordering
} = ( get_rounded_price
($order->{ecost_tax_included
}) - get_rounded_price
($order->{ecost_tax_excluded
}) ) * $order->{quantity
};
3059 # The user entered the rrp tax excluded
3060 $order->{rrp_tax_excluded
} = $order->{rrp
};
3062 # rrp tax included = rrp tax excluded * ( 1 - tax rate )
3063 $order->{rrp_tax_included
} = $order->{rrp_tax_excluded
} * ( 1 + $order->{tax_rate_on_ordering
} );
3065 # ecost tax excluded = rrp tax excluded * ( 1 - discount )
3066 $order->{ecost_tax_excluded
} = $order->{rrp_tax_excluded
} * ( 1 - $discount );
3068 # ecost tax included = rrp tax excluded * ( 1 + tax rate ) * ( 1 - discount ) = ecost tax excluded * ( 1 + tax rate )
3069 $order->{ecost_tax_included
} = $order->{ecost_tax_excluded
} * ( 1 + $order->{tax_rate_on_ordering
} );
3071 # tax value = quantity * ecost tax included * tax rate
3072 $order->{tax_value_on_ordering
} = $order->{quantity
} * get_rounded_price
($order->{ecost_tax_excluded
}) * $order->{tax_rate_on_ordering
};
3077 $order->{tax_rate_on_receiving
} //= $order->{tax_rate
};
3078 if ( $bookseller->invoiceincgst ) {
3079 # Trick for unitprice. If the unit price rounded value is the same as the ecost rounded value
3080 # we need to keep the exact ecost value
3081 if ( Koha
::Number
::Price
->new( $order->{unitprice
} )->round == Koha
::Number
::Price
->new( $order->{ecost_tax_included
} )->round ) {
3082 $order->{unitprice
} = $order->{ecost_tax_included
};
3085 # The user entered the unit price tax included
3086 $order->{unitprice_tax_included
} = $order->{unitprice
};
3088 # unit price tax excluded = unit price tax included / ( 1 + tax rate )
3089 $order->{unitprice_tax_excluded
} = $order->{unitprice_tax_included
} / ( 1 + $order->{tax_rate_on_receiving
} );
3092 # Trick for unitprice. If the unit price rounded value is the same as the ecost rounded value
3093 # we need to keep the exact ecost value
3094 if ( Koha
::Number
::Price
->new( $order->{unitprice
} )->round == Koha
::Number
::Price
->new( $order->{ecost_tax_excluded
} )->round ) {
3095 $order->{unitprice
} = $order->{ecost_tax_excluded
};
3098 # The user entered the unit price tax excluded
3099 $order->{unitprice_tax_excluded
} = $order->{unitprice
};
3102 # unit price tax included = unit price tax included * ( 1 + tax rate )
3103 $order->{unitprice_tax_included
} = $order->{unitprice_tax_excluded
} * ( 1 + $order->{tax_rate_on_receiving
} );
3106 # tax value = quantity * unit price tax excluded * tax rate
3107 $order->{tax_value_on_receiving
} = $order->{quantity
} * get_rounded_price
($order->{unitprice_tax_excluded
}) * $order->{tax_rate_on_receiving
};
3113 =head3 GetOrderUsers
3115 $order_users_ids = &GetOrderUsers($ordernumber);
3117 Returns a list of all borrowernumbers that are in order users list
3122 my ($ordernumber) = @_;
3124 return unless $ordernumber;
3127 SELECT borrowernumber
3129 WHERE ordernumber
= ?
3131 my $dbh = C4
::Context
->dbh;
3132 my $sth = $dbh->prepare($query);
3133 $sth->execute($ordernumber);
3134 my $results = $sth->fetchall_arrayref( {} );
3136 my @borrowernumbers;
3137 foreach (@
$results) {
3138 push @borrowernumbers, $_->{'borrowernumber'};
3141 return @borrowernumbers;
3144 =head3 ModOrderUsers
3146 my @order_users_ids = (1, 2, 3);
3147 &ModOrderUsers($ordernumber, @basketusers_ids);
3149 Delete all users from order users list, and add users in C<@order_users_ids>
3155 my ( $ordernumber, @order_users_ids ) = @_;
3157 return unless $ordernumber;
3159 my $dbh = C4
::Context
->dbh;
3161 DELETE FROM aqorder_users
3162 WHERE ordernumber
= ?
3164 my $sth = $dbh->prepare($query);
3165 $sth->execute($ordernumber);
3168 INSERT INTO aqorder_users
(ordernumber
, borrowernumber
)
3171 $sth = $dbh->prepare($query);
3172 foreach my $order_user_id (@order_users_ids) {
3173 $sth->execute( $ordernumber, $order_user_id );
3177 sub NotifyOrderUsers
{
3178 my ($ordernumber) = @_;
3180 my @borrowernumbers = GetOrderUsers
($ordernumber);
3181 return unless @borrowernumbers;
3183 my $order = GetOrder
( $ordernumber );
3184 for my $borrowernumber (@borrowernumbers) {
3185 my $patron = Koha
::Patrons
->find( $borrowernumber );
3186 my $library = $patron->library->unblessed;
3187 my $biblio = Koha
::Biblios
->find( $order->{biblionumber
} )->unblessed;
3188 my $letter = C4
::Letters
::GetPreparedLetter
(
3189 module
=> 'acquisition',
3190 letter_code
=> 'ACQ_NOTIF_ON_RECEIV',
3191 branchcode
=> $library->{branchcode
},
3192 lang
=> $patron->lang,
3194 'branches' => $library,
3195 'borrowers' => $patron->unblessed,
3196 'biblio' => $biblio,
3197 'aqorders' => $order,
3201 C4
::Letters
::EnqueueLetter
(
3204 borrowernumber
=> $borrowernumber,
3205 LibraryName
=> C4
::Context
->preference("LibraryName"),
3206 message_transport_type
=> 'email',
3208 ) or warn "can't enqueue letter $letter";
3213 =head3 FillWithDefaultValues
3215 FillWithDefaultValues( $marc_record );
3217 This will update the record with default value defined in the ACQ framework.
3218 For all existing fields, if a default value exists and there are no subfield, it will be created.
3219 If the field does not exist, it will be created too.
3223 sub FillWithDefaultValues
{
3225 my $tagslib = C4
::Biblio
::GetMarcStructure
( 1, 'ACQ', { unsafe
=> 1 } );
3228 C4
::Biblio
::GetMarcFromKohaField
( 'items.itemnumber', '' );
3229 for my $tag ( sort keys %$tagslib ) {
3231 next if $tag == $itemfield;
3232 for my $subfield ( sort keys %{ $tagslib->{$tag} } ) {
3233 next if IsMarcStructureInternal
($tagslib->{$tag}{$subfield});
3234 my $defaultvalue = $tagslib->{$tag}{$subfield}{defaultvalue
};
3235 if ( defined $defaultvalue and $defaultvalue ne '' ) {
3236 my @fields = $record->field($tag);
3238 for my $field (@fields) {
3239 unless ( defined $field->subfield($subfield) ) {
3240 $field->add_subfields(
3241 $subfield => $defaultvalue );
3246 $record->insert_fields_ordered(
3248 $tag, '', '', $subfield => $defaultvalue
3263 Koha Development Team <http://koha-community.org/>