+# 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 = '';
+ my @cust_contact = grep $_->selfservice_access, $self->cust_contact;
+ $cust_main = $cust_contact[0]->cust_main if scalar(@cust_contact) == 1;
+
+ my $agentnum = $cust_main ? $cust_main->agentnum : '';
+ my $msgnum = $conf->config('selfservice-password_reset_msgnum', $agentnum);
+ #die "selfservice-password_reset_msgnum unset" unless $msgnum;
+ return "selfservice-password_reset_msgnum unset" unless $msgnum;
+ my $msg_template = qsearchs('msg_template', { msgnum => $msgnum } );
+ return "selfservice-password_reset_msgnum cannot be loaded" unless $msg_template;
+ 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 $cust_msg = $msg_template->prepare( %msg_template );
+ my $error = $cust_msg->insert;
+ return $error if $error;
+ my $queue = new FS::queue {
+ 'job' => 'FS::cust_msg::process_send',
+ 'custnum' => $cust_main ? $cust_main->custnum : '',
+ };
+ $queue->insert( $cust_msg->custmsgnum );
+
+ } 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',
+ } );
+}
+
+=item cgi_contact_fields
+
+Returns a list reference containing the set of contact fields used in the web
+interface for one-line editing (i.e. excluding contactnum, prospectnum, custnum
+and locationnum, as well as password fields, but including fields for
+contact_email and contact_phone records.)
+
+=cut
+
+sub cgi_contact_fields {
+ #my $class = shift;
+
+ my @contact_fields = qw(
+ classnum first last title comment emailaddress selfservice_access
+ invoice_dest
+ );
+
+ push @contact_fields, 'phonetypenum'. $_->phonetypenum
+ foreach qsearch({table=>'phone_type', order_by=>'weight'});
+
+ \@contact_fields;
+
+}
+
+use FS::upgrade_journal;
+sub _upgrade_data { #class method
+ my ($class, %opts) = @_;
+
+ # before anything else, migrate contact.custnum to cust_contact records
+ unless ( FS::upgrade_journal->is_done('contact_invoice_dest') ) {
+
+ local($skip_fuzzyfiles) = 1;
+
+ foreach my $contact (qsearch('contact', {})) {
+ my $error = $contact->replace;
+ die $error if $error;
+ }
+
+ FS::upgrade_journal->set_done('contact_invoice_dest');
+ }
+
+
+ # always migrate cust_main_invoice records over
+ local $FS::cust_main::import = 1; # override require_phone and such
+ my $search = FS::Cursor->new('cust_main_invoice', {});
+ my %custnum_dest;
+ while (my $cust_main_invoice = $search->fetch) {
+ my $custnum = $cust_main_invoice->custnum;
+ my $dest = $cust_main_invoice->dest;
+ my $cust_main = $cust_main_invoice->cust_main;
+
+ if ( $dest =~ /^\d+$/ ) {
+ my $svc_acct = FS::svc_acct->by_key($dest);
+ die "custnum $custnum, invoice destination svcnum $svc_acct does not exist\n"
+ if !$svc_acct;
+ $dest = $svc_acct->email;
+ }
+ push @{ $custnum_dest{$custnum} ||= [] }, $dest;
+
+ my $error = $cust_main_invoice->delete;
+ if ( $error ) {
+ die "custnum $custnum, cleaning up cust_main_invoice: $error\n";
+ }
+ }
+
+ foreach my $custnum (keys %custnum_dest) {
+ my $dests = $custnum_dest{$custnum};
+ my $cust_main = FS::cust_main->by_key($custnum);
+ my $error = $cust_main->replace( invoicing_list => $dests );
+ if ( $error ) {
+ die "custnum $custnum, creating contact: $error\n";
+ }
+ }
+