Bug 12969: Add a subroutine to calculate VAT and prices
This patch adds a new subroutine populate_order_with_prices in the C4::Acquisition module. Its goal is to refactore the VAT and prices calculation into Koha. All scripts will use this subroutine. Test plan: Verify that the prices in t/Prices.t are consistent with the values listed in the file "Prices and VAT calculation - before" submit on bug 12964. Verify that prove t/Prices.t returns green Signed-off-by: Paola Rossi <paola.rossi@cineca.it> Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de> Signed-off-by: Tomas Cohen Arazi <tomascohen@gmail.com>
This commit is contained in:
parent
e525f51032
commit
a19958ee2c
|
|
@ -32,6 +32,7 @@ use C4::Templates qw(gettemplate);
|
|||
use Koha::DateUtils qw( dt_from_string output_pref );
|
||||
use Koha::Acquisition::Order;
|
||||
use Koha::Acquisition::Bookseller;
|
||||
use Koha::Number::Price;
|
||||
|
||||
use Time::localtime;
|
||||
use HTML::Entities;
|
||||
|
|
@ -2888,6 +2889,77 @@ sub GetBiblioCountByBasketno {
|
|||
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 ($params) = @_;
|
||||
|
||||
my $order = $params->{order};
|
||||
my $booksellerid = $params->{booksellerid};
|
||||
return unless $booksellerid;
|
||||
|
||||
my $bookseller = Koha::Acquisition::Bookseller->fetch({ id => $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};
|
||||
}
|
||||
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};
|
||||
}
|
||||
}
|
||||
|
||||
# Not used yet
|
||||
#if ($receiving) {
|
||||
# if ( $bookseller->{invoiceincgst} ) {
|
||||
# $order->{unitpricegsti} = $order->{unitprice};
|
||||
# $order->{unitpricegste} =
|
||||
# $order->{unitpricegsti} / ( 1 + $order->{gstrate} );
|
||||
# }
|
||||
# else {
|
||||
# $order->{unitpricegste} = $order->{unitprice};
|
||||
# $order->{unitpricegsti} =
|
||||
# $order->{unitpricegste} * ( 1 + $order->{gstrate} );
|
||||
# }
|
||||
# $order->{gstvalue} =
|
||||
# $order->{quantityreceived} *
|
||||
# $order->{unitpricegste} *
|
||||
# $order->{gstrate};
|
||||
#}
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,15 @@ sub unformat {
|
|||
return Number::Format->new(%$format_params)->unformat_number($self->value);
|
||||
}
|
||||
|
||||
sub round {
|
||||
my ( $self ) = @_;
|
||||
return unless defined $self->value;
|
||||
|
||||
my $format_params = $self->_format_params;
|
||||
|
||||
return Number::Format->new(%$format_params)->round($self->value);
|
||||
}
|
||||
|
||||
sub _format_params {
|
||||
my ( $self, $params ) = @_;
|
||||
my $with_symbol = $params->{with_symbol} || 0;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,403 @@
|
|||
use Modern::Perl;
|
||||
use Test::More tests => 8;
|
||||
use Test::MockModule;
|
||||
|
||||
use C4::Acquisition;
|
||||
use C4::Bookseller;
|
||||
use C4::Context;
|
||||
|
||||
use Koha::Number::Price;
|
||||
|
||||
use t::lib::Mocks;
|
||||
|
||||
t::lib::Mocks::mock_preference( 'gist', '0.02|0.05|0.196' );
|
||||
|
||||
my $bookseller_module = Test::MockModule->new('Koha::Acquisition::Bookseller');
|
||||
|
||||
my ( $basketno_0_0, $basketno_1_1, $basketno_1_0, $basketno_0_1 );
|
||||
my ( $invoiceid_0_0, $invoiceid_1_1, $invoiceid_1_0, $invoiceid_0_1 );
|
||||
my $today;
|
||||
|
||||
for my $currency_format ( qw( US FR ) ) {
|
||||
t::lib::Mocks::mock_preference( 'CurrencyFormat', $currency_format );
|
||||
subtest 'Configuration 1: 0 0' => sub {
|
||||
plan tests => 7;
|
||||
$bookseller_module->mock(
|
||||
'fetch',
|
||||
sub {
|
||||
return { listincgst => 0, invoiceincgst => 0 };
|
||||
}
|
||||
);
|
||||
|
||||
my $biblionumber_0_0 = 42;
|
||||
|
||||
my $order_0_0 = {
|
||||
biblionumber => $biblionumber_0_0,
|
||||
quantity => 2,
|
||||
listprice => 82.000000,
|
||||
unitprice => 73.80000,
|
||||
quantityreceived => 2,
|
||||
basketno => $basketno_0_0,
|
||||
invoiceid => $invoiceid_0_0,
|
||||
rrp => 82.00,
|
||||
ecost => 73.80,
|
||||
gstrate => 0.0500,
|
||||
discount => 10.0000,
|
||||
datereceived => $today
|
||||
};
|
||||
$order_0_0 = C4::Acquisition::populate_order_with_prices(
|
||||
{
|
||||
order => $order_0_0,
|
||||
booksellerid => 'just_something',
|
||||
ordering => 1,
|
||||
}
|
||||
);
|
||||
|
||||
# Note that this configuration is correct \o/
|
||||
compare(
|
||||
{
|
||||
got => $order_0_0->{rrpgsti},
|
||||
expected => 86.10,
|
||||
conf => '0 0',
|
||||
field => 'rrpgsti'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_0_0->{rrpgste},
|
||||
expected => 82.00,
|
||||
conf => '0 0',
|
||||
field => 'rrpgsti'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_0_0->{ecostgsti},
|
||||
expected => 77.49,
|
||||
conf => '0 0',
|
||||
field => 'ecostgsti'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_0_0->{ecostgste},
|
||||
expected => 73.80,
|
||||
conf => '0 0',
|
||||
field => 'ecostgste'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_0_0->{gstvalue},
|
||||
expected => 7.38,
|
||||
conf => '0 0',
|
||||
field => 'gstvalue'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_0_0->{totalgsti},
|
||||
expected => 154.98,
|
||||
conf => '0 0',
|
||||
field => 'totalgsti'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_0_0->{totalgste},
|
||||
expected => 147.60,
|
||||
conf => '0 0',
|
||||
field => 'totalgste'
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
subtest 'Configuration 1: 1 1' => sub {
|
||||
plan tests => 7;
|
||||
$bookseller_module->mock(
|
||||
'fetch',
|
||||
sub {
|
||||
return { listincgst => 1, invoiceincgst => 1 };
|
||||
}
|
||||
);
|
||||
|
||||
my $biblionumber_1_1 = 43;
|
||||
my $order_1_1 = {
|
||||
biblionumber => $biblionumber_1_1,
|
||||
quantity => 2,
|
||||
listprice => 82.000000,
|
||||
unitprice => 73.800000,
|
||||
quantityreceived => 2,
|
||||
basketno => $basketno_1_1,
|
||||
invoiceid => $invoiceid_1_1,
|
||||
rrp => 82.00,
|
||||
ecost => 73.80,
|
||||
gstrate => 0.0500,
|
||||
discount => 10.0000,
|
||||
datereceived => $today
|
||||
};
|
||||
|
||||
$order_1_1 = C4::Acquisition::populate_order_with_prices(
|
||||
{
|
||||
order => $order_1_1,
|
||||
booksellerid => 'just_something',
|
||||
ordering => 1,
|
||||
}
|
||||
);
|
||||
|
||||
# Note that this configuration is *not* correct
|
||||
# gstvalue should be 7.03 instead of 7.02
|
||||
compare(
|
||||
{
|
||||
got => $order_1_1->{rrpgsti},
|
||||
expected => 82.00,
|
||||
conf => '1 1',
|
||||
field => 'rrpgsti'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_1_1->{rrpgste},
|
||||
expected => 78.10,
|
||||
conf => '1 1',
|
||||
field => 'rrpgsti'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_1_1->{ecostgsti},
|
||||
expected => 73.80,
|
||||
conf => '1 1',
|
||||
field => 'ecostgsti'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_1_1->{ecostgste},
|
||||
expected => 70.29,
|
||||
conf => '1 1',
|
||||
field => 'ecostgste'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_1_1->{gstvalue},
|
||||
expected => 7.02,
|
||||
conf => '1 1',
|
||||
field => 'gstvalue'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_1_1->{totalgsti},
|
||||
expected => 147.60,
|
||||
conf => '1 1',
|
||||
field => 'totalgsti'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_1_1->{totalgste},
|
||||
expected => 140.58,
|
||||
conf => '1 1',
|
||||
field => 'totalgste'
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
subtest 'Configuration 1: 1 0' => sub {
|
||||
plan tests => 7;
|
||||
$bookseller_module->mock(
|
||||
'fetch',
|
||||
sub {
|
||||
return { listincgst => 1, invoiceincgst => 0 };
|
||||
}
|
||||
);
|
||||
|
||||
my $biblionumber_1_0 = 44;
|
||||
my $order_1_0 = {
|
||||
biblionumber => $biblionumber_1_0,
|
||||
quantity => 2,
|
||||
listprice => 82.000000,
|
||||
unitprice => 73.804500,
|
||||
quantityreceived => 2,
|
||||
basketno => $basketno_1_1,
|
||||
invoiceid => $invoiceid_1_1,
|
||||
rrp => 82.01,
|
||||
ecost => 73.80,
|
||||
gstrate => 0.0500,
|
||||
discount => 10.0000,
|
||||
datereceived => $today
|
||||
};
|
||||
|
||||
$order_1_0 = C4::Acquisition::populate_order_with_prices(
|
||||
{
|
||||
order => $order_1_0,
|
||||
booksellerid => 'just_something',
|
||||
ordering => 1,
|
||||
}
|
||||
);
|
||||
|
||||
# Note that this configuration is *not* correct!
|
||||
# rrp gsti should be 82 (what we inserted!)
|
||||
# gstvalue should be 7.03 instead of 7.02
|
||||
|
||||
compare(
|
||||
{
|
||||
got => $order_1_0->{rrpgsti},
|
||||
expected => 82.01,
|
||||
conf => '1 0',
|
||||
field => 'rrpgsti'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_1_0->{rrpgste},
|
||||
expected => 78.10,
|
||||
conf => '1 0',
|
||||
field => 'rrpgsti'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_1_0->{ecostgsti},
|
||||
expected => 73.80,
|
||||
conf => '1 0',
|
||||
field => 'ecostgsti'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_1_0->{ecostgste},
|
||||
expected => 70.29,
|
||||
conf => '1 0',
|
||||
field => 'ecostgste'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_1_0->{gstvalue},
|
||||
expected => 7.02,
|
||||
conf => '1 0',
|
||||
field => 'gstvalue'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_1_0->{totalgsti},
|
||||
expected => 147.60,
|
||||
conf => '1 0',
|
||||
field => 'totalgsti'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_1_0->{totalgste},
|
||||
expected => 140.58,
|
||||
conf => '1 0',
|
||||
field => 'totalgste'
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
subtest 'Configuration 1: 0 1' => sub {
|
||||
plan tests => 7;
|
||||
$bookseller_module->mock(
|
||||
'fetch',
|
||||
sub {
|
||||
return { listincgst => 0, invoiceincgst => 1 };
|
||||
}
|
||||
);
|
||||
|
||||
my $biblionumber_0_1 = 45;
|
||||
my $order_0_1 = {
|
||||
biblionumber => $biblionumber_0_1,
|
||||
quantity => 2,
|
||||
listprice => 82.000000,
|
||||
unitprice => 73.800000,
|
||||
quantityreceived => 2,
|
||||
basketno => $basketno_1_1,
|
||||
invoiceid => $invoiceid_1_1,
|
||||
rrp => 82.00,
|
||||
ecost => 73.80,
|
||||
gstrate => 0.0500,
|
||||
discount => 10.0000,
|
||||
datereceived => $today
|
||||
};
|
||||
|
||||
$order_0_1 = C4::Acquisition::populate_order_with_prices(
|
||||
{
|
||||
order => $order_0_1,
|
||||
booksellerid => 'just_something',
|
||||
ordering => 1,
|
||||
}
|
||||
);
|
||||
|
||||
# Note that this configuration is correct \o/
|
||||
compare(
|
||||
{
|
||||
got => $order_0_1->{rrpgsti},
|
||||
expected => 86.10,
|
||||
conf => '1 0',
|
||||
field => 'rrpgsti'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_0_1->{rrpgste},
|
||||
expected => 82.00,
|
||||
conf => '1 0',
|
||||
field => 'rrpgsti'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_0_1->{ecostgsti},
|
||||
expected => 77.49,
|
||||
conf => '1 0',
|
||||
field => 'ecostgsti'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_0_1->{ecostgste},
|
||||
expected => 73.80,
|
||||
conf => '1 0',
|
||||
field => 'ecostgste'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_0_1->{gstvalue},
|
||||
expected => 7.38,
|
||||
conf => '1 0',
|
||||
field => 'gstvalue'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_0_1->{totalgsti},
|
||||
expected => 154.98,
|
||||
conf => '1 0',
|
||||
field => 'totalgsti'
|
||||
}
|
||||
);
|
||||
compare(
|
||||
{
|
||||
got => $order_0_1->{totalgste},
|
||||
expected => 147.60,
|
||||
conf => '1 0',
|
||||
field => 'totalgste'
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
sub compare {
|
||||
my ($params) = @_;
|
||||
is(
|
||||
Koha::Number::Price->new( $params->{got} )->format,
|
||||
Koha::Number::Price->new( $params->{expected} )->format,
|
||||
"configuration $params->{conf}: $params->{field} should be correctly calculated"
|
||||
);
|
||||
}
|
||||
Loading…
Reference in New Issue