LP1825851 server print additions WIP
authorBill Erickson <berickxx@gmail.com>
Thu, 11 Jul 2019 15:42:04 +0000 (11:42 -0400)
committerBill Erickson <berickxx@gmail.com>
Thu, 11 Jul 2019 15:42:04 +0000 (11:42 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/share/print/print.service.ts
Open-ILS/src/eg2/src/app/share/util/sample-data.service.ts
Open-ILS/src/eg2/src/app/staff/admin/server/print-template.component.ts
Open-ILS/src/eg2/src/app/staff/share/holds/grid.component.html
Open-ILS/src/eg2/src/app/staff/share/holds/grid.component.ts
Open-ILS/src/perlmods/lib/OpenILS/WWW/PrintTemplate.pm
Open-ILS/src/sql/Pg/upgrade/XXXX.schema.server-print-templates.sql

index 79762af..abba31c 100644 (file)
@@ -70,12 +70,12 @@ export class PrintService {
             formData.append('template_id', '' + printReq.templateId);
         }
         if (printReq.templateOwner) {
-            formData.append('owner', '' + printReq.templateOwner);
+            formData.append('template_owner', '' + printReq.templateOwner);
         }
         formData.append('template_data', js2JSON(printReq.contextData));
-        formData.append('locale', this.locale.currentLocaleCode());
+        formData.append('template_locale', this.locale.currentLocaleCode());
 
-        // Sometimes we want to know the time zone of the browser,
+        // Sometimes we want to know the time zone of the browser/user,
         // regardless of any org unit settings.
         if (OpenSRF.tz) {
             formData.append('client_timezone', OpenSRF.tz);
index 71bcd56..1efb45f 100644 (file)
@@ -6,6 +6,8 @@ import {IdlService, IdlObject} from '@eg/core/idl.service';
 // TODO: I could also imagine this coming from a web service or
 // even a flat file of web-served JSON.
 
+const NOW_DATE = new Date().toISOString();
+
 // Copied from sample of Concerto data set
 const DATA = {
     au: [
@@ -20,6 +22,18 @@ const DATA = {
         {first_given_name: 'Jo',       second_given_name: 'Mai',       family_name: 'Madden'},
         {first_given_name: 'Maomi',    second_given_name: 'Julie',     family_name: 'Harding'}
     ],
+    ac: [
+        {barcode: '908897239000'},
+        {barcode: '908897239001'},
+        {barcode: '908897239002'},
+        {barcode: '908897239003'},
+        {barcode: '908897239004'},
+        {barcode: '908897239005'},
+        {barcode: '908897239006'},
+        {barcode: '908897239007'},
+        {barcode: '908897239008'},
+        {barcode: '908897239009'}
+    ],
     aua: [
         {street1: '1809 Target Way', city: 'Vero beach', state: 'FL', post_code: 32961},
         {street1: '3481 Facility Island', city: 'Campton', state: 'KY', post_code: 41301},
@@ -31,6 +45,42 @@ const DATA = {
         {street1: '759 Doubtful Government Extension', city: 'Sellersville', state: 'PA', post_code: 18960},
         {street1: '5431 Japanese Work Rapid', city: 'Society hill', state: 'SC', post_code: 29593},
         {street1: '5253 Agricultural Exhibition Stravenue', city: 'La place', state: 'IL', post_code: 61936}
+    ],
+    ahr: [
+        {request_time: NOW_DATE, hold_type: 'T', capture_time: null,     fulfillment_time: null},
+        {request_time: NOW_DATE, hold_type: 'T', capture_time: null,     fulfillment_time: null},
+        {request_time: NOW_DATE, hold_type: 'V', capture_time: null,     fulfillment_time: null},
+        {request_time: NOW_DATE, hold_type: 'C', capture_time: null,     fulfillment_time: null},
+        {request_time: NOW_DATE, hold_type: 'T', capture_time: null,     fulfillment_time: null, frozen: true},
+        {request_time: NOW_DATE, hold_type: 'T', capture_time: NOW_DATE, fulfillment_time: null},
+        {request_time: NOW_DATE, hold_type: 'T', capture_time: NOW_DATE, fulfillment_time: null},
+        {request_time: NOW_DATE, hold_type: 'T', capture_time: NOW_DATE, fulfillment_time: NOW_DATE},
+        {request_time: NOW_DATE, hold_type: 'T', capture_time: NOW_DATE, fulfillment_time: NOW_DATE},
+        {request_time: NOW_DATE, hold_type: 'T', capture_time: NOW_DATE, fulfillment_time: NOW_DATE}
+    ],
+    acp: [
+        {barcode: '208897239000'},
+        {barcode: '208897239001'},
+        {barcode: '208897239002'},
+        {barcode: '208897239003'},
+        {barcode: '208897239004'},
+        {barcode: '208897239005'},
+        {barcode: '208897239006'},
+        {barcode: '208897239007'},
+        {barcode: '208897239008'},
+        {barcode: '208897239009'}
+    ],
+    mwde: [
+        {title: "Sinidos sinfónicos : an orchestral sampler"},
+        {title: "Piano concerto, op. 38"},
+        {title: "Critical entertainments : music old and new"},
+        {title: "Piano concerto in C major, op. 39"},
+        {title: "Double concerto in A minor, op. 102 ; Variations on a theme by Haydn, op. 56a ; Tragic overture, op. 81"},
+        {title: "Trombone concerto (1991) subject: american"},
+        {title: "Violin concerto no. 2 ; Six duos (from 44 Duos)"},
+        {title: "Piano concerto no. 1 (1926) ; Rhapsody, op. 1 (1904)"},
+        {title: "Piano concertos 2 & 3 & the devil makes me?"},
+        {title: "Composition student recital, April 6, 2000, Huntington University / composition students of Daniel Bédard"},
     ]
 };
 
index 19c9bf0..d94cb9f 100644 (file)
@@ -36,11 +36,10 @@ export class PrintTemplateComponent implements OnInit {
 
     // Define some sample data that can be used for various templates
     // Data will be filled out via the sample data service.
+    // Keys map to print template names
     sampleData: any = {
-        patron_address: {
-            patron: null,
-            address: null
-        }
+        patron_address: {},
+        holds_for_bib: {}
     }
 
     constructor(
@@ -70,12 +69,39 @@ export class PrintTemplateComponent implements OnInit {
 
         // NOTE: server templates work fine with IDL objects, but
         // vanilla hashes are easier to work with in the admin UI.
-        const patrons = this.idl.toHash(this.samples.listOfThings('au', 10));
-        const addresses = this.idl.toHash(this.samples.listOfThings('aua', 10));
+
+        // Classes for which sample data exists
+        const classes = ['au', 'ac', 'aua', 'ahr', 'acp', 'mwde'];
+        const samples: any = {};
+        classes.forEach(class_ => samples[class_] = 
+            this.idl.toHash(this.samples.listOfThings(class_, 10)))
+
+        // Flesh some patrons with cards
+        const patron0 = this.idl.clone(samples.au[0]);
+        const patron1 = this.idl.clone(samples.au[1]);
+        const patron2 = this.idl.clone(samples.au[2]);
+        patron0.card = samples.ac[0];
+        patron1.card = samples.ac[1];
+        patron2.card = samples.ac[2];
 
         this.sampleData.patron_address = {
-            patron:  patrons[0],
-            address: addresses[0]
+            patron:  samples.au[0],
+            address: samples.aua[0]
+        };
+
+        this.sampleData.holds_for_bib = {
+            title: samples.mwde[0].title,
+            holds: [
+                {
+                    hold: samples.ahr[0],
+                    patron: patron0,
+                    copy: samples.acp[0]
+                }, {
+                    hold: samples.ahr[1],
+                    patron: patron1,
+                    copy: samples.acp[1]
+                }
+            ]
         };
     }
 
index db3d31b..0ebc0a6 100644 (file)
         i18-group group="Hold" i18n-label label="Cancel Hold"
         (onClick)="showCancelDialog($event)"></eg-grid-toolbar-action>
 
+      <eg-grid-toolbar-action
+        i18-group group="Hold" i18n-label label="Print Holds"
+        (onClick)="printHolds()"></eg-grid-toolbar-action>
+
       <eg-grid-column i18n-label label="Hold ID" path='id' [index]="true" datatype="id">
       </eg-grid-column>
 
index bdecd41..1b707c6 100644 (file)
@@ -18,6 +18,7 @@ import {HoldRetargetDialogComponent
 import {HoldTransferDialogComponent} from './transfer-dialog.component';
 import {HoldCancelDialogComponent} from './cancel-dialog.component';
 import {HoldManageDialogComponent} from './manage-dialog.component';
+import {PrintService} from '@eg/share/print/print.service';
 
 /** Holds grid with access to detail page and other actions */
 
@@ -389,6 +390,9 @@ export class HoldsGridComponent implements OnInit {
             );
         }
     }
+
+    printHolds() {
+    }
 }
 
 
index 7cfc448..697d951 100644 (file)
@@ -57,23 +57,23 @@ sub handler {
     # Let pcrud handle the authz
     $e->personality('open-ils.pcrud');
 
-    my $owner = $cgi->param('owner') || $e->requestor->ws_ou;
-    my $locale = $cgi->param('locale') || 'en-US';
+    my $tmpl_owner = $cgi->param('template_owner') || $e->requestor->ws_ou;
+    my $tmpl_locale = $cgi->param('template_locale') || 'en-US';
+    my $tmpl_id = $cgi->param('template_id');
+    my $tmpl_name = $cgi->param('template_name');
+    my $tmpl_data = $cgi->param('template_data');
     my $client_timezone = $cgi->param('client_timezone');
-    my $template_id = $cgi->param('template_id');
-    my $template_name = $cgi->param('template_name');
-    my $template_data = $cgi->param('template_data');
 
-    return Apache2::Const::HTTP_BAD_REQUEST 
-        unless $template_name || $template_id;
+    return Apache2::Const::HTTP_BAD_REQUEST unless $tmpl_name || $tmpl_id;
 
-    my $template = find_template($e, $template_id, $template_name, $locale, $owner)
+    my $template = 
+        find_template($e, $tmpl_id, $tmpl_name, $tmpl_locale, $tmpl_owner)
         or return Apache2::Const::NOT_FOUND;
 
     my $data;
-    eval { $data = OpenSRF::Utils::JSON->JSON2perl($template_data); };
+    eval { $data = OpenSRF::Utils::JSON->JSON2perl($tmpl_data); };
     if ($@) {
-        $logger->error("Invalid JSON in template compilation: $template_data");
+        $logger->error("Invalid JSON in template compilation: $tmpl_data");
         return Apache2::Const::HTTP_BAD_REQUEST;
     }
 
@@ -84,11 +84,11 @@ sub handler {
     my $tmpl = $template->template;
 
     my $context = {
-        locale => $locale,
+        template_locale => $tmpl_locale,
         client_timezone => $client_timezone,
         staff => $e->requestor,
         staff_org => $staff_org,
-        staff_org_timezone => get_org_timezone($staff_org->id),
+        staff_org_timezone => get_org_timezone($e, $staff_org->id),
         helpers => $helpers,
         template_data => $data
     };
@@ -110,7 +110,7 @@ sub handler {
     } else {
 
         (my $error = $tt->error) =~ s/\n/ /og;
-        $logger->error("Error processing Trigger template: $error");
+        $logger->error("Error processing print template: $error");
         return Apache2::Const::HTTP_INTERNAL_SERVER_ERROR;
     }
 }
@@ -120,9 +120,15 @@ sub get_org_timezone {
     my ($e, $org_id) = @_;
 
     if (!$org_timezone_cache{$org_id}) {
-        $org_timezone_cache{$org_id} = 
-            $U->ou_ancestor_setting_value($org_id, 'lib.timezone')
-            || DateTime->now(time_zone => 'local')->time_zone->name;
+
+        # open-ils.auth call required since our $e is in pcrud mode.
+        my $value = $U->simplereq(
+            'open-ils.actor',
+            'open-ils.actor.ou_setting.ancestor_default', 
+            $org_id, 'lib.timezone');
+
+        $org_timezone_cache{$org_id} = $value ? $value->{value} : 
+            DateTime->now(time_zone => 'local')->time_zone->name;
     }
 
     return $org_timezone_cache{$org_id};
@@ -184,8 +190,12 @@ $helpers = {
         my $date = shift;
         my $tz = shift;
 
-        $date->set_time_zone($tz) if $tz;
+        $logger->info("setting TZ = $tz");
+
         $date = DateTime::Format::ISO8601->new->parse_datetime(clean_ISO8601($date));
+        $date->set_time_zone($tz) if $tz;
+        $logger->info("setting TZ XXX = $tz");
+
         return sprintf(
             "%0.2d:%0.2d:%0.2d %0.2d-%0.2d-%0.4d",
             $date->hour,
@@ -195,12 +205,12 @@ $helpers = {
             $date->month,
             $date->year
         );
-    }
+    },
 
-    format_current_date => sub {
+    current_date => sub {
         my $tz = shift || 'local';
-        my $date = DateTime->new(time_zone => $tz);
-        return $helpers->format_date($date);
+        my $date = DateTime->now(time_zone => $tz);
+        return $helpers->{format_date}->($date);
     }
 };
 
index 96ce998..3a42e9c 100644 (file)
@@ -48,13 +48,13 @@ VALUES (
     2, 'holds_for_bib', 'en-US', FALSE,
     (SELECT id FROM actor.org_unit WHERE parent_ou IS NULL),
     oils_i18n_gettext(2, 'Holds for Bib Record', 'cpt', 'label'),
-$TEMPLATE$
 [%-
     USE date;
     SET holds = template_data.holds;
+    SET title = template_data.title;
 -%]
 <div>
-  <div>Holds for record: [% holds.0.title %]</div>
+  <div>Holds for record: [% title %]</div>
   <hr/>
   <style>#holds-for-bib-table td { padding: 5px; }</style>
   <table id="holds-for-bib-table">
@@ -74,19 +74,21 @@ $TEMPLATE$
           date.format(helpers.format_date(
             hold.hold.request_time, staff_org_timezone), '%x %r', locale) 
         %]</td>
-        <td>[% hold.patron.barcode %]</td>
-        <td>[% hold.patron.last %]</td>
+        <td>[% hold.patron.card.barcode %]</td>
+        <td>[% hold.patron.family_name %]</td>
         <td>[% hold.patron.alias %]</td>
         <td>[% hold.copy.barcode %]</td>
       </tr>
+      [% END %]
     </tbody>
   </table>
   <hr/>
   <div>
     [% staff_org.shortname %] 
-    [% date.format(helpers.format_current_date(client_timezone), '%x %r', locale) %]
+    [% date.format(helpers.current_date(client_timezone), '%x %r', locale) %]
   </div>
   <div>Printed by [% staff.first_given_name %]</div>
+</div>
 <br/>
 
 $TEMPLATE$