fix pdf generation by removing obsolete module
[koha.git] / acqui / pdfformat / ffzg.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
11 # under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 3 of the License, or
13 # (at your option) any later version.
14 #
15 # Koha is distributed in the hope that it will be useful, but
16 # WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
19 #
20 # You should have received a copy of the GNU General Public License
21 # along with Koha; if not, see <http://www.gnu.org/licenses>.
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::ffzg;
25 use vars qw($VERSION @ISA @EXPORT);
26 use MIME::Base64;
27 use List::MoreUtils qw/uniq/;
28 use strict;
29 use warnings;
30 use utf8;
31
32 use Koha::Number::Price;
33 use Koha::DateUtils;
34
35 use Data::Dump qw(dump); # FIXME
36
37 BEGIN {
38          use Exporter   ();
39          our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
40         # set the version for version checking
41          $VERSION     = 1.00;
42         @ISA    = qw(Exporter);
43         @EXPORT = qw(printpdf);
44 }
45
46
47 #be careful, all the sizes (height, width, etc...) are in mm, not PostScript points (the default measurment of PDF::API2).
48 #The constants exported transform 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.
49 use constant mm => 25.4 / 72;
50 use constant in => 1 / 72;
51 use constant pt => 1;
52
53 use PDF::API2;
54 #A4 paper specs
55 my ($height, $width) = (297, 210);
56 use PDF::Table;
57
58 sub _pdf_font {
59         my ($pdf, $font) = @_;
60         # $font = Times, Times-Bold
61
62         my $mapping = {
63                 'Times'      => '/usr/share/fonts/truetype/dejavu/DejaVuSansCondensed.ttf',
64                 'Times-Bold' => '/usr/share/fonts/truetype/dejavu/DejaVuSansCondensed-Bold.ttf',
65         };
66
67         if ( my $ttf = $mapping->{$font} ) {
68 #               warn "XXX using $ttf font insted of $font";
69                 return $pdf->ttfont( $ttf );
70
71         } else {
72                 warn "ERROR: can't find ttf font $font, fallback to corefont";
73                 return $pdf->corefont($font, -encoding => "utf8");
74         }
75
76 }
77
78
79 sub printhead {
80     my ($pdf, $basketgroup, $bookseller) = @_;
81
82     # get library name
83     my $libraryname = C4::Context->preference("LibraryName");
84     # get branch details
85     my $freedeliveryplace = $basketgroup->{freedeliveryplace};
86 warn "XXX freedeliveryplace = ", dump($freedeliveryplace);
87
88     # open 1st page (with the header)
89     my $page = $pdf->openpage(1);
90
91     # create a text
92     my $text = $page->text;
93         $text->fillcolor('black');
94 #       $text->fillcolor('red');
95
96
97     # print order info, on the default PDF
98     $text->font( _pdf_font( $pdf, "Times-Bold" ), 12/pt );
99 #    $text->translate(100/mm,  ($height-24)/mm);
100         $text->translate(283/pt, 774/pt);
101         $text->text( $basketgroup->{'id'} . '-' . $basketgroup->{'ffzg_nr'} . '/' . $basketgroup->{'ffzg_year'} );
102
103     $text->font( _pdf_font( $pdf, "Times" ), 10/pt );
104
105     # print the date FIXME
106 #    $text->translate(140/mm,  ($height-24)/mm);
107     $text->translate(420.75/pt,  773.93/pt);
108     $text->text($basketgroup->{ffzg_date});
109
110 #warn "XXX bookseller ", dump( $bookseller );
111
112     # print bookseller infos
113         my $y_pt = 727;
114         foreach my $line ( $bookseller->{name}, split(/[\n\r]+/, $bookseller->{postal}) ) {
115             $text->translate(336/pt, $y_pt/pt);
116                 $text->text($line);
117                 $y_pt -= 12;
118         }
119
120         # Lokacija za isporuku -- Zbirka...
121     $text->translate(62/pt, 590/pt);
122     $text->text($basketgroup->{deliverycomment});
123
124     $text->translate(58/pt, 556/pt);
125     $text->text("Narudžbenicu ispisala: " . C4::Context->userenv->{"firstname"} . " " .  C4::Context->userenv->{"surname"} );
126 #    $text->translate(58/pt, 556/pt - 10/pt);
127 #       $text->text("basketgroup: " . $basketgroup->{'id'});
128
129 }
130
131 sub print_tables {
132     my ($pdf, $basketgroup, $baskets, $orders) = @_;
133
134     my $cur_format = C4::Context->preference("CurrencyFormat");
135
136         my $a_titles = [[
137                 'Rbr.',
138                 'košarica / narudžba',
139                 'Naslov',
140                 'Kol.',
141                 'Cijena bez PDV-a',
142                 'Cijena s PDV-om',
143                 'Popust %',
144                 'Popust iznos',
145                 'Porez',
146                 'Ukupno bez PDV-a',
147                 'Ukupno s PDV-om'
148         ]];
149
150         my $rbr = 1;
151
152         my $order_total;
153         my $basket_totals;
154
155     for my $basket (@$baskets){
156
157 #warn "XXX basket = ",dump( $basket );
158
159                 my $basket_total;
160
161         my $titleinfo;
162         foreach my $order (@{$orders->{$basket->{basketno}}}) {
163 #warn "XXX order = ",dump($order);
164
165                         $order->{discount_value} = $order->{rrpgste} - $order->{ecostgste};
166                         $basket_total->{$_} += $order->{$_} foreach (qw( totalgste totalgsti gstvalue quantity ));
167                         $basket_total->{$_} += $order->{$_} * $order->{quantity} foreach (qw( rrpgste rrpgsti ecostgste discount_value ));
168                         push @{$basket_total->{gstrate}}, $order->{gstrate};
169
170             $titleinfo = "";
171             if ( C4::Context->preference("marcflavour") eq 'UNIMARC' ) {
172                 $titleinfo =  $order->{title} . " / " . $order->{author} .
173                     ( $order->{isbn} ? " ISBN: " . $order->{isbn} : '' ) .
174                     ( $order->{en} ? " EN: " . $order->{en} : '' ) .
175                     ( $order->{itemtype} ? ", " . $order->{itemtype} : '' ) .
176                     ( $order->{edition} ? ", " . $order->{edition} : '' ) .
177                     ( $order->{publishercode} ? ' published by '. $order->{publishercode} : '') .
178                     ( $order->{publicationyear} ? ', '. $order->{publicationyear} : '');
179             }
180             else { # MARC21, NORMARC
181                 $titleinfo =  $order->{title} . " " . $order->{author} .
182                     ( $order->{isbn} ? " ISBN: " . $order->{isbn} : '' ) .
183                     ( $order->{en} ? " EN: " . $order->{en} : '' ) .
184                     ( $order->{itemtype} ? " " . $order->{itemtype} : '' ) .
185                     ( $order->{edition} ? ", " . $order->{edition} : '' ) .
186                     ( $order->{publishercode} ? ' published by '. $order->{publishercode} : '') .
187                     ( $order->{copyrightdate} ? ' '. $order->{copyrightdate} : '');
188             }
189
190             push @$a_titles, [
191                                 $rbr++ . '.',
192                                 $basket->{basketno} . ' / ' . $order->{ordernumber},
193                 $titleinfo, #. ($order->{order_vendornote} ? "\n----------------\nNote for vendor : " . $order->{order_vendornote} : '' ),
194                 $order->{quantity},
195                 Koha::Number::Price->new( $order->{rrpgste} )->format,
196                 Koha::Number::Price->new( $order->{rrpgsti} )->format,
197                 Koha::Number::Price->new( $order->{discount} )->format . '%',
198                 Koha::Number::Price->new( $order->{discount_value})->format,
199                 Koha::Number::Price->new( $order->{gstrate} * 100 )->format . '%',
200                 Koha::Number::Price->new( $order->{totalgste} )->format,
201                 Koha::Number::Price->new( $order->{totalgsti} )->format,
202             ];
203         }
204
205                 $basket_total->{$_} = $basket->{$_} foreach qw( basketname basketno );
206                 $basket_total->{gstrate} = join(" ", map { Koha::Number::Price->new($_ * 100)->format . '%' } uniq @{ $basket_total->{gstrate} } );
207
208                 push @$basket_totals, $basket_total;
209
210                 $order_total->{$_} += $basket_total->{$_} foreach qw( rrpgste rrpgsti totalgste totalgsti gstvalue quantity ecostgste discount_value );
211                 push @{$order_total->{gstrate}}, $basket_total->{gstrate};
212     }
213
214         $order_total->{gstrate} = join(" ", uniq @{ $order_total->{gstrate} } );
215
216 warn "XXX basket_totals = ",dump( $basket_totals );
217 warn "XXX order_total = ", dump( $order_total );
218
219         push @$a_titles, [
220                 '',
221                 '',
222                 'Ukupno:',
223                 $order_total->{quantity},
224                 Koha::Number::Price->new( $order_total->{rrpgste} )->format,
225                 Koha::Number::Price->new( $order_total->{rrpgsti} )->format,
226                 '', # discount
227                 Koha::Number::Price->new( $order_total->{discount_value})->format,
228                 '', # gstrate
229                 Koha::Number::Price->new( $order_total->{totalgste} )->format,
230                 Koha::Number::Price->new( $order_total->{totalgsti} )->format,
231         ];
232
233         my $a_baskets = [[
234                 'Br. košarice',
235         'Košarica',
236                 'Cijena bez PDV-a',
237                 'Cijena s PDV-om',
238                 'Porez',
239                 'Iznos poreza',
240                 'Popust iznos',
241                 'Ukupno bez PDV-a',
242                 'Ukupno s PDV-om',
243         ]];
244         foreach my $basket_total ( @$basket_totals ) {
245                 push @$a_baskets, [ map {
246                                 m/^basket/
247                                 ? $basket_total->{$_}
248                                 : Koha::Number::Price->new($basket_total->{$_})->format . ( m/^gstrate$/ ? '%' : '' )
249                         } qw(
250                         basketno
251                         basketname
252                         rrpgste
253                         rrpgsti
254                         gstrate
255                         gstvalue
256                         discount_value
257                         totalgste
258                         totalgsti
259                 ) ];
260         }
261         push @$a_baskets, [ '', 'Ukupno', map { Koha::Number::Price->new($order_total->{$_})->format } qw(
262                 rrpgste
263                 rrpgsti
264                 gstrate
265                 gstvalue
266                 discount_value
267                 totalgste
268                 totalgsti
269         ) ];
270         $a_baskets->[-1]->[4] = ''; # remove gstreate from total
271
272     $pdf->mediabox($height/mm, $width/mm);
273         my $page = $pdf->openpage(1);
274         my $pdftable = new PDF::Table();
275
276         my ($end_page, $pages_spanned, $table_bot_y) =
277         $pdftable->table($pdf, $page, $a_titles,
278                 x => 10/mm, # 57/pt
279                 w => ($width - 20)/mm,
280                 start_y => 470/pt,
281                 next_y  => $height/mm - 25/mm,
282                 start_h => $height/mm - 470/pt, # - 25/mm,
283                 next_h  => $height/mm - ( 2 * 25/mm ),
284                 padding => 3,
285                 padding_top => 2,
286                 background_color_odd  => "lightgray",
287                 font       => _pdf_font( $pdf, "Times" ),
288                 font_size => 8/pt,
289                 header_props   =>    {
290                         font       => _pdf_font( $pdf, "Times" ),
291                         font_size  => 8/pt,
292                         font_color => 'white',
293                         bg_color   => 'gray',
294                         repeat     => 1,
295                 },
296                 column_props => [
297                         {}, # rbr
298                         {}, # basket/order
299                         { min_w => 55/mm },
300                         { justify => 'right' },
301                         { justify => 'right' },
302                         { justify => 'right' },
303                         { justify => 'right' },
304                         { justify => 'right' },
305                         { justify => 'right' },
306                         { justify => 'right' },
307                         { justify => 'right' },
308                 ],
309         );
310
311         $table_bot_y -= 10/mm;
312
313         if ( $table_bot_y < 25/mm + ( 3 + @$a_baskets ) * 12/pt ) {
314                 warn "XXX force baskets to next page\n";
315                 $table_bot_y = $height/mm - 25/mm;
316                 $end_page = $pdf->page();
317         }
318
319         my $text = $end_page->text;
320         $text->font( _pdf_font( $pdf, "Times" ), 10/pt );
321         $text->translate(20/mm, $table_bot_y );
322 #       $text->fillcolor('red');
323         $text->text("Trošak po košaricama");
324
325         $table_bot_y -= 5/mm;
326         $page = $end_page;
327
328         $pdftable->table($pdf, $page, $a_baskets,
329                 x => 10/mm, # 57/pt
330                 w => ($width - 20)/mm,
331                 start_y => $table_bot_y,
332                 next_y  => 250/mm,
333                 start_h => 250/mm,
334                 next_h  => 250/mm,
335                 padding => 3,
336                 padding_top => 2,
337                 background_color_odd  => "lightgray",
338                 font       => _pdf_font( $pdf, "Times" ),
339                 font_size => 8/pt,
340                 header_props   =>    {
341                         font       => _pdf_font( $pdf, "Times" ),
342                         font_size  => 8/pt,
343                         font_color => 'white',
344                         bg_color   => 'gray',
345                         repeat     => 1,
346                 },
347                 column_props => [
348                         {},
349                         {},
350                         { justify => 'right' },
351                         { justify => 'right' },
352                         { justify => 'right' },
353                         { justify => 'right' },
354                         { justify => 'right' },
355                         { justify => 'right' },
356                         { justify => 'right' },
357                 ],
358         );
359
360 }
361 sub printfooters {
362         my ($pdf, $basketgroup) = @_;
363         for (my $i=1;$i <= $pdf->pages;$i++) {
364                 my $page = $pdf->openpage($i);
365                 my $text = $page->text;
366                 $text->font( _pdf_font( $pdf, "Times" ), 3/mm );
367                 $text->translate(10/mm,  10/mm);
368                 $text->text("Page $i / ".$pdf->pages);
369 #               $text->text("Page $i / ".$pdf->pages . "    basketgroup: " . $basketgroup->{id});
370                 $text->translate($width/mm - 40/mm,  10/mm);
371                 $text->text("basketgroup: " . $basketgroup->{id});
372         }
373 }
374
375 sub printpdf {
376     my ($basketgroup, $bookseller, $baskets, $orders, $GST) = @_;
377 warn "XXX basketgroup = ",dump($basketgroup);
378
379         if ( ! $basketgroup->{ffzg_year} ) {
380                 if ( $basketgroup->{ffzg_date} =~ m/^(\d\d\d\d)-(\d\d)-(\d\d)\s.*/ ) {
381                         my ( $yyyy, $mm, $dd ) = ( $1, $2, $3 );
382                         my $dbh = C4::Context->dbh;
383                         $dbh->begin_work;
384                         my $sth = $dbh->prepare(qq{ select max(ffzg_nr) from aqbasketgroups where ffzg_year = ? });
385                         $sth->execute( $yyyy );
386                         my ($nr) = $sth->fetchrow_array;
387                         $nr++;
388                         $sth = $dbh->prepare(qq{ update aqbasketgroups set ffzg_year = ?, ffzg_nr = ? where id = ? });
389                         $sth->execute( $yyyy, $nr, $basketgroup->{id} );
390
391                         $dbh->commit;
392                         warn "XXX ",$basketgroup->{id}, " basketgroup got $yyyy-$nr\n";
393
394                         $basketgroup->{ffzg_year} = $yyyy;
395                         $basketgroup->{ffzg_nr}   = $nr;
396                 }
397         }
398
399         $basketgroup->{ffzg_date} =~ s/\s.+//; # strip time from datetime
400
401     # open the default PDF that will be used for base (1st page already filled)
402     my $pdf_template = C4::Context->config('intrahtdocs') . '/' . C4::Context->preference('template') . '/pdf/ffzg-narudzbenica.pdf';
403     my $pdf = PDF::API2->open($pdf_template);
404     $pdf->pageLabel( 0, {
405         -style => 'roman',
406     } ); # start with roman numbering
407     # fill the 1st page (basketgroup information)
408     printhead($pdf, $basketgroup, $bookseller);
409
410     print_tables($pdf, $basketgroup, $baskets, $orders);
411
412
413     # print something on each page (usually the footer, but you could also put a header
414     printfooters($pdf, $basketgroup);
415     return $pdf->stringify;
416 }
417
418 1;