=item object
Additional context object (currently, can be a cust_main, cust_pkg,
-cust_bill, svc_acct, cust_pay, or cust_pay_pending object).
+cust_bill, cust_pay, cust_pay_pending, or svc_(acct, phone, broadband,
+domain) ). If the object is a svc_*, its cust_pkg will be fetched and
+used for substitution.
+
+As a special case, this may be an arrayref of two objects. Both
+objects will be available for substitution, with their field names
+prefixed with 'new_' and 'old_' respectively. This is used in the
+rt_ticket export when exporting "replace" events.
+
+=item from_config
+
+Configuration option to use as the source address, based on the customer's
+agentnum. If unspecified (or the named option is empty), 'invoice_from'
+will be used.
+
+The I<from_addr> field in the template takes precedence over this.
=item to
Destination address. The default is to use the customer's
-invoicing_list addresses.
+invoicing_list addresses. Multiple addresses may be comma-separated.
=back
# create substitution table
###
my %hash;
- foreach my $obj ($cust_main, $object || ()) {
+ my @objects = ($cust_main);
+ my @prefixes = ('');
+ my $svc;
+ if( ref $object ) {
+ if( ref($object) eq 'ARRAY' ) {
+ # [new, old], for provisioning tickets
+ push @objects, $object->[0], $object->[1];
+ push @prefixes, 'new_', 'old_';
+ $svc = $object->[0] if $object->[0]->isa('FS::svc_Common');
+ }
+ else {
+ push @objects, $object;
+ push @prefixes, '';
+ $svc = $object if $object->isa('FS::svc_Common');
+ }
+ }
+ if( $svc ) {
+ push @objects, $svc->cust_svc->cust_pkg;
+ push @prefixes, '';
+ }
+
+ foreach my $obj (@objects) {
+ my $prefix = shift @prefixes;
foreach my $name (@{ $subs->{$obj->table} }) {
if(!ref($name)) {
# simple case
- $hash{$name} = $obj->$name();
+ $hash{$prefix.$name} = $obj->$name();
}
elsif( ref($name) eq 'ARRAY' ) {
# [ foo => sub { ... } ]
- $hash{$name->[0]} = $name->[1]->($obj);
+ $hash{$prefix.($name->[0])} = $name->[1]->($obj);
}
else {
warn "bad msg_template substitution: '$name'\n";
# and email
###
- my @to = ($opt{'to'}) || $cust_main->invoicing_list_emailonly;
- warn "prepared msg_template with no email destination (custnum ".
- $cust_main->custnum.")\n"
- if !@to;
+ my @to;
+ if ( exists($opt{'to'}) ) {
+ @to = split(/\s*,\s*/, $opt{'to'});
+ }
+ else {
+ @to = $cust_main->invoicing_list_emailonly;
+ }
+ # no warning when preparing with no destination
my $conf = new FS::Conf;
+ my $from_addr = $self->from_addr;
+
+ if ( !$from_addr ) {
+ if ( $opt{'from_config'} ) {
+ $from_addr = scalar( $conf->config($opt{'from_config'},
+ $cust_main->agentnum) );
+ }
+ $from_addr ||= scalar( $conf->config('invoice_from',
+ $cust_main->agentnum) );
+ }
(
- 'from' => $self->from_addr ||
- scalar( $conf->config('invoice_from', $cust_main->agentnum) ),
+ 'from' => $from_addr,
'to' => \@to,
'bcc' => $self->bcc_addr || undef,
'subject' => $subject,
adjourn susp expire
labels_short
),
+ [ pkg => sub { shift->part_pkg->pkg } ],
[ cancel => sub { shift->getfield('cancel') } ], # grrr...
[ start_ymd => sub { $ymd->(shift->getfield('start_date')) } ],
[ setup_ymd => sub { $ymd->(shift->getfield('setup')) } ],
# for welcome and limit warning messages
'svc_acct' => [qw(
+ svcnum
username
+ domain
),
[ password => sub { shift->getfield('_password') } ],
],
+ 'svc_domain' => [qw(
+ svcnum
+ domain
+ ),
+ [ registrar => sub {
+ my $registrar = qsearchs('registrar',
+ { registrarnum => shift->registrarnum} );
+ $registrar ? $registrar->registrarname : ''
+ }
+ ],
+ [ catchall => sub {
+ my $svc_acct = qsearchs('svc_acct', { svcnum => shift->catchall });
+ $svc_acct ? $svc_acct->email : ''
+ }
+ ],
+ ],
+ 'svc_phone' => [qw(
+ svcnum
+ phonenum
+ countrycode
+ domain
+ )
+ ],
+ 'svc_broadband' => [qw(
+ svcnum
+ speed_up
+ speed_down
+ ip_addr
+ mac_addr
+ )
+ ],
# for payment receipts
'cust_pay' => [qw(
paynum