]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Trigger/Reactor.pm
0312 - JEDI template support for multiple ISBNs
[working/Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Trigger / Reactor.pm
1 package OpenILS::Application::Trigger::Reactor;
2 use strict; use warnings;
3 use Template;
4 use DateTime;
5 use DateTime::Format::ISO8601;
6 use OpenSRF::Utils qw/:datetime/;
7 use OpenSRF::Utils::Logger qw(:logger);
8 use OpenILS::Application::AppUtils;
9 use OpenILS::Utils::CStoreEditor qw/:funcs/;
10 my $U = 'OpenILS::Application::AppUtils';
11
12 sub fourty_two { return 42 }
13 sub NOOP_True  { return  1 }
14 sub NOOP_False { return  0 }
15
16
17
18 # helper functions inserted into the TT environment
19 my $_TT_helpers = {
20
21     # turns a date into something TT can understand
22     format_date => sub {
23         my $date = shift;
24         $date = DateTime::Format::ISO8601->new->parse_datetime(cleanse_ISO8601($date));
25         return sprintf(
26             "%0.2d:%0.2d:%0.2d %0.2d-%0.2d-%0.4d",
27             $date->hour,
28             $date->minute,
29             $date->second,
30             $date->day,
31             $date->month,
32             $date->year
33         );
34     },
35
36     # escapes a string for inclusion in an XML document.  escapes &, <, and > characters
37     escape_xml => sub {
38         my $str = shift;
39         $str =~ s/&/&amp;/sog;
40         $str =~ s/</&lt;/sog;
41         $str =~ s/>/&gt;/sog;
42         return $str;
43     },
44
45     escape_json => sub {
46         my $str = shift;
47         $str =~ s/([\x{0080}-\x{fffd}])/sprintf('\u%0.4x',ord($1))/sgoe;
48         return $str;
49     },
50
51     # returns the calculated user locale
52     get_user_locale => sub { 
53         my $user_id = shift;
54         return $U->get_user_locale($user_id);
55     },
56
57     # returns the calculated copy price
58     get_copy_price => sub {
59         my $copy_id = shift;
60         return $U->get_copy_price(new_editor(), $copy_id);
61     },
62
63     # given a copy, returns the title and author in a hash
64     get_copy_bib_basics => sub {
65         my $copy_id = shift;
66         my $copy = new_editor()->retrieve_asset_copy([
67             $copy_id,
68             {
69                 flesh => 2,
70                 flesh_fields => {
71                     acp => ['call_number'],
72                     acn => ['record']
73                 }
74             }
75         ]);
76         if($copy->call_number->id == -1) {
77             return {
78                 title  => $copy->dummy_title,
79                 author => $copy->dummy_author,
80             };
81         } else {
82             my $mvr = $U->record_to_mvr($copy->call_number->record);
83             return {
84                 title  => $mvr->title,
85                 author => $mvr->author
86             };
87         }
88     },
89
90     # returns the org unit setting value
91     get_org_setting => sub {
92         my($org_id, $setting) = @_;
93         return $U->ou_ancestor_setting_value($org_id, $setting);
94     },
95
96     # This basically greps/maps out ths isbn string values, but also promotes the first isbn-13 to the
97     # front of the line (so that the EDI translator takes it as primary) if there is one.
98     get_li_isbns => sub {
99         my $attrs = shift;
100         my @isbns;
101         my $primary;
102         foreach (@$attrs) {
103             $_->attr_name eq 'isbn' or next;
104             my $val = $_->attr_value;
105             if (! $primary and length($val) == 13) {
106                 $primary = $val;
107             } else {
108                 push @isbns, $val;
109             }
110         }
111         $primary and unshift @isbns, $primary;
112         $logger->error("get_li_isbns returning isbns: " . join(', ', @isbns));
113         return @isbns;
114     },
115
116     # helpers.get_li_attr('isbn_13', li.attributes)
117     # returns matching line item attribute, or undef
118     get_li_attr => sub {
119         my $name = shift or return;     # the first arg is always the name
120         my ($type, $attr) = (scalar(@_) == 1) ? (undef, $_[0]) : @_;
121         # if the next is the last, it's the attributes, otherwise type
122         # use Data::Dumper; $logger->warn("get_li_attr: " . Dumper($attr));
123         ($name and @$attr) or return;
124         my $length;
125         $name =~ s/^(\D+)_(\d+)$/$1/ and $length = $2;
126         foreach (@$attr) {
127             $_->attr_name eq $name or next;
128             next if $length and $length != length($_->attr_value);
129             return $_->attr_value if (! $type) or $type eq $_->attr_type;
130         }
131         return;
132     },
133 };
134
135
136 # processes templates.  Returns template output on success, undef on error
137 sub run_TT {
138     my $self = shift;
139     my $env = shift;
140     my $nostore = shift;
141     return undef unless $env->{template};
142
143     my $error;
144     my $output = '';
145     my $tt = Template->new;
146     # my $tt = Template->new(ENCODING => 'utf8');   # ??
147     $env->{helpers} = $_TT_helpers;
148
149     unless( $tt->process(\$env->{template}, $env, \$output) ) {
150         $output = undef;
151         ($error = $tt->error) =~ s/\n/ /og;
152         $logger->error("Error processing Trigger template: $error");
153     }
154
155     if ( $error or (!$nostore && $output) ) {
156         my $t_o = Fieldmapper::action_trigger::event_output->new;
157         $t_o->data( ($error) ? $error : $output );
158         $t_o->is_error( ($error) ? 't' : 'f' );
159
160         $env->{EventProcessor}->editor->xact_begin;
161         $t_o = $env->{EventProcessor}->editor->create_action_trigger_event_output( $t_o );
162
163         my $state = (ref $$env{event} eq 'ARRAY') ? $$env{event}->[0]->state : $env->{event}->state;
164         my $key = ($error) ? 'error_output' : 'template_output';
165         $env->{EventProcessor}->update_state( $state, { $key => $t_o->id } );
166     }
167         
168     return $output;
169 }
170
171
172 1;