summaryrefslogtreecommitdiff
path: root/FS
diff options
context:
space:
mode:
authorIvan Kohler <ivan@freeside.biz>2013-07-02 11:53:40 -0700
committerIvan Kohler <ivan@freeside.biz>2013-07-02 11:53:40 -0700
commita563de5fc2f42abf16fbcfda7cf5bc5f1ce794e7 (patch)
tree21ed995983a9ef1f51055c8e4c6c6300863c5c66 /FS
parent93f2d729dcc5c1bbf424a61ee49b985a4e3ed1d6 (diff)
selfservice, TNG, RT#22193
Diffstat (limited to 'FS')
-rw-r--r--FS/FS/ClientAPI/MyAccount.pm199
-rw-r--r--FS/FS/Conf.pm7
-rw-r--r--FS/FS/TicketSystem/RT_Internal.pm27
-rw-r--r--FS/FS/cust_main.pm13
-rw-r--r--FS/FS/cust_svc.pm21
-rw-r--r--FS/bin/freeside-selfservice-server5
-rwxr-xr-xFS/bin/freeside-selfservice-xmlrpcd4
7 files changed, 178 insertions, 98 deletions
diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm
index 01e0ebc..88266da 100644
--- a/FS/FS/ClientAPI/MyAccount.pm
+++ b/FS/FS/ClientAPI/MyAccount.pm
@@ -133,6 +133,36 @@ sub skin_info {
'logo' => scalar($conf->config_binary('logo.png', $agentnum )),
( map { $_ => join("\n", $conf->config("selfservice-$_", $agentnum ) ) }
qw( head body_header body_footer company_address ) ),
+ 'menu' => join("\n", $conf->config("ng_selfservice-menu", $agentnum ) ) ||
+ 'main.php Home
+
+ services.php Services
+ services.php My Services
+ services_new.php Order a new service
+
+ personal.php Profile
+ personal.php Personal Information
+ password.php Change Password
+
+ payment.php Payments
+ payment_cc.php Credit Card Payment
+ payment_ach.php Electronic Check Payment
+ payment_paypal.php PayPal Payment
+ payment_webpay.php Webpay Payments
+
+ usage.php Usage
+ usage_data.php Data usage
+ usage_cdr.php Call usage
+
+ tickets.php Help Desk
+ tickets.php Open Tickets
+ tickets_resolved.php Resolved Tickets
+ ticket_create.php Create a new ticket
+
+ docs.php FAQs
+
+ logout.php Logout
+ ',
};
_cache->set("skin_info_cache_agent$agentnum", $skin_info_cache_agent);
@@ -365,58 +395,29 @@ sub customer_info {
my %return;
my $conf = new FS::Conf;
- if ($conf->exists('cust_main-require_address2')) {
- $return{'require_address2'} = '1';
- }else{
- $return{'require_address2'} = '';
- }
+ $return{'require_address2'} = $conf->exists('cust_main-require_address2');
- if ( $FS::TicketSystem::system ) {
- warn "$me customer_info: initializing ticket system\n" if $DEBUG;
- FS::TicketSystem->init();
- }
+# if ( $FS::TicketSystem::system ) {
+# warn "$me customer_info: initializing ticket system\n" if $DEBUG;
+# FS::TicketSystem->init();
+# }
if ( $custnum ) { #customer record
+ %return = ( %return, %{ customer_info_short($p) } );
+
+ #redundant with customer_info_short, but we need it for several things below
my $search = { 'custnum' => $custnum };
$search->{'agentnum'} = $session->{'agentnum'} if $context eq 'agent';
my $cust_main = qsearchs('cust_main', $search )
or return { 'error' => "unknown custnum $custnum" };
- $return{display_custnum} = $cust_main->display_custnum;
+ my $list_tickets = list_tickets($p);
+ $return{'tickets'} = $list_tickets->{'tickets'};
- if ( $session->{'pkgnum'} ) {
- $return{balance} = $cust_main->balance_pkgnum( $session->{'pkgnum'} );
- #next_bill_date from cust_pkg?
+ if ( $session->{'pkgnum'} ) {
+ #XXX open invoices in the pkg-balances case
} else {
- $return{balance} = $cust_main->balance;
- $return{next_bill_date} = $cust_main->next_bill_date;
- $return{next_bill_date_pretty} =
- $return{next_bill_date} ? time2str('%m/%d/%Y', $return{next_bill_date} )
- : '(none)';
- }
-
- my @tickets = $cust_main->tickets;
- # unavoidable false laziness w/ httemplate/view/cust_main/tickets.html
- if ( $FS::TicketSystem::system && FS::TicketSystem->selfservice_priority ) {
- my $dir = $conf->exists('ticket_system-priority_reverse') ? -1 : 1;
- $return{tickets} = [
- sort {
- (
- ($a->{'_selfservice_priority'} eq '') <=>
- ($b->{'_selfservice_priority'} eq '')
- ) ||
- ( $dir *
- ($b->{'_selfservice_priority'} <=> $a->{'_selfservice_priority'})
- )
- } @tickets
- ];
- }
- else {
- $return{tickets} = \@tickets;
- }
-
- unless ( $session->{'pkgnum'} ) {
my @open = map {
{
invnum => $_->invnum,
@@ -434,29 +435,17 @@ sub customer_info {
time2str('%m/%d/%Y', $return{'last_invoice_date'} );
}
- $return{countrydefault} = scalar($conf->config('countrydefault'));
-
+ #customer_info_short always has nobalance on..
$return{small_custview} =
small_custview( $cust_main,
$return{countrydefault},
( $session->{'pkgnum'} ? 1 : 0 ), #nobalance
);
- $return{name} = $cust_main->first. ' '. $cust_main->get('last');
-
$return{has_ship_address} = $cust_main->has_ship_address;
$return{status} = $cust_main->status;
$return{statuscolor} = $cust_main->statuscolor;
- for (@cust_main_editable_fields) {
- $return{$_} = $cust_main->get($_);
- }
-
- for (@location_editable_fields) {
- $return{$_} = $cust_main->bill_location->get($_);
- $return{'ship_'.$_} = $cust_main->ship_location->get($_);
- }
- $return{has_ship_address} = $cust_main->has_ship_address;
# compatibility: some places in selfservice use this to determine
# if there's a ship address
if ( $return{has_ship_address} ) {
@@ -464,16 +453,6 @@ sub customer_info {
$return{ship_first} = $cust_main->first;
}
- if ( $cust_main->payby =~ /^(CARD|DCRD)$/ ) {
- $return{payinfo} = $cust_main->paymask;
- @return{'month', 'year'} = $cust_main->paydate_monthyear;
- }
-
- $return{'invoicing_list'} =
- join(', ', grep { $_ !~ /^(POST|FAX)$/ } $cust_main->invoicing_list );
- $return{'postal_invoicing'} =
- 0 < ( grep { $_ eq 'POST' } $cust_main->invoicing_list );
-
if (scalar($conf->config('support_packages'))) {
my @support_services = ();
foreach ($cust_main->support_services) {
@@ -500,12 +479,6 @@ sub customer_info {
$return{discount_terms_hash} = { $cust_main->discount_terms_hash };
}
- if ( $session->{'svcnum'} ) {
- my $cust_svc = qsearchs('cust_svc', { 'svcnum' => $session->{'svcnum'} });
- $return{'svc_label'} = ($cust_svc->label)[1] if $cust_svc;
- $return{'svcnum'} = $session->{'svcnum'};
- }
-
} elsif ( $session->{'svcnum'} ) { #no customer record
my $svc_acct = qsearchs('svc_acct', { 'svcnum' => $session->{'svcnum'} } )
@@ -544,6 +517,17 @@ sub customer_info_short {
$return{display_custnum} = $cust_main->display_custnum;
+ if ( $session->{'pkgnum'} ) {
+ $return{balance} = $cust_main->balance_pkgnum( $session->{'pkgnum'} );
+ #next_bill_date from cust_pkg?
+ } else {
+ $return{balance} = $cust_main->balance;
+ $return{next_bill_date} = $cust_main->next_bill_date;
+ $return{next_bill_date_pretty} =
+ $return{next_bill_date} ? time2str('%m/%d/%Y', $return{next_bill_date} )
+ : '(none)';
+ }
+
$return{countrydefault} = scalar($conf->config('countrydefault'));
$return{small_custview} =
@@ -571,10 +555,11 @@ sub customer_info_short {
@return{'month', 'year'} = $cust_main->paydate_monthyear;
}
+ my @invoicing_list = $cust_main->invoicing_list;
$return{'invoicing_list'} =
- join(', ', grep { $_ !~ /^(POST|FAX)$/ } $cust_main->invoicing_list );
- #$return{'postal_invoicing'} =
- # 0 < ( grep { $_ eq 'POST' } $cust_main->invoicing_list );
+ join(', ', grep { $_ !~ /^(POST|FAX)$/ } @invoicing_list );
+ $return{'postal_invoicing'} =
+ 0 < ( grep { $_ eq 'POST' } @invoicing_list );
if ( $session->{'svcnum'} ) {
my $cust_svc = qsearchs('cust_svc', { 'svcnum' => $session->{'svcnum'} });
@@ -1585,8 +1570,9 @@ sub list_pkgs {
my $primary_cust_svc = $_->primary_cust_svc;
+{ $_->hash,
$_->part_pkg->hash,
- pkg_label => $_->pkg_locale,
- status => $_->status,
+ pkg_label => $_->pkg_locale,
+ status => $_->status,
+ statuscolor => $_->statuscolor,
part_svc =>
[ map { $_->hashref }
grep { $_->selfservice_access ne 'hidden' }
@@ -1622,6 +1608,7 @@ sub list_pkgs {
],
'small_custview' =>
small_custview( $cust_main, $conf->config('countrydefault') ),
+ 'date_format' => $conf->config('date_format') || '%m/%d/%Y',
};
}
@@ -2926,13 +2913,59 @@ sub process_reset_passwd {
}
+sub list_tickets {
+ my $p = shift;
+ my($context, $session, $custnum) = _custoragent_session_custnum($p);
+ return { 'error' => $session } if $context eq 'error';
+
+ my @tickets = ();
+ if ( $session->{'pkgnum'} ) {
+
+ #tickets for specific service with pkg-balances on
+ my $cust_pkg = qsearchs('cust_pkg', { 'custnum' => $custnum,
+ 'pkgnum' => $session->{'pkgnum'} })
+ or return { 'error' => 'unknown package' };
+ foreach my $cust_svc ( $cust_pkg->cust_svc ) {
+ push @tickets, $cust_svc->tickets( $p->{status} );
+ }
+
+ } else {
+
+ my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } )
+ or return { 'error' => "unknown custnum $custnum" };
+
+ @tickets = $cust_main->tickets( $p->{status} );
+ }
+
+ # unavoidable false laziness w/ httemplate/view/cust_main/tickets.html
+ if ( $FS::TicketSystem::system && FS::TicketSystem->selfservice_priority ) {
+ my $conf = new FS::Conf;
+ my $dir = $conf->exists('ticket_system-priority_reverse') ? -1 : 1;
+ +{ tickets => [
+ sort {
+ (
+ ($a->{'_selfservice_priority'} eq '') <=>
+ ($b->{'_selfservice_priority'} eq '')
+ ) ||
+ ( $dir *
+ ($b->{'_selfservice_priority'} <=> $a->{'_selfservice_priority'})
+ )
+ } @tickets
+ ]
+ };
+ } else {
+ +{ tickets => \@tickets };
+ }
+
+}
+
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();
+# warn "$me create_ticket: initializing ticket system\n" if $DEBUG;
+# FS::TicketSystem->init();
my $conf = new FS::Conf;
my $queue = $p->{'queue'}
@@ -3047,10 +3080,10 @@ sub get_ticket {
my($context, $session, $custnum) = _custoragent_session_custnum($p);
return { 'error' => $session } if $context eq 'error';
- warn "$me get_ticket: initializing ticket system\n" if $DEBUG;
- FS::TicketSystem->init();
- return { 'error' => 'get_ticket configuration error' }
- if $FS::TicketSystem::system ne 'RT_Internal';
+# warn "$me get_ticket: initializing ticket system\n" if $DEBUG;
+# FS::TicketSystem->init();
+# return { 'error' => 'get_ticket configuration error' }
+# if $FS::TicketSystem::system ne 'RT_Internal';
# check existence and ownership as part of this
warn "$me get_ticket: fetching ticket\n" if $DEBUG;
@@ -3122,8 +3155,8 @@ sub adjust_ticket_priority {
my($context, $session, $custnum) = _custoragent_session_custnum($p);
return { 'error' => $session } if $context eq 'error';
- warn "$me adjust_ticket_priority: initializing ticket system\n" if $DEBUG;
- FS::TicketSystem->init;
+# warn "$me adjust_ticket_priority: initializing ticket system\n" if $DEBUG;
+# FS::TicketSystem->init;
my $ss_priority = FS::TicketSystem->selfservice_priority;
return { 'error' => 'adjust_ticket_priority configuration error' }
diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm
index 75bba36..c4cc015 100644
--- a/FS/FS/Conf.pm
+++ b/FS/FS/Conf.pm
@@ -4647,6 +4647,13 @@ and customer address. Include units.',
},
{
+ 'key' => 'ng_selfservice-menu',
+ 'section' => 'self-service',
+ 'description' => 'Custom menu for the next-generation self-service interface. Each line is in the format "link Label", for example "main.php Home". Sub-menu items are listed on subsequent lines. Blank lines terminate the submenu.', #more docs/examples would be helpful
+ 'type' => 'textarea',
+ },
+
+ {
'key' => 'signup-no_company',
'section' => 'self-service',
'description' => "Don't display a field for company name on signup.",
diff --git a/FS/FS/TicketSystem/RT_Internal.pm b/FS/FS/TicketSystem/RT_Internal.pm
index 665c166..d0913d8 100644
--- a/FS/FS/TicketSystem/RT_Internal.pm
+++ b/FS/FS/TicketSystem/RT_Internal.pm
@@ -111,7 +111,7 @@ properly.
# create an RT::Tickets object for a specified custnum or svcnum
sub _tickets_search {
- my ( $self, $type, $number, $limit, $priority ) = @_;
+ my( $self, $type, $number, $limit, $priority, $status ) = @_;
$type =~ /^Customer|Service$/ or die "invalid type: $type";
$number =~ /^\d+$/ or die "invalid custnum/svcnum: $number";
@@ -136,9 +136,28 @@ sub _tickets_search {
}
}
- $rtql .= ' AND ( ' .
- join(' OR ', map { "Status = '$_'" } $self->statuses) .
- ' )';
+ my @statuses;
+ if ( defined($status) && $status ) {
+ if ( ref($status) ) {
+ if ( ref($status) eq 'HASH' ) {
+ @statuses = grep $status->{$_}, keys %$status;
+ } elsif ( ref($status) eq 'ARRAY' ) {
+ @statuses = @$status;
+ } else {
+ #what should be the failure mode here? die? return no tickets?
+ die 'unknown status ref '. ref($status);
+ }
+ } else {
+ @statuses = ( $status );
+ }
+ @statuses = grep /^\w+$/, @statuses; #injection prevention
+ } else {
+ @statuses = $self->statuses;
+ }
+
+ $rtql .= ' AND ( '.
+ join(' OR ', map { "Status = '$_'" } @statuses).
+ ' ) ';
warn "$me _customer_tickets_search:\n$rtql\n" if $DEBUG;
$Tickets->FromSQL($rtql);
diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm
index 7e3e26a..940b22a 100644
--- a/FS/FS/cust_main.pm
+++ b/FS/FS/cust_main.pm
@@ -4135,14 +4135,17 @@ sub cust_statuscolor {
__PACKAGE__->statuscolors->{$self->cust_status};
}
-=item tickets
+=item tickets [ STATUS ]
Returns an array of hashes representing the customer's RT tickets.
+An optional status (or arrayref or hashref of statuses) may be specified.
+
=cut
sub tickets {
my $self = shift;
+ my $status = ( @_ && $_[0] ) ? shift : '';
my $num = $conf->config('cust_main-max_tickets') || 10;
my @tickets = ();
@@ -4150,7 +4153,12 @@ sub tickets {
if ( $conf->config('ticket_system') ) {
unless ( $conf->config('ticket_system-custom_priority_field') ) {
- @tickets = @{ FS::TicketSystem->customer_tickets($self->custnum, $num) };
+ @tickets = @{ FS::TicketSystem->customer_tickets( $self->custnum,
+ $num,
+ undef,
+ $status,
+ )
+ };
} else {
@@ -4162,6 +4170,7 @@ sub tickets {
@{ FS::TicketSystem->customer_tickets( $self->custnum,
$num - scalar(@tickets),
$priority,
+ $status,
)
};
}
diff --git a/FS/FS/cust_svc.pm b/FS/FS/cust_svc.pm
index 6aa254f..2066a05 100644
--- a/FS/FS/cust_svc.pm
+++ b/FS/FS/cust_svc.pm
@@ -805,14 +805,17 @@ sub get_session_history {
}
-=item tickets
+=item tickets [ STATUS ]
Returns an array of hashes representing the tickets linked to this service.
+An optional status (or arrayref or hashref of statuses) may be specified.
+
=cut
sub tickets {
my $self = shift;
+ my $status = ( @_ && $_[0] ) ? shift : '';
my $conf = FS::Conf->new;
my $num = $conf->config('cust_main-max_tickets') || 10;
@@ -821,7 +824,12 @@ sub tickets {
if ( $conf->config('ticket_system') ) {
unless ( $conf->config('ticket_system-custom_priority_field') ) {
- @tickets = @{ FS::TicketSystem->service_tickets($self->svcnum, $num) };
+ @tickets = @{ FS::TicketSystem->service_tickets( $self->svcnum,
+ $num,
+ undef,
+ $status,
+ )
+ };
} else {
@@ -831,10 +839,11 @@ sub tickets {
last if scalar(@tickets) >= $num;
push @tickets,
@{ FS::TicketSystem->service_tickets( $self->svcnum,
- $num - scalar(@tickets),
- $priority,
- )
- };
+ $num - scalar(@tickets),
+ $priority,
+ $status,
+ )
+ };
}
}
}
diff --git a/FS/bin/freeside-selfservice-server b/FS/bin/freeside-selfservice-server
index 9df313f..8ce74d5 100644
--- a/FS/bin/freeside-selfservice-server
+++ b/FS/bin/freeside-selfservice-server
@@ -16,6 +16,7 @@ use FS::UID qw(adminsuidsetup forksuidsetup);
use FS::ClientAPI qw( load_clientapi_modules );
use FS::ClientAPI_SessionCache;
use FS::Record qw( qsearch qsearchs );
+use FS::TicketSystem;
use FS::Conf;
use FS::cust_svc;
@@ -157,12 +158,10 @@ while (1) {
warn "child $pid spawned\n" if $Debug;
} else { #kid time
- ##get new db handle
$FS::UID::dbh->{InactiveDestroy} = 1;
forksuidsetup($user);
- #get db handle
- #adminsuidsetup($user);
+ FS::TicketSystem->init();
my $type = $packet->{_packet};
warn "calling $type handler\n" if $Debug;
diff --git a/FS/bin/freeside-selfservice-xmlrpcd b/FS/bin/freeside-selfservice-xmlrpcd
index acf516a..423d2c3 100755
--- a/FS/bin/freeside-selfservice-xmlrpcd
+++ b/FS/bin/freeside-selfservice-xmlrpcd
@@ -28,6 +28,7 @@ use FS::UID qw( adminsuidsetup forksuidsetup dbh );
use FS::Conf;
use FS::ClientAPI qw( load_clientapi_modules );
use FS::ClientAPI_XMLRPC; #FS::SelfService::XMLRPC;
+use FS::TicketSystem;
#freeside
my $FREESIDE_LOG = "%%%FREESIDE_LOG%%%";
@@ -195,6 +196,9 @@ sub server_do_fork {
#freeside db connection, etc.
forksuidsetup($user);
+ #why isn't this needed ala freeside-selfservice-server??
+ #FS::TicketSystem->init();
+
return;
}
}