RT#38217: Send email when logging conditions are met
[freeside.git] / httemplate / edit / msg_template / email.html
1 <& /edit/elements/edit.html,
2      'post_url'         => $fsurl.'edit/process/msg_template.html', 
3      'html_init'        => '<TABLE id="outerTable"><TR><TD>',
4      'body_etc'         => $body_etc,
5      'name_singular'    => 'template',
6      'table'            => 'msg_template',
7      'viewall_dir'      => 'browse',
8      'agent_virt'       => 1,
9      'agent_null'       => 1,
10      'agent_null_right' => [ 'View global templates', 'Edit global templates' ],
11
12      'fields'           => \@fields,
13      'labels'           => { 
14                              'msgnum'    => 'Template',
15                              'agentnum'  => 'Agent',
16                              'msgname'   => 'Template name',
17                              'from_addr' => 'From: ',
18                              'bcc_addr'  => 'Bcc: ',
19                              'locale'    => 'Locale',
20                              'subject'   => 'Subject: ',
21                              'body'      => 'Message body',
22                            },
23      'edit_callback'    => \&edit_callback,
24      'error_callback'   => \&edit_callback,
25      'html_bottom'      => '</DIV>',
26      'html_table_bottom'=> \&html_table_bottom,
27      'html_foot'        => ( $no_submit ? '' : "</TD>$sidebar</TR></TABLE>" ),
28      'no_submit'        => $no_submit,
29 &>
30 <%init>
31 use FS::template_image;
32
33 my $curuser = $FS::CurrentUser::CurrentUser;
34
35 die "access denied"
36   unless $curuser->access_right([ 'View templates', 'View global templates',
37                                   'Edit templates', 'Edit global templates',
38                                ]);
39
40 my $body_etc = '';
41 $body_etc = q!onload="document.getElementById('locale').onchange()"!
42   if $cgi->param('locale') eq 'new';
43
44 my $msgnum = $cgi->param('msgnum');
45 my $msg_template = $msgnum ? qsearchs('msg_template', {msgnum=>$msgnum}) : '';
46
47 my $no_submit = 0;
48 my @fields = ();
49 if ( $curuser->access_right('Edit global templates') 
50      || (    $curuser->access_right('Edit templates')
51           && $msg_template
52           && $msg_template->agentnum
53           && $curuser->agentnums_href->{$msg_template->agentnum}
54         )
55    )
56 {
57   push @fields,
58       { field => 'msgclass',
59         type  => 'hidden',
60         value => 'email',
61       },
62       { field => 'agentnum',
63         type  => 'select-agent',
64       },
65       { field => 'msgname',   size=>60, },
66       { field => 'from_addr', size=>60, },
67       { field => 'bcc_addr',  size=>60, },
68       { type  => 'tablebreak-tabs',
69         include_opt_callback => \&menubar_opt_callback,
70       },
71       # template_content fields
72       { field => 'locale', type => 'hidden' },
73       { field => 'subject',   size=>60, },
74       { field => 'body',
75         type  => 'htmlarea',
76         width => 763,
77         config=> { extraPlugins => 'blockprotect' },
78       },
79   ;
80 } else { #readonly
81
82   $no_submit = 1;
83
84   push @fields,
85       { field => 'agentnum',
86         type  => 'select-agent',
87         fixed => 1,
88       },
89       { field => 'msgname',   type => 'fixed', },
90       { field => 'from_addr', type => 'fixed', },
91       { field => 'bcc_addr',  type => 'fixed', },
92       { type  => 'tablebreak-tabs',
93         include_opt_callback => \&menubar_opt_callback,
94       },
95       # template_content fields
96       { field => 'locale',  type => 'hidden' },
97       { field => 'subject', type => 'fixed', },
98       { field    => 'body',
99         type     => 'fixed',
100         noescape => 1,
101       },
102   ;
103
104 }
105
106 sub new_callback {
107   my ($cgi, $object, $fields_listref, $opt_hashref) = @_;
108   my $template_content = new FS::template_content { 'locale' => '' };
109   $object->{'Hash'} = { $object->hash, $template_content->hash };
110 }
111
112 sub edit_callback {
113   my ($cgi, $object, $fields_listref, $opt_hashref) = @_;
114   $cgi->param('locale') =~ /^(\w*)$/ or die 'bad locale '.$cgi->param('locale');
115   my $locale = $1;
116
117   # fetch the content object and merge its fields
118   my %args = (
119     'msgnum' => $object->msgnum,
120     'locale' => $locale
121   );
122   my $template_content = qsearchs('template_content', \%args) 
123                         || new FS::template_content( { %args });
124   $object->{'Hash'} = { $object->hash, $template_content->hash };
125
126   # set up the locale selector if this is a new content
127   if ( $locale eq 'new' ) {
128
129     # make a list of available locales
130     my $content_locales = $object->content_locales;
131     my @locales = grep { !exists($content_locales->{$_}) } 
132                          FS::Conf->new->config('available-locales');
133     my %labels;
134     foreach (@locales) {
135       my %info = FS::Locales->locale_info($_);
136       $labels{$_} = $info{'label'};
137     }
138     unshift @locales, 'new';
139     $labels{'new'} = 'Select language';
140
141     # insert a field def
142     my $i = 0;
143     $i++ until ( $fields_listref->[$i]->{'field'} eq 'locale' );
144     my $locale_field = $fields_listref->[$i];
145
146     my $onchange_locale = "document.getElementById('submit').disabled = 
147     (this.options[this.selectedIndex].value == 'new');";
148
149     %$locale_field = (
150       field   => 'locale',
151       type    => 'select',
152       options => \@locales,
153       labels  => \%labels,
154       curr_value  => 'new',
155       onchange    => $onchange_locale,
156     );
157   }
158 }
159
160 sub menubar_opt_callback {
161   my $object = shift;
162   # generate no tabs for new msg_templates.
163   my $msgnum = $object->msgnum or return; 
164   my (@tabs, @options, %labels);
165   push @tabs, mt('Default'), '';
166   my $display_new = 0;
167   my $selected = '';
168   foreach my $l (FS::Locales->locales) {
169     if ( exists $object->content_locales->{$l} ) {
170       my %info = FS::Locales->locale_info($l);
171       push @tabs, 
172            $info{'label'},
173            ';locale='.$l;
174       $selected = $info{'label'} if $object->locale eq $l;
175     }
176     else {
177       $display_new = 1; # there is at least one unused locale left
178     }
179   }
180   push @tabs, mt('New'), ';locale=new' if $display_new;
181   $selected = mt('New') if $object->locale eq 'new';
182   $selected ||= mt('Default');
183   (
184     'url_base' => $fsurl.'edit/msg_template.html?msgnum='.$msgnum,
185     'selected' => $selected,
186     'tabs'     => \@tabs
187   );
188 }
189
190 my $onchange_locale = '';
191
192 # Create hints pane
193
194 my %substitutions = (
195   'cust_main' => [
196     '$display_custnum'=> 'Customer#',
197     '$agentnum'       => 'Agent#',
198     '$agent_name'     => 'Agent name',
199     '$payby'          => 'Payment method',
200     '$paymask'        => 'Card/account# (masked)',
201     '$payname'        => 'Name on card/bank name',
202     '$paytype'        => 'Account type',
203     '$payip'          => 'IP address used to submit payment info',
204     '$num_ncancelled_pkgs'  => '# of active packages',
205     '$num_cancelled_pkgs'   => '# of cancelled packages',
206     '$num_pkgs'       => '# of packages',
207     '$classname'      => 'Customer class',
208     '$categoryname'   => 'Customer category',
209     '$balance'        => 'Current balance',
210     '$credit_limit'   => 'Credit limit',
211     '$invoicing_list_emailonly' => 'Billing email address',
212     #'$cust_status'    => 'Status (raw internal label)',
213     '$cust_status_label' => 'Status (display label)',
214     '$cust_statuscolor'  => 'Status color code',
215     '$company_name'   => 'Our company name',
216     '$company_address'=> 'Our company address',
217     '$company_phonenum' => 'Our phone number',
218     '$selfservice_server_base_url' => 'Base URL of customer self-service',
219   ],
220   'contact' => [ # duplicate this for shipping
221     '$name'           => 'Company and contact name',
222     '$name_short'     => 'Company or contact name',
223     '$company'        => 'Company name',
224     '$contact'        => 'Contact name (last, first)',
225     '$contact_firstlast'=> 'Contact name (first last)',
226     '$first'          => 'First name',
227     '$last'           => 'Last name',
228     '$address1'       => 'Address line 1',
229     '$address2'       => 'Address line 2',
230     '$city'           => 'City',
231     '$county'         => 'County',
232     '$state'          => 'State',
233     '$zip'            => 'Zip',
234     '$country'        => 'Country',
235     '$daytime'        => 'Day phone',
236     '$night'          => 'Night phone',
237     '$mobile'         => 'Mobile phone',
238     '$fax'            => 'Fax',
239   ],
240   'service' => [
241     '$ship_address1'  => 'Address line 1',
242     '$ship_address2'  => 'Address line 2',
243     '$ship_city'      => 'City',
244     '$ship_county'    => 'County',
245     '$ship_state'     => 'State',
246     '$ship_zip'       => 'Zip',
247     '$ship_country'   => 'Country',
248   ],
249   'cust_bill' => [
250     '$invnum'         => 'Invoice#',
251     '$_date_pretty'   => 'Invoice date',
252     '$due_date'       => 'Invoice due date (timestamp)',
253     '$due_date2str'   => 'Invoice due date (human readable)',
254   ],
255   'cust_pkg' => [
256     '$pkgnum'         => 'Package#',
257     '$pkg'            => 'Package description',
258     '$pkg_label'      => 'Description + comment',
259     '$status'         => 'Status',
260     '$statuscolor'    => 'Status color code',
261     '$start_ymd'      => 'Start date',
262     '$setup_ymd'      => 'Setup date',
263     '$last_bill_ymd'  => 'Last bill date',
264     '$next_bill_ymd'  => 'Next bill date',
265     '$susp_ymd'       => 'Suspended on date',
266     '$cancel_ymd'     => 'Canceled on date',
267     '$adjourn_ymd'    => 'Adjournment date',
268     '$expire_ymd'     => 'Expiration date',
269     '$labels_short'   => 'Service labels',
270     '$location_label' => 'Service location',
271   ],
272   'svc_acct'  => [
273     '$svcnum'         => 'Service#',
274     '$username'       => 'Login name',
275     '$password'       => 'Password',
276     '$domain'         => 'Domain name',
277   ],
278   'svc_domain' => [
279     '$svcnum'         => 'Service#',
280     '$domain'         => 'Domain name',
281     '$registrar'      => 'Registrar name',
282     '$catchall'       => 'Catchall email',
283   ],
284   'svc_phone' => [
285     '$svcnum'         => 'Service#',
286     '$phonenum'       => 'Phone number',
287     '$countrycode'    => 'Country code',
288     '$domain'         => 'Domain name'
289   ],
290   'svc_broadband' => [
291     '$svcnum'         => 'Service#',
292     '$ip_addr'        => 'IP address',
293     '$mac_addr'       => 'MAC address',
294     '$speed_up'       => 'Upstream speed',
295     '$speed_down'     => 'Downstream speed',
296   ],
297   'cust_pay'  => [
298     '$paynum'         => 'Payment#',
299     '$paid'           => 'Amount',
300     '$payby'          => 'Payment method',
301     '$date'           => 'Payment date',
302     '$payinfo'        => 'Card/account# (masked)',
303     '$error'          => 'Decline reason',
304   ],
305   'system_log' => [
306     '$logmessage'     => 'Log entry message',
307     '$loglevel'       => 'Log entry level',
308     '$logcontext'     => 'Log entry context',
309   ],
310 );
311
312 tie my %sections, 'Tie::IxHash', (
313 'contact'   => 'Name and contact info (billing)',
314 'service'   => 'Service address',
315 'cust_main' => 'Customer status and payment info',
316 'cust_pkg'  => 'Package fields',
317 'cust_bill' => 'Invoice fields',
318 'cust_pay'  => 'Payment fields',
319 'svc_acct'  => 'Login service fields',
320 'svc_domain'=> 'Domain service fields',
321 'svc_phone' => 'Phone service fields',
322 'svc_broadband' => 'Broadband service fields',
323 'system_log' => 'System log fields',
324 );
325
326 my $widget = new HTML::Widgets::SelectLayers(
327   'options'   => \%sections,
328   'form_name' => 'dummy',
329   'html_between'=>'</FORM><FONT SIZE=-1>',
330   'selected_layer'=>(keys(%sections))[0],
331   'layer_callback' => sub {
332     my $section = shift;
333     my $html = include('/elements/table-grid.html');
334     my @hints = @{ $substitutions{$section} };
335     while(@hints) {
336       my $key = shift @hints;
337       $html .= qq!\n<TR><TD><A href="javascript:insertHtml('{$key}')">$key</A></TD>!;
338       $html .= "\n<TD>".shift(@hints).'</TD></TR>';
339     }
340     $html .= "\n</TABLE>";
341     return $html;
342   },
343 );
344
345 my $sidebar = '
346 <SCRIPT TYPE="text/javascript">
347 function insertHtml(what) {
348   var oEditor = CKEDITOR.instances["body"];
349   oEditor.insertHtml(what);
350 };
351
352 function areyousure(url, message) {
353   if (confirm(message))
354     window.location.href = url;
355 }
356 </SCRIPT>
357 <TD valign="top"><FORM name="dummy">
358 Substitutions: '
359 . $widget->html .
360 '<P>Click above links to insert substitution code.</P>
361 <P>
362 Enclose substitutions and other Perl expressions in braces:
363 <BR>{ $name } = ExampleCo (Smith, John)
364 <BR>{ time2str("%D", time) } = '.time2str("%D", time).'
365 </P>';
366 $sidebar .= include('/elements/template_image-dialog.html',
367               'callback' => 'insertHtml'
368             );
369 $sidebar .= '<P><A HREF="javascript:insertImageDialog()">Insert Uploaded Image</A></P>
370 </FONT></TD>
371 ';
372
373 sub html_table_bottom {
374   my $object = shift;
375   $cgi->param('locale') =~ /^(\w+)$/;
376   my $locale = $1;
377   my $html;
378   if ( $locale and $locale ne 'new' ) {
379     # set up a delete link
380     my $msgnum = $object->msgnum;
381     my $url = $fsurl."misc/delete-template_content.html?msgnum=$msgnum;locale=$1";
382     my $link = qq!<A HREF="javascript:areyousure('$url','Really delete this template?')">! .
383       'Delete this template' .
384       '</A>';
385     $html = qq!<TR><TD></TD>
386       <TD STYLE="font-style: italic; font-size: small">$link</TD></TR>!;
387   }
388   $html;
389 }
390
391 </%init>