Added sample self-checkout checkout receipt
authorerickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 25 Nov 2009 21:38:37 +0000 (21:38 +0000)
committererickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 25 Nov 2009 21:38:37 +0000 (21:38 +0000)
added generic (public/perm-checkin) circ event runner
Added 'g' qualifier to event path-fleshing method name munging
Added explicit exception when environment path is not valid
Added virtual hours_of_operation field for org units

git-svn-id: svn://svn.open-ils.org/ILS/trunk@15030 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/examples/fm_IDL.xml
Open-ILS/src/perlmods/OpenILS/Application/AppUtils.pm
Open-ILS/src/perlmods/OpenILS/Application/Circ.pm
Open-ILS/src/perlmods/OpenILS/Application/Trigger/Event.pm
Open-ILS/src/sql/Pg/002.schema.config.sql
Open-ILS/src/sql/Pg/950.data.seed-values.sql
Open-ILS/src/sql/Pg/upgrade/0094.data.selfcheck-receipt-template.sql [new file with mode: 0644]

index e4a1890..aeabe14 100644 (file)
@@ -3034,7 +3034,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
                        <field reporter:label="Resources" name="resources" oils_persist:virtual="true" reporter:datatype="link"/>
                        <field reporter:label="Resource Attributes" name="rsrc_attrs" oils_persist:virtual="true" reporter:datatype="link"/>
                        <field reporter:label="Attribute Values" name="attr_vals" oils_persist:virtual="true" reporter:datatype="link"/>
-
+                       <field reporter:label="Hours of Operation" name="hours_of_operation" oils_persist:virtual="true" reporter:datatype="link"/>
                </fields>
                <links>
                        <link field="billing_address" reltype="has_a" key="id" map="" class="aoa"/>
@@ -3062,6 +3062,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
                        <link field="resources" reltype="has_many" key="owner" map="" class="brsrc"/>
                        <link field="rsrc_attrs" reltype="has_many" key="owner" map="" class="bra"/>
                        <link field="attr_vals" reltype="has_many" key="owner" map="" class="brav"/>
+                       <link field="hours_of_operation" reltype="might_have" key="id" map="" class="aouhoo"/>
                </links>
         <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
             <actions>
index f3b7a7c..2a0fff9 100644 (file)
@@ -1481,7 +1481,7 @@ sub xact_org {
 # most appropriate event.  create the event, fire it, then return the resulting
 # event with fleshed template_output and error_output
 sub fire_object_event {
-    my($self, $event_def, $hook, $object, $context_org) = @_;
+    my($self, $event_def, $hook, $object, $context_org, $granularity, $user_data) = @_;
 
     my $e = OpenILS::Utils::CStoreEditor->new;
     my $def;
@@ -1496,6 +1496,7 @@ sub fire_object_event {
 
     } else {
         # find the most appropriate event def depending on context org
+
         my $orgs = $self->get_org_ancestors($context_org);
         $orgs = $e->search_actor_org_unit(
             [{id => $orgs}, {flesh => 1, flesh_fields => {aou => ['ou_type']}}]);
@@ -1511,26 +1512,51 @@ sub fire_object_event {
         return $e->event unless $def;
     }
 
-    my $event_id = $self->simplereq(
-        'open-ils.trigger', $auto_method, $def->id, $object, $context_org);
+    if($def->group_field) {
+        # we have a list of objects
+        $object = [$object] unless ref $object eq 'ARRAY';
+
+        my @event_ids;
+        $user_data ||= [];
+        for my $i (0..$#$object) {
+            my $obj = $$object[$i];
+            my $udata = $$user_data[$i];
+            my $event_id = $self->simplereq(
+                'open-ils.trigger', $auto_method, $def->id, $obj, $context_org, $udata);
+            push(@event_ids, $event_id);
+        }
 
-    my $fire = 'open-ils.trigger.event.fire';
+        $logger->info("EVENTS = " . OpenSRF::Utils::JSON->perl2JSON(\@event_ids));
 
-    if($def->group_field) {
-        $fire =~ s/event/event_group/o;
-        $event_id = [$event_id];
-    }
+        my $resp = $self->simplereq(
+            'open-ils.trigger', 
+            'open-ils.trigger.event_group.fire',
+            \@event_ids);
 
-    my $resp = $self->simplereq('open-ils.trigger', $fire, $event_id);
-    return 0 unless $resp and ($resp->{event} or $resp->{events});
-    my $evt = $resp->{event} ? $resp->{event} : $resp->{events}->[0];
+        return undef unless $resp and $resp->{events} and @{$resp->{events}};
 
-    return 0 unless $evt;
+        return $e->retrieve_action_trigger_event([
+            $resp->{events}->[0]->id,
+            {flesh => 1, flesh_fields => {atev => ['template_output', 'error_output']}}
+        ]);
 
-    return $e->retrieve_action_trigger_event([
-        $evt->id,
-        {flesh => 1, flesh_fields => {atev => ['template_output', 'error_output']}}
-    ]);
+    } else {
+
+        my $event_id = $self->simplereq(
+            'open-ils.trigger', $auto_method, $def->id, $object, $context_org, $user_data);
+
+        my $resp = $self->simplereq(
+            'open-ils.trigger', 
+            'open-ils.trigger.event.fire', 
+            $event_id);
+
+        return undef unless $resp and $resp->{event};
+
+        return $e->retrieve_action_trigger_event([
+            $resp->{event}->id,
+            {flesh => 1, flesh_fields => {atev => ['template_output', 'error_output']}}
+        ]);
+    }
 }
 
 
index 10be02c..99495b4 100644 (file)
@@ -1278,7 +1278,27 @@ sub test_batch_circ_events {
     return $U->fire_object_event($event_def, undef, $circ, $e->requestor->ws_ou)
 }
 
+__PACKAGE__->register_method(
+       method  => "fire_circ_events", 
+       api_name        => "open-ils.circ.fire_circ_trigger_events",
+    signature => q/
+        General event def runner for circ objects.  If no event def ID
+        is provided, the hook will be used to find the best event_def
+        match based on the context org unit
+    /
+);
 
+sub fire_circ_events {
+    my($self, $conn, $auth, $org_id, $event_def, $hook, $granularity, $circ_ids, $user_data) = @_;
+
+    my $e = new_editor(authtoken => $auth);
+       return $e->event unless $e->checkauth;
+    return $e->event unless $e->allowed('VIEW_CIRCULATIONS', $org_id);
+
+    my $circs = $e->batch_retrieve_action_circulation($circ_ids);
+    return undef unless @$circs;
+    return $U->fire_object_event($event_def, $hook, $circs, $org_id, $granularity, $user_data)
+}
 
 __PACKAGE__->register_method(
        method  => "user_payments_list",
index 9eaf4a3..00d2c10 100644 (file)
@@ -433,11 +433,17 @@ sub _object_by_path {
     my $label = shift;
     my $path = shift;
 
+
     my $step = shift(@$path);
 
+
     my $fhint = Fieldmapper->publish_fieldmapper->{$context->class_name}{links}{$step}{class};
     my $fclass = $self->_fm_class_by_hint( $fhint );
 
+    OpenSRF::EX::ERROR->throw(
+        "$step is not a field on ".$context->class_name."  Please repair the environment.")
+        unless $fhint;
+
     my $ffield = Fieldmapper->publish_fieldmapper->{$context->class_name}{links}{$step}{key};
     my $rtype = Fieldmapper->publish_fieldmapper->{$context->class_name}{links}{$step}{reltype};
 
@@ -452,7 +458,7 @@ sub _object_by_path {
 
     $meth .= $fclass;
     $meth =~ s/Fieldmapper:://;
-    $meth =~ s/::/_/;
+    $meth =~ s/::/_/g;
 
     my $ed = grep( /open-ils.cstore/, @{$fclass->Controller} ) ?
             $self->editor :
@@ -460,6 +466,8 @@ sub _object_by_path {
 
     my $obj = $context->$step(); 
 
+    $logger->debug("_object_by_path(): meth=$meth, obj=$obj, multi=$multi, step=$step, lfield=$lfield");
+
     if (!ref $obj) {
         $obj = $ed->$meth( 
             ($multi) ?
index bc919a1..7a9d220 100644 (file)
@@ -51,7 +51,7 @@ CREATE TABLE config.upgrade_log (
     install_date    TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
 );
 
-INSERT INTO config.upgrade_log (version) VALUES ('0093'); -- miker
+INSERT INTO config.upgrade_log (version) VALUES ('0094'); -- berick
 
 CREATE TABLE config.bib_source (
        id              SERIAL  PRIMARY KEY,
index 5c23bb3..c398375 100644 (file)
@@ -2615,4 +2615,108 @@ INSERT INTO config.org_unit_setting_type ( name, label, description, datatype )
         'bool'
     );
 
+-- self-check checkout receipt
+
+INSERT INTO action_trigger.hook (key, core_type, description, passive) 
+    VALUES (
+        'format.selfcheck.checkout',
+        'circ',
+        'Formats circ objects for self-checkout receipt',
+        TRUE
+    );
+
+INSERT INTO action_trigger.event_definition (id, active, owner, name, hook, validator, reactor, group_field, granularity, template )
+    VALUES (
+        10,
+        TRUE,
+        1,
+        'Self-Checkout Receipt',
+        'format.selfcheck.checkout',
+        'NOOP_True',
+        'ProcessTemplate',
+        'usr',
+        'print-on-demand',
+$$
+[%- USE date -%]
+[%- SET user = target.0.usr -%]
+[%- SET lib = target.0.circ_lib -%]
+[%- SET lib_addr = target.0.circ_lib.billing_address -%]
+[%- SET hours = lib.hours_of_operation -%]
+<div>
+    <style> li { padding: 8px; margin 5px; }</style>
+    <div>[% date.format %]</div>
+    <div>[% lib.name %]</div>
+    <div>[% lib_addr.street1 %] [% lib_addr.street2 %]</div>
+    <div>[% lib_addr.city %], [% lib_addr.state %] [% lb_addr.post_code %]</div>
+    <div>[% lib.phone %]</div>
+    <br/>
+
+    [% user.family_name %], [% user.first_given_name %]
+    <ol>
+    [% FOR circ IN target %]
+        [%-
+            SET idx = loop.count - 1;
+            SET user_data =  EventProcessor.findEvent( event.$idx ).environment.user_data 
+        -%]
+        <li>
+            <div>[% helpers.get_copy_bib_basics(circ.target_copy.id).title %]</div>
+            <div>Barcode: [% circ.target_copy.barcode %]</div>
+            [% IF user_data.renewal_failure %]
+                <div style='color:red;'>Renewal Failed</div>
+            [% ELSE %]
+                <div>Due Date: [% date.format(helpers.format_date(circ.due_date), '%Y-%m-%d') %]</div>
+            [% END %]
+        </li>
+    [% END %]
+    </ol>
+    
+    <div>
+        Library Hours
+        [%- BLOCK format_time; date.format(time _ ' 1/1/1000', format='%I:%M %p'); END -%]
+        <div>
+            Monday 
+            [% PROCESS format_time time = hours.dow_0_open %] 
+            [% PROCESS format_time time = hours.dow_0_close %] 
+        </div>
+        <div>
+            Tuesday 
+            [% PROCESS format_time time = hours.dow_1_open %] 
+            [% PROCESS format_time time = hours.dow_1_close %] 
+        </div>
+        <div>
+            Wednesday 
+            [% PROCESS format_time time = hours.dow_2_open %] 
+            [% PROCESS format_time time = hours.dow_2_close %] 
+        </div>
+        <div>
+            Thursday
+            [% PROCESS format_time time = hours.dow_3_open %] 
+            [% PROCESS format_time time = hours.dow_3_close %] 
+        </div>
+        <div>
+            Friday
+            [% PROCESS format_time time = hours.dow_4_open %] 
+            [% PROCESS format_time time = hours.dow_4_close %] 
+        </div>
+        <div>
+            Saturday
+            [% PROCESS format_time time = hours.dow_5_open %] 
+            [% PROCESS format_time time = hours.dow_5_close %] 
+        </div>
+        <div>
+            Sunday 
+            [% PROCESS format_time time = hours.dow_6_open %] 
+            [% PROCESS format_time time = hours.dow_6_close %] 
+        </div>
+    </div>
+</div>
+$$
+);
+
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES
+    ( 10, 'target_copy'),
+    ( 10, 'circ_lib.billing_address'),
+    ( 10, 'circ_lib.hours_of_operation'),
+    ( 10, 'usr');
 
diff --git a/Open-ILS/src/sql/Pg/upgrade/0094.data.selfcheck-receipt-template.sql b/Open-ILS/src/sql/Pg/upgrade/0094.data.selfcheck-receipt-template.sql
new file mode 100644 (file)
index 0000000..6149a50
--- /dev/null
@@ -0,0 +1,108 @@
+BEGIN;
+
+INSERT INTO config.upgrade_log (version) VALUES ('0094');
+
+INSERT INTO action_trigger.hook (key, core_type, description, passive) 
+    VALUES (
+        'format.selfcheck.checkout',
+        'circ',
+        'Formats circ objects for self-checkout receipt',
+        TRUE
+    );
+
+INSERT INTO action_trigger.event_definition (id, active, owner, name, hook, validator, reactor, group_field, granularity, template )
+    VALUES (
+        10,
+        TRUE,
+        1,
+        'Self-Checkout Receipt',
+        'format.selfcheck.checkout',
+        'NOOP_True',
+        'ProcessTemplate',
+        'usr',
+        'print-on-demand',
+$$
+[%- USE date -%]
+[%- SET user = target.0.usr -%]
+[%- SET lib = target.0.circ_lib -%]
+[%- SET lib_addr = target.0.circ_lib.billing_address -%]
+[%- SET hours = lib.hours_of_operation -%]
+<div>
+    <style> li { padding: 8px; margin 5px; }</style>
+    <div>[% date.format %]</div>
+    <div>[% lib.name %]</div>
+    <div>[% lib_addr.street1 %] [% lib_addr.street2 %]</div>
+    <div>[% lib_addr.city %], [% lib_addr.state %] [% lb_addr.post_code %]</div>
+    <div>[% lib.phone %]</div>
+    <br/>
+
+    [% user.family_name %], [% user.first_given_name %]
+    <ol>
+    [% FOR circ IN target %]
+        [%-
+            SET idx = loop.count - 1;
+            SET user_data =  EventProcessor.findEvent( event.$idx ).environment.user_data 
+        -%]
+        <li>
+            <div>[% helpers.get_copy_bib_basics(circ.target_copy.id).title %]</div>
+            <div>Barcode: [% circ.target_copy.barcode %]</div>
+            [% IF user_data.renewal_failure %]
+                <div style='color:red;'>Renewal Failed</div>
+            [% ELSE %]
+                <div>Due Date: [% date.format(helpers.format_date(circ.due_date), '%Y-%m-%d') %]</div>
+            [% END %]
+        </li>
+    [% END %]
+    </ol>
+    
+    <div>
+        Library Hours
+        [%- BLOCK format_time; date.format(time _ ' 1/1/1000', format='%I:%M %p'); END -%]
+        <div>
+            Monday 
+            [% PROCESS format_time time = hours.dow_0_open %] 
+            [% PROCESS format_time time = hours.dow_0_close %] 
+        </div>
+        <div>
+            Tuesday 
+            [% PROCESS format_time time = hours.dow_1_open %] 
+            [% PROCESS format_time time = hours.dow_1_close %] 
+        </div>
+        <div>
+            Wednesday 
+            [% PROCESS format_time time = hours.dow_2_open %] 
+            [% PROCESS format_time time = hours.dow_2_close %] 
+        </div>
+        <div>
+            Thursday
+            [% PROCESS format_time time = hours.dow_3_open %] 
+            [% PROCESS format_time time = hours.dow_3_close %] 
+        </div>
+        <div>
+            Friday
+            [% PROCESS format_time time = hours.dow_4_open %] 
+            [% PROCESS format_time time = hours.dow_4_close %] 
+        </div>
+        <div>
+            Saturday
+            [% PROCESS format_time time = hours.dow_5_open %] 
+            [% PROCESS format_time time = hours.dow_5_close %] 
+        </div>
+        <div>
+            Sunday 
+            [% PROCESS format_time time = hours.dow_6_open %] 
+            [% PROCESS format_time time = hours.dow_6_close %] 
+        </div>
+    </div>
+</div>
+$$
+);
+
+
+INSERT INTO action_trigger.environment ( event_def, path) VALUES
+    ( 10, 'target_copy'),
+    ( 10, 'circ_lib.billing_address'),
+    ( 10, 'circ_lib.hours_of_operation'),
+    ( 10, 'usr');
+
+COMMIT;