View | Details | Raw Unified | Return to bug 6473
Collapse All | Expand All

(-)a/C4/Acquisition.pm (-13 / +43 lines)
Lines 3000-3007 sub GetBiblioCountByBasketno { Link Here
3000
    return $sth->fetchrow;
3000
    return $sth->fetchrow;
3001
}
3001
}
3002
3002
3003
# Note this subroutine should be moved to Koha::Acquisition::Order
3003
=head3 populate_order_with_prices
3004
# Will do when a DBIC decision will be taken.
3004
3005
$order = populate_order_with_prices({
3006
    order        => $order #a hashref with the order values
3007
    booksellerid => $booksellerid #FIXME - should obtain from order basket
3008
    receiving    => 1 # boolean representing order stage, should pass only this or ordering
3009
    ordering     => 1 # boolean representing order stage
3010
});
3011
3012
3013
Sets calculated values for an order - all values are stored with pull precision regardless of rounding preference except fot
3014
tax value which is calculated on rounded values if requested
3015
3016
For ordering the values set are:
3017
    rrp_tax_included
3018
    rrp_tax_excluded
3019
    ecost_tax_included
3020
    ecost_tax_excluded
3021
    tax_value_on_ordering
3022
For receiving the value set are:
3023
    unitprice_tax_included
3024
    unitprice_tax_excluded
3025
    tax_value_on_receiving
3026
3027
Note: When receiving if the rounded value of the unitprice matches the rounded value of the ecost then then ecost (full precision) is used.
3028
3029
Returns a hashref of the order
3030
3031
FIXME: Move this to Koha::Acquisition::Order.pm
3032
3033
=cut
3034
3005
sub populate_order_with_prices {
3035
sub populate_order_with_prices {
3006
    my ($params) = @_;
3036
    my ($params) = @_;
3007
3037
Lines 3025-3035 sub populate_order_with_prices { Link Here
3025
            # rrp tax excluded = rrp tax included / ( 1 + tax rate )
3055
            # rrp tax excluded = rrp tax included / ( 1 + tax rate )
3026
            $order->{rrp_tax_excluded} = $order->{rrp_tax_included} / ( 1 + $order->{tax_rate_on_ordering} );
3056
            $order->{rrp_tax_excluded} = $order->{rrp_tax_included} / ( 1 + $order->{tax_rate_on_ordering} );
3027
3057
3058
            # ecost tax included = rrp tax included  ( 1 - discount )
3059
            $order->{ecost_tax_included} = $order->{rrp_tax_included} * ( 1 - $discount );
3060
3028
            # ecost tax excluded = rrp tax excluded * ( 1 - discount )
3061
            # ecost tax excluded = rrp tax excluded * ( 1 - discount )
3029
            $order->{ecost_tax_excluded} = $order->{rrp_tax_excluded} * ( 1 - $discount );
3062
            $order->{ecost_tax_excluded} = $order->{rrp_tax_excluded} * ( 1 - $discount );
3030
3063
3031
            # ecost tax included = rrp tax included  ( 1 - discount )
3064
            # tax value = quantity * ecost tax excluded * tax rate
3032
            $order->{ecost_tax_included} = $order->{rrp_tax_included} * ( 1 - $discount );
3065
            $order->{tax_value_on_ordering} = ( get_rounded_price($order->{ecost_tax_included}) - get_rounded_price($order->{ecost_tax_excluded}) ) * $order->{quantity};
3066
3033
        }
3067
        }
3034
        else {
3068
        else {
3035
            # The user entered the rrp tax excluded
3069
            # The user entered the rrp tax excluded
Lines 3041-3056 sub populate_order_with_prices { Link Here
3041
            # ecost tax excluded = rrp tax excluded * ( 1 - discount )
3075
            # ecost tax excluded = rrp tax excluded * ( 1 - discount )
3042
            $order->{ecost_tax_excluded} = $order->{rrp_tax_excluded} * ( 1 - $discount );
3076
            $order->{ecost_tax_excluded} = $order->{rrp_tax_excluded} * ( 1 - $discount );
3043
3077
3044
            # ecost tax included = rrp tax excluded * ( 1 + tax rate ) * ( 1 - discount )
3078
            # ecost tax included = rrp tax excluded * ( 1 + tax rate ) * ( 1 - discount ) = ecost tax excluded * ( 1 + tax rate )
3045
            $order->{ecost_tax_included} =
3079
            $order->{ecost_tax_included} = $order->{ecost_tax_excluded} * ( 1 + $order->{tax_rate_on_ordering} );
3046
                $order->{rrp_tax_excluded} *
3047
                ( 1 + $order->{tax_rate_on_ordering} ) *
3048
                ( 1 - $discount );
3049
        }
3050
3080
3051
        # tax value = quantity * ecost tax excluded * tax rate
3081
            # tax value = quantity * ecost tax included * tax rate
3052
        $order->{tax_value_on_ordering} =
3082
            $order->{tax_value_on_ordering} = $order->{quantity} * get_rounded_price($order->{ecost_tax_excluded}) * $order->{tax_rate_on_ordering};
3053
            $order->{quantity} * get_rounded_price($order->{ecost_tax_excluded}) * $order->{tax_rate_on_ordering};
3083
        }
3054
    }
3084
    }
3055
3085
3056
    if ($receiving) {
3086
    if ($receiving) {
(-)a/acqui/ordered.pl (-1 / +1 lines)
Lines 99-105 while ( my $data = $sth->fetchrow_hashref ) { Link Here
99
        $left = $data->{'quantity'};
99
        $left = $data->{'quantity'};
100
    }
100
    }
101
    if ( $left && $left > 0 ) {
101
    if ( $left && $left > 0 ) {
102
        my $subtotal = $left * get_rounded_price($data->{'ecost_tax_included'});
102
        my $subtotal = get_rounded_price( $left * $data->{'ecost_tax_included'} );
103
        $data->{subtotal} = sprintf( "%.2f", $subtotal );
103
        $data->{subtotal} = sprintf( "%.2f", $subtotal );
104
        $data->{'left'} = $left;
104
        $data->{'left'} = $left;
105
        push @ordered, $data;
105
        push @ordered, $data;
(-)a/t/db_dependent/Acquisition/populate_order_with_prices.t (-1 / +165 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/env perl
2
3
use Modern::Perl;
4
5
use Test::More tests => 34;
6
use C4::Acquisition;
7
use C4::Context;
8
use Koha::Database;
9
use t::lib::TestBuilder;
10
use t::lib::Mocks;
11
12
# Start transaction
13
my $schema = Koha::Database->new()->schema();
14
$schema->storage->txn_begin();
15
16
my $dbh = C4::Context->dbh;
17
$dbh->{RaiseError} = 1;
18
19
my $builder = t::lib::TestBuilder->new;
20
21
my $bookseller_inc_tax = Koha::Acquisition::Bookseller->new(
22
    {
23
        name          => "Tax included",
24
        address1      => "bookseller's address",
25
        phone         => "0123456",
26
        active        => 1,
27
        listincgst    => 1,
28
        invoiceincgst => 1,
29
    }
30
)->store;
31
32
my $bookseller_exc_tax = Koha::Acquisition::Bookseller->new(
33
    {
34
        name          => "Tax excluded",
35
        address1      => "bookseller's address",
36
        phone         => "0123456",
37
        active        => 1,
38
        listincgst    => 0,
39
        invoiceincgst => 0,
40
    }
41
)->store;
42
43
my $order_exc_tax = {
44
    tax_rate  => .1965,
45
    discount  => .42,
46
    rrp       => 16.99,
47
    unitprice => 9.85,
48
    quantity  => 8,
49
};
50
51
#Vendor prices exclude tax, no rounding, ordering
52
t::lib::Mocks::mock_preference('OrderPriceRounding', '');
53
my $order_with_prices = C4::Acquisition::populate_order_with_prices({
54
    ordering     => 1,
55
    booksellerid => $bookseller_exc_tax->id,
56
    order        => $order_exc_tax,
57
});
58
59
is( $order_with_prices->{rrp_tax_excluded}+0      ,16.99      ,"Ordering tax excluded, no round: rrp tax excluded is rrp");
60
is( $order_with_prices->{rrp_tax_included}+0      ,20.328535  ,"Ordering tax excluded, no round: rrp tax included is rr tax excluded * (1 + tax rate on ordering)");
61
is( $order_with_prices->{ecost_tax_excluded}+0    ,9.8542     ,"Ordering tax excluded, no round: ecost tax excluded is rrp * ( 1 - discount )");
62
is( $order_with_prices->{ecost_tax_included}+0    ,11.7905503 ,"Ordering tax excluded, no round: ecost tax included is ecost tax excluded * (1 + tax rate on ordering)");
63
is( $order_with_prices->{tax_value_on_ordering}+0 ,15.4908024 ,"Ordering tax excluded, no round: tax value on ordering is quantity * ecost_tax_excluded * tax rate on ordering");
64
65
#Vendor prices exclude tax, no rounding, receiving
66
$order_with_prices = C4::Acquisition::populate_order_with_prices({
67
    receiving     => 1,
68
    booksellerid => $bookseller_exc_tax->id,
69
    order        => $order_exc_tax,
70
});
71
72
is( $order_with_prices->{unitprice}+0              ,9.8542     ,"Receiving tax excluded, no round, rounded ecost tax excluded = rounded unitprice : unitprice is ecost tax excluded");
73
is( $order_with_prices->{unitprice_tax_excluded}+0 ,9.8542     ,"Receiving tax excluded, no round, rounded ecost tax excluded = rounded unitprice : unitprice tax excluded is ecost tax excluded");
74
is( $order_with_prices->{unitprice_tax_included}+0 ,11.7905503 ,"Receiving tax excluded, no round: unitprice tax included is unitprice tax excluded * (1 + tax rate on ordering)");
75
is( $order_with_prices->{tax_value_on_ordering}+0  ,15.4908024 ,"Receiving tax excluded, no round: tax value on receiving is quantity * unitprice_tax_excluded * tax rate on receiving");
76
77
#Vendor prices exclude tax, rounding to nearest cent, ordering
78
t::lib::Mocks::mock_preference('OrderPriceRounding', 'nearest_cent');
79
$order_with_prices = C4::Acquisition::populate_order_with_prices({
80
    ordering     => 1,
81
    booksellerid => $bookseller_exc_tax->id,
82
    order        => $order_exc_tax,
83
});
84
85
is( $order_with_prices->{rrp_tax_excluded}+0      ,16.99      ,"Ordering tax excluded, round: rrp tax excluded is rrp");
86
is( $order_with_prices->{rrp_tax_included}+0      ,20.328535  ,"Ordering tax excluded, round: rrp tax included is rr tax excluded * (1 + tax rate on ordering)");
87
is( $order_with_prices->{ecost_tax_excluded}+0    ,9.8542     ,"Ordering tax excluded, round: ecost tax excluded is rrp * ( 1 - discount )");
88
is( $order_with_prices->{ecost_tax_included}+0    ,11.7905503 ,"Ordering tax excluded, round: ecost tax included is ecost tax excluded * (1 + tax rate on ordering)");
89
is( $order_with_prices->{tax_value_on_ordering}+0 ,15.4842    ,"Ordering tax excluded, round: tax value on ordering is quantity * ecost_tax_excluded * tax rate on ordering");
90
91
#Vendor prices exclude tax, no rounding, receiving
92
$order_with_prices = C4::Acquisition::populate_order_with_prices({
93
    receiving     => 1,
94
    booksellerid => $bookseller_exc_tax->id,
95
    order        => $order_exc_tax,
96
});
97
98
is( $order_with_prices->{unitprice_tax_excluded}+0 ,9.8542     ,"Receiving tax excluded, round, rounded ecost tax excluded = rounded unitprice : unitprice tax excluded is ecost tax excluded");
99
is( $order_with_prices->{unitprice_tax_included}+0 ,11.7905503 ,"Receiving tax excluded, round: unitprice tax included is unitprice tax excluded * (1 + tax rate on ordering)");
100
is( $order_with_prices->{tax_value_on_receiving}+0  ,15.4842   ,"Receiving tax excluded, round: tax value on receiving is quantity * unitprice_tax_excluded * tax rate on receiving");
101
102
103
104
my $order_inc_tax = {
105
    tax_rate  => .1965,
106
    discount  => .42,
107
    rrp       => 20.33,
108
    unitprice => 11.79,
109
    quantity  => 8,
110
};
111
112
#Vendor prices include tax, no rounding, ordering
113
t::lib::Mocks::mock_preference('OrderPriceRounding', '');
114
$order_with_prices = C4::Acquisition::populate_order_with_prices({
115
    ordering     => 1,
116
    booksellerid => $bookseller_inc_tax->id,
117
    order        => $order_inc_tax,
118
});
119
120
is( $order_with_prices->{rrp_tax_included}+0      ,20.33            ,"Ordering tax included, no round: rrp tax included is rrp");
121
is( $order_with_prices->{rrp_tax_excluded}+0      ,16.9912244045132 ,"Ordering tax included, no round: rrp tax excluded is rrp tax included / (1 + tax rate on ordering)");
122
is( $order_with_prices->{ecost_tax_included}+0    ,11.7914          ,"Ordering tax included, no round: ecost tax included is rrp tax included * (1 - discount)");
123
is( $order_with_prices->{ecost_tax_excluded}+0    ,9.85491015461764 ,"Ordering tax included, no round: ecost tax excluded is rrp tax excluded * ( 1 - discount )");
124
is( $order_with_prices->{tax_value_on_ordering}+0 ,15.4919187630589 ,"Ordering tax included, no round: tax value on ordering is ( ecost tax included - ecost tax excluded ) * quantity");
125
126
127
#Vendor prices include tax, no rounding, receiving
128
$order_with_prices = C4::Acquisition::populate_order_with_prices({
129
    receiving     => 1,
130
    booksellerid => $bookseller_inc_tax->id,
131
    order        => $order_inc_tax,
132
});
133
134
is( $order_with_prices->{unitprice}+0              ,11.7914          ,"Receiving tax included, no round, rounded ecost tax excluded = rounded unitprice : unitprice is ecost tax excluded");
135
is( $order_with_prices->{unitprice_tax_included}+0 ,11.7914          ,"Receiving tax included, no round: unitprice tax included is unitprice");
136
is( $order_with_prices->{unitprice_tax_excluded}+0 ,9.85491015461764 ,"Receiving tax included, no round: unitprice tax excluded is unitprice tax included / (1 + tax rate on receiving)");
137
is( $order_with_prices->{tax_value_on_ordering}+0  ,15.4919187630589 ,"Receiving tax included, no round: tax value on receiving is quantity * unitprice_tax_excluded * tax rate on receiving");
138
139
#Vendor prices include tax, rounding to nearest cent, ordering
140
t::lib::Mocks::mock_preference('OrderPriceRounding', 'nearest_cent');
141
$order_with_prices = C4::Acquisition::populate_order_with_prices({
142
    ordering     => 1,
143
    booksellerid => $bookseller_inc_tax->id,
144
    order        => $order_inc_tax,
145
});
146
147
is( $order_with_prices->{rrp_tax_included}+0      ,20.33            ,"Ordering tax included, round: rrp tax included is rrp");
148
is( $order_with_prices->{rrp_tax_excluded}+0      ,16.9912244045132 ,"Ordering tax included, round: rrp tax excluded is rounded rrp tax included * (1 + tax rate on ordering)");
149
is( $order_with_prices->{ecost_tax_included}+0    ,11.7914          ,"Ordering tax included, round: ecost tax included is rounded rrp * ( 1 - discount )");
150
is( $order_with_prices->{ecost_tax_excluded}+0    ,9.85491015461764 ,"Ordering tax included, round: ecost tax excluded is rounded ecost tax excluded * (1 - discount)");
151
is( $order_with_prices->{tax_value_on_ordering}+0 ,15.52            ,"Ordering tax included, round: tax value on ordering is (ecost_tax_included - ecost_tax_excluded) * quantity");
152
153
#Vendor prices include tax, no rounding, receiving
154
$order_with_prices = C4::Acquisition::populate_order_with_prices({
155
    receiving     => 1,
156
    booksellerid => $bookseller_inc_tax->id,
157
    order        => $order_inc_tax,
158
});
159
160
is( $order_with_prices->{unitprice_tax_included}+0 ,11.7914          ,"Receiving tax included, round: rounded ecost tax included = rounded unitprice : unitprice tax excluded is ecost tax included");
161
is( $order_with_prices->{unitprice_tax_excluded}+0 ,9.85491015461764 ,"Receiving tax included, round: unitprice tax excluded is unitprice tax included / (1 + tax rate on ordering)");
162
is( $order_with_prices->{tax_value_on_receiving}+0  ,15.4842         ,"Receiving tax included, round: tax value on receiving is quantity * (rounded unitprice_tax_excluded) * tax rate on receiving");
163
164
165
$schema->storage->txn_rollback();

Return to bug 6473