From 6bbc9325ad07c39822c49ccb2d35473454f38305 Mon Sep 17 00:00:00 2001
From: Jonathan Druart <jonathan.druart@biblibre.com>
Date: Wed, 19 Nov 2014 17:01:17 +0100
Subject: [PATCH] Bug 13323: Tax rate can change on receiving

This commit permits to update the tax rate on receiving.
---
 C4/Acquisition.pm                                  | 37 ++++++++-----
 acqui/basket.pl                                    |  5 ++
 acqui/basketgroup.pl                               |  2 +
 acqui/finishreceive.pl                             |  3 +-
 acqui/invoice.pl                                   |  3 +
 acqui/neworderempty.pl                             |  4 +-
 acqui/orderreceive.pl                              | 64 ++++++++++------------
 acqui/parcel.pl                                    |  4 +-
 .../prog/en/modules/acqui/orderreceive.tt          | 29 +++++++---
 t/Prices.t                                         | 17 +++---
 10 files changed, 100 insertions(+), 68 deletions(-)

diff --git a/C4/Acquisition.pm b/C4/Acquisition.pm
index 931cbef..0eb9e38 100644
--- a/C4/Acquisition.pm
+++ b/C4/Acquisition.pm
@@ -1447,12 +1447,12 @@ sub ModReceiveOrder {
         | if defined $order->{unitprice};
 
         $query .= q|
-            , rrp = ?, rrp_tax_included = ?, rrp_tax_excluded = ?
-        | if defined $order->{rrp};
+            ,tax_value_on_receiving = ?
+        | if defined $order->{tax_value_on_receiving};
 
         $query .= q|
-            , ecost = ?, ecost_tax_included = ?, ecost_tax_excluded = ?
-        | if defined $order->{ecost};
+            ,tax_rate_on_receiving = ?
+        | if defined $order->{tax_rate_on_receiving};
 
         $query .= q|
             , order_internalnote = ?
@@ -1466,12 +1466,15 @@ sub ModReceiveOrder {
         if ( defined $order->{unitprice} ) {
             push @params, $order->{unitprice}, $order->{unitprice_tax_included}, $order->{unitprice_tax_excluded};
         }
-        if ( defined $order->{rrp} ) {
-            push @params, $order->{rrp}, $order->{rrp_tax_included}, $order->{rrp_tax_excluded};
+
+        if ( defined $order->{tax_value_on_receiving} ) {
+            push @params, $order->{tax_value_on_receiving};
         }
-        if ( defined $order->{ecost} ) {
-            push @params, $order->{ecost}, $order->{ecost_tax_included}, $order->{ecost_tax_excluded};
+
+        if ( defined $order->{tax_rate_on_receiving} ) {
+            push @params, $order->{tax_rate_on_receiving};
         }
+
         if ( defined $order->{order_internalnote} ) {
             push @params, $order->{order_internalnote};
         }
@@ -2832,12 +2835,13 @@ sub populate_order_with_prices {
     $discount /= 100 if $discount > 1;
 
     if ($ordering) {
+        $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} );
+            $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 );
@@ -2850,7 +2854,7 @@ sub populate_order_with_prices {
             $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} );
+            $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 );
@@ -2858,32 +2862,35 @@ sub populate_order_with_prices {
             # ecost tax included = rrp tax excluded * ( 1 - tax rate ) * ( 1 - discount )
             $order->{ecost_tax_included} =
                 $order->{rrp_tax_excluded} *
-                ( 1 + $order->{tax_rate} ) *
+                ( 1 + $order->{tax_rate_on_ordering} ) *
                 ( 1 - $discount );
         }
 
         # tax value = quantity * ecost tax excluded * tax rate
-        $order->{tax_value} = $order->{quantity} * $order->{ecost_tax_excluded} * $order->{tax_rate};
+        $order->{tax_value_on_ordering} = 
+            $order->{quantity} * $order->{ecost_tax_excluded} * $order->{tax_rate_on_ordering};
     }
 
     if ($receiving) {
+        $order->{tax_rate_on_receiving} //= $order->{tax_rate};
         if ( $bookseller->{invoiceincgst} ) {
             # 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} );
+            $order->{unitprice_tax_excluded} = $order->{unitprice_tax_included} / ( 1 + $order->{tax_rate_on_receiving} );
         }
         else {
             # 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} );
+            $order->{unitprice_tax_included} = $order->{unitprice_tax_excluded} * ( 1 + $order->{tax_rate_on_receiving} );
         }
 
         # tax value = quantity * unit price tax excluded * tax rate
-        $order->{tax_value} = $order->{quantity} * $order->{unitprice_tax_excluded} * $order->{tax_rate};
+        $order->{tax_value_on_receiving} = $order->{quantity} * $order->{unitprice_tax_excluded} * $order->{tax_rate_on_receiving};
     }
 
     return $order;
diff --git a/acqui/basket.pl b/acqui/basket.pl
index f4705be..f8a8a05 100755
--- a/acqui/basket.pl
+++ b/acqui/basket.pl
@@ -349,6 +349,9 @@ if ( $op eq 'delete_confirm' ) {
             $template->param( uncertainprices => 1 );
         }
 
+        $line->{tax_rate} = $line->{tax_rate_on_ordering};
+        $line->{tax_value} = $line->{tax_value_on_ordering};
+
         push @books_loop, $line;
 
         $foot{$$line{tax_rate}}{tax_rate} = $$line{tax_rate};
@@ -448,6 +451,8 @@ sub get_order_infos {
 
     $line{total_tax_included} = $line{ecost_tax_included} * $line{quantity};
     $line{total_tax_excluded} = $line{ecost_tax_excluded} * $line{quantity};
+    $line{tax_value} = $line{tax_value_on_ordering};
+    $line{tax_rate} = $line{tax_rate_on_ordering};
 
     if ( $line{uncertainprice} ) {
         $line{rrp_tax_excluded} .= ' (Uncertain)';
diff --git a/acqui/basketgroup.pl b/acqui/basketgroup.pl
index ecf0d36..79590b5 100755
--- a/acqui/basketgroup.pl
+++ b/acqui/basketgroup.pl
@@ -170,6 +170,8 @@ sub printbasketgrouppdf{
                 croak $@;
             }
 
+            $ord->{tax_value} = $ord->{tax_value_on_ordering};
+            $ord->{tax_rate} = $ord->{tax_rate_on_ordering};
             $ord->{total_tax_included} = $ord->{ecost_tax_included} * $ord->{quantity};
             $ord->{total_tax_excluded} = $ord->{ecost_tax_excluded} * $ord->{quantity};
 
diff --git a/acqui/finishreceive.pl b/acqui/finishreceive.pl
index b156b7c..b1df953 100755
--- a/acqui/finishreceive.pl
+++ b/acqui/finishreceive.pl
@@ -47,7 +47,7 @@ my $ordernumber      = $input->param('ordernumber');
 my $origquantityrec  = $input->param('origquantityrec');
 my $quantityrec      = $input->param('quantityrec');
 my $quantity         = $input->param('quantity');
-my $unitprice        = $input->param('cost');
+my $unitprice        = $input->param('unitprice');
 my $invoiceid        = $input->param('invoiceid');
 my $invoice          = GetInvoice($invoiceid);
 my $invoiceno        = $invoice->{invoicenumber};
@@ -81,6 +81,7 @@ if ($quantityrec > $origquantityrec ) {
     }
 
     $order->{order_internalnote} = $input->param("order_internalnote");
+    $order->{tax_rate_on_receiving} = $input->param("tax_rate");
     $order->{unitprice} = $unitprice;
 
     my $bookseller = Koha::Acquisition::Bookseller->fetch({ id => $booksellerid });
diff --git a/acqui/invoice.pl b/acqui/invoice.pl
index 562b480..9fcef0e 100755
--- a/acqui/invoice.pl
+++ b/acqui/invoice.pl
@@ -126,6 +126,9 @@ foreach my $order (@$orders) {
     $line->{total_tax_excluded} = Koha::Number::Price->new( $line->{unitprice_tax_excluded} * $line->{quantity} )->format;
     $line->{total_tax_included} = Koha::Number::Price->new( $line->{unitprice_tax_included} * $line->{quantity} )->format;
 
+    $line->{tax_value} = $line->{tax_value_on_receiving};
+    $line->{tax_rate} = $line->{tax_rate_on_receiving};
+
     $foot{$$line{tax_rate}}{tax_rate} = $$line{tax_rate};
     $foot{$$line{tax_rate}}{tax_value} += $$line{tax_value};
     $total_tax_value += $$line{tax_value};
diff --git a/acqui/neworderempty.pl b/acqui/neworderempty.pl
index 809ebe1..06f21c7 100755
--- a/acqui/neworderempty.pl
+++ b/acqui/neworderempty.pl
@@ -307,7 +307,7 @@ if ( defined $subscriptionid ) {
         $budget_id              = $lastOrderReceived->{budgetid};
         $data->{listprice}      = $lastOrderReceived->{listprice};
         $data->{uncertainprice} = $lastOrderReceived->{uncertainprice};
-        $data->{tax_rate}        = $lastOrderReceived->{tax_rate};
+        $data->{tax_rate}       = $lastOrderReceived->{tax_rate_on_ordering};
         $data->{discount}       = $lastOrderReceived->{discount};
         $data->{rrp}            = $lastOrderReceived->{rrp};
         $data->{ecost}          = $lastOrderReceived->{ecost};
@@ -390,7 +390,7 @@ $template->param(
     quantityrec      => $quantity,
     rrp              => $data->{'rrp'},
     gst_values       => \@gst_values,
-    tax_rate          => $data->{tax_rate} ? $data->{tax_rate}+0.0 : $bookseller->{tax_rate} ? $bookseller->{tax_rate}+0.0 : 0,
+    tax_rate         => $data->{tax_rate_on_ordering} ? $data->{tax_rate_on_ordering}+0.0 : $bookseller->{tax_rate} ? $bookseller->{tax_rate}+0.0 : 0,
     listprice        => sprintf( "%.2f", $data->{listprice} || $data->{price} || $listprice),
     total            => sprintf( "%.2f", ($data->{ecost} || 0) * ($data->{'quantity'} || 0) ),
     ecost            => sprintf( "%.2f", $data->{ecost} || 0),
diff --git a/acqui/orderreceive.pl b/acqui/orderreceive.pl
index 3f92c27..23b1b8f 100755
--- a/acqui/orderreceive.pl
+++ b/acqui/orderreceive.pl
@@ -162,32 +162,29 @@ if ($AcqCreateItem eq 'receiving') {
 }
 
 $order->{quantityreceived} = '' if $order->{quantityreceived} == 0;
-$order->{unitprice} = '' if $order->{unitprice} == 0;
-
-my $rrp;
-my $ecost;
-my $unitprice;
-if ( $bookseller->{listincgst} ) {
-    if ( $bookseller->{invoiceincgst} ) {
-        $rrp = $order->{rrp};
-        $ecost = $order->{ecost};
-        $unitprice = $order->{unitprice};
-    } else {
-        $rrp = $order->{rrp} / ( 1 + $order->{tax_rate} );
-        $ecost = $order->{ecost} / ( 1 + $order->{tax_rate} );
-        $unitprice = $order->{unitprice} / ( 1 + $order->{tax_rate} );
+
+my $unitprice = $order->{unitprice};
+my ( $rrp, $ecost );
+if ( $bookseller->{invoiceincgst} ) {
+    $rrp = $order->{rrp_tax_included};
+    $ecost = $order->{ecost_tax_included};
+    unless ( $unitprice != 0 and defined $unitprice) {
+        $unitprice = $order->{ecost_tax_included};
     }
 } else {
-    if ( $bookseller->{invoiceincgst} ) {
-        $rrp = $order->{rrp} * ( 1 + $order->{tax_rate} );
-        $ecost = $order->{ecost} * ( 1 + $order->{tax_rate} );
-        $unitprice = $order->{unitprice} * ( 1 + $order->{tax_rate} );
-    } else {
-        $rrp = $order->{rrp};
-        $ecost = $order->{ecost};
-        $unitprice = $order->{unitprice};
+    $rrp = $order->{rrp_tax_excluded};
+    $ecost = $order->{ecost_tax_excluded};
+    unless ( $unitprice != 0 and defined $unitprice) {
+        $unitprice = $order->{ecost_tax_excluded};
     }
- }
+}
+
+my $tax_rate;
+if( defined $order->{tax_rate_on_receiving} ) {
+    $tax_rate = $order->{tax_rate_on_receiving} + 0.0;
+} else {
+    $tax_rate = $order->{tax_rate_on_ordering} + 0.0;
+}
 
 my $suggestion = GetSuggestionInfoFromBiblionumber($order->{biblionumber});
 
@@ -196,6 +193,11 @@ my $member = GetMember( borrowernumber => $authorisedby );
 
 my $budget = GetBudget( $order->{budget_id} );
 
+# get option values for gist syspref
+my @gst_values = map {
+    option => $_ + 0.0
+}, split( '\|', C4::Context->preference("gist") );
+
 $template->param(
     AcqCreateItem         => $AcqCreateItem,
     count                 => 1,
@@ -215,8 +217,10 @@ $template->param(
     quantity              => $order->{'quantity'},
     quantityreceivedplus1 => $order->{'quantityreceived'} + 1,
     quantityreceived      => $order->{'quantityreceived'},
-    rrp                   => sprintf( "%.2f", $rrp ),
-    ecost                 => sprintf( "%.2f", $ecost ),
+    rrp                   => $rrp,
+    ecost                 => $ecost,
+    unitprice             => $unitprice,
+    tax_rate              => $tax_rate,
     memberfirstname       => $member->{firstname} || "",
     membersurname         => $member->{surname} || "",
     invoiceid             => $invoice->{invoiceid},
@@ -228,6 +232,7 @@ $template->param(
     suggestionid          => $suggestion->{suggestionid},
     surnamesuggestedby    => $suggestion->{surnamesuggestedby},
     firstnamesuggestedby  => $suggestion->{firstnamesuggestedby},
+    gst_values            => \@gst_values,
 );
 
 my $borrower = GetMember( 'borrowernumber' => $loggedinuser );
@@ -265,15 +270,6 @@ foreach my $period (@$periods) {
 
 $template->{'VARS'}->{'budget_loop'} = \@budget_loop;
 
-# regardless of the content of $unitprice e.g 0 or '' or any string will return in these cases 0.00
-# and the 'IF' in the .tt will show 0.00 and not 'ecost' (see BZ 7129)
-# So if $unitprice == 0 we don't create unitprice
-if ( $unitprice != 0) {
-    $template->param(
-        unitprice             => sprintf( "%.2f", $unitprice),
-    );
-}
-
 my $op = $input->param('op');
 if ($op and $op eq 'edit'){
     $template->param(edit   =>   1);
diff --git a/acqui/parcel.pl b/acqui/parcel.pl
index 9353e74..bcd04eb 100755
--- a/acqui/parcel.pl
+++ b/acqui/parcel.pl
@@ -111,7 +111,6 @@ unless( $invoiceid and $invoice->{invoiceid} ) {
 
 my $booksellerid = $invoice->{booksellerid};
 my $bookseller = Koha::Acquisition::Bookseller->fetch({ id => $booksellerid });
-my $gst = $bookseller->{tax_rate} // C4::Context->preference("gist") // 0;
 my $datereceived = C4::Dates->new();
 
 my @orders        = @{ $invoice->{orders} };
@@ -148,6 +147,9 @@ for my $order ( @orders ) {
         $line{holds} += scalar( @$holds );
     }
     $line{budget} = GetBudgetByOrderNumber( $line{ordernumber} );
+
+    $line{tax_value} = $line{tax_value_on_receiving};
+    $line{tax_rate} = $line{tax_rate_on_receiving};
     $foot{$line{tax_rate}}{tax_rate} = $line{tax_rate};
     $foot{$line{tax_rate}}{tax_value} += $line{tax_value};
     $total_tax_excluded += $line{unitprice_tax_excluded} * $line{quantity};
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt
index 8321f93..69859eb 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/acqui/orderreceive.tt
@@ -1,3 +1,4 @@
+[% USE Price %]
 [% INCLUDE 'doc-head-open.inc' %]
 <title>Koha &rsaquo; Acquisitions &rsaquo; Receipt summary for : [% name %] [% IF ( invoice ) %]invoice, [% invoice %][% END %]</title>
 [% INCLUDE 'doc-head-close.inc' %]
@@ -258,7 +259,6 @@
     <input type="hidden" name="ordernumber" value="[% ordernumber %]" />
     <input type="hidden" name="booksellerid" value="[% booksellerid %]" />
     <input type="hidden" name="datereceived" value="[% datereceived_iso %]" />
-    <input type="hidden" name="tax_rate" value="[% tax_rate %]" />
 	</div>
 	<div class="yui-u">
     <fieldset class="rows">
@@ -322,14 +322,29 @@
           [% END %][%# IF (AcqCreateItemReceiving) %]
 		</li>
 
+        [% IF ( gst_values ) %]
+            <li>
+                <label for="tax_rate">Tax rate: </label>
+                <select name="tax_rate" id="tax_rate">
+                [% FOREACH gst IN gst_values %]
+                    [% IF gst.option == tax_rate %]
+                        <option value="[% gst.option %]" selected="selected">[% gst.option * 100 | format("%.1f") %]%</option>
+                    [% ELSE %]
+                        <option value="[% gst.option %]">[% gst.option * 100 | format("%.1f") %]%</option>
+                    [% END %]
+                [% END %]
+                </select>
+            </li>
+        [% ELSE %]
+            <input type="hidden" name="tax_rate" value="0" />
+        [% END %]
+
         <li><label for="rrp">Replacement cost: </label>[% rrp | $Price %]</li>
         <li><label for="ecost">Budgeted cost: </label>[% ecost | $Price %]</li>
-        <li><label for="cost">Actual cost:</label>
-        [% IF ( unitprice ) %]
-             <input type="text" size="20" name="cost" id="cost" value="[% unitprice | $Price %]" />
-        [% ELSE %]
-             <input type="text" size="20" name="cost" id="cost" value="[% ecost | $Price %]" />
-        [% END %]</li>
+        <li>
+            <label for="unitprice">Actual cost:</label>
+            <input type="text" size="20" name="unitprice" id="unitprice" value="[% unitprice | $Price %]" />
+        </li>
         <li><label for="order_internalnote">Internal note: </label><textarea name="order_internalnote" width="40" rows="8" >[% order_internalnote %]</textarea></li>
         <li><label for="order_vendornote">Vendor note: </label><span>[% order_vendornote %]</span></li>
         </ol>
diff --git a/t/Prices.t b/t/Prices.t
index ea5ae2e..a432149 100644
--- a/t/Prices.t
+++ b/t/Prices.t
@@ -87,13 +87,14 @@ for my $currency_format ( qw( US FR ) ) {
         );
         compare(
             {
-                got      => $order_0_0->{tax_value},
+                got      => $order_0_0->{tax_value_on_ordering},
                 expected => 7.38,
                 conf     => '0 0',
                 field    => 'tax_value'
             }
         );
 
+        # 
         $order_0_0 = C4::Acquisition::populate_order_with_prices(
             {
                 order        => $order_0_0,
@@ -120,7 +121,7 @@ for my $currency_format ( qw( US FR ) ) {
         );
         compare(
             {
-                got      => $order_0_0->{tax_value},
+                got      => $order_0_0->{tax_value_on_receiving},
                 expected => 7.38,
                 conf     => '0 0',
                 field    => 'tax_value'
@@ -195,7 +196,7 @@ for my $currency_format ( qw( US FR ) ) {
         );
         compare(
             {
-                got      => $order_1_1->{tax_value},
+                got      => $order_1_1->{tax_value_on_ordering},
                 expected => 7.03,
                 conf     => '1 1',
                 field    => 'tax_value'
@@ -228,7 +229,7 @@ for my $currency_format ( qw( US FR ) ) {
         );
         compare(
             {
-                got      => $order_1_1->{tax_value},
+                got      => $order_1_1->{tax_value_on_receiving},
                 expected => 7.03,
                 conf     => '1 1',
                 field    => 'tax_value'
@@ -303,7 +304,7 @@ for my $currency_format ( qw( US FR ) ) {
         );
         compare(
             {
-                got      => $order_1_0->{tax_value},
+                got      => $order_1_0->{tax_value_on_ordering},
                 expected => 7.03,
                 conf     => '1 0',
                 field    => 'tax_value'
@@ -336,7 +337,7 @@ for my $currency_format ( qw( US FR ) ) {
         );
         compare(
             {
-                got      => $order_1_0->{tax_value},
+                got      => $order_1_0->{tax_value_on_receiving},
                 expected => 7.03,
                 conf     => '1 0',
                 field    => 'tax_value'
@@ -411,7 +412,7 @@ for my $currency_format ( qw( US FR ) ) {
         );
         compare(
             {
-                got      => $order_0_1->{tax_value},
+                got      => $order_0_1->{tax_value_on_ordering},
                 expected => 7.38,
                 conf     => '0 1',
                 field    => 'tax_value'
@@ -444,7 +445,7 @@ for my $currency_format ( qw( US FR ) ) {
         );
         compare(
             {
-                got      => $order_0_1->{tax_value},
+                got      => $order_0_1->{tax_value_on_receiving},
                 expected => 7.38,
                 conf     => '0 1',
                 field    => 'tax_value'
-- 
2.1.0