package FS::ClientAPI::MyAccount;
+use 5.008; #require 5.8+ for Time::Local 1.05+
use strict;
-use vars qw( $cache $DEBUG );
+use vars qw( $cache $DEBUG $me );
use subs qw( _cache _provision );
use Data::Dumper;
use Digest::MD5 qw(md5_hex);
use Date::Format;
use Business::CreditCard;
use Time::Duration;
+use Time::Local qw(timelocal_nocheck);
use FS::UI::Web::small_custview qw(small_custview); #less doh
use FS::UI::Web;
use FS::UI::bytecount qw( display_bytecount );
use FS::Conf;
-use FS::Record qw(qsearch qsearchs);
+#use FS::UID qw(dbh);
+use FS::Record qw(qsearch qsearchs dbh);
use FS::Msgcat qw(gettext);
use FS::Misc qw(card_types);
use FS::ClientAPI_SessionCache;
use FS::payby;
use FS::acct_rt_transaction;
use HTML::Entities;
+use FS::TicketSystem;
$DEBUG = 0;
-
-#false laziness with FS::cust_main
-BEGIN {
- eval "use Time::Local;";
- die "Time::Local minimum version 1.05 required with Perl versions before 5.6"
- if $] < 5.006 && !defined($Time::Local::VERSION);
- eval "use Time::Local qw(timelocal_nocheck);";
-}
+$me = '[FS::ClientAPI::MyAccount]';
use vars qw( @cust_main_editable_fields );
@cust_main_editable_fields = qw(
}
sub skin_info {
- #my $p = shift;
+ my $p = shift;
+
+ my($context, $session, $custnum) = _custoragent_session_custnum($p);
+ #return { 'error' => $session } if $context eq 'error';
+
+ my $agentnum = '';
+ if ( $context eq 'customer' ) {
+
+ my $sth = dbh->prepare('SELECT agentnum FROM cust_main WHERE custnum = ?')
+ or die dbh->errstr;
+
+ $sth->execute($custnum) or die $sth->errstr;
+
+ $agentnum = $sth->fetchrow_arrayref->[0]
+ or die "no agentnum for custnum $custnum";
+
+ #} elsif ( $context eq 'agent' ) {
+ } elsif ( $p->{'agentnum'} =~ /^(\d+)$/ ) {
+ $agentnum = $1;
+ }
my $conf = new FS::Conf;
- use vars qw($skin_info); #cache for performance.
- #agentnum eventually...? but if they're not logged in yet.. ?
+ #false laziness w/Signup.pm
- $skin_info ||= {
- 'head' => join("\n", $conf->config('selfservice-head') ),
- 'body_header' => join("\n", $conf->config('selfservice-body_header') ),
- 'body_footer' => join("\n", $conf->config('selfservice-body_footer') ),
- 'body_bgcolor' => scalar( $conf->config('selfservice-body_bgcolor') ),
- 'box_bgcolor' => scalar( $conf->config('selfservice-box_bgcolor') ),
+ my $skin_info_cache_agent = _cache->get("skin_info_cache_agent$agentnum");
- 'company_name' => scalar($conf->config('company_name')),
- };
+ if ( $skin_info_cache_agent ) {
+
+ warn "$me loading cached skin info for agentnum $agentnum\n"
+ if $DEBUG > 1;
+
+ } else {
+
+ warn "$me populating skin info cache for agentnum $agentnum\n"
+ if $DEBUG > 1;
+
+ $skin_info_cache_agent = {
+ 'agentnum' => $agentnum,
+ ( map { $_ => scalar( $conf->config($_, $agentnum) ) }
+ qw( company_name ) ),
+ ( map { $_ => scalar( $conf->config("selfservice-$_", $agentnum ) ) }
+ qw( body_bgcolor box_bgcolor
+ text_color link_color vlink_color hlink_color alink_color
+ font title_color title_align title_size menu_bgcolor menu_fontsize
+ )
+ ),
+ ( map { $_ => $conf->exists("selfservice-$_", $agentnum ) }
+ qw( menu_skipblanks menu_skipheadings menu_nounderline )
+ ),
+ ( map { $_ => scalar($conf->config_binary("selfservice-$_", $agentnum)) }
+ qw( title_left_image title_right_image
+ menu_top_image menu_body_image menu_bottom_image
+ )
+ ),
+ 'logo' => scalar($conf->config_binary('logo.png', $agentnum )),
+ ( map { $_ => join("\n", $conf->config("selfservice-$_", $agentnum ) ) }
+ qw( head body_header body_footer company_address ) ),
+ };
- $skin_info;
+ _cache->set("skin_info_cache_agent$agentnum", $skin_info_cache_agent);
+
+ }
+
+ #{ %$skin_info_cache_agent };
+ $skin_info_cache_agent;
}
my $conf = new FS::Conf;
my %info = (
- %{ skin_info() },
+ %{ skin_info($p) },
'phone_login' => $conf->exists('selfservice_server-phone_login'),
'single_domain'=> scalar($conf->config('selfservice_server-single_domain')),
);
my $p = shift;
if ( $p->{'session_id'} ) {
_cache->remove($p->{'session_id'});
- return { %{ skin_info() }, 'error' => '' };
+ return { %{ skin_info($p) }, 'error' => '' };
} else {
- return { %{ skin_info() }, 'error' => "Can't resume session" }; #better error message
+ return { %{ skin_info($p) }, 'error' => "Can't resume session" }; #better error message
}
}
];
return { %$info,
- 'custnum' => $custnum,
- 'pkgnum' => $session->{'pkgnum'},
- 'svcnum' => $session->{'svcnum'},
- 'nonprimary' => $session->{'nonprimary'},
+ 'custnum' => $custnum,
+ 'access_pkgnum' => $session->{'pkgnum'},
+ 'access_svcnum' => $session->{'svcnum'},
};
}
( $session->{'pkgnum'} ? 1 : 0 ), #nobalance
);
- warn $return{small_custview};
-
$return{name} = $cust_main->first. ' '. $cust_main->get('last');
for (@cust_main_editable_fields) {
$new->set( 'payby' => $p->{'auto'} ? 'CARD' : 'DCRD' );
- }elsif ( $payby =~ /^(CHEK|DCHK)$/ ) {
+ } elsif ( $payby =~ /^(CHEK|DCHK)$/ ) {
+
my $payinfo;
$p->{'payinfo1'} =~ /^([\dx]+)$/
or return { 'error' => "illegal account number ". $p->{'payinfo1'} };
my $payinfo2 = $1;
$payinfo = $payinfo1. '@'. $payinfo2;
- if ( $payinfo eq $cust_main->paymask ) {
- $new->payinfo($cust_main->payinfo);
- } else {
- $new->payinfo($payinfo);
- }
+ $new->payinfo( ($payinfo eq $cust_main->paymask)
+ ? $cust_main->payinfo
+ : $payinfo
+ );
$new->set( 'payby' => $p->{'auto'} ? 'CHEK' : 'DCHK' );
- }elsif ( $payby =~ /^(BILL)$/ ) {
+ } elsif ( $payby =~ /^(BILL)$/ ) {
+ #no-op
} elsif ( $payby ) { #notyet ready
return { 'error' => "unknown payby $payby" };
}
'show_ss' => $conf->exists('show_ss'),
'show_stateid' => $conf->exists('show_stateid'),
'show_paystate' => $conf->exists('show_bankstate'),
+
+ 'save_unchecked' => $conf->exists('selfservice-save_unchecked'),
};
}
my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
or return { 'error' => "unknown custnum $custnum" };
+ $p->{'amount'} =~ /^\s*(\d+(\.\d{2})?)\s*$/
+ or return { 'error' => gettext('illegal_amount') };
+ my $amount = $1;
+ return { error => 'Amount must be greater than 0' } unless $amount > 0;
+
$p->{'payname'} =~ /^([\w \,\.\-\']+)$/
or return { 'error' => gettext('illegal_name'). " payname: ". $p->{'payname'} };
my $payname = $1;
$payinfo = $p->{'payinfo'};
+ #more intelligent mathing will be needed here if you change
+ #card_masking_method and don't remove existing paymasks
$payinfo = $cust_main->payinfo
if $cust_main->paymask eq $payinfo;
'CHEK' => [ qw( ss paytype paystate stateid stateid_state payip ) ],
);
- my $error = $cust_main->realtime_bop( $FS::payby::payby2bop{$payby}, $p->{'amount'},
+ my $error = $cust_main->realtime_bop( $FS::payby::payby2bop{$payby}, $amount,
'quiet' => 1,
'payinfo' => $payinfo,
'paydate' => $p->{'year'}. '-'. $p->{'month'}. '-01',
my $new = new FS::cust_main { $cust_main->hash };
if ($payby eq 'CARD' || $payby eq 'DCRD') {
$new->set( $_ => $p->{$_} )
- foreach qw( payinfo payname paystart_month paystart_year payissue payip
+ foreach qw( payname paystart_month paystart_year payissue payip
address1 address2 city state zip country );
$new->set( 'payby' => $p->{'auto'} ? 'CARD' : 'DCRD' );
} elsif ($payby eq 'CHEK' || $payby eq 'DCHK') {
$new->set( $_ => $p->{$_} )
foreach qw( payname payip paytype paystate
stateid stateid_state );
- $new->set( 'payinfo' => $payinfo );
$new->set( 'payby' => $p->{'auto'} ? 'CHEK' : 'DCHK' );
}
+ $new->set( 'payinfo' => $payinfo );
$new->set( 'paydate' => $p->{'year'}. '-'. $p->{'month'}. '-01' );
my $error = $new->replace($cust_main);
- return { 'error' => $error } if $error;
- $cust_main = $new;
+ if ( $error ) {
+ #no, this causes customers to process their payments again
+ #return { 'error' => $error };
+ #XXX just warn verosely for now so i can figure out how these happen in
+ # the first place, eventually should redirect them to the "change
+ #address" page but indicate the payment did process??
+ delete($p->{'payinfo'}); #don't want to log this!
+ warn "WARNING: error changing customer info when processing payment (not returning to customer as a processing error): $error\n".
+ "NEW: ". Dumper($new)."\n".
+ "OLD: ". Dumper($cust_main)."\n".
+ "PACKET: ". Dumper($p)."\n";
+ #} else {
+ #not needed...
+ #$cust_main = $new;
+ }
}
return { 'error' => '' };
}
sub realtime_collect {
-
my $p = shift;
my $session = _cache->get($p->{'session_id'})
'method' => $p->{'method'},
'pkgnum' => $session->{'pkgnum'},
'session_id' => $p->{'session_id'},
+ 'apply' => 1,
);
return { 'error' => $error } unless ref( $error );
# @svc_x;
{
- #no#'svcnum' => $session->{'svcnum'},
+ 'svcnum' => $session->{'svcnum'},
'custnum' => $custnum,
'svcs' => [
map {
}
+sub create_ticket {
+ my $p = shift;
+ my($context, $session, $custnum) = _custoragent_session_custnum($p);
+ return { 'error' => $session } if $context eq 'error';
+
+ warn "$me create_ticket: initializing ticket system\n" if $DEBUG;
+ FS::TicketSystem->init();
+
+ my $conf = new FS::Conf;
+ my $queue = $p->{'queue'}
+ || $conf->config('ticket_system-selfservice_queueid')
+ || $conf->config('ticket_system-default_queueid');
+
+ warn "$me create_ticket: creating ticket\n" if $DEBUG;
+ my $err_or_ticket = FS::TicketSystem->create_ticket(
+ '', #create RT session based on FS CurrentUser (fs_selfservice)
+ 'queue' => $queue,
+ 'custnum' => $custnum,
+ 'svcnum' => $session->{'svcnum'},
+ map { $_ => $p->{$_} } qw( requestor cc subject message mime_type )
+ );
+
+ if ( ref($err_or_ticket) ) {
+ warn "$me create_ticket: sucessful: ". $err_or_ticket->id. "\n"
+ if $DEBUG;
+ return { 'error' => '',
+ 'ticket_id' => $err_or_ticket->id,
+ };
+ } else {
+ warn "$me create_ticket: unsucessful: $err_or_ticket\n"
+ if $DEBUG;
+ return { 'error' => $err_or_ticket };
+ }
+
+
+}
+
#--
sub _custoragent_session_custnum {