Bug 8435: DBRev 3.13.00.038
[koha.git] / acqui / pdfformat / layout3pagesfr.pm
1 #!/usr/bin/perl
2
3 #example script to print a basketgroup
4 #written 07/11/08 by john.soros@biblibre.com and paul.poulain@biblibre.com
5
6 # Copyright 2008-2009, 2013 BibLibre SARL
7 #
8 # This file is part of Koha.
9 #
10 # Koha is free software; you can redistribute it and/or modify it under the
11 # terms of the GNU General Public License as published by the Free Software
12 # Foundation; either version 3 of the License, or (at your option) any later
13 # version.
14 #
15 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
16 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
17 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License along
20 # with Koha; if not, see <http://www.gnu.org/licenses>.
21
22 #you can use any PDF::API2 module, all you need to do is return the stringifyed pdf object from the printpdf sub.
23 package pdfformat::layout3pagesfr;
24 use vars qw($VERSION @ISA @EXPORT);
25 use Number::Format qw(format_price);
26 use MIME::Base64;
27 use List::MoreUtils qw/uniq/;
28 use strict;
29 use warnings;
30 use utf8;
31
32 use C4::Branch qw(GetBranchDetail GetBranchName);
33
34 BEGIN {
35          use Exporter   ();
36          our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
37          # set the version for version checking
38          $VERSION     = 1.00;
39          @ISA    = qw(Exporter);
40          @EXPORT = qw(printpdf);
41 }
42
43
44 #be careful, all the sizes (height, width, etc...) are in mm, not PostScript points (the default measurment of PDF::API2).
45 #The constants exported tranform that into PostScript points (/mm for milimeter, /in for inch, pt is postscript point, and as so is there only to show what is happening.
46 use constant mm => 25.4 / 72;
47 use constant in => 1 / 72;
48 use constant pt => 1;
49
50 use PDF::API2;
51 #A4 paper specs
52 my ($height, $width) = (297, 210);
53 use PDF::Table;
54
55 sub printorders {
56     my ($pdf, $basketgroup, $baskets, $orders) = @_;
57
58     my $cur_format = C4::Context->preference("CurrencyFormat");
59     my $num;
60
61     if ( $cur_format eq 'FR' ) {
62         $num = new Number::Format(
63             'decimal_fill'      => '2',
64             'decimal_point'     => ',',
65             'int_curr_symbol'   => '',
66             'mon_thousands_sep' => ' ',
67             'thousands_sep'     => ' ',
68             'mon_decimal_point' => ','
69         );
70     } else {  # US by default..
71         $num = new Number::Format(
72             'int_curr_symbol'   => '',
73             'mon_thousands_sep' => ',',
74             'mon_decimal_point' => '.'
75         );
76     }
77
78     $pdf->mediabox($height/mm, $width/mm);
79     my $number = 3;
80     for my $basket (@$baskets){
81         my $page = $pdf->page();
82
83         # print basket header (box)
84         my $box = $page->gfx;
85         $box->rectxy(($width - 10)/mm, ($height - 5)/mm, 10/mm, ($height - 25)/mm);
86         $box->stroke;
87 #         $box->restore();
88
89         # create a text
90         my $text = $page->text;
91         # add basketgroup number
92         $text->font( $pdf->corefont("Times", -encoding => "utf8"), 6/mm );
93         $text->translate(20/mm,  ($height-15)/mm);
94         $text->text("Commande N°".$basketgroup->{'id'}.". Panier N° ".$basket->{basketno}.". ".$basket->{booksellernote});
95         $text->translate(20/mm,  ($height-20)/mm);
96         $text->font( $pdf->corefont("Times", -encoding => "utf8"), 4/mm );
97         $text->text( ( $basket->{billingplace} ? "Facturation à " . C4::Branch::GetBranchName( $basket->{billingplace} ) : "" )
98             . ( $basket->{billingplace} and $basket->{deliveryplace} ? " et " : "" )
99             . ( $basket->{deliveryplace} ? "livraison à " . C4::Branch::GetBranchName( $basket->{deliveryplace}) : "" )
100         );
101
102         my $pdftable = new PDF::Table();
103         my $abaskets;
104         my $arrbasket;
105         my @keys = ('Document', 'Qte', 'Prix', 'Prix net', '% Remise', 'Remise', 'Taux TVA', 'Total HT', 'Total TTC');
106         for my $bkey (@keys) {
107             push(@$arrbasket, $bkey);
108         }
109         push(@$abaskets, $arrbasket);
110         foreach my $line (@{$orders->{$basket->{basketno}}}) {
111             $arrbasket = undef;
112             push( @$arrbasket,
113                 $line->{title} . " / " . $line->{author} . ( $line->{isbn} ? " ISBN : " . $line->{isbn} : '' ) . ( $line->{en} ? " EN : " . $line->{en} : '' ) . ", " . $line->{itemtype} . ( $line->{publishercode} ? ' published by '. $line->{publishercode} : ""),
114                 $line->{quantity},
115                 $num->format_price($line->{rrpgste}),
116                 $num->format_price($line->{rrpgsti}),
117                 $num->format_price($line->{discount}).'%',
118                 $num->format_price($line->{rrpgste} - $line->{ecostgste}),
119                 $num->format_price($line->{gstrate} * 100).'%',
120                 $num->format_price($line->{totalgste}),
121                 $num->format_price($line->{totalgsti}),
122             );
123             push(@$abaskets, $arrbasket);
124         }
125
126         $pdftable->table($pdf, $page, $abaskets,
127                                         x => 10/mm,
128                                         w => ($width - 20)/mm,
129                                         start_y => 270/mm,
130                                         next_y  => 285/mm,
131                                         start_h => 250/mm,
132                                         next_h  => 250/mm,
133                                         padding => 5,
134                                         padding_right => 5,
135                                         background_color_odd  => "lightgray",
136                                         font       => $pdf->corefont("Times", -encoding => "utf8"),
137                                         font_size => 3/mm,
138                                         header_props   =>    {
139                                             font       => $pdf->corefont("Times", -encoding => "utf8"),
140                                             font_size  => 9,
141                                             bg_color   => 'gray',
142                                             repeat     => 1,
143                                         },
144                                         column_props => [
145                                             {
146                                                 min_w => 85/mm,       # Minimum column width.
147                                             },
148                                             {
149                                                 justify => 'right', # One of left|right ,
150                                             },
151                                             {
152                                                 justify => 'right', # One of left|right ,
153                                             },
154                                             {
155                                                 justify => 'right', # One of left|right ,
156                                             },
157                                             {
158                                                 justify => 'right', # One of left|right ,
159                                             },
160                                             {
161                                                 justify => 'right', # One of left|right ,
162                                             },
163                                             {
164                                                 justify => 'right', # One of left|right ,
165                                             },
166                                             {
167                                                 justify => 'right', # One of left|right ,
168                                             },
169                                             {
170                                                 justify => 'right', # One of left|right ,
171                                             },
172                                         ],
173              );
174     }
175     $pdf->mediabox($width/mm, $height/mm);
176 }
177
178 sub printbaskets {
179     my ($pdf, $basketgroup, $hbaskets, $bookseller, $GSTrate, $orders) = @_;
180
181     # get library name
182     my $libraryname = C4::Context->preference("LibraryName");
183
184     my $cur_format = C4::Context->preference("CurrencyFormat");
185     my $num;
186
187     if ( $cur_format eq 'FR' ) {
188         $num = new Number::Format(
189             'decimal_fill'      => '2',
190             'decimal_point'     => ',',
191             'int_curr_symbol'   => '',
192             'mon_thousands_sep' => ' ',
193             'thousands_sep'     => ' ',
194             'mon_decimal_point' => ','
195         );
196     } else {  # US by default..
197         $num = new Number::Format(
198             'int_curr_symbol'   => '',
199             'mon_thousands_sep' => ',',
200             'mon_decimal_point' => '.'
201         );
202     }
203
204     $pdf->mediabox($width/mm, $height/mm);
205     my $page = $pdf->openpage(2);
206     # create a text
207     my $text = $page->text;
208
209     # add basketgroup number
210     $text->font( $pdf->corefont("Times", -encoding => "utf8"), 6/mm );
211     $text->translate(($width-40)/mm,  ($height-53)/mm);
212     $text->text("".$basketgroup->{'id'});
213     # print the libraryname in the header
214     $text->font( $pdf->corefont("Times", -encoding => "utf8"), 6/mm );
215     $text->translate(30/mm,  ($height-28.5)/mm);
216     $text->text($libraryname);
217     my $pdftable = new PDF::Table();
218     my $abaskets;
219     my $arrbasket;
220     # header of the table
221     my @keys = ('Lot', 'Panier', 'Prix', 'Prix net', 'Taux TVA', 'TVA', 'Remise', 'Total HT', 'Total TTC');
222     for my $bkey (@keys) {
223         push(@$arrbasket, $bkey);
224     }
225     my ($grandtotalrrpgsti, $grandtotalrrpgste, $grandtotalgsti, $grandtotalgste, $grandtotalgstvalue, $grandtotaldiscount);
226     # calculate each basket total
227     push(@$abaskets, $arrbasket);
228     for my $basket (@$hbaskets) {
229         my @gst;
230         $arrbasket = undef;
231         my ($totalrrpgste, $totalrrpgsti, $totalgste, $totalgsti, $totalgstvalue, $totaldiscount);
232         my $ords = $orders->{$basket->{basketno}};
233         my $ordlength = @$ords;
234         foreach my $ord (@$ords) {
235             $totalgste += $ord->{totalgste};
236             $totalgsti += $ord->{totalgsti};
237             $totalgstvalue += $ord->{gstvalue};
238             $totaldiscount += ($ord->{rrpgste} - $ord->{ecostgste} ) * $ord->{quantity};
239             $totalrrpgste += $ord->{rrpgste} * $ord->{quantity};
240             $totalrrpgsti += $ord->{rrpgsti} * $ord->{quantity};
241             push @gst, $ord->{gstrate};
242         }
243         @gst = uniq map { $_ * 100 } @gst;
244         $totalgsti = $num->round($totalgsti);
245         $totalgste = $num->round($totalgste);
246         $grandtotalrrpgste += $totalrrpgste;
247         $grandtotalrrpgsti += $totalrrpgsti;
248         $grandtotalgsti += $totalgsti;
249         $grandtotalgste += $totalgste;
250         $grandtotalgstvalue += $totalgstvalue;
251         $grandtotaldiscount += $totaldiscount;
252         my @gst_string = map{$num->format_price( $_ ) . '%'} @gst;
253         push(@$arrbasket,
254             $basket->{contractname},
255             $basket->{basketname} . ' (No. ' . $basket->{basketno} . ')',
256             $num->format_price($totalrrpgste),
257             $num->format_price($totalrrpgsti),
258             "@gst_string",
259             $num->format_price($totalgstvalue),
260             $num->format_price($totaldiscount),
261             $num->format_price($totalgste),
262             $num->format_price($totalgsti)
263         );
264         push(@$abaskets, $arrbasket);
265     }
266     # now, push total
267     undef $arrbasket;
268     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);
269     push @$abaskets,$arrbasket;
270     # height is width and width is height in this function, as the pdf is in landscape mode for the Tables.
271
272     $pdftable->table($pdf, $page, $abaskets,
273                                     x => 5/mm,
274                                     w => ($width - 10)/mm,
275                                     start_y =>  230/mm,
276                                     next_y  => 230/mm,
277                                     start_h => 230/mm,
278                                     next_h  => 230/mm,
279                                     font       => $pdf->corefont("Times", -encoding => "utf8"),
280                                     font_size => 3/mm,
281                                     padding => 5,
282                                     padding_right => 10,
283                                     background_color_odd  => "lightgray",
284                                     header_props   =>    {
285                                         bg_color   => 'gray',
286                                         repeat     => 1,
287                                     },
288                                     column_props => [
289                                         {
290                                         },
291                                         {
292                                         },
293                                         {
294                                             justify => 'right',
295                                         },
296                                         {
297                                             justify => 'right',
298                                         },
299                                         {
300                                             justify => 'right',
301                                         },
302                                         {
303                                             justify => 'right',
304                                         },
305                                         {
306                                             justify => 'right',
307                                         },
308                                     ],
309     );
310     $pdf->mediabox($height/mm, $width/mm);
311 }
312
313 sub printhead {
314     my ($pdf, $basketgroup, $bookseller) = @_;
315
316     # get library name
317     my $libraryname = C4::Context->preference("LibraryName");
318     # get branch details
319     my $billingdetails  = GetBranchDetail( $basketgroup->{billingplace} );
320     my $deliverydetails = GetBranchDetail( $basketgroup->{deliveryplace} );
321     my $freedeliveryplace = $basketgroup->{freedeliveryplace};
322     # get the subject
323     my $subject;
324
325     # open 1st page (with the header)
326     my $page = $pdf->openpage(1);
327
328     # create a text
329     my $text = $page->text;
330
331     # print the libraryname in the header
332     $text->font( $pdf->corefont("Times", -encoding => "utf8"), 6/mm );
333     $text->translate(30/mm,  ($height-28.5)/mm);
334     $text->text($libraryname);
335
336     # print order info, on the default PDF
337     $text->font( $pdf->corefont("Times", -encoding => "utf8"), 8/mm );
338     $text->translate(100/mm,  ($height-5-48)/mm);
339     $text->text($basketgroup->{'id'});
340
341     # print the date
342     my $today = C4::Dates->today();
343     $text->translate(130/mm,  ($height-5-48)/mm);
344     $text->text($today);
345
346     $text->font( $pdf->corefont("Times", -encoding => "utf8"), 4/mm );
347
348     # print billing infos
349     $text->translate(100/mm,  ($height-86)/mm);
350     $text->text($libraryname);
351     $text->translate(100/mm,  ($height-97)/mm);
352     $text->text($billingdetails->{branchname});
353     $text->translate(100/mm,  ($height-108.5)/mm);
354     $text->text($billingdetails->{branchphone});
355     $text->translate(100/mm,  ($height-115.5)/mm);
356     $text->text($billingdetails->{branchfax});
357     $text->translate(100/mm,  ($height-122.5)/mm);
358     $text->text($billingdetails->{branchaddress1});
359     $text->translate(100/mm,  ($height-127.5)/mm);
360     $text->text($billingdetails->{branchaddress2});
361     $text->translate(100/mm,  ($height-132.5)/mm);
362     $text->text($billingdetails->{branchaddress3});
363     $text->translate(100/mm,  ($height-137.5)/mm);
364     $text->text(join(' ', $billingdetails->{branchzip}, $billingdetails->{branchcity}, $billingdetails->{branchcountry}));
365     $text->translate(100/mm,  ($height-147.5)/mm);
366     $text->text($billingdetails->{branchemail});
367
368     # print subject
369     $text->translate(100/mm,  ($height-145.5)/mm);
370     $text->text($subject);
371
372     # print bookseller infos
373     $text->translate(100/mm,  ($height-180)/mm);
374     $text->text($bookseller->{name});
375     $text->translate(100/mm,  ($height-185)/mm);
376     $text->text($bookseller->{postal});
377     $text->translate(100/mm,  ($height-190)/mm);
378     $text->text($bookseller->{address1});
379     $text->translate(100/mm,  ($height-195)/mm);
380     $text->text($bookseller->{address2});
381     $text->translate(100/mm,  ($height-200)/mm);
382     $text->text($bookseller->{address3});
383
384     # print delivery infos
385     $text->font( $pdf->corefont("Times-Bold", -encoding => "utf8"), 4/mm );
386     $text->translate(50/mm,  ($height-237)/mm);
387     if ($freedeliveryplace) {
388         my $start = 242;
389         my @fdp = split('\n', $freedeliveryplace);
390         foreach (@fdp) {
391             $text->text($_);
392             $text->translate( 50 / mm, ( $height - $start ) / mm );
393             $start += 5;
394         }
395     } else {
396         $text->text($deliverydetails->{branchaddress1});
397         $text->translate(50/mm,  ($height-242)/mm);
398         $text->text($deliverydetails->{branchaddress2});
399         $text->translate(50/mm,  ($height-247)/mm);
400         $text->text($deliverydetails->{branchaddress3});
401         $text->translate(50/mm,  ($height-252)/mm);
402         $text->text(join(' ', $deliverydetails->{branchzip}, $deliverydetails->{branchcity}, $deliverydetails->{branchcountry}));
403     }
404     $text->translate(50/mm,  ($height-262)/mm);
405     $text->text($basketgroup->{deliverycomment});
406 }
407
408 sub printfooters {
409         my ($pdf) = @_;
410         for (my $i=1;$i <= $pdf->pages;$i++) {
411         my $page = $pdf->openpage($i);
412         my $text = $page->text;
413         $text->font( $pdf->corefont("Times", -encoding => "utf8"), 3/mm );
414         $text->translate(10/mm,  10/mm);
415         $text->text("Page $i / ".$pdf->pages);
416         }
417 }
418
419 sub printpdf {
420     my ($basketgroup, $bookseller, $baskets, $orders, $GST) = @_;
421     # open the default PDF that will be used for base (1st page already filled)
422     my $pdf_template = C4::Context->config('intrahtdocs') . '/' . C4::Context->preference('template') . '/pdf/layout3pagesfr.pdf';
423     my $pdf = PDF::API2->open($pdf_template);
424     $pdf->pageLabel( 0, {
425         -style => 'roman',
426     } ); # start with roman numbering
427     # fill the 1st page (basketgroup information)
428     printhead($pdf, $basketgroup, $bookseller);
429     # fill the 2nd page (orders summary)
430     printbaskets($pdf, $basketgroup, $baskets, $bookseller, $GST, $orders);
431     # fill other pages (orders)
432     printorders($pdf, $basketgroup, $baskets, $orders);
433     # print something on each page (usually the footer, but you could also put a header
434     printfooters($pdf);
435     return $pdf->stringify;
436 }
437
438 1;