Bug 9506: FIX GST values for the basketgroup print action
authorJonathan Druart <jonathan.druart@biblibre.com>
Wed, 30 Jan 2013 10:33:37 +0000 (11:33 +0100)
committerJared Camins-Esakov <jcamins@cpbibliography.com>
Sat, 23 Mar 2013 04:28:57 +0000 (00:28 -0400)
Due to the multi VAT development (Bug 5335), values are not well calculated in
the pdf generated by the basketgroup print action.

Test plan:
- Add one or more basket to a basketgroup.
- Close and print this basketgroup
- Check that different values correspond to values in the basket detail page.

Don't forget to test with different parameters (multiple vat, vendor
include/don't include tax).

Signed-off-by: Mathieu Saby <mathieu.saby@univ-rennes2.fr>
Signed-off-by: Katrin Fischer <Katrin.Fischer.83@web.de>
Signed-off-by: Jared Camins-Esakov <jcamins@cpbibliography.com>
acqui/basketgroup.pl
acqui/pdfformat/layout2pages.pm
acqui/pdfformat/layout3pages.pm

index 6b7e5bf..8782a45 100755 (executable)
@@ -53,6 +53,7 @@ use C4::Output;
 use CGI;
 
 use C4::Bookseller qw/GetBookSellerFromId/;
+use C4::Budgets qw/ConvertCurrency/;
 use C4::Acquisition qw/CloseBasketgroup ReOpenBasketgroup GetOrders GetBasketsByBasketgroup GetBasketsByBookseller ModBasketgroup NewBasketgroup DelBasketgroup GetBasketgroups ModBasket GetBasketgroup GetBasket GetBasketGroupAsCSV/;
 use C4::Bookseller qw/GetBookSellerFromId/;
 use C4::Branch qw/GetBranches/;
@@ -210,63 +211,75 @@ sub printbasketgrouppdf{
         my @ba_orders;
         my @ords = &GetOrders($basket->{basketno});
         for my $ord (@ords) {
-            # ba_order is filled with : 
+
+            next unless ( $ord->{biblionumber} or $ord->{quantity}> 0 );
+            eval {
+                require C4::Biblio;
+                import C4::Biblio;
+            };
+            if ($@){
+                croak $@;
+            }
+            eval {
+                require C4::Koha;
+                import C4::Koha;
+            };
+            if ($@){
+                croak $@;
+            }
+
+            $ord->{rrp} = ConvertCurrency( $ord->{'currency'}, $ord->{rrp} );
+            if ( $bookseller->{'listincgst'} ) {
+                $ord->{rrpgsti} = sprintf( "%.2f", $ord->{rrp} );
+                $ord->{gstgsti} = sprintf( "%.2f", $ord->{gstrate} * 100 );
+                $ord->{rrpgste} = sprintf( "%.2f", $ord->{rrp} / ( 1 + ( $ord->{gstgsti} / 100 ) ) );
+                $ord->{gstgste} = sprintf( "%.2f", $ord->{gstgsti} / ( 1 + ( $ord->{gstgsti} / 100 ) ) );
+                $ord->{ecostgsti} = sprintf( "%.2f", $ord->{ecost} );
+                $ord->{ecostgste} = sprintf( "%.2f", $ord->{ecost} / ( 1 + ( $ord->{gstgsti} / 100 ) ) );
+                $ord->{gstvalue} = sprintf( "%.2f", ( $ord->{ecostgsti} - $ord->{ecostgste} ) * $ord->{quantity});
+                $ord->{totalgste} = sprintf( "%.2f", $ord->{quantity} * $ord->{ecostgste} );
+                $ord->{totalgsti} = sprintf( "%.2f", $ord->{quantity} * $ord->{ecostgsti} );
+            } else {
+                $ord->{rrpgsti} = sprintf( "%.2f", $ord->{rrp} * ( 1 + ( $ord->{gstrate} ) ) );
+                $ord->{rrpgste} = sprintf( "%.2f", $ord->{rrp} );
+                $ord->{gstgsti} = sprintf( "%.2f", $ord->{gstrate} * 100 );
+                $ord->{gstgste} = sprintf( "%.2f", $ord->{gstrate} * 100 );
+                $ord->{ecostgsti} = sprintf( "%.2f", $ord->{ecost} * ( 1 + ( $ord->{gstrate} ) ) );
+                $ord->{ecostgste} = sprintf( "%.2f", $ord->{ecost} );
+                $ord->{gstvalue} = sprintf( "%.2f", ( $ord->{ecostgsti} - $ord->{ecostgste} ) * $ord->{quantity});
+                $ord->{totalgste} = sprintf( "%.2f", $ord->{quantity} * $ord->{ecostgste} );
+                $ord->{totalgsti} = sprintf( "%.2f", $ord->{quantity} * $ord->{ecostgsti} );
+            }
+            my $bib = GetBiblioData($ord->{biblionumber});
+            my $itemtypes = GetItemTypes();
+
+            #FIXME DELETE ME
             # 0      1        2        3         4            5         6       7      8        9
             #isbn, itemtype, author, title, publishercode, quantity, listprice ecost discount gstrate
-            my @ba_order;
-            if ( $ord->{biblionumber} && $ord->{quantity}> 0 ) {
-                eval {
-                   require C4::Biblio;
-                   import C4::Biblio;
-               };
-               if ($@){
-                   croak $@;
-               }
-                eval {
-                   require C4::Koha;
-                   import C4::Koha;
-               };
-               if ($@){
-                   croak $@;
-               }
-                my $bib = GetBiblioData($ord->{biblionumber});
-                my $itemtypes = GetItemTypes();
-                if($ord->{isbn}){
-                    push(@ba_order, $ord->{isbn});
-                } else {
-                    push(@ba_order, undef);
-                }
-                if ($ord->{itemtype} and $bib->{itemtype}){
-                    push(@ba_order, $itemtypes->{$bib->{itemtype}}->{description});
-                } else {
-                    push(@ba_order, undef);
-                }
-#             } else {
-#                 push(@ba_order, undef, undef);
-                for my $key (qw/author title publishercode quantity listprice ecost/) {
-                    push(@ba_order, $ord->{$key});                                                  #Order lines
-                }
-                push(@ba_order, $bookseller->{discount});
-                push(@ba_order, $bookseller->{gstrate}*100 // C4::Context->preference("gist") // 0);
-                push(@ba_orders, \@ba_order);
-                # Editor Number
-                my $en;
-                my $marcrecord=eval{MARC::Record::new_from_xml( $ord->{marcxml},'UTF-8' )};
-                if ($marcrecord){
-                    if ( C4::Context->preference("marcflavour") eq 'UNIMARC' ) {
-                        $en = $marcrecord->subfield( '345', "b" );
-                    } elsif ( C4::Context->preference("marcflavour") eq 'MARC21' ) {
-                        $en = $marcrecord->subfield( '037', "a" );
-                    }
-                }
-                if($en){
-                    push(@ba_order, $en);
-                } else {
-                    push(@ba_order, undef);
+
+            # Editor Number
+            my $en;
+            my $marcrecord=eval{MARC::Record::new_from_xml( $ord->{marcxml},'UTF-8' )};
+            if ($marcrecord){
+                if ( C4::Context->preference("marcflavour") eq 'UNIMARC' ) {
+                    $en = $marcrecord->subfield( '345', "b" );
+                } elsif ( C4::Context->preference("marcflavour") eq 'MARC21' ) {
+                    $en = $marcrecord->subfield( '037', "a" );
                 }
             }
+
+            my $ba_order = {
+                isbn => ($ord->{isbn} ? $ord->{isbn} : undef),
+                itemtype => ( $ord->{itemtype} and $bib->{itemtype} ? $itemtypes->{$bib->{itemtype}}->{description} : undef ),
+                en => ( $en ? $en : undef ),
+            };
+            for my $key ( qw/ gstrate author title itemtype publishercode discount quantity rrpgsti rrpgste gstgsti gstgste ecostgsti ecostgste gstvalue totalgste totalgsti / ) {
+                $ba_order->{$key} = $ord->{$key};
+            }
+
+            push(@ba_orders, $ba_order);
         }
-        $orders{$basket->{basketno}}=\@ba_orders;
+        $orders{$basket->{basketno}} = \@ba_orders;
     }
     print $input->header(
         -type       => 'application/pdf',
index 6d5925e..3bd184a 100644 (file)
@@ -82,24 +82,24 @@ sub printorders {
     
     my $abaskets;
     my $arrbasket;
-    my @keys = ('Basket (N°)','Document','Qty','RRT GST Inc.','Discount','Discount price GST Exc.','GST', 'Total GST Inc.'); 
+    my @keys = ('Basket (N°)', 'Document', 'Qty', 'RRP tax inc.', 'Discount', 'GST', 'Total tax exc.', 'Total tax inc.');
     for my $bkey (@keys) {
         push(@$arrbasket, $bkey);
     }
     push(@$abaskets, $arrbasket);
-    
+
     for my $basket (@$baskets){
         for my $line (@{$orders->{$basket->{basketno}}}) {
             $arrbasket = undef;
-            push( @$arrbasket, 
-                $basket->{basketno}, 
-                @$line[3]." / ".@$line[2].(@$line[0]?" ISBN : ".@$line[0]:'').(@$line[10]?" EN : ".@$line[10]:'').", ".@$line[1].(@$line[4]?' published by '.@$line[4]:''),
-                @$line[5],
-                $num->format_price(@$line[6]),
-                $num->format_price(@$line[8]).'%',
-                $num->format_price(@$line[7]/(1+@$line[9]/100)),
-                $num->format_price(@$line[9]).'%',
-                $num->format_price($num->round(@$line[7])*@$line[5])
+            push( @$arrbasket,
+                $basket->{basketno},
+                $line->{title} . " / " . $line->{author} . ( $line->{isbn} ? " ISBN : " . $line->{isbn} : '' ) . ( $line->{en} ? " EN : " . $line->{en} : '' ) . ", " . $line->{itemtype} . ( $line->{publishercode} ? ' published by '. $line->{publishercode} : ""),
+                $line->{quantity},
+                $num->format_price($line->{rrpgsti}),
+                $num->format_price($line->{discount}).'%',
+                $num->format_price($line->{gstrate} * 100).'%',
+                $num->format_price($line->{totalgste}),
+                $num->format_price($line->{totalgsti}),
             );
             push(@$abaskets, $arrbasket);
         }
index 1c5a68c..38ca298 100644 (file)
@@ -102,18 +102,27 @@ sub printorders {
         my $pdftable = new PDF::Table();
         my $abaskets;
         my $arrbasket;
-        my @keys = ('Document','Qty','RRT GST Inc.','Discount','Discount price GST Exc.','GST', 'Total GST Inc.'); 
+        my @keys = ('Document', 'Qty', 'RRP tax exc.', 'RRP tax inc.', 'Discount', 'Discount price', 'GST rate', 'Total tax exc.', 'Total tax inc.');
         for my $bkey (@keys) {
             push(@$arrbasket, $bkey);
         }
         push(@$abaskets, $arrbasket);
-#         @{$orders->{$basket->{basketno}}});
         foreach my $line (@{$orders->{$basket->{basketno}}}) {
             $arrbasket = undef;
-            push(@$arrbasket, @$line[3]." / ".@$line[2].(@$line[0]?" ISBN : ".@$line[0]:'').(@$line[10]?" EN : ".@$line[10]:'').", ".@$line[1].(@$line[4]?' published by '.@$line[4]:''), @$line[5],$num->format_price(@$line[6]),$num->format_price(@$line[8]).'%',$num->format_price(@$line[7]/(1+@$line[9]/100)),$num->format_price(@$line[9]).'%',$num->format_price($num->round(@$line[7])*@$line[5]));
+            push( @$arrbasket,
+                $line->{title} . " / " . $line->{author} . ( $line->{isbn} ? " ISBN : " . $line->{isbn} : '' ) . ( $line->{en} ? " EN : " . $line->{en} : '' ) . ", " . $line->{itemtype} . ( $line->{publishercode} ? ' published by '. $line->{publishercode} : ""),
+                $line->{quantity},
+                $num->format_price($line->{rrpgste}),
+                $num->format_price($line->{rrpgsti}),
+                $num->format_price($line->{discount}).'%',
+                $num->format_price($line->{rrpgste} - $line->{ecostgste}),
+                $num->format_price($line->{gstrate} * 100).'%',
+                $num->format_price($line->{totalgste}),
+                $num->format_price($line->{totalgsti}),
+            );
             push(@$abaskets, $arrbasket);
         }
-        
+
         $pdftable->table($pdf, $page, $abaskets,
                                         x => 10/mm,
                                         w => ($width - 20)/mm,
@@ -128,13 +137,19 @@ sub printorders {
                                         font_size => 3/mm,
                                         header_props   =>    {
                                             font       => $pdf->corefont("Times", -encoding => "utf8"),
-                                            font_size  => 10,
+                                            font_size  => 9,
                                             bg_color   => 'gray',
                                             repeat     => 1,
                                         },
                                         column_props => [
                                             {
-                                                min_w => 100/mm,       # Minimum column width.
+                                                min_w => 85/mm,       # Minimum column width.
+                                            },
+                                            {
+                                                justify => 'right', # One of left|right ,
+                                            },
+                                            {
+                                                justify => 'right', # One of left|right ,
                                             },
                                             {
                                                 justify => 'right', # One of left|right ,
@@ -203,34 +218,54 @@ sub printbaskets {
     my $abaskets;
     my $arrbasket;
     # header of the table
-    my @keys = ('Lot',  'Basket (N°)', 'RRT GST Inc.', 'Discount', 'Discount price','GST rate', 'Total GST exc.','GST', 'Total GST Inc.');
+    my @keys = ('Lot',  'Basket (N°)','Total RRP tax exc.', 'Total RRP tax inc.', 'GST rate', 'GST', 'Total discount', 'Total tax exc.', 'Total tax inc.');
     for my $bkey (@keys) {
         push(@$arrbasket, $bkey);
     }
-    my $grandtotal=0;
-    my $grandgst=0;
+    my ($grandtotalrrpgsti, $grandtotalrrpgste, $grandtotalgsti, $grandtotalgste, $grandtotalgstvalue, $grandtotaldiscount);
+    my @gst;
     # calculate each basket total
     push(@$abaskets, $arrbasket);
     for my $basket (@$hbaskets) {
         $arrbasket = undef;
-        my ($total, $gst, $totallist) = (0, 0, 0);
+        my ($totalrrpgste, $totalrrpgsti, $totalgste, $totalgsti, $totalgstvalue, $totaldiscount);
         my $ords = $orders->{$basket->{basketno}};
         my $ordlength = @$ords;
         foreach my $ord (@$ords) {
-            $total += @$ord[5] * @$ord[7];
-            $gst   += (@$ord[5] * @$ord[7]) * $GSTrate/(1+$GSTrate);
-            $totallist += @$ord[5]*@$ord[6];
+            $totalgste += $ord->{totalgste};
+            $totalgsti += $ord->{totalgsti};
+            $totalgstvalue += $ord->{gstvalue};
+            $totaldiscount += ($ord->{rrpgste} - $ord->{ecostgste} ) * $ord->{quantity};
+            $totalrrpgste += $ord->{rrpgste} * $ord->{quantity};
+            $totalrrpgsti += $ord->{rrpgsti} * $ord->{quantity};
+            push @gst, $ord->{gstrate} * 100
+                unless grep {$ord->{gstrate} * 100 == $_ ? $_ : ()} @gst;
         }
-        $total=$num->round($total);
-        $gst=$num->round($gst);
-        $grandtotal +=$total;
-        $grandgst +=$gst;
-        push(@$arrbasket, $basket->{contractname}, $basket->{basketname}.'(N°'.$basket->{basketno}.')',$num->format_price($totallist), $num->format_price($bookseller->{discount}).'%', $num->format_price($total), $num->format_price($GSTrate*100).'%', $num->format_price($total-$gst), $num->format_price($gst), $num->format_price($total));
+        $totalgsti = $num->round($totalgsti);
+        $totalgste = $num->round($totalgste);
+        $grandtotalrrpgste += $totalrrpgste;
+        $grandtotalrrpgsti += $totalrrpgsti;
+        $grandtotalgsti += $totalgsti;
+        $grandtotalgste += $totalgste;
+        $grandtotalgstvalue += $totalgstvalue;
+        $grandtotaldiscount += $totaldiscount;
+        my @gst_string = map{$num->format_price( $_ ) . '%'} @gst;
+        push(@$arrbasket,
+            $basket->{contractname},
+            $basket->{basketname} . ' (N°' . $basket->{basketno} . ')',
+            $num->format_price($totalrrpgste),
+            $num->format_price($totalrrpgsti),
+            "@gst_string",
+            $num->format_price($totalgstvalue),
+            $num->format_price($totaldiscount),
+            $num->format_price($totalgste),
+            $num->format_price($totalgsti)
+        );
         push(@$abaskets, $arrbasket);
     }
     # now, push total
     undef $arrbasket;
-    push @$arrbasket,'','','','Total',$num->format_price($grandtotal),'',$num->format_price($grandtotal-$grandgst), $num->format_price($grandgst),$num->format_price($grandtotal);
+    push @$arrbasket,'','Total', $num->format_price($grandtotalrrpgste), $num->format_price($grandtotalrrpgsti), '', $num->format_price($grandtotalgstvalue), $num->format_price($grandtotaldiscount), $num->format_price($grandtotalgste), $num->format_price($grandtotalgsti);
     push @$abaskets,$arrbasket;
     # height is width and width is height in this function, as the pdf is in landscape mode for the Tables.
 
@@ -270,12 +305,6 @@ sub printbaskets {
                                         {
                                             justify => 'right',
                                         },
-                                        {
-                                            justify => 'right',
-                                        },
-                                        {
-                                            justify => 'right',
-                                        },
                                     ],
     );
     $pdf->mediabox($height/mm, $width/mm);