use C4::Debug;
use C4::Templates qw(gettemplate);
use Koha::DateUtils qw( dt_from_string output_pref );
-use Koha::Acquisition::Order;
+use Koha::Acquisition::Baskets;
use Koha::Acquisition::Booksellers;
+use Koha::Acquisition::Orders;
+use Koha::Biblios;
+use Koha::Exceptions;
+use Koha::Items;
use Koha::Number::Price;
use Koha::Libraries;
+use Koha::CsvProfiles;
+use Koha::Patrons;
use C4::Koha;
&DelInvoice
&MergeInvoices
- &GetItemnumbersFromOrder
-
&AddClaim
&GetBiblioCountByBasketno
&NotifyOrderUsers
&FillWithDefaultValues
+
+ &get_rounded_price
+ &get_rounding_sql
);
}
}
-# Returns the itemnumber(s) associated with the ordernumber given in parameter
-sub GetItemnumbersFromOrder {
- my ($ordernumber) = @_;
- my $dbh = C4::Context->dbh;
- my $query = "SELECT itemnumber FROM aqorders_items WHERE ordernumber=?";
- my $sth = $dbh->prepare($query);
- $sth->execute($ordernumber);
- my @tab;
-
- while (my $order = $sth->fetchrow_hashref) {
- push @tab, $order->{'itemnumber'};
- }
-
- return @tab;
-
-}
-
-
-
-
-
-
=head1 NAME
C4::Acquisition - Koha functions for dealing with orders and acquisitions
=head3 NewBasket
$basket = &NewBasket( $booksellerid, $authorizedby, $basketname,
- $basketnote, $basketbooksellernote, $basketcontractnumber, $deliveryplace, $billingplace, $is_standing );
+ $basketnote, $basketbooksellernote, $basketcontractnumber, $deliveryplace, $billingplace, $is_standing, $create_items );
Create a new basket in aqbasket table
sub NewBasket {
my ( $booksellerid, $authorisedby, $basketname, $basketnote,
$basketbooksellernote, $basketcontractnumber, $deliveryplace,
- $billingplace, $is_standing ) = @_;
+ $billingplace, $is_standing, $create_items ) = @_;
my $dbh = C4::Context->dbh;
my $query =
'INSERT INTO aqbasket (creationdate,booksellerid,authorisedby) '
$basketnote ||= q{};
$basketbooksellernote ||= q{};
ModBasketHeader( $basket, $basketname, $basketnote, $basketbooksellernote,
- $basketcontractnumber, $booksellerid, $deliveryplace, $billingplace, $is_standing );
+ $basketcontractnumber, $booksellerid, $deliveryplace, $billingplace, $is_standing, $create_items );
return $basket;
}
my $dbh = C4::Context->dbh;
$dbh->do('UPDATE aqbasket SET closedate=now() WHERE basketno=?', {}, $basketno );
- $dbh->do( q{UPDATE aqorders SET orderstatus = 'ordered' WHERE basketno = ? AND orderstatus != 'complete'},
- {}, $basketno);
+ $dbh->do(
+q{UPDATE aqorders SET orderstatus = 'ordered' WHERE basketno = ? AND orderstatus NOT IN ( 'complete', 'cancelled')},
+ {}, $basketno
+ );
return;
}
UPDATE aqorders
SET orderstatus = 'new'
WHERE basketno = ?
- AND orderstatus != 'complete'
+ AND orderstatus NOT IN ( 'complete', 'cancelled' )
}, {}, $basketno);
return;
}
=cut
sub GetBasketAsCSV {
- my ($basketno, $cgi) = @_;
+ my ($basketno, $cgi, $csv_profile_id) = @_;
my $basket = GetBasket($basketno);
my @orders = GetOrders($basketno);
my $contract = GetContract({
});
my $template = C4::Templates::gettemplate("acqui/csv/basket.tt", "intranet", $cgi);
-
my @rows;
- foreach my $order (@orders) {
- my $bd = GetBiblioData( $order->{'biblionumber'} );
- my $row = {
- contractname => $contract->{'contractname'},
- ordernumber => $order->{'ordernumber'},
- entrydate => $order->{'entrydate'},
- isbn => $order->{'isbn'},
- author => $bd->{'author'},
- title => $bd->{'title'},
- publicationyear => $bd->{'publicationyear'},
- publishercode => $bd->{'publishercode'},
- collectiontitle => $bd->{'collectiontitle'},
- notes => $order->{'order_vendornote'},
- quantity => $order->{'quantity'},
- rrp => $order->{'rrp'},
- };
- for my $place ( qw( deliveryplace billingplace ) ) {
- if ( my $library = Koha::Libraries->find( $row->{deliveryplace} ) ) {
- $row->{$place} = $library->branchname
+ if ($csv_profile_id) {
+ my $csv_profile = Koha::CsvProfiles->find( $csv_profile_id );
+ Koha::Exceptions::ObjectNotFound->throw( 'There is no valid csv profile given') unless $csv_profile;
+
+ my $csv = Text::CSV_XS->new({'quote_char'=>'"','escape_char'=>'"','sep_char'=>$csv_profile->csv_separator,'binary'=>1});
+ my $csv_profile_content = $csv_profile->content;
+ my ( @headers, @fields );
+ while ( $csv_profile_content =~ /
+ ([^=\|]+) # header
+ =?
+ ([^\|]*) # fieldname (table.row or row)
+ \|? /gxms
+ ) {
+ my $header = $1;
+ my $field = ($2 eq '') ? $1 : $2;
+
+ $header =~ s/^\s+|\s+$//g; # Trim whitespaces
+ push @headers, $header;
+
+ $field =~ s/[^\.]*\.{1}//; # Remove the table name if exists.
+ $field =~ s/^\s+|\s+$//g; # Trim whitespaces
+ push @fields, $field;
+ }
+ for my $order (@orders) {
+ my @row;
+ my $biblio = Koha::Biblios->find( $order->{biblionumber} );
+ my $biblioitem = $biblio->biblioitem;
+ $order = { %$order, %{ $biblioitem->unblessed } };
+ if ($contract) {
+ $order = {%$order, %$contract};
}
+ $order = {%$order, %$basket, %{ $biblio->unblessed }};
+ for my $field (@fields) {
+ push @row, $order->{$field};
+ }
+ push @rows, \@row;
}
- foreach(qw(
- contractname author title publishercode collectiontitle notes
- deliveryplace billingplace
- ) ) {
- # Double the quotes to not be interpreted as a field end
- $row->{$_} =~ s/"/""/g if $row->{$_};
+ my $content = join( $csv_profile->csv_separator, @headers ) . "\n";
+ for my $row ( @rows ) {
+ $csv->combine(@$row);
+ my $string = $csv->string;
+ $content .= $string . "\n";
}
- push @rows, $row;
+ return $content;
}
+ else {
+ foreach my $order (@orders) {
+ my $biblio = Koha::Biblios->find( $order->{biblionumber} );
+ my $biblioitem = $biblio->biblioitem;
+ my $row = {
+ contractname => $contract->{'contractname'},
+ ordernumber => $order->{'ordernumber'},
+ entrydate => $order->{'entrydate'},
+ isbn => $order->{'isbn'},
+ author => $biblio->author,
+ title => $biblio->title,
+ publicationyear => $biblioitem->publicationyear,
+ publishercode => $biblioitem->publishercode,
+ collectiontitle => $biblioitem->collectiontitle,
+ notes => $order->{'order_vendornote'},
+ quantity => $order->{'quantity'},
+ rrp => $order->{'rrp'},
+ };
+ for my $place ( qw( deliveryplace billingplace ) ) {
+ if ( my $library = Koha::Libraries->find( $row->{deliveryplace} ) ) {
+ $row->{$place} = $library->branchname
+ }
+ }
+ foreach(qw(
+ contractname author title publishercode collectiontitle notes
+ deliveryplace billingplace
+ ) ) {
+ # Double the quotes to not be interpreted as a field end
+ $row->{$_} =~ s/"/""/g if $row->{$_};
+ }
+ push @rows, $row;
+ }
- @rows = sort {
- if(defined $a->{publishercode} and defined $b->{publishercode}) {
- $a->{publishercode} cmp $b->{publishercode};
- }
- } @rows;
+ @rows = sort {
+ if(defined $a->{publishercode} and defined $b->{publishercode}) {
+ $a->{publishercode} cmp $b->{publishercode};
+ }
+ } @rows;
- $template->param(rows => \@rows);
+ $template->param(rows => \@rows);
- return $template->output;
+ return $template->output;
+ }
}
my $basketgroup = GetBasketgroup( $$basket{basketgroupid} );
foreach my $order (@orders) {
- my $bd = GetBiblioData( $order->{'biblionumber'} );
+ my $biblio = Koha::Biblios->find( $order->{biblionumber} );
+ my $biblioitem = $biblio->biblioitem;
my $row = {
clientnumber => $bookseller->accountnumber,
basketname => $basket->{basketname},
ordernumber => $order->{ordernumber},
- author => $bd->{author},
- title => $bd->{title},
- publishercode => $bd->{publishercode},
- publicationyear => $bd->{publicationyear},
- collectiontitle => $bd->{collectiontitle},
+ author => $biblio->author,
+ title => $biblio->title,
+ publishercode => $biblioitem->publishercode,
+ publicationyear => $biblioitem->publicationyear,
+ collectiontitle => $biblioitem->collectiontitle,
isbn => $order->{isbn},
quantity => $order->{quantity},
rrp_tax_included => $order->{rrp_tax_included},
=item C<$is_standing> is the "is_standing" field in the aqbasket table.
+=item C<$create_items> should be set to 'ordering', 'receiving' or 'cataloguing' (or undef, in which
+case the AcqCreateItem syspref takes precedence).
+
=back
=cut
sub ModBasketHeader {
- my ($basketno, $basketname, $note, $booksellernote, $contractnumber, $booksellerid, $deliveryplace, $billingplace, $is_standing) = @_;
+ my ($basketno, $basketname, $note, $booksellernote, $contractnumber, $booksellerid, $deliveryplace, $billingplace, $is_standing, $create_items) = @_;
+
+ $is_standing ||= 0;
my $query = qq{
UPDATE aqbasket
- SET basketname=?, note=?, booksellernote=?, booksellerid=?, deliveryplace=?, billingplace=?, is_standing=?
+ SET basketname=?, note=?, booksellernote=?, booksellerid=?, deliveryplace=?, billingplace=?, is_standing=?, create_items=?
WHERE basketno=?
};
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare($query);
- $sth->execute($basketname, $note, $booksellernote, $booksellerid, $deliveryplace, $billingplace, $is_standing, $basketno);
+ $sth->execute($basketname, $note, $booksellernote, $booksellerid, $deliveryplace, $billingplace, $is_standing, $create_items || undef, $basketno);
if ( $contractnumber ) {
my $query2 ="UPDATE aqbasket SET contractnumber=? WHERE basketno=?";
my $dbh = C4::Context->dbh;
my $query = q{
- SELECT aqbasket.*,
+ 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,
SUM(aqorders.quantity) AS total_items,
SUM(
IF ( aqorders.orderstatus = 'cancelled', aqorders.quantity, 0 )
COUNT(DISTINCT aqorders.biblionumber) AS total_biblios,
SUM(
IF(aqorders.datereceived IS NULL
- AND aqorders.datecancellationprinted IS NULL
+ AND (aqorders.datecancellationprinted IS NULL OR aqorders.datecancellationprinted='0000-00-00')
, aqorders.quantity
, 0)
- ) AS expected_items
+ ) AS expected_items,
+ SUM( aqorders.uncertainprice ) AS uncertainprices
FROM aqbasket
LEFT JOIN aqorders ON aqorders.basketno = aqbasket.basketno
WHERE booksellerid = ?};
+ $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";
+
unless ( $allbaskets ) {
- $query.=" AND (closedate IS NULL OR (aqorders.quantity > aqorders.quantityreceived AND datecancellationprinted IS NULL))";
+ # Don't show the basket if it's NOT CLOSED or is FULLY RECEIVED
+ $query.=" HAVING (closedate IS NULL OR (
+ SUM(
+ IF(aqorders.datereceived IS NULL
+ AND (aqorders.datecancellationprinted IS NULL OR aqorders.datecancellationprinted='0000-00-00')
+ , aqorders.quantity
+ , 0)
+ ) > 0))"
}
- $query.=" GROUP BY aqbasket.basketno";
my $sth = $dbh->prepare($query);
$sth->execute($supplierid);
branch).
First parameter can be either a borrowernumber or a hashref as returned by
-C4::Members::GetMember.
+Koha::Patron->unblessed
Second parameter can be either a basketno or a hashref as returned by
C4::Acquisition::GetBasket.
my ($borrower, $basket, $userflags) = @_;
if (!ref $borrower) {
- $borrower = C4::Members::GetMember(borrowernumber => $borrower);
+ # FIXME This needs to be replaced
+ # We should not accept both scalar and array
+ # Tests need to be updated
+ $borrower = Koha::Patrons->find( $borrower )->unblessed;
}
if (!ref $basket) {
$basket = GetBasket($basket);
if ($AcqViewBaskets eq 'user'
&& $basket->{authorisedby} != $borrowernumber
- && grep($borrowernumber, GetBasketUsers($basketno)) == 0) {
- return 0;
+ && ! grep { $borrowernumber eq $_ } GetBasketUsers($basketno)) {
+ return 0;
}
if ($AcqViewBaskets eq 'branch' && defined $basket->{branch}
UPDATE aqorders
SET quantity = ?,
orderstatus = 'partial'|;
- $query .= q|, order_internalnote = ?| if defined $order->{order_internalnote};
$query .= q| WHERE ordernumber = ?|;
my $sth = $dbh->prepare($query);
$sth->execute(
( $is_standing ? 1 : ($order->{quantity} - $quantrec) ),
- ( defined $order->{order_internalnote} ? $order->{order_internalnote} : () ),
$order->{ordernumber}
);
+ if ( not $order->{subscriptionid} && defined $order->{order_internalnote} ) {
+ $dbh->do(
+ q|UPDATE aqorders
+ SET order_internalnote = ?
+ WHERE ordernumber = ?|, {},
+ $order->{order_internalnote}, $order->{ordernumber}
+ );
+ }
+
# Recalculate tax_value
$dbh->do(q|
UPDATE aqorders
SET
- tax_value_on_ordering = quantity * ecost_tax_excluded * tax_rate_on_ordering,
- tax_value_on_receiving = quantity * unitprice_tax_excluded * tax_rate_on_receiving
+ tax_value_on_ordering = quantity * | . get_rounding_sql(q|ecost_tax_excluded|) . q| * tax_rate_on_ordering,
+ tax_value_on_receiving = quantity * | . get_rounding_sql(q|unitprice_tax_excluded|) . q| * tax_rate_on_receiving
WHERE ordernumber = ?
|, undef, $order->{ordernumber});
$order->{tax_rate_on_ordering} //= 0;
$order->{unitprice_tax_excluded} //= 0;
$order->{tax_rate_on_receiving} //= 0;
- $order->{tax_value_on_ordering} = $order->{quantity} * $order->{ecost_tax_excluded} * $order->{tax_rate_on_ordering};
- $order->{tax_value_on_receiving} = $order->{quantity} * $order->{unitprice_tax_excluded} * $order->{tax_rate_on_receiving};
+ $order->{tax_value_on_ordering} = $order->{quantity} * get_rounded_price($order->{ecost_tax_excluded}) * $order->{tax_rate_on_ordering};
+ $order->{tax_value_on_receiving} = $order->{quantity} * get_rounded_price($order->{unitprice_tax_excluded}) * $order->{tax_rate_on_receiving};
$order->{datereceived} = $datereceived;
$order->{invoiceid} = $invoice->{invoiceid};
$order->{orderstatus} = 'complete';
- $new_ordernumber = Koha::Acquisition::Order->new($order)->insert->{ordernumber};
+ $new_ordernumber = Koha::Acquisition::Order->new($order)->store->ordernumber; # TODO What if the store fails?
if ($received_items) {
foreach my $itemnumber (@$received_items) {
|;
$query .= q|
+ , replacementprice = ?
+ | if defined $order->{replacementprice};
+
+ $query .= q|
, unitprice = ?, unitprice_tax_included = ?, unitprice_tax_excluded = ?
| if defined $order->{unitprice};
my $sth = $dbh->prepare( $query );
my @params = ( $quantrec, $datereceived, $invoice->{invoiceid}, ( $budget_id ? $budget_id : $order->{budget_id} ) );
+ if ( defined $order->{replacementprice} ) {
+ push @params, $order->{replacementprice};
+ }
+
if ( defined $order->{unitprice} ) {
push @params, $order->{unitprice}, $order->{unitprice_tax_included}, $order->{unitprice_tax_excluded};
}
my $parent_ordernumber = $order->{'parent_ordernumber'};
- my @itemnumbers = GetItemnumbersFromOrder( $ordernumber );
+ my $order_obj = Koha::Acquisition::Orders->find( $ordernumber ); # FIXME rewrite all this subroutine using this object
+ my @itemnumbers = $order_obj->items->get_column('itemnumber');
if($parent_ordernumber == $ordernumber || not $parent_ordernumber) {
# The order line has no parent, just mark it as not received
};
$sth = $dbh->prepare($query);
$sth->execute(0, undef, undef, $ordernumber);
- _cancel_items_receipt( $ordernumber );
+ _cancel_items_receipt( $order_obj );
} else {
# The order line has a parent, increase parent quantity and delete
# the order line.
$dbh->do(q|
UPDATE aqorders
SET
- tax_value_on_ordering = quantity * ecost_tax_excluded * tax_rate_on_ordering,
- tax_value_on_receiving = quantity * unitprice_tax_excluded * tax_rate_on_receiving
+ tax_value_on_ordering = quantity * | . get_rounding_sql(q|ecost_tax_excluded|) . q| * tax_rate_on_ordering,
+ tax_value_on_receiving = quantity * | . get_rounding_sql(q|unitprice_tax_excluded|) . q| * tax_rate_on_receiving
WHERE ordernumber = ?
|, undef, $parent_ordernumber);
- _cancel_items_receipt( $ordernumber, $parent_ordernumber );
+ _cancel_items_receipt( $order_obj, $parent_ordernumber );
# Delete order line
$query = qq{
DELETE FROM aqorders
}
- if(C4::Context->preference('AcqCreateItem') eq 'ordering') {
+ if( $order_obj->basket->effective_create_items eq 'ordering' ) {
my @affects = split q{\|}, C4::Context->preference("AcqItemSetSubfieldsWhenReceiptIsCancelled");
if ( @affects ) {
for my $in ( @itemnumbers ) {
- my $biblionumber = C4::Biblio::GetBiblionumberFromItemnumber( $in );
- my $frameworkcode = GetFrameworkCode($biblionumber);
- my ( $itemfield ) = GetMarcFromKohaField( 'items.itemnumber', $frameworkcode );
- my $item = C4::Items::GetMarcItem( $biblionumber, $in );
+ my $item = Koha::Items->find( $in ); # FIXME We do not need that, we already have Koha::Items from $order_obj->items
+ my $biblio = $item->biblio;
+ my ( $itemfield ) = GetMarcFromKohaField( 'items.itemnumber', $biblio->frameworkcode );
+ my $item_marc = C4::Items::GetMarcItem( $biblio->biblionumber, $in );
for my $affect ( @affects ) {
my ( $sf, $v ) = split q{=}, $affect, 2;
- foreach ( $item->field($itemfield) ) {
+ foreach ( $item_marc->field($itemfield) ) {
$_->update( $sf => $v );
}
}
- C4::Items::ModItemFromMarc( $item, $biblionumber, $in );
+ C4::Items::ModItemFromMarc( $item_marc, $biblio->biblionumber, $in );
}
}
}
}
sub _cancel_items_receipt {
- my ( $ordernumber, $parent_ordernumber ) = @_;
- $parent_ordernumber ||= $ordernumber;
+ my ( $order, $parent_ordernumber ) = @_;
+ $parent_ordernumber ||= $order->ordernumber;
- my @itemnumbers = GetItemnumbersFromOrder($ordernumber);
- if(C4::Context->preference('AcqCreateItem') eq 'receiving') {
+ my $items = $order->items;
+ if ( $order->basket->effective_create_items eq 'receiving' ) {
# Remove items that were created at receipt
my $query = qq{
DELETE FROM items, aqorders_items
};
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare($query);
- foreach my $itemnumber (@itemnumbers) {
- $sth->execute($itemnumber, $itemnumber);
+ while ( my $item = $items->next ) {
+ $sth->execute($item->itemnumber, $item->itemnumber);
}
} else {
# Update items
- foreach my $itemnumber (@itemnumbers) {
- ModItemOrder($itemnumber, $parent_ordernumber);
+ while ( my $item = $items->next ) {
+ ModItemOrder($item->itemnumber, $parent_ordernumber);
}
}
}
@results = &SearchOrders({
ordernumber => $ordernumber,
search => $search,
- biblionumber => $biblionumber,
ean => $ean,
booksellerid => $booksellerid,
basketno => $basketno,
+ basketname => $basketname,
+ basketgroupname => $basketgroupname,
owner => $owner,
pending => $pending
ordered => $ordered
+ biblionumber => $biblionumber,
+ budget_id => $budget_id
});
-Searches for orders.
+Searches for orders filtered by criteria.
+C<$ordernumber> Finds matching orders or transferred orders by ordernumber.
+C<$search> Finds orders matching %$search% in title, author, or isbn.
C<$owner> Finds order for the logged in user.
C<$pending> Finds pending orders. Ignores completed and cancelled orders.
C<$ordered> Finds orders to receive only (status 'ordered' or 'partial').
biblio.*,
biblioitems.isbn,
biblioitems.biblioitemnumber,
+ biblioitems.publishercode,
+ biblioitems.publicationyear,
aqbasket.authorisedby,
aqbasket.booksellerid,
aqbasket.closedate,
sub DelOrder {
my ( $bibnum, $ordernumber, $delete_biblio, $reason ) = @_;
-
my $error;
my $dbh = C4::Context->dbh;
my $query = "
}
$sth->finish;
- my @itemnumbers = GetItemnumbersFromOrder( $ordernumber );
- foreach my $itemnumber (@itemnumbers){
- my $delcheck = C4::Items::DelItemCheck( $bibnum, $itemnumber );
+ my $order = Koha::Acquisition::Orders->find($ordernumber);
+ my $items = $order->items;
+ while ( my $item = $items->next ) { # Should be moved to Koha::Acquisition::Order->delete
+ my $delcheck = C4::Items::DelItemCheck( $bibnum, $item->itemnumber );
if($delcheck != 1) {
$error->{'delitem'} = 1;
if($delete_biblio) {
# We get the number of remaining items
- my $itemcount = C4::Items::GetItemsCount($bibnum);
+ my $biblio = Koha::Biblios->find( $bibnum );
+ my $itemcount = $biblio->items->count;
# If there are no items left,
if ( $itemcount == 0 ) {
return unless ($ordernumber and $basketno);
- my $order = GetOrder( $ordernumber );
- return if $order->{datereceived};
+ my $order = Koha::Acquisition::Orders->find( $ordernumber ) or return;
+ return if $order->datereceived;
+
+ $order = $order->unblessed;
+
my $basket = GetBasket($basketno);
return unless $basket;
delete $order->{parent_ordernumber};
$order->{'basketno'} = $basketno;
- my $newordernumber = Koha::Acquisition::Order->new($order)->insert->{ordernumber};
+ my $newordernumber = Koha::Acquisition::Order->new($order)->store->ordernumber;
$query = q{
UPDATE aqorders_items
return $newordernumber;
}
+=head3 get_rounding_sql
+
+ $rounding_sql = get_rounding_sql($column_name);
+
+returns the correct SQL routine based on OrderPriceRounding system preference.
+
+=cut
+
+sub get_rounding_sql {
+ my ( $round_string ) = @_;
+ my $rounding_pref = C4::Context->preference('OrderPriceRounding') // q{};
+ if ( $rounding_pref eq "nearest_cent" ) {
+ return "CAST($round_string*100 AS SIGNED)/100";
+ }
+ return $round_string;
+}
+
+=head3 get_rounded_price
+
+ $rounded_price = get_rounded_price( $price );
+
+returns a price rounded as specified in OrderPriceRounding system preference.
+
+=cut
+
+sub get_rounded_price {
+ my ( $price ) = @_;
+ my $rounding_pref = C4::Context->preference('OrderPriceRounding') // q{};
+ if( $rounding_pref eq 'nearest_cent' ) {
+ return Koha::Number::Price->new( $price )->round();
+ }
+ return $price;
+}
+
+
=head2 FUNCTIONS ABOUT PARCELS
=head3 GetParcels
AND aqbasket.closedate IS NOT NULL
AND (aqorders.datecancellationprinted IS NULL OR aqorders.datecancellationprinted='0000-00-00')
";
- my $having = "";
if ($dbdriver eq "mysql") {
$select .= "
aqorders.quantity - COALESCE(aqorders.quantityreceived,0) AS quantity,
$from .= " AND (closedate <= DATE_SUB(CAST(now() AS date),INTERVAL ? DAY)) " ;
push @query_params, $delay;
}
- $having = "
- HAVING quantity <> 0
- AND unitpricesupplier <> 0
- AND unitpricelib <> 0
- ";
+ $from .= " AND aqorders.quantity - COALESCE(aqorders.quantityreceived,0) <> 0";
} else {
# FIXME: account for IFNULL as above
$select .= "
$from .= " AND (closedate <= (CAST(now() AS date) -(INTERVAL ? DAY)) ";
push @query_params, $delay;
}
+ $from .= " AND aqorders.quantity <> 0";
}
if (defined $supplierid) {
$from .= ' AND aqbasket.booksellerid = ? ';
push @query_params, C4::Context->userenv->{branch};
}
$from .= " AND orderstatus <> 'cancelled' ";
- my $query = "$select $from $having\nORDER BY latesince, basketno, borrowers.branchcode, supplier";
+ my $query = "$select $from \nORDER BY latesince, basketno, borrowers.branchcode, supplier";
$debug and print STDERR "GetLateOrders query: $query\nGetLateOrders args: " . join(" ",@query_params);
my $sth = $dbh->prepare($query);
$sth->execute(@query_params);
my $ordernumber = $params{ordernumber};
my $search_children_too = $params{search_children_too} || 0;
my $created_by = $params{created_by} || [];
+ my $ordernumbers = $params{ordernumbers} || [];
+ my $additional_fields = $params{additional_fields} // [];
my @order_loop;
my $total_qty = 0;
my $total_qtyreceived = 0;
my $total_price = 0;
+ #get variation of isbn
+ my @isbn_params;
+ my @isbns;
+ if ($isbn){
+ if ( C4::Context->preference("SearchWithISBNVariations") ){
+ @isbns = C4::Koha::GetVariationsOfISBN( $isbn );
+ foreach my $isb (@isbns){
+ push @isbn_params, '?';
+ }
+ }
+ unless (@isbns){
+ push @isbns, $isbn;
+ push @isbn_params, '?';
+ }
+ }
+
my $dbh = C4::Context->dbh;
my $query ="
SELECT
push @query_params, "%$author%";
}
- if ( $isbn ) {
- $query .= " AND biblioitems.isbn LIKE ? ";
- push @query_params, "%$isbn%";
+ if ( @isbns ) {
+ $query .= " AND ( biblioitems.isbn LIKE " . join (" OR biblioitems.isbn LIKE ", @isbn_params ) . ")";
+ foreach my $isb (@isbns){
+ push @query_params, "%$isb%";
+ }
}
+
if ( $ean ) {
$query .= " AND biblioitems.ean = ? ";
push @query_params, "$ean";
push @query_params, @$created_by;
}
+ if ( @$ordernumbers ) {
+ $query .= ' AND (aqorders.ordernumber IN ( ' . join (',', ('?') x @$ordernumbers ) . '))';
+ push @query_params, @$ordernumbers;
+ }
+ if ( @$additional_fields ) {
+ my @baskets = Koha::Acquisition::Baskets->filter_by_additional_fields($additional_fields);
+
+ return [] unless @baskets;
+
+ # No parameterization because record IDs come directly from DB
+ $query .= ' AND aqbasket.basketno IN ( ' . join( ',', map { $_->basketno } @baskets ) . ' )';
+ }
if ( C4::Context->preference("IndependentBranches") ) {
unless ( C4::Context->IsSuperLibrarian() ) {
$results = GetRecentAcqui($days);
-C<$results> is a ref to a table which containts hashref
+C<$results> is a ref to a table which contains hashref
=cut
my $dbh = C4::Context->dbh;
my $query = qq{
- SELECT aqinvoices.*, aqbooksellers.name AS suppliername,
+ SELECT aqinvoices.invoiceid, aqinvoices.invoicenumber, aqinvoices.booksellerid, aqinvoices.shipmentdate, aqinvoices.billingdate, aqinvoices.closedate, aqinvoices.shipmentcost, aqinvoices.shipmentcost_budgetid, aqinvoices.message_id,
+ aqbooksellers.name AS suppliername,
COUNT(
DISTINCT IF(
aqorders.datereceived IS NOT NULL,
}
$query .= " WHERE " . join(" AND ", @bind_strs) if @bind_strs;
- $query .= " GROUP BY aqinvoices.invoiceid ";
+ $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";
if($args{order_by}) {
my ($column, $direction) = split / /, $args{order_by};
SELECT aqorders.*,
biblio.*,
biblio.copyrightdate,
+ biblioitems.isbn,
biblioitems.publishercode,
biblioitems.publicationyear,
aqbasket.basketname,
return $sth->fetchrow;
}
-# Note this subroutine should be moved to Koha::Acquisition::Order
-# Will do when a DBIC decision will be taken.
+=head3 populate_order_with_prices
+
+$order = populate_order_with_prices({
+ order => $order #a hashref with the order values
+ booksellerid => $booksellerid #FIXME - should obtain from order basket
+ receiving => 1 # boolean representing order stage, should pass only this or ordering
+ ordering => 1 # boolean representing order stage
+});
+
+
+Sets calculated values for an order - all values are stored with pull precision regardless of rounding preference except fot
+tax value which is calculated on rounded values if requested
+
+For ordering the values set are:
+ rrp_tax_included
+ rrp_tax_excluded
+ ecost_tax_included
+ ecost_tax_excluded
+ tax_value_on_ordering
+For receiving the value set are:
+ unitprice_tax_included
+ unitprice_tax_excluded
+ tax_value_on_receiving
+
+Note: When receiving if the rounded value of the unitprice matches the rounded value of the ecost then then ecost (full precision) is used.
+
+Returns a hashref of the order
+
+FIXME: Move this to Koha::Acquisition::Order.pm
+
+=cut
+
sub populate_order_with_prices {
my ($params) = @_;
# rrp tax excluded = rrp tax included / ( 1 + tax rate )
$order->{rrp_tax_excluded} = $order->{rrp_tax_included} / ( 1 + $order->{tax_rate_on_ordering} );
+ # ecost tax included = rrp tax included ( 1 - discount )
+ $order->{ecost_tax_included} = $order->{rrp_tax_included} * ( 1 - $discount );
+
# ecost tax excluded = rrp tax excluded * ( 1 - discount )
$order->{ecost_tax_excluded} = $order->{rrp_tax_excluded} * ( 1 - $discount );
- # ecost tax included = rrp tax included ( 1 - discount )
- $order->{ecost_tax_included} = $order->{rrp_tax_included} * ( 1 - $discount );
+ # tax value = quantity * ecost tax excluded * tax rate
+ $order->{tax_value_on_ordering} = ( get_rounded_price($order->{ecost_tax_included}) - get_rounded_price($order->{ecost_tax_excluded}) ) * $order->{quantity};
+
}
else {
# The user entered the rrp tax excluded
# ecost tax excluded = rrp tax excluded * ( 1 - discount )
$order->{ecost_tax_excluded} = $order->{rrp_tax_excluded} * ( 1 - $discount );
- # ecost tax included = rrp tax excluded * ( 1 - tax rate ) * ( 1 - discount )
- $order->{ecost_tax_included} =
- $order->{rrp_tax_excluded} *
- ( 1 + $order->{tax_rate_on_ordering} ) *
- ( 1 - $discount );
- }
+ # ecost tax included = rrp tax excluded * ( 1 + tax rate ) * ( 1 - discount ) = ecost tax excluded * ( 1 + tax rate )
+ $order->{ecost_tax_included} = $order->{ecost_tax_excluded} * ( 1 + $order->{tax_rate_on_ordering} );
- # tax value = quantity * ecost tax excluded * tax rate
- $order->{tax_value_on_ordering} =
- $order->{quantity} * $order->{ecost_tax_excluded} * $order->{tax_rate_on_ordering};
+ # tax value = quantity * ecost tax included * tax rate
+ $order->{tax_value_on_ordering} = $order->{quantity} * get_rounded_price($order->{ecost_tax_excluded}) * $order->{tax_rate_on_ordering};
+ }
}
if ($receiving) {
}
# tax value = quantity * unit price tax excluded * tax rate
- $order->{tax_value_on_receiving} = $order->{quantity} * $order->{unitprice_tax_excluded} * $order->{tax_rate_on_receiving};
+ $order->{tax_value_on_receiving} = $order->{quantity} * get_rounded_price($order->{unitprice_tax_excluded}) * $order->{tax_rate_on_receiving};
}
return $order;
my $order = GetOrder( $ordernumber );
for my $borrowernumber (@borrowernumbers) {
- my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber );
- my $library = Koha::Libraries->find( $borrower->{branchcode} )->unblessed;
- my $biblio = C4::Biblio::GetBiblio( $order->{biblionumber} );
+ my $patron = Koha::Patrons->find( $borrowernumber );
+ my $library = $patron->library->unblessed;
+ my $biblio = Koha::Biblios->find( $order->{biblionumber} )->unblessed;
my $letter = C4::Letters::GetPreparedLetter(
module => 'acquisition',
letter_code => 'ACQ_NOTIF_ON_RECEIV',
branchcode => $library->{branchcode},
+ lang => $patron->lang,
tables => {
'branches' => $library,
- 'borrowers' => $borrower,
+ 'borrowers' => $patron->unblessed,
'biblio' => $biblio,
'aqorders' => $order,
},