Bug 18465 - Patron card creator: Print on duplex card printer
authorMarc Véron <veron@veron.ch>
Thu, 20 Apr 2017 18:43:11 +0000 (20:43 +0200)
committerJonathan Druart <jonathan.druart@bugs.koha-community.org>
Thu, 6 Jul 2017 17:52:54 +0000 (14:52 -0300)
Card printers with duplex functionality need as input a PDF file where odd pages contain
the front side and even pages the back side of the cards.

This patch adds such functionality.

To prepare test:
- In Patron card creator > Templates, prepare a 1 up template (1 column / 1 row) that
  fits to a single card. Give it a name like 'Duplex card template'
  (Attention, Card with and Card height seem to have wrong labels, that will go
  to a separate bug).
- In Patron card creator > Layouts create a layout for the front side and one for
  the back side. Give them names to easily remember (Card front layout, Card back layout)
- Go to Patron card creator > Batches and test both layouts together with the
  1 up template. Save and keepp both test files as reference.

To test:
- Apply patch. Restart memcached and plack.
- Go to Patron card creator > Batches
- Click "Export" for a batch
- In the following screen, note the new field "Select a layout for the back side"
  with a hint what it is used for
- Leave it on 'Back side layout not used', export and compare output with test ooutput
  from preparation. It should be the same
- Select the layout you prepared for the back side.
- Export - this file should contain 2 PDF pages per patron, one first with the
  front side, second with the back side.

Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
koha-tmpl/intranet-tmpl/prog/en/modules/help/patroncards/manage.tt
koha-tmpl/intranet-tmpl/prog/en/modules/patroncards/print.tt
patroncards/create-pdf.pl
patroncards/print.pl

index 80306f8..703ffc4 100644 (file)
@@ -11,6 +11,7 @@
 <h1>Templates</h1>
 
 <p>A template is the label/card stock you are using. This might be Avery 5160 for address labels, Gaylord 47-284 for spine labels or Avery 28371 for your patron cards, just to give a couple of examples. These labels will include all of the information you will need for setting up a Koha, this information may be on the packaging, and if not it can usually be found on the vendor's website.</p>
+<p>To print to a duplex card printer you need a '1 up template' (1 row / 1 column) and for both card sides a separate layout.</p>
 
 <h2>Batches</h2>
 
@@ -18,4 +19,4 @@
 
 <p><strong>See the full documentation for the Patron Card Creator in the <a href="http://manual.koha-community.org/[% helpVersion %]/en/patroncardcreator.html">manual</a> (online).</strong></p>
 
-[% INCLUDE 'help-bottom.inc' %]
\ No newline at end of file
+[% INCLUDE 'help-bottom.inc' %]
index 2691254..950cf4e 100644 (file)
                         [% IF ( batche.label_ids ) %]
                         <legend>[% batche.card_count %] Single patron cards</legend>
                         <p>
-                                <a class="document pdf" href="/cgi-bin/koha/patroncards/[% batche.create_script %]?batch_id=[% batche.batch_id %]&amp;template_id=[% batche.template_id %]&amp;layout_id=[% batche.layout_id %]&amp;start_card=[% batche.start_card %][% batche.label_ids %]">label_single_[% batche.card_count %].pdf</a>
+                                <a class="document pdf" href="/cgi-bin/koha/patroncards/[% batche.create_script %]?batch_id=[% batche.batch_id %]&amp;template_id=[% batche.template_id %]&amp;layout_id=[% batche.layout_id %]]&amp;layout_back_id=[% batche.layout_back_id %]&amp;start_card=[% batche.start_card %][% batche.label_ids %]">label_single_[% batche.card_count %].pdf</a>
                         </p>
                         [% ELSIF ( batche.borrower_numbers ) %]
                         <legend>[% batche.card_count %] Single Patron Cards</legend>
                         <p>
-                                <a class="document pdf" href="/cgi-bin/koha/patroncards/[% batche.create_script %]?template_id=[% batche.template_id %]&amp;layout_id=[% batche.layout_id %]&amp;start_card=[% batche.start_card %][% batche.borrower_numbers %]">label_single_[% batche.card_count %].pdf</a>
+                                <a class="document pdf" href="/cgi-bin/koha/patroncards/[% batche.create_script %]?template_id=[% batche.template_id %]&amp;layout_id=[% batche.layout_id %]&amp;layout_back_id=[% batche.layout_back_id %]&amp;start_card=[% batche.start_card %][% batche.borrower_numbers %]">label_single_[% batche.card_count %].pdf</a>
                         </p>
                         [% ELSE %]
                         <legend>Card batch number [% batche.batch_id %]</legend>
                         <p>
-                                <a class="document pdf" href="/cgi-bin/koha/patroncards/create-pdf.pl?batch_id=[% batche.batch_id %]&amp;template_id=[% batche.template_id %]&amp;layout_id=[% batche.layout_id %]&amp;start_card=[% batche.start_card %]">label_batch_[% batche.batch_id %].pdf</a>
+                                <a class="document pdf" href="/cgi-bin/koha/patroncards/create-pdf.pl?batch_id=[% batche.batch_id %]&amp;template_id=[% batche.template_id %]&amp;layout_id=[% batche.layout_id %]&amp;layout_back_id=[% batche.layout_back_id %]&amp;start_card=[% batche.start_card %]">label_batch_[% batche.batch_id %].pdf</a>
                         </p>
                         [% END %]
                     [% END %]
                             </select>
                         </li>
                         <li>
+                            <label style="width:9em" for="layout_back_id">Select a layout for back side: </label>
+                            <select name="layout_back_id" id="layout_back_id">
+                                <option value="0">Back side layout not used</option>
+                                [% FOREACH layout IN layouts %]
+                                <option value="[% layout.layout_id %]">[% layout.layout_name %]</option>
+                                [% END %]
+                            </select>
+                            <span class="hint">Used for duplex printers (needs a '1 up template')</span>
+                        </li>
+
+                        <li>
                             <label style="width:9em" for="start_card">Enter starting card position: </label>
                             <input type="text" size="5" id="start_card" name="start_card" class="focus" title="Starting card number" value="1" />
                         </li>
index e660af6..9f21a50 100755 (executable)
@@ -26,6 +26,7 @@ use Graphics::Magick;
 use XML::Simple;
 use POSIX qw(ceil);
 use autouse 'Data::Dumper' => qw(Dumper);
+use Clone qw(clone);
 
 use C4::Debug;
 use C4::Context;
@@ -48,6 +49,7 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user({
 my $batch_id    = $cgi->param('batch_id') if $cgi->param('batch_id');
 my $template_id = $cgi->param('template_id') || undef;
 my $layout_id   = $cgi->param('layout_id') || undef;
+my $layout_back_id   = $cgi->param('layout_back_id') || undef;
 my $start_card = $cgi->param('start_card') || 1;
 my @label_ids   = $cgi->multi_param('label_id') if $cgi->param('label_id');
 my @borrower_numbers  = $cgi->multi_param('borrower_number') if $cgi->param('borrower_number');
@@ -70,6 +72,7 @@ $pdf = C4::Creators::PDF->new(InitVars => 0);
 my $batch = C4::Patroncards::Batch->retrieve(batch_id => $batch_id);
 my $pc_template = C4::Patroncards::Template->retrieve(template_id => $template_id, profile_id => 1);
 my $layout = C4::Patroncards::Layout->retrieve(layout_id => $layout_id);
+my $layout_back = C4::Patroncards::Layout->retrieve(layout_id => $layout_back_id) if ( $layout_back_id );
 
 $| = 1;
 
@@ -110,6 +113,7 @@ else {
 }
 
 my $layout_xml = XMLin($layout->get_attr('layout_xml'), ForceArray => 1);
+my $layout_back_xml = XMLin($layout_back->get_attr('layout_xml'), ForceArray => 1) if ( defined $layout_back );
 
 if ($layout_xml->{'page_side'} eq 'B') { # rearrange items on backside of page to swap columns
     my $even = 1;
@@ -127,12 +131,17 @@ if ($layout_xml->{'page_side'} eq 'B') { # rearrange items on backside of page t
 CARD_ITEMS:
 foreach my $item (@{$items}) {
     if ($item) {
+
+#my $print_layout_xml = $layout_back_xml;
+        my $print_layout_xml = (( ($cardscount % 2  == 1) && ( $layout_back_id ) ) ?
+            clone($layout_back_xml) : clone($layout_xml) );
+
         $cardscount ++;
         my $borrower_number = $item->{'borrower_number'};
         my $card_number = GetMember(borrowernumber => $borrower_number)->{'cardnumber'};
 
 #       Set barcode data
-        $layout_xml->{'barcode'}->[0]->{'data'} = $card_number if $layout_xml->{'barcode'};
+        $print_layout_xml->{'barcode'}->[0]->{'data'} = $card_number if $print_layout_xml->{'barcode'};
 
 #       Create a new patroncard object
         my $patron_card = C4::Patroncards::Patroncard->new(
@@ -142,17 +151,17 @@ foreach my $item (@{$items}) {
                 lly                     => $lly,
                 height                  => $pc_template->get_attr('label_height'), # of the card
                 width                   => $pc_template->get_attr('label_width'),
-                layout                  => $layout_xml,
+                layout                  => $print_layout_xml,
                 text_wrap_cols          => 30, #FIXME: hardcoded,
         );
 
-        $patron_card->draw_guide_box($pdf) if $layout_xml->{'guide_box'};
-        $patron_card->draw_barcode($pdf) if $layout_xml->{'barcode'};
+        $patron_card->draw_guide_box($pdf) if $print_layout_xml->{'guide_box'};
+        $patron_card->draw_barcode($pdf) if $print_layout_xml->{'barcode'};
 
 #       Do image foo and place binary image data into layout hash
         my $image_data = {};
         my $error = undef;
-        my $images = $layout_xml->{'images'};
+        my $images = $print_layout_xml->{'images'};
         PROCESS_IMAGES:
         foreach (keys %{$images}) {
             if (grep{m/source/} keys(%{$images->{$_}->{'data_source'}->[0]})) {
@@ -232,6 +241,12 @@ foreach my $item (@{$items}) {
         $patron_card->draw_text($pdf);
     }
     ($llx, $lly, $new_page) = $pc_template->get_next_label_pos();
+
+    if ( ($cardscount % 2  == 1) && ( $layout_back_id ) ) {
+        $pdf->Page();
+        redo; # Use same patron data again for backside in card printer
+    }
+
     $pdf->Page() if $new_page;
 }
 # No errors occurred within eval, we can issue the pdf
index fdadfc9..c57be1d 100755 (executable)
@@ -45,6 +45,7 @@ my @label_ids = $cgi->multi_param('label_id') if $cgi->param('label_id');   # th
 my @batch_ids = $cgi->multi_param('batch_id') if $cgi->param('batch_id');
 my $patronlist_id = $cgi->param('patronlist_id') || undef;
 my $layout_id = $cgi->param('layout_id') || undef;
+my $layout_back_id = $cgi->param('layout_back_id') || undef;
 my $template_id = $cgi->param('template_id') || undef;
 my $start_card = $cgi->param('start_card') || 1;
 my @borrower_numbers = $cgi->multi_param('borrower_number') if $cgi->param('borrower_number');
@@ -67,6 +68,7 @@ if ($op eq 'export') {
                          batch_id        => $batch_ids[0],
                          template_id     => $template_id,
                          layout_id       => $layout_id,
+                         layout_back_id  => $layout_back_id,
                          start_card      => $start_card,
                          label_ids       => $label_id_param,
                          card_count      => scalar(@label_ids),
@@ -82,6 +84,7 @@ if ($op eq 'export') {
         push (@batches, {create_script   => ($output_format eq 'pdf' ? 'create-pdf.pl' : 'create-csv.pl'),
                          template_id     => $template_id,
                          layout_id       => $layout_id,
+                         layout_back_id  => $layout_back_id,
                          start_card      => $start_card,
                          borrower_numbers    => $borrower_number_param,
                          card_count      => scalar(@borrower_numbers),
@@ -97,6 +100,7 @@ if ($op eq 'export') {
                             batch_id        => $batch_id,
                             template_id     => $template_id,
                             layout_id       => $layout_id,
+                            layout_back_id  => $layout_back_id,
                             start_card      => $start_card,
                             });
         }
@@ -110,6 +114,7 @@ if ($op eq 'export') {
                          patronlist_id   => $patronlist_id,
                          template_id     => $template_id,
                          layout_id       => $layout_id,
+                         layout_back_id  => $layout_back_id,
                          start_card      => $start_card,
                          referer         => $referer,
                         );