Merge remote-tracking branch 'origin/new/bug_8525'
[koha.git] / acqui / pdfformat / layout3pages.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 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 2 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, write to the Free Software Foundation, Inc.,
21 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
23 #you can use any PDF::API2 module, all you need to do is return the stringifyed pdf object from the printpdf sub.
24 package pdfformat::layout3pages;
25 use vars qw($VERSION @ISA @EXPORT);
26 use Number::Format qw(format_price);
27 use MIME::Base64;
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("Order N°".$basketgroup->{'id'}.". Basket 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} ? "Billing at " . C4::Branch::GetBranchName( $basket->{billingplace} ) : "" )
98             . ( $basket->{billingplace} and $basket->{deliveryplace} ? " and " : "" )
99             . ( $basket->{deliveryplace} ? "delivery at " . C4::Branch::GetBranchName( $basket->{deliveryplace}) : "" )
100         );
101
102         my $pdftable = new PDF::Table();
103         my $abaskets;
104         my $arrbasket;
105         my @keys = ('Document','Qty','RRT GST Inc.','Discount','Discount price GST Exc.','GST', 'Total GST Inc.'); 
106         for my $bkey (@keys) {
107             push(@$arrbasket, $bkey);
108         }
109         push(@$abaskets, $arrbasket);
110 #         @{$orders->{$basket->{basketno}}});
111         foreach my $line (@{$orders->{$basket->{basketno}}}) {
112             $arrbasket = undef;
113             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]));
114             push(@$abaskets, $arrbasket);
115         }
116         
117         $pdftable->table($pdf, $page, $abaskets,
118                                         x => 10/mm,
119                                         w => ($width - 20)/mm,
120                                         start_y => 270/mm,
121                                         next_y  => 285/mm,
122                                         start_h => 250/mm,
123                                         next_h  => 250/mm,
124                                         padding => 5,
125                                         padding_right => 5,
126                                         background_color_odd  => "lightgray",
127                                         font       => $pdf->corefont("Times", -encoding => "utf8"),
128                                         font_size => 3/mm,
129                                         header_props   =>    {
130                                             font       => $pdf->corefont("Times", -encoding => "utf8"),
131                                             font_size  => 10,
132                                             bg_color   => 'gray',
133                                             repeat     => 1,
134                                         },
135                                         column_props => [
136                                             {
137                                                 min_w => 100/mm,       # Minimum column width.
138                                             },
139                                             {
140                                                 justify => 'right', # One of left|right ,
141                                             },
142                                             {
143                                                 justify => 'right', # One of left|right ,
144                                             },
145                                             {
146                                                 justify => 'right', # One of left|right ,
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              );
159     }
160     $pdf->mediabox($width/mm, $height/mm);
161 }
162
163 sub printbaskets {
164     my ($pdf, $basketgroup, $hbaskets, $bookseller, $GSTrate, $orders) = @_;
165     
166     # get library name
167     my $libraryname = C4::Context->preference("LibraryName");
168     
169     my $cur_format = C4::Context->preference("CurrencyFormat");
170     my $num;
171     
172     if ( $cur_format eq 'FR' ) {
173         $num = new Number::Format(
174             'decimal_fill'      => '2',
175             'decimal_point'     => ',',
176             'int_curr_symbol'   => '',
177             'mon_thousands_sep' => ' ',
178             'thousands_sep'     => ' ',
179             'mon_decimal_point' => ','
180         );
181     } else {  # US by default..
182         $num = new Number::Format(
183             'int_curr_symbol'   => '',
184             'mon_thousands_sep' => ',',
185             'mon_decimal_point' => '.'
186         );
187     }
188     
189     $pdf->mediabox($width/mm, $height/mm);
190     my $page = $pdf->openpage(2);
191     # create a text
192     my $text = $page->text;
193     
194     # add basketgroup number
195     $text->font( $pdf->corefont("Times", -encoding => "utf8"), 6/mm );
196     $text->translate(($width-40)/mm,  ($height-53)/mm);
197     $text->text("".$basketgroup->{'id'});
198     # print the libraryname in the header
199     $text->font( $pdf->corefont("Times", -encoding => "utf8"), 6/mm );
200     $text->translate(30/mm,  ($height-28.5)/mm);
201     $text->text($libraryname);
202     my $pdftable = new PDF::Table();
203     my $abaskets;
204     my $arrbasket;
205     # header of the table
206     my @keys = ('Lot',  'Basket (N°)', 'RRT GST Inc.', 'Discount', 'Discount price','GST rate', 'Total GST exc.','GST', 'Total GST Inc.');
207     for my $bkey (@keys) {
208         push(@$arrbasket, $bkey);
209     }
210     my $grandtotal=0;
211     my $grandgst=0;
212     # calculate each basket total
213     push(@$abaskets, $arrbasket);
214     for my $basket (@$hbaskets) {
215         $arrbasket = undef;
216         my ($total, $gst, $totallist) = (0, 0, 0);
217         my $ords = $orders->{$basket->{basketno}};
218         my $ordlength = @$ords;
219         foreach my $ord (@$ords) {
220             $total += @$ord[5] * @$ord[7];
221             $gst   += (@$ord[5] * @$ord[7]) * $GSTrate/(1+$GSTrate);
222             $totallist += @$ord[5]*@$ord[6];
223         }
224         $total=$num->round($total);
225         $gst=$num->round($gst);
226         $grandtotal +=$total;
227         $grandgst +=$gst;
228         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));
229         push(@$abaskets, $arrbasket);
230     }
231     # now, push total
232     undef $arrbasket;
233     push @$arrbasket,'','','','Total',$num->format_price($grandtotal),'',$num->format_price($grandtotal-$grandgst), $num->format_price($grandgst),$num->format_price($grandtotal);
234     push @$abaskets,$arrbasket;
235     # height is width and width is height in this function, as the pdf is in landscape mode for the Tables.
236
237     $pdftable->table($pdf, $page, $abaskets,
238                                     x => 5/mm,
239                                     w => ($width - 10)/mm,
240                                     start_y =>  230/mm,
241                                     next_y  => 230/mm,
242                                     start_h => 230/mm,
243                                     next_h  => 230/mm,
244                                     font       => $pdf->corefont("Times", -encoding => "utf8"),
245                                     font_size => 3/mm,
246                                     padding => 5,
247                                     padding_right => 10,
248                                     background_color_odd  => "lightgray",
249                                     header_props   =>    {
250                                         bg_color   => 'gray',
251                                         repeat     => 1,
252                                     },
253                                     column_props => [
254                                         {
255                                         },
256                                         {
257                                         },
258                                         {
259                                             justify => 'right',
260                                         },
261                                         {
262                                             justify => 'right',
263                                         },
264                                         {
265                                             justify => 'right',
266                                         },
267                                         {
268                                             justify => 'right',
269                                         },
270                                         {
271                                             justify => 'right',
272                                         },
273                                         {
274                                             justify => 'right',
275                                         },
276                                         {
277                                             justify => 'right',
278                                         },
279                                     ],
280     );
281     $pdf->mediabox($height/mm, $width/mm);
282 }
283
284 sub printhead {
285     my ($pdf, $basketgroup, $bookseller) = @_;
286
287     # get library name
288     my $libraryname = C4::Context->preference("LibraryName");
289     # get branch details
290     my $billingdetails  = GetBranchDetail( $basketgroup->{billingplace} );
291     my $deliverydetails = GetBranchDetail( $basketgroup->{deliveryplace} );
292     my $freedeliveryplace = $basketgroup->{freedeliveryplace};
293     # get the subject
294     my $subject;
295
296     # open 1st page (with the header)
297     my $page = $pdf->openpage(1);
298     
299     # create a text
300     my $text = $page->text;
301     
302     # print the libraryname in the header
303     $text->font( $pdf->corefont("Times", -encoding => "utf8"), 6/mm );
304     $text->translate(30/mm,  ($height-28.5)/mm);
305     $text->text($libraryname);
306
307     # print order info, on the default PDF
308     $text->font( $pdf->corefont("Times", -encoding => "utf8"), 8/mm );
309     $text->translate(100/mm,  ($height-5-48)/mm);
310     $text->text($basketgroup->{'id'});
311     
312     # print the date
313     my $today = C4::Dates->today();
314     $text->translate(130/mm,  ($height-5-48)/mm);
315     $text->text($today);
316     
317     $text->font( $pdf->corefont("Times", -encoding => "utf8"), 4/mm );
318     
319     # print billing infos
320     $text->translate(100/mm,  ($height-86)/mm);
321     $text->text($libraryname);
322     $text->translate(100/mm,  ($height-97)/mm);
323     $text->text($billingdetails->{branchname});
324     $text->translate(100/mm,  ($height-108.5)/mm);
325     $text->text($billingdetails->{branchphone});
326     $text->translate(100/mm,  ($height-115.5)/mm);
327     $text->text($billingdetails->{branchfax});
328     $text->translate(100/mm,  ($height-122.5)/mm);
329     $text->text($billingdetails->{branchaddress1});
330     $text->translate(100/mm,  ($height-127.5)/mm);
331     $text->text($billingdetails->{branchaddress2});
332     $text->translate(100/mm,  ($height-132.5)/mm);
333     $text->text($billingdetails->{branchaddress3});
334     $text->translate(100/mm,  ($height-137.5)/mm);
335     $text->text(join(' ', $billingdetails->{branchzip}, $billingdetails->{branchcity}, $billingdetails->{branchcountry}));
336     $text->translate(100/mm,  ($height-147.5)/mm);
337     $text->text($billingdetails->{branchemail});
338     
339     # print subject
340     $text->translate(100/mm,  ($height-145.5)/mm);
341     $text->text($subject);
342     
343     # print bookseller infos
344     $text->translate(100/mm,  ($height-180)/mm);
345     $text->text($bookseller->{name});
346     $text->translate(100/mm,  ($height-185)/mm);
347     $text->text($bookseller->{postal});
348     $text->translate(100/mm,  ($height-190)/mm);
349     $text->text($bookseller->{address1});
350     $text->translate(100/mm,  ($height-195)/mm);
351     $text->text($bookseller->{address2});
352     $text->translate(100/mm,  ($height-200)/mm);
353     $text->text($bookseller->{address3});
354     
355     # print delivery infos
356     $text->font( $pdf->corefont("Times-Bold", -encoding => "utf8"), 4/mm );
357     $text->translate(50/mm,  ($height-237)/mm);
358     if ($freedeliveryplace) {
359         my $start = 242;
360         my @fdp = split('\n', $freedeliveryplace);
361         foreach (@fdp) {
362             $text->text($_);
363             $text->translate( 50 / mm, ( $height - $start ) / mm );
364             $start += 5;
365         }
366     } else {
367         $text->text($deliverydetails->{branchaddress1});
368         $text->translate(50/mm,  ($height-242)/mm);
369         $text->text($deliverydetails->{branchaddress2});
370         $text->translate(50/mm,  ($height-247)/mm);
371         $text->text($deliverydetails->{branchaddress3});
372         $text->translate(50/mm,  ($height-252)/mm);
373         $text->text(join(' ', $deliverydetails->{branchzip}, $deliverydetails->{branchcity}, $deliverydetails->{branchcountry}));
374     }
375     $text->translate(50/mm,  ($height-262)/mm);
376     $text->text($basketgroup->{deliverycomment});
377 }
378
379 sub printfooters {
380         my ($pdf) = @_;
381         for (my $i=1;$i <= $pdf->pages;$i++) {
382         my $page = $pdf->openpage($i);
383         my $text = $page->text;
384         $text->font( $pdf->corefont("Times", -encoding => "utf8"), 3/mm );
385         $text->translate(10/mm,  10/mm);
386         $text->text("Page $i / ".$pdf->pages);
387         }
388 }
389
390 sub printpdf {
391     my ($basketgroup, $bookseller, $baskets, $orders, $GST) = @_;
392     # open the default PDF that will be used for base (1st page already filled)
393     my $pdf_template = C4::Context->config('intrahtdocs') . '/' . C4::Context->preference('template') . '/pdf/layout3pages.pdf';
394     my $pdf = PDF::API2->open($pdf_template);
395     $pdf->pageLabel( 0, {
396         -style => 'roman',
397     } ); # start with roman numbering
398     # fill the 1st page (basketgroup information)
399     printhead($pdf, $basketgroup, $bookseller);
400     # fill the 2nd page (orders summary)
401     printbaskets($pdf, $basketgroup, $baskets, $bookseller, $GST, $orders);
402     # fill other pages (orders)
403     printorders($pdf, $basketgroup, $baskets, $orders);
404     # print something on each page (usually the footer, but you could also put a header
405     printfooters($pdf);
406     return $pdf->stringify;
407 }
408
409 1;