97cf50fe7b02e1b1807088acb4920eeed576ebbe
[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   #XXX html escape this stuff
170   my %hash = map { $_ => $cust_main->$_() } @{ $subs->{'cust_main'} };
171   unless ( ! $object || $object->table eq 'cust_main' ) {
172     %hash = ( %hash, map { $_ => $object->$_() } @{ $subs->{$object->table} } );
173   }
174
175   my $subject_tmpl = new Text::Template (
176     TYPE   => 'STRING',
177     SOURCE => $self->subject,
178   );
179   my $subject = $subject_tmpl->fill_in( HASH => \%hash );
180
181   my $body_tmpl = new Text::Template (
182     TYPE   => 'STRING',
183     SOURCE => $self->body,
184   );
185   my $body = $body_tmpl->fill_in( HASH => \%hash );
186
187   ###
188   # and email
189   ###
190
191   my @to = $cust_main->invoicing_list_emailonly;
192   #unless (@to) { #XXX do something }
193
194   my $conf = new FS::Conf;
195
196   send_email(
197     generate_email(
198        #XXX override from in event?
199       'from' => scalar( $conf->config('invoice_from', $cust_main->agentnum) ),
200       'to'   => \@to,
201       'subject'   => $subject,
202       'html_body' => $body,
203       #XXX auto-make a text copy w/HTML::FormatText?
204       #  alas, us luddite mutt/pine users just aren't that big a deal
205     )
206   );
207
208 }
209
210 #return contexts and fill-in values
211 sub substitutions {
212   { 'cust_main' => [qw(
213       display_custnum agentnum agent_name
214
215       last first company
216       name name_short contact contact_firstlast
217       address1 address2 city county state zip
218       country
219       daytime night fax
220
221       has_ship_address
222       ship_last ship_first ship_company
223       ship_name ship_name_short ship_contact ship_contact_firstlast
224       ship_address1 ship_address2 ship_city ship_county ship_state ship_zip
225       ship_country
226       ship_daytime ship_night ship_fax
227
228       payby paymask payname paytype payip
229       num_cancelled_pkgs num_ncancelled_pkgs num_pkgs
230       classname categoryname
231       balance
232       invoicing_list_emailonly
233       cust_status ucfirst_cust_status cust_statuscolor
234     )],
235     #XXX make these pretty: signupdate dundate paydate_monthyear usernum
236     # next_bill_date
237
238     'cust_pkg'  => [qw(
239     )],
240     #XXX these are going to take more pretty-ing up
241
242     'cust_bill' => [qw(
243       invnum
244     )],
245     #XXX not really thinking about cust_bill substitutions quite yet
246
247   };
248 }
249
250 =back
251
252 =head1 BUGS
253
254 =head1 SEE ALSO
255
256 L<FS::Record>, schema.html from the base documentation.
257
258 =cut
259
260 1;
261