notices, RT#8324
[freeside.git] / FS / FS / msg_template.pm
1 package FS::msg_template;
2
3 use strict;
4 use base qw( FS::Record );
5 use Text::Template;
6 use FS::Misc qw( generate_email send_email );
7 use FS::Conf;
8 use FS::Record qw( qsearch qsearchs );
9
10 =head1 NAME
11
12 FS::msg_template - Object methods for msg_template records
13
14 =head1 SYNOPSIS
15
16   use FS::msg_template;
17
18   $record = new FS::msg_template \%hash;
19   $record = new FS::msg_template { 'column' => 'value' };
20
21   $error = $record->insert;
22
23   $error = $new_record->replace($old_record);
24
25   $error = $record->delete;
26
27   $error = $record->check;
28
29 =head1 DESCRIPTION
30
31 An FS::msg_template object represents a customer message template.
32 FS::msg_template inherits from FS::Record.  The following fields are currently
33 supported:
34
35 =over 4
36
37 =item msgnum
38
39 primary key
40
41 =item msgname
42
43 msgname
44
45 =item agentnum
46
47 agentnum
48
49 =item mime_type
50
51 mime_type
52
53 =item body
54
55 body
56
57 =item disabled
58
59 disabled
60
61
62 =back
63
64 =head1 METHODS
65
66 =over 4
67
68 =item new HASHREF
69
70 Creates a new template.  To add the template to the database, see L<"insert">.
71
72 Note that this stores the hash reference, not a distinct copy of the hash it
73 points to.  You can ask the object for a copy with the I<hash> method.
74
75 =cut
76
77 # the new method can be inherited from FS::Record, if a table method is defined
78
79 sub table { 'msg_template'; }
80
81 =item insert
82
83 Adds this record to the database.  If there is an error, returns the error,
84 otherwise returns false.
85
86 =cut
87
88 # the insert method can be inherited from FS::Record
89
90 =item delete
91
92 Delete this record from the database.
93
94 =cut
95
96 # the delete method can be inherited from FS::Record
97
98 =item replace OLD_RECORD
99
100 Replaces the OLD_RECORD with this one in the database.  If there is an error,
101 returns the error, otherwise returns false.
102
103 =cut
104
105 # the replace method can be inherited from FS::Record
106
107 =item check
108
109 Checks all fields to make sure this is a valid template.  If there is
110 an error, returns the error, otherwise returns false.  Called by the insert
111 and replace methods.
112
113 =cut
114
115 # the check method should currently be supplied - FS::Record contains some
116 # data checking routines
117
118 sub check {
119   my $self = shift;
120
121   my $error = 
122     $self->ut_numbern('msgnum')
123     || $self->ut_text('msgname')
124     || $self->ut_foreign_keyn('agentnum', 'agent', 'agentnum')
125     || $self->ut_textn('mime_type')
126     || $self->ut_anything('body')
127     || $self->ut_enum('disabled', [ '', 'Y' ] )
128   ;
129   return $error if $error;
130
131   $self->mime_type('text/html') unless $self->mime_type;
132
133   $self->SUPER::check;
134 }
135
136 =item send OPTION => VALUE, ...
137
138 Fills in the template and emails it to the customer.
139
140 Options are passed as a list of name/value pairs:
141
142 =over 4
143
144 =item cust_main
145
146 Customer object (required).
147
148 =item object
149
150 Additional context object (currently, can be a cust_main object, cust_pkg
151 object, or cust_bill object).
152
153 =back
154
155 =cut
156
157 sub send {
158   my( $self, %opt ) = @_;
159
160   my $cust_main = $opt{'cust_main'};
161   my $object = $opt{'object'};
162
163   ###
164   # fill-in
165   ###
166
167   my $subs = $self->substitutions;
168   
169   use Data::Dumper;
170   warn Dumper($subs);
171
172   #XXX html escape this stuff
173   my %hash = map { $_ => $cust_main->$_() } @{ $subs->{'cust_main'} };
174   unless ( ! $object || $object->table eq 'cust_main' ) {
175     %hash = ( %hash, map { $_ => $object->$_() } @{ $subs->{$object->table} } );
176   }
177   warn Dumper(\%hash);
178
179   my $subject_tmpl = new Text::Template (
180     TYPE   => 'STRING',
181     SOURCE => $self->subject,
182   );
183   my $subject = $subject_tmpl->fill_in( HASH => \%hash );
184
185   my $body_tmpl = new Text::Template (
186     TYPE   => 'STRING',
187     SOURCE => $self->body,
188   );
189   my $body = $body_tmpl->fill_in( HASH => \%hash );
190
191   ###
192   # and email
193   ###
194
195   my @to = $cust_main->invoicing_list_emailonly;
196   #unless (@to) { #XXX do something }
197
198   my $conf = new FS::Conf;
199
200   send_email(
201     generate_email(
202        #XXX override from in event?
203       'from' => scalar( $conf->config('invoice_from', $cust_main->agentnum) ),
204       'to'   => \@to,
205       'subject'   => $subject,
206       'html_body' => $body,
207       #XXX auto-make a text copy w/HTML::FormatText?
208       #  alas, us luddite mutt/pine users just aren't that big a deal
209     )
210   );
211
212 }
213
214 #return contexts and fill-in values
215 sub substitutions {
216   { 'cust_main' => [qw(
217       display_custnum agentnum agent_name
218
219       last first company
220       name name_short contact contact_firstlast
221       address1 address2 city county state zip
222       country
223       daytime night fax
224
225       has_ship_address
226       ship_last ship_first ship_company
227       ship_name ship_name_short ship_contact ship_contact_firstlast
228       ship_address1 ship_address2 ship_city ship_county ship_state ship_zip
229       ship_country
230       ship_daytime ship_night ship_fax
231
232       payby paymask payname paytype payip
233       num_cancelled_pkgs num_ncancelled_pkgs num_pkgs
234       classname categoryname
235       balance
236       invoicing_list_emailonly
237       cust_status ucfirst_cust_status cust_statuscolor
238     )],
239     #XXX make these pretty: signupdate dundate paydate_monthyear usernum
240     # next_bill_date
241
242     'cust_pkg'  => [qw(
243     )],
244     #XXX these are going to take more pretty-ing up
245
246     'cust_bill' => [qw(
247       invnum
248     )],
249     #XXX not really thinking about cust_bill substitutions quite yet
250
251   };
252 }
253
254 =back
255
256 =head1 BUGS
257
258 =head1 SEE ALSO
259
260 L<FS::Record>, schema.html from the base documentation.
261
262 =cut
263
264 1;
265