summaryrefslogtreecommitdiff
path: root/FS
diff options
context:
space:
mode:
authorIvan Kohler <ivan@freeside.biz>2013-12-30 01:43:30 -0800
committerIvan Kohler <ivan@freeside.biz>2013-12-30 01:43:30 -0800
commitc9450c02f7ac2f904a6ffabb07b6b2d5bca1fd4a (patch)
tree00af6b8101403aeb051b5f6db1f82a7baf982e6c /FS
parent6033d0297f7e50318b76f83c5b61f05110e58e33 (diff)
self-service access for contacts, RT#25533
Diffstat (limited to 'FS')
-rw-r--r--FS/FS/ClientAPI/MyAccount.pm313
-rw-r--r--FS/FS/Conf.pm3
-rw-r--r--FS/FS/Setup.pm3
-rw-r--r--FS/FS/contact.pm187
-rw-r--r--FS/FS/msg_template.pm41
5 files changed, 470 insertions, 77 deletions
diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm
index b7ac0ea0a..748ae0c75 100644
--- a/FS/FS/ClientAPI/MyAccount.pm
+++ b/FS/FS/ClientAPI/MyAccount.pm
@@ -7,6 +7,7 @@ use subs qw( _cache _provision );
use IO::Scalar;
use Data::Dumper;
use Digest::MD5 qw(md5_hex);
+use Digest::SHA qw(sha512_hex);
use Date::Format;
use Time::Duration;
use Time::Local qw(timelocal_nocheck);
@@ -44,6 +45,7 @@ use FS::cust_pkg;
use FS::payby;
use FS::acct_rt_transaction;
use FS::msg_template;
+use FS::contact;
$DEBUG = 1;
$me = '[FS::ClientAPI::MyAccount]';
@@ -179,6 +181,7 @@ sub login {
my $conf = new FS::Conf;
my $svc_x = '';
+ my $session = {};
if ( $p->{'domain'} eq 'svc_phone'
&& $conf->exists('selfservice_server-phone_login') ) {
@@ -196,8 +199,19 @@ sub login {
$svc_x = $svc_phone;
+ } elsif ( $p->{email}
+ && (my $contact = FS::contact->by_selfservice_email($p->{email}))
+ )
+ {
+ return { error => 'Incorrect password.' }
+ unless $contact->authenticate_password($p->{'password'});
+
+ $session->{'custnum'} = $contact->custnum;
+
} else {
+ ( $p->{username}, $p->{domain} ) = split('@', $p->{email}) if $p->{email};
+
my $svc_domain = qsearchs('svc_domain', { 'domain' => $p->{'domain'} } )
or return { error => 'Domain '. $p->{'domain'}. ' not found' };
@@ -220,31 +234,33 @@ sub login {
}
- my $session = {
- 'svcnum' => $svc_x->svcnum,
- };
+ if ( $svc_x ) {
+
+ $session->{'svcnum'} = $svc_x->svcnum;
- my $cust_svc = $svc_x->cust_svc;
- my $cust_pkg = $cust_svc->cust_pkg;
- if ( $cust_pkg ) {
- my $cust_main = $cust_pkg->cust_main;
- $session->{'custnum'} = $cust_main->custnum;
- if ( $conf->exists('pkg-balances') ) {
- my @cust_pkg = grep { $_->part_pkg->freq !~ /^(0|$)/ }
- $cust_main->ncancelled_pkgs;
- $session->{'pkgnum'} = $cust_pkg->pkgnum
- if scalar(@cust_pkg) > 1;
+ my $cust_svc = $svc_x->cust_svc;
+ my $cust_pkg = $cust_svc->cust_pkg;
+ if ( $cust_pkg ) {
+ my $cust_main = $cust_pkg->cust_main;
+ $session->{'custnum'} = $cust_main->custnum;
+ if ( $conf->exists('pkg-balances') ) {
+ my @cust_pkg = grep { $_->part_pkg->freq !~ /^(0|$)/ }
+ $cust_main->ncancelled_pkgs;
+ $session->{'pkgnum'} = $cust_pkg->pkgnum
+ if scalar(@cust_pkg) > 1;
+ }
}
- }
- #my $pkg_svc = $svc_acct->cust_svc->pkg_svc;
- #return { error => 'Only primary user may log in.' }
- # if $conf->exists('selfservice_server-primary_only')
- # && ( ! $pkg_svc || $pkg_svc->primary_svc ne 'Y' );
- my $part_pkg = $cust_pkg->part_pkg;
- return { error => 'Only primary user may log in.' }
- if $conf->exists('selfservice_server-primary_only')
- && $cust_svc->svcpart != $part_pkg->svcpart([qw( svc_acct svc_phone )]);
+ #my $pkg_svc = $svc_acct->cust_svc->pkg_svc;
+ #return { error => 'Only primary user may log in.' }
+ # if $conf->exists('selfservice_server-primary_only')
+ # && ( ! $pkg_svc || $pkg_svc->primary_svc ne 'Y' );
+ my $part_pkg = $cust_pkg->part_pkg;
+ return { error => 'Only primary user may log in.' }
+ if $conf->exists('selfservice_server-primary_only')
+ && $cust_svc->svcpart != $part_pkg->svcpart([qw( svc_acct svc_phone )]);
+
+ }
my $session_id;
do {
@@ -2846,6 +2862,54 @@ sub myaccount_passwd {
}
+#regular pw change in self-service should change contact pw too, otherwise its way too confusing. hell its confusing they're separate at all, but alas. need to support the "ISP provides email that's used as a contact email" case as well as we can.
+# sub contact_passwd {
+# my $p = shift;
+# my($context, $session, $custnum) = _custoragent_session_custnum($p);
+# return { 'error' => $session } if $context eq 'error';
+#
+# return { 'error' => 'Not logged in as a contact.' }
+# unless $session->{'contactnum'};
+#
+# return { 'error' => "New passwords don't match." }
+# if $p->{'new_password'} ne $p->{'new_password2'};
+#
+# return { 'error' => 'Enter new password' }
+# unless length($p->{'new_password'});
+#
+# #my $search = { 'custnum' => $custnum };
+# #$search->{'agentnum'} = $session->{'agentnum'} if $context eq 'agent';
+# $custnum =~ /^(\d+)$/ or die "illegal custnum";
+# my $search = " AND selfservice_access IS NOT NULL ".
+# " AND selfservice_access = 'Y' ".
+# " AND ( disabled IS NULL OR disabled = '' )".
+# " AND custnum IS NOT NULL AND custnum = $1";
+# $search .= " AND agentnum = ". $session->{'agentnum'} if $context eq 'agent';
+#
+# my $contact = qsearchs( {
+# 'table' => 'contact',
+# 'addl_from' => 'LEFT JOIN cust_main USING ( custnum ) ',
+# 'hashref' => { 'contactnum' => $session->{'contactnum'}, },
+# 'extra_sql' => $search, #important
+# } )
+# or return { 'error' => "Email not found" }; #? how did we get logged in?
+# # deleted since then?
+#
+# my $error = '';
+#
+# # use these svc_acct length restrictions??
+# my $conf = new FS::Conf;
+# $error = 'Password too short.'
+# if length($p->{'new_password'}) < ($conf->config('passwordmin') || 6);
+# $error = 'Password too long.'
+# if length($p->{'new_password'}) > ($conf->config('passwordmax') || 8);
+#
+# $error ||= $contact->change_password($p->{'new_password'});
+#
+# return { 'error' => $error, };
+#
+# }
+
sub reset_passwd {
my $p = shift;
@@ -2853,22 +2917,57 @@ sub reset_passwd {
my $verification = $conf->config('selfservice-password_reset_verification')
or return { 'error' => 'Password resets disabled' };
- my $username = $p->{'username'};
+ my $contact = '';
+ my $svc_acct = '';
+ my $cust_main = '';
+ if ( $p->{'email'} ) { #new-style, changes contact and svc_acct
+
+ $contact = FS::contact->by_selfservice_email($p->{'email'});
+
+ $cust_main = $contact->cust_main if $contact;
+
+ #also look for an svc_acct, otherwise it would be super confusing
- my $svc_domain = qsearchs('svc_domain', { 'domain' => $p->{'domain'} } )
- or return { 'error' => 'Account not found' };
+ my($username, $domain) = split('@', $p->{'email'});
+ my $svc_domain = qsearchs('svc_domain', { 'domain' => $domain } );
+ if ( $svc_domain ) {
+ $svc_acct = qsearchs('svc_acct', { 'username' => $p->{'username'},
+ 'domsvc' => $svc_domain->svcnum }
+ );
+ if ( $svc_acct ) {
+ my $cust_pkg = $svc_acct->cust_svc->cust_pkg;
+ $cust_main ||= $cust_pkg->cust_main if $cust_pkg;
+
+ #precaution: don't change svc_acct password not part of the same
+ # customer as contact
+ $svc_acct = '' if ! $cust_pkg
+ || $cust_pkg->custnum != $cust_main->custnum;
+ }
+
+ }
+
+ return { 'error' => 'Email address not found' }
+ unless $contact || $svc_acct;
+
+ } elsif ( $p->{'username'} ) { #old style, looks in svc_acct only
+
+ my $svc_domain = qsearchs('svc_domain', { 'domain' => $p->{'domain'} } )
+ or return { 'error' => 'Account not found' };
+
+ $svc_acct = qsearchs('svc_acct', { 'username' => $p->{'username'},
+ 'domsvc' => $svc_domain->svcnum }
+ )
+ or return { 'error' => 'Account not found' };
- my $svc_acct = qsearchs('svc_acct', { 'username' => $p->{'username'},
- 'domsvc' => $svc_domain->svcnum }
- )
- or return { 'error' => 'Account not found' };
+ my $cust_pkg = $svc_acct->cust_svc->cust_pkg
+ or return { 'error' => 'Account not found' };
- my $cust_pkg = $svc_acct->cust_svc->cust_pkg
- or return { 'error' => 'Account not found' };
+ $cust_main = $cust_pkg->cust_main;
- my $cust_main = $cust_pkg->cust_main;
+ }
my %verify = (
+ 'email' => sub { 1; },
'paymask' => sub {
my( $p, $cust_main ) = @_;
$cust_main->payby =~ /^(CARD|DCRD|CHEK|DCHK)$/
@@ -2899,35 +2998,54 @@ sub reset_passwd {
}
- #okay, we're verified, now create a unique session
+ #okay, we're verified
- my $reset_session = {
- 'svcnum' => $svc_acct->svcnum,
- };
+ if ( $contact ) {
- my $timeout = '1 hour'; #?
+ my $error = $contact->send_reset_email(
+ 'svcnum' => ($svc_acct ? $svc_acct->svcnum : ''),
+ );
+
+ if ( $error ) {
+ return { 'error' => $error }; #????
+ }
+
+ } elsif ( $svc_acct ) {
+
+ #create a unique session
+
+ my $reset_session = {
+ 'svcnum' => $svc_acct->svcnum,
+ };
+
+ my $timeout = '1 hour'; #?
+
+ my $reset_session_id;
+ do {
+ $reset_session_id = sha512_hex(time(). {}. rand(). $$)
+ } until ( ! defined _cache->get("reset_passwd_$reset_session_id") );
+ #just in case
+
+ _cache->set( "reset_passwd_$reset_session_id", $reset_session, $timeout );
+
+ #email it
+
+ my $msgnum = $conf->config('selfservice-password_reset_msgnum',
+ $cust_main->agentnum);
+ #die "selfservice-password_reset_msgnum unset" unless $msgnum;
+ return { 'error' => "selfservice-password_reset_msgnum unset" }
+ unless $msgnum;
+ my $msg_template = qsearchs('msg_template', { msgnum => $msgnum } );
+ my $error = $msg_template->send( 'cust_main' => $cust_main,
+ 'object' => $svc_acct,
+ 'substitutions' => {
+ 'session_id' => $reset_session_id,
+ }
+ );
+ if ( $error ) {
+ return { 'error' => $error }; #????
+ }
- my $reset_session_id;
- do {
- $reset_session_id = md5_hex(md5_hex(time(). {}. rand(). $$))
- } until ( ! defined _cache->get("reset_passwd_$reset_session_id") ); #just in case
-
- _cache->set( "reset_passwd_$reset_session_id", $reset_session, $timeout );
-
- #email it
-
- my $msgnum = $conf->config('selfservice-password_reset_msgnum', $cust_main->agentnum);
- #die "selfservice-password_reset_msgnum unset" unless $msgnum;
- return { 'error' => "selfservice-password_reset_msgnum unset" } unless $msgnum;
- my $msg_template = qsearchs('msg_template', { msgnum => $msgnum } );
- my $error = $msg_template->send( 'cust_main' => $cust_main,
- 'object' => $svc_acct,
- 'substitutions' => {
- 'session_id' => $reset_session_id,
- }
- );
- if ( $error ) {
- return { 'error' => $error }; #????
}
return { 'error' => '' };
@@ -2943,14 +3061,38 @@ sub check_reset_passwd {
my $reset_session = _cache->get('reset_passwd_'. $p->{'session_id'})
or return { 'error' => "Can't resume session" }; #better error message
- my $svcnum = $reset_session->{'svcnum'};
+ if ( $reset_session->{'svcnum'} ) {
- my $svc_acct = qsearchs('svc_acct', { 'svcnum' => $svcnum } )
- or return { 'error' => "Service not found" };
+ my $svcnum = $reset_session->{'svcnum'};
- return { 'error' => '',
- 'username' => $svc_acct->username,
- };
+ my $svc_acct = qsearchs('svc_acct', { 'svcnum' => $svcnum } )
+ or return { 'error' => "Service not found" };
+
+ return { 'error' => '',
+ 'session_id' => $p->{'session_id'},
+ 'username' => $svc_acct->username,
+ };
+
+ } elsif ( $reset_session->{'contactnum'} ) {
+
+ my $contactnum = $reset_session->{'contactnum'};
+
+ my $contact = qsearchs('contact', { 'contactnum' => $contactnum } )
+ or return { 'error' => "Contact not found" };
+
+ my @contact_email = $contact->contact_email;
+ return { 'error' => 'No contact email' } unless @contact_email;
+
+ return { 'error' => '',
+ 'session_id' => $p->{'session_id'},
+ 'email' => $contact_email[0]->email, #the first?
+ };
+
+ } else {
+
+ return { 'error' => 'No svcnum or contactnum in session' }; #??
+
+ }
}
@@ -2970,20 +3112,43 @@ sub process_reset_passwd {
my $reset_session = _cache->get('reset_passwd_'. $p->{'session_id'})
or return { 'error' => "Can't resume session" }; #better error message
- my $svcnum = $reset_session->{'svcnum'};
+ if ( $reset_session->{'svcnum'} ) {
- my $svc_acct = qsearchs('svc_acct', { 'svcnum' => $svcnum } )
- or return { 'error' => "Service not found" };
+ my $svcnum = $reset_session->{'svcnum'};
- $svc_acct->set_password($p->{'new_password'});
- my $error = $svc_acct->replace();
+ my $svc_acct = qsearchs('svc_acct', { 'svcnum' => $svcnum } )
+ or return { 'error' => "Service not found" };
- my($label, $value) = $svc_acct->cust_svc->label;
+ $svc_acct->set_password($p->{'new_password'});
+ my $error = $svc_acct->replace();
- return { 'error' => $error,
- #'label' => $label,
- #'value' => $value,
- };
+ return { 'error' => $error } if $error;
+
+ #my($label, $value) = $svc_acct->cust_svc->label;
+ #return { 'error' => $error,
+ # #'label' => $label,
+ # #'value' => $value,
+ # };
+
+ }
+
+ if ( $reset_session->{'contactnum'} ) {
+
+ my $contactnum = $reset_session->{'contactnum'};
+
+ my $contact = qsearchs('contact', { 'contactnum' => $contactnum } )
+ or return { 'error' => "Contact not found" };
+
+ my $error = $contact->change_password($p->{'new_password'});
+
+ return { 'error' => $error }; # if $error;
+
+ }
+
+ #password changed ,so remove session, don't want it reused
+ _cache->remove($p->{'session_id'});
+
+ return { 'error' => '' };
}
diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm
index 268b603d0..efe994703 100644
--- a/FS/FS/Conf.pm
+++ b/FS/FS/Conf.pm
@@ -2836,7 +2836,8 @@ and customer address. Include units.',
'description' => 'If enabled, specifies the type of verification required for self-service password resets.',
'type' => 'select',
'select_hash' => [ '' => 'Password reset disabled',
- 'paymask,amount,zip' => 'Verify with credit card (or bank account) last 4 digits, payment amount and zip code',
+ 'email' => 'Click on a link in email',
+ 'paymask,amount,zip' => 'Click on a link in email, and also verify with credit card (or bank account) last 4 digits, payment amount and zip code',
],
},
diff --git a/FS/FS/Setup.pm b/FS/FS/Setup.pm
index e27b66fc5..29130fa61 100644
--- a/FS/FS/Setup.pm
+++ b/FS/FS/Setup.pm
@@ -400,6 +400,9 @@ sub initial_data {
#phone types
'phone_type' => [],
+ #message templates
+ 'msg_template' => [],
+
;
\%hash;
diff --git a/FS/FS/contact.pm b/FS/FS/contact.pm
index 9b4546e43..0828c5969 100644
--- a/FS/FS/contact.pm
+++ b/FS/FS/contact.pm
@@ -2,6 +2,7 @@ package FS::contact;
use base qw( FS::Record );
use strict;
+use Scalar::Util qw( blessed );
use FS::Record qw( qsearch qsearchs dbh );
use FS::prospect_main;
use FS::cust_main;
@@ -9,6 +10,7 @@ use FS::contact_class;
use FS::cust_location;
use FS::contact_phone;
use FS::contact_email;
+use FS::queue;
=head1 NAME
@@ -173,6 +175,14 @@ sub insert {
}
#}
+ if ( $self->selfservice_access ) {
+ my $error = $self->send_reset_email( queue=>1 );
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ }
+
$dbh->commit or die $dbh->errstr if $oldAutoCommit;
'';
@@ -230,6 +240,12 @@ returns the error, otherwise returns false.
sub replace {
my $self = shift;
+ my $old = ( blessed($_[0]) && $_[0]->isa('FS::Record') )
+ ? shift
+ : $self->replace_old;
+
+ $self->$_( $self->$_ || $old->$_ ) for qw( _password _password_encoding );
+
local $SIG{INT} = 'IGNORE';
local $SIG{QUIT} = 'IGNORE';
local $SIG{TERM} = 'IGNORE';
@@ -240,7 +256,7 @@ sub replace {
local $FS::UID::AutoCommit = 0;
my $dbh = dbh;
- my $error = $self->SUPER::replace(@_);
+ my $error = $self->SUPER::replace($old);
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return $error;
@@ -269,7 +285,7 @@ sub replace {
}
}
- if ( defined($self->get('emailaddress')) ) {
+ if ( defined($self->hashref->{'emailaddress'}) ) {
#ineffecient but whatever, how many email addresses can there be?
@@ -307,6 +323,19 @@ sub replace {
}
#}
+ if ( ( $old->selfservice_access eq '' && $self->selfservice_access
+ && ! $self->_password
+ )
+ || $self->_resend()
+ )
+ {
+ my $error = $self->send_reset_email( queue=>1 );
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ }
+
$dbh->commit or die $dbh->errstr if $oldAutoCommit;
'';
@@ -388,6 +417,11 @@ and replace methods.
sub check {
my $self = shift;
+ if ( $self->selfservice_access eq 'R' ) {
+ $self->selfservice_access('Y');
+ $self->_resend('Y');
+ }
+
my $error =
$self->ut_numbern('contactnum')
|| $self->ut_foreign_keyn('prospectnum', 'prospect_main', 'prospectnum')
@@ -457,6 +491,155 @@ sub cust_main {
qsearchs('cust_main', { 'custnum' => $self->custnum } );
}
+sub by_selfservice_email {
+ my($class, $email) = @_;
+
+ my $contact_email = qsearchs({
+ 'table' => 'contact_email',
+ 'addl_from' => ' LEFT JOIN contact USING ( contactnum ) ',
+ 'hashref' => { 'emailaddress' => $email, },
+ 'extra_sql' => " AND selfservice_access = 'Y' ".
+ " AND ( disabled IS NULL OR disabled = '' )",
+ }) or return '';
+
+warn $contact_email;
+
+ $contact_email->contact;
+
+}
+
+#these three functions are very much false laziness w/FS/FS/Auth/internal.pm
+# and should maybe be libraried in some way for other password needs
+
+use Crypt::Eksblowfish::Bcrypt qw( bcrypt_hash en_base64 de_base64);
+
+sub authenticate_password {
+ my($self, $check_password) = @_;
+
+ if ( $self->_password_encoding eq 'bcrypt' ) {
+
+ my( $cost, $salt, $hash ) = split(',', $self->_password);
+
+ my $check_hash = en_base64( bcrypt_hash( { key_nul => 1,
+ cost => $cost,
+ salt => de_base64($salt),
+ },
+ $check_password
+ )
+ );
+
+ $hash eq $check_hash;
+
+ } else {
+
+ return 0 if $self->_password eq '';
+
+ $self->_password eq $check_password;
+
+ }
+
+}
+
+sub change_password {
+ my($self, $new_password) = @_;
+
+ $self->change_password_fields( $new_password );
+
+ $self->replace;
+
+}
+
+sub change_password_fields {
+ my($self, $new_password) = @_;
+
+ $self->_password_encoding('bcrypt');
+
+ my $cost = 8;
+
+ my $salt = pack( 'C*', map int(rand(256)), 1..16 );
+
+ my $hash = bcrypt_hash( { key_nul => 1,
+ cost => $cost,
+ salt => $salt,
+ },
+ $new_password,
+ );
+
+ $self->_password(
+ join(',', $cost, en_base64($salt), en_base64($hash) )
+ );
+
+}
+
+# end of false laziness w/FS/FS/Auth/internal.pm
+
+
+#false laziness w/ClientAPI/MyAccount/reset_passwd
+use Digest::SHA qw(sha512_hex);
+use FS::Conf;
+use FS::ClientAPI_SessionCache;
+sub send_reset_email {
+ my( $self, %opt ) = @_;
+
+ my @contact_email = $self->contact_email or return '';
+
+ my $reset_session = {
+ 'contactnum' => $self->contactnum,
+ 'svcnum' => $opt{'svcnum'},
+ };
+
+ my $timeout = '24 hours'; #?
+
+ my $reset_session_id;
+ do {
+ $reset_session_id = sha512_hex(time(). {}. rand(). $$)
+ } until ( ! defined $self->myaccount_cache->get("reset_passwd_$reset_session_id") );
+ #just in case
+
+ $self->myaccount_cache->set( "reset_passwd_$reset_session_id", $reset_session, $timeout );
+
+ #email it
+
+ my $conf = new FS::Conf;
+
+ my $cust_main = $self->cust_main
+ or die "no customer"; #reset a password for a prospect contact? someday
+
+ my $msgnum = $conf->config('selfservice-password_reset_msgnum', $cust_main->agentnum);
+ #die "selfservice-password_reset_msgnum unset" unless $msgnum;
+ return { 'error' => "selfservice-password_reset_msgnum unset" } unless $msgnum;
+ my $msg_template = qsearchs('msg_template', { msgnum => $msgnum } );
+ my %msg_template = (
+ 'to' => join(',', map $_->emailaddress, @contact_email ),
+ 'cust_main' => $cust_main,
+ 'object' => $self,
+ 'substitutions' => { 'session_id' => $reset_session_id }
+ );
+
+ if ( $opt{'queue'} ) { #or should queueing just be the default?
+
+ my $queue = new FS::queue {
+ 'job' => 'FS::Misc::process_send_email',
+ 'custnum' => $cust_main->custnum,
+ };
+ $queue->insert( $msg_template->prepare( %msg_template ) );
+
+ } else {
+
+ $msg_template->send( %msg_template );
+
+ }
+
+}
+
+use vars qw( $myaccount_cache );
+sub myaccount_cache {
+ #my $class = shift;
+ $myaccount_cache ||= new FS::ClientAPI_SessionCache( {
+ 'namespace' => 'FS::ClientAPI::MyAccount',
+ } );
+}
+
=back
=head1 BUGS
diff --git a/FS/FS/msg_template.pm b/FS/FS/msg_template.pm
index 4e1f4da24..bc2b3827c 100644
--- a/FS/FS/msg_template.pm
+++ b/FS/FS/msg_template.pm
@@ -558,6 +558,9 @@ sub substitutions {
[ company_phonenum => sub {
$conf->config('company_phonenum', shift->agentnum)
} ],
+ [ selfservice_server_base_url => sub {
+ $conf->config('selfservice_server-base_url') #, shift->agentnum)
+ } ],
],
# next_bill_date
'cust_pkg' => [qw(
@@ -700,6 +703,10 @@ sub agent {
sub _upgrade_data {
my ($self, %opts) = @_;
+ ###
+ # First move any historical templates in config to real message templates
+ ###
+
my @fixes = (
[ 'alerter_msgnum', 'alerter_template', '', '', '' ],
[ 'cancel_msgnum', 'cancelmessage', 'cancelsubject', '', '' ],
@@ -791,6 +798,11 @@ sub _upgrade_data {
} # if alerter_msgnum
}
+
+ ###
+ # Move subject and body from msg_template to template_content
+ ###
+
foreach my $msg_template ( qsearch('msg_template', {}) ) {
if ( $msg_template->subject || $msg_template->body ) {
# create new default content
@@ -814,6 +826,35 @@ sub _upgrade_data {
die $error if $error;
}
}
+
+ ###
+ # Add new-style default templates if missing
+ ###
+ $self->_populate_initial_data;
+
+}
+
+sub _populate_initial_data { #class method
+ #my($class, %opts) = @_;
+ #my $class = shift;
+
+ eval "use FS::msg_template::InitialData;";
+ die $@ if $@;
+
+ my $initial_data = FS::msg_template::InitialData->_initial_data;
+
+ foreach my $hash ( @$initial_data ) {
+
+ next if $hash->{_conf} && $conf->config( $hash->{_conf} );
+
+ my $msg_template = new FS::msg_template($hash);
+ my $error = $msg_template->insert( @{ $hash->{_insert_args} || [] } );
+ die $error if $error;
+
+ $conf->set( $hash->{_conf}, $msg_template->msgnum ) if $hash->{_conf};
+
+ }
+
}
sub eviscerate {