use C4::Templates qw(gettemplate);
use Koha::DateUtils qw( dt_from_string output_pref );
use Koha::Acquisition::Order;
-use Koha::Acquisition::Bookseller;
+use Koha::Acquisition::Booksellers;
+use Koha::Biblios;
use Koha::Number::Price;
use Koha::Libraries;
my $contract = GetContract({
contractnumber => $basket->{contractnumber}
});
- my $bookseller = Koha::Acquisition::Bookseller->fetch({ id => $basket->{booksellerid} });
+ my $bookseller = Koha::Acquisition::Booksellers->find( $basket->{booksellerid} );
my $basketgroup = GetBasketgroup( $$basket{basketgroupid} );
foreach my $order (@orders) {
my $bd = GetBiblioData( $order->{'biblionumber'} );
my $row = {
- clientnumber => $bookseller->{accountnumber},
+ clientnumber => $bookseller->accountnumber,
basketname => $basket->{basketname},
ordernumber => $order->{ordernumber},
author => $bd->{author},
collectiontitle => $bd->{collectiontitle},
isbn => $order->{isbn},
quantity => $order->{quantity},
- rrp => $order->{rrp},
- discount => $bookseller->{discount},
- ecost => $order->{ecost},
+ rrp_tax_included => $order->{rrp_tax_included},
+ rrp_tax_excluded => $order->{rrp_tax_excluded},
+ discount => $bookseller->discount,
+ ecost_tax_included => $order->{ecost_tax_included},
+ ecost_tax_excluded => $order->{ecost_tax_excluded},
notes => $order->{order_vendornote},
entrydate => $order->{entrydate},
- booksellername => $bookseller->{name},
- bookselleraddress => $bookseller->{address1},
- booksellerpostal => $bookseller->{postal},
+ booksellername => $bookseller->name,
+ bookselleraddress => $bookseller->address1,
+ booksellerpostal => $bookseller->postal,
contractnumber => $contract->{contractnumber},
contractname => $contract->{contractname},
};
=head3 ModReceiveOrder
- &ModReceiveOrder({
- biblionumber => $biblionumber,
- ordernumber => $ordernumber,
- quantityreceived => $quantityreceived,
- user => $user,
- cost => $cost,
- ecost => $ecost,
- invoiceid => $invoiceid,
- rrp => $rrp,
- budget_id => $budget_id,
- datereceived => $datereceived,
- received_itemnumbers => \@received_itemnumbers,
- order_internalnote => $order_internalnote,
- order_vendornote => $order_vendornote,
- });
+ my ( $date_received, $new_ordernumber ) = ModReceiveOrder(
+ {
+ biblionumber => $biblionumber,
+ order => $order,
+ quantityreceived => $quantityreceived,
+ user => $user,
+ invoice => $invoice,
+ budget_id => $budget_id,
+ received_itemnumbers => \@received_itemnumbers,
+ order_internalnote => $order_internalnote,
+ }
+ );
Updates an order, to reflect the fact that it was received, at least
-in part. All arguments not mentioned below update the fields with the
-same name in the aqorders table of the Koha database.
+in part.
If a partial order is received, splits the order into two.
-Updates the order with bibilionumber C<$biblionumber> and ordernumber
-C<$ordernumber>.
+Updates the order with biblionumber C<$biblionumber> and ordernumber
+C<$order->{ordernumber}>.
=cut
sub ModReceiveOrder {
- my ( $params ) = @_;
- my $biblionumber = $params->{biblionumber};
- my $ordernumber = $params->{ordernumber};
- my $quantrec = $params->{quantityreceived};
- my $user = $params->{user};
- my $cost = $params->{cost};
- my $ecost = $params->{ecost};
- my $invoiceid = $params->{invoiceid};
- my $rrp = $params->{rrp};
- my $budget_id = $params->{budget_id};
- my $datereceived = $params->{datereceived};
+ my ($params) = @_;
+ my $biblionumber = $params->{biblionumber};
+ my $order = { %{ $params->{order} } }; # Copy the order, we don't want to modify it
+ my $invoice = $params->{invoice};
+ my $quantrec = $params->{quantityreceived};
+ my $user = $params->{user};
+ my $budget_id = $params->{budget_id};
my $received_items = $params->{received_items};
- my $order_internalnote = $params->{order_internalnote};
- my $order_vendornote = $params->{order_vendornote};
my $dbh = C4::Context->dbh;
- $datereceived = output_pref(
- {
- dt => ( $datereceived ? dt_from_string( $datereceived ) : dt_from_string ),
- dateformat => 'iso',
- dateonly => 1,
- }
- );
+ my $datereceived = ( $invoice and $invoice->{datereceived} ) ? $invoice->{datereceived} : dt_from_string;
my $suggestionid = GetSuggestionFromBiblionumber( $biblionumber );
if ($suggestionid) {
ModSuggestion( {suggestionid=>$suggestionid,
);
}
- my $result_set = $dbh->selectall_arrayref(
-q{SELECT *, aqbasket.is_standing FROM aqorders LEFT JOIN aqbasket USING (basketno) WHERE biblionumber=? AND aqorders.ordernumber=?},
- { Slice => {} }, $biblionumber, $ordernumber
- );
+ my $result_set = $dbh->selectrow_arrayref(
+ q{SELECT aqbasket.is_standing
+ FROM aqbasket
+ WHERE basketno=?},{ Slice => {} }, $order->{basketno});
+ my $is_standing = $result_set->[0]; # we assume we have a unique basket
- # we assume we have a unique order
- my $order = $result_set->[0];
-
- my $new_ordernumber = $ordernumber;
- if ( $order->{is_standing} || $order->{quantity} > $quantrec ) {
+ my $new_ordernumber = $order->{ordernumber};
+ if ( $is_standing || $order->{quantity} > $quantrec ) {
# Split order line in two parts: the first is the original order line
# without received items (the quantity is decreased),
# the second part is a new order line with quantity=quantityrec
UPDATE aqorders
SET quantity = ?,
orderstatus = 'partial'|;
- $query .= q|, order_internalnote = ?| if defined $order_internalnote;
- $query .= q|, order_vendornote = ?| if defined $order_vendornote;
+ $query .= q|, order_internalnote = ?| if defined $order->{order_internalnote};
$query .= q| WHERE ordernumber = ?|;
my $sth = $dbh->prepare($query);
$sth->execute(
- ( $order->{is_standing} ? 1 : ( $order->{quantity} - $quantrec ) ),
- ( defined $order_internalnote ? $order_internalnote : () ),
- ( defined $order_vendornote ? $order_vendornote : () ),
- $ordernumber
+ ( $is_standing ? 1 : ($order->{quantity} - $quantrec) ),
+ ( defined $order->{order_internalnote} ? $order->{order_internalnote} : () ),
+ $order->{ordernumber}
);
- delete $order->{'ordernumber'};
- $order->{'budget_id'} = ( $budget_id || $order->{'budget_id'} );
- $order->{'quantity'} = $quantrec;
- $order->{'quantityreceived'} = $quantrec;
- $order->{'datereceived'} = $datereceived;
- $order->{'invoiceid'} = $invoiceid;
- $order->{'unitprice'} = $cost;
- $order->{'rrp'} = $rrp;
- $order->{ecost} = $ecost;
- $order->{'orderstatus'} = 'complete';
+ # 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
+ WHERE ordernumber = ?
+ |, undef, $order->{ordernumber});
+
+ delete $order->{ordernumber};
+ $order->{budget_id} = ( $budget_id || $order->{budget_id} );
+ $order->{quantity} = $quantrec;
+ $order->{quantityreceived} = $quantrec;
+ $order->{ecost_tax_excluded} //= 0;
+ $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->{datereceived} = $datereceived;
+ $order->{invoiceid} = $invoice->{invoiceid};
+ $order->{orderstatus} = 'complete';
$new_ordernumber = Koha::Acquisition::Order->new($order)->insert->{ordernumber};
if ($received_items) {
}
} else {
my $query = q|
- update aqorders
- set quantityreceived=?,datereceived=?,invoiceid=?,
- unitprice=?,rrp=?,ecost=?,budget_id=?,orderstatus='complete'|;
- $query .= q|, order_internalnote = ?| if defined $order_internalnote;
- $query .= q|, order_vendornote = ?| if defined $order_vendornote;
+ UPDATE aqorders
+ SET quantityreceived = ?,
+ datereceived = ?,
+ invoiceid = ?,
+ budget_id = ?,
+ orderstatus = 'complete'
+ |;
+
+ $query .= q|
+ , unitprice = ?, unitprice_tax_included = ?, unitprice_tax_excluded = ?
+ | if defined $order->{unitprice};
+
+ $query .= q|
+ ,tax_value_on_receiving = ?
+ | if defined $order->{tax_value_on_receiving};
+
+ $query .= q|
+ ,tax_rate_on_receiving = ?
+ | if defined $order->{tax_rate_on_receiving};
+
+ $query .= q|
+ , order_internalnote = ?
+ | if defined $order->{order_internalnote};
+
$query .= q| where biblionumber=? and ordernumber=?|;
+
my $sth = $dbh->prepare( $query );
- $sth->execute(
- $quantrec,
- $datereceived,
- $invoiceid,
- $cost,
- $rrp,
- $ecost,
- ( $budget_id ? $budget_id : $order->{budget_id} ),
- ( defined $order_internalnote ? $order_internalnote : () ),
- ( defined $order_vendornote ? $order_vendornote : () ),
- $biblionumber,
- $ordernumber
- );
+ my @params = ( $quantrec, $datereceived, $invoice->{invoiceid}, ( $budget_id ? $budget_id : $order->{budget_id} ) );
+
+ if ( defined $order->{unitprice} ) {
+ push @params, $order->{unitprice}, $order->{unitprice_tax_included}, $order->{unitprice_tax_excluded};
+ }
+
+ if ( defined $order->{tax_value_on_receiving} ) {
+ push @params, $order->{tax_value_on_receiving};
+ }
+
+ if ( defined $order->{tax_rate_on_receiving} ) {
+ push @params, $order->{tax_rate_on_receiving};
+ }
+
+ if ( defined $order->{order_internalnote} ) {
+ push @params, $order->{order_internalnote};
+ }
+
+ push @params, ( $biblionumber, $order->{ordernumber} );
+
+ $sth->execute( @params );
# All items have been received, sent a notification to users
- NotifyOrderUsers( $ordernumber );
+ NotifyOrderUsers( $order->{ordernumber} );
}
return ($datereceived, $new_ordernumber);
" receipt";
return;
}
+
+ # 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
+ WHERE ordernumber = ?
+ |, undef, $parent_ordernumber);
+
_cancel_items_receipt( $ordernumber, $parent_ordernumber );
# Delete order line
$query = qq{
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 $sth->fetchrow;
}
-# This is *not* the good way to calcul prices
-# But it's how it works at the moment into Koha
-# This will be fixed later.
# Note this subroutine should be moved to Koha::Acquisition::Order
# Will do when a DBIC decision will be taken.
sub populate_order_with_prices {
my $booksellerid = $params->{booksellerid};
return unless $booksellerid;
- my $bookseller = Koha::Acquisition::Bookseller->fetch({ id => $booksellerid });
+ my $bookseller = Koha::Acquisition::Booksellers->find( $booksellerid );
my $receiving = $params->{receiving};
my $ordering = $params->{ordering};
my $discount = $order->{discount};
$discount /= 100 if $discount > 1;
- $order->{rrp} = Koha::Number::Price->new( $order->{rrp} )->round;
- $order->{ecost} = Koha::Number::Price->new( $order->{ecost} )->round;
if ($ordering) {
- if ( $bookseller->{listincgst} ) {
- $order->{rrpgsti} = $order->{rrp};
- $order->{rrpgste} = Koha::Number::Price->new(
- $order->{rrpgsti} / ( 1 + $order->{gstrate} ) )->round;
- $order->{ecostgsti} = $order->{ecost};
- $order->{ecostgste} = Koha::Number::Price->new(
- $order->{ecost} / ( 1 + $order->{gstrate} ) )->round;
- $order->{gstvalue} = Koha::Number::Price->new(
- ( $order->{ecostgsti} - $order->{ecostgste} ) *
- $order->{quantity} )->round;
- $order->{totalgste} = $order->{ecostgste} * $order->{quantity};
- $order->{totalgsti} = $order->{ecostgsti} * $order->{quantity};
+ $order->{tax_rate_on_ordering} //= $order->{tax_rate};
+ if ( $bookseller->listincgst ) {
+ # The user entered the rrp tax included
+ $order->{rrp_tax_included} = $order->{rrp};
+
+ # 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 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 );
}
else {
- $order->{rrpgste} = $order->{rrp};
- $order->{rrpgsti} = Koha::Number::Price->new(
- $order->{rrp} * ( 1 + $order->{gstrate} ) )->round;
- $order->{ecostgste} = $order->{ecost};
- $order->{ecostgsti} = Koha::Number::Price->new(
- $order->{ecost} * ( 1 + $order->{gstrate} ) )->round;
- $order->{gstvalue} = Koha::Number::Price->new(
- ( $order->{ecostgsti} - $order->{ecostgste} ) *
- $order->{quantity} )->round;
- $order->{totalgste} = $order->{ecostgste} * $order->{quantity};
- $order->{totalgsti} = $order->{ecostgsti} * $order->{quantity};
+ # The user entered the rrp tax excluded
+ $order->{rrp_tax_excluded} = $order->{rrp};
+
+ # rrp tax included = rrp tax excluded * ( 1 - tax rate )
+ $order->{rrp_tax_included} = $order->{rrp_tax_excluded} * ( 1 + $order->{tax_rate_on_ordering} );
+
+ # 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 );
}
+
+ # tax value = quantity * ecost tax excluded * tax rate
+ $order->{tax_value_on_ordering} =
+ $order->{quantity} * $order->{ecost_tax_excluded} * $order->{tax_rate_on_ordering};
}
if ($receiving) {
- if ( $bookseller->{listincgst} ) {
- $order->{unitpricegsti} = Koha::Number::Price->new( $order->{unitprice} )->round;
- $order->{unitpricegste} = Koha::Number::Price->new(
- $order->{unitpricegsti} / ( 1 + $order->{gstrate} ) )->round;
+ $order->{tax_rate_on_receiving} //= $order->{tax_rate};
+ if ( $bookseller->invoiceincgst ) {
+ # Trick for unitprice. If the unit price rounded value is the same as the ecost rounded value
+ # we need to keep the exact ecost value
+ if ( Koha::Number::Price->new( $order->{unitprice} )->round == Koha::Number::Price->new( $order->{ecost_tax_included} )->round ) {
+ $order->{unitprice} = $order->{ecost_tax_included};
+ }
+
+ # The user entered the unit price tax included
+ $order->{unitprice_tax_included} = $order->{unitprice};
+
+ # unit price tax excluded = unit price tax included / ( 1 + tax rate )
+ $order->{unitprice_tax_excluded} = $order->{unitprice_tax_included} / ( 1 + $order->{tax_rate_on_receiving} );
}
else {
- $order->{unitpricegste} = Koha::Number::Price->new( $order->{unitprice} )->round;
- $order->{unitpricegsti} = Koha::Number::Price->new(
- $order->{unitpricegste} * ( 1 + $order->{gstrate} ) )->round;
+ # Trick for unitprice. If the unit price rounded value is the same as the ecost rounded value
+ # we need to keep the exact ecost value
+ if ( Koha::Number::Price->new( $order->{unitprice} )->round == Koha::Number::Price->new( $order->{ecost_tax_excluded} )->round ) {
+ $order->{unitprice} = $order->{ecost_tax_excluded};
+ }
+
+ # The user entered the unit price tax excluded
+ $order->{unitprice_tax_excluded} = $order->{unitprice};
+
+
+ # unit price tax included = unit price tax included * ( 1 + tax rate )
+ $order->{unitprice_tax_included} = $order->{unitprice_tax_excluded} * ( 1 + $order->{tax_rate_on_receiving} );
}
- $order->{gstvalue} = Koha::Number::Price->new(
- ( $order->{unitpricegsti} - $order->{unitpricegste} )
- * $order->{quantityreceived} )->round;
- $order->{totalgste} = $order->{unitpricegste} * $order->{quantity};
- $order->{totalgsti} = $order->{unitpricegsti} * $order->{quantity};
+ # 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};
}
return $order;
sub FillWithDefaultValues {
my ($record) = @_;
- my $tagslib = C4::Biblio::GetMarcStructure( 1, 'ACQ' );
+ my $tagslib = C4::Biblio::GetMarcStructure( 1, 'ACQ', { unsafe => 1 } );
if ($tagslib) {
my ($itemfield) =
C4::Biblio::GetMarcFromKohaField( 'items.itemnumber', '' );