use C4::Debug;
use C4::Templates qw(gettemplate);
use Koha::DateUtils qw( dt_from_string output_pref );
+use Koha::Acquisition::Baskets;
use Koha::Acquisition::Booksellers;
use Koha::Acquisition::Orders;
use Koha::Biblios;
&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
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 = ?};
unless ( $allbaskets ) {
# Don't show the basket if it's NOT CLOSED or is FULLY RECEIVED
- $query.=" HAVING (closedate IS NULL OR (expected_items > 0))"
+ $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))"
}
my $sth = $dbh->prepare($query);
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';
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
$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);
my @affects = split q{\|}, C4::Context->preference("AcqItemSetSubfieldsWhenReceiptIsCancelled");
if ( @affects ) {
for my $in ( @itemnumbers ) {
- my $item = Koha::Items->find( $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 );
my ( $order, $parent_ordernumber ) = @_;
$parent_ordernumber ||= $order->ordernumber;
- my @itemnumbers = GetItemnumbersFromOrder($order->ordernumber); # FIXME Must be $order->items
+ my $items = $order->items;
if ( $order->basket->effective_create_items eq 'receiving' ) {
# Remove items that were created at receipt
my $query = qq{
};
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);
}
}
}
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;
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
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;
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() ) {
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;