use FS::msg_template;
use FS::contact;
use FS::cust_contact;
+use FS::cust_location;
-$DEBUG = 1;
+use FS::ClientAPI::MyAccount::quotation; # just for code organization
+
+$DEBUG = 0;
$me = '[FS::ClientAPI::MyAccount]';
use vars qw( @cust_main_editable_fields @location_editable_fields );
'logo' => scalar($conf->config_binary('logo.png', $agentnum )),
( map { $_ => join("\n", $conf->config("selfservice-$_", $agentnum ) ) }
qw( head body_header body_footer company_address ) ),
+ 'money_char' => $conf->config("money_char") || '$',
'menu' => join("\n", $conf->config("ng_selfservice-menu", $agentnum ) ) ||
'main.php Home
}
# no usage to hide here
- } elsif ( $svcdb eq 'svc_phone' ) {
+ } elsif ( $svcdb eq 'svc_phone' or $svcdb eq 'svc_pbx' ) {
if (!$hide_usage) {
# could potentially show lots of things...
$hash{'outbound'} = 1;
$hash{'inbound'} = 0;
- if ( $part_pkg->plan eq 'voip_inbound' ) {
- $hash{'outbound'} = 0;
- $hash{'inbound'} = 1;
- } elsif ( $part_pkg->option('selfservice_inbound_format')
- or $conf->config('selfservice-default_inbound_cdr_format')
- ) {
- $hash{'inbound'} = 1;
+ if ( $svcdb eq 'svc_phone' ) {
+ if ( $part_pkg->plan eq 'voip_inbound' ) {
+ $hash{'outbound'} = 0;
+ $hash{'inbound'} = 1;
+ } elsif ( $part_pkg->option('selfservice_inbound_format')
+ or $conf->config('selfservice-default_inbound_cdr_format')
+ ) {
+ $hash{'inbound'} = 1;
+ }
}
foreach (qw(inbound outbound)) {
# hmm...we can't filter by status here, because there might
# XXX CDR type support...
# XXX any way to do a paged search on this?
# we have to return the results all at once...
- my($svc_phone, $begin, $end, %opt) = @_;
+ my($svc_x, $begin, $end, %opt) = @_;
map [ $_->downstream_csv(%opt, 'keeparray' => 1) ],
- $svc_phone->get_cdrs(
- 'begin'=>$begin,
- 'end'=>$end,
+ $svc_x->get_cdrs(
+ 'begin' => $begin,
+ 'end' => $end,
'disable_charged_party' => 1,
%opt
);
sub list_cdr_usage {
my $p = shift;
- _usage_details( \&_list_cdr_usage, $p,
- 'svcdb' => 'svc_phone',
- );
+ _usage_details( \&_list_cdr_usage, $p );
}
sub _usage_details {
my $search = { 'svcnum' => $p->{'svcnum'} };
$search->{'agentnum'} = $session->{'agentnum'} if $context eq 'agent';
- my $svcdb = $opt{'svcdb'} || 'svc_acct';
-
- my $svc_x = qsearchs( $svcdb, $search );
+ my $cust_svc = qsearchs( 'cust_svc', $search );
return { 'error' => 'No service selected in list_svc_usage' }
- unless $svc_x;
+ unless $cust_svc;
- my $cust_pkg = $svc_x->cust_svc->cust_pkg;
+ my $svc_x = $cust_svc->svc_x;
+ my $svcdb = $svc_x->table;
+ my $cust_pkg = $cust_svc->cust_pkg;
my $freq = $cust_pkg->part_pkg->freq;
my %callback_opt;
my $header = [];
- if ( $svcdb eq 'svc_phone' ) {
+ if ( $svcdb eq 'svc_phone' or $svcdb eq 'svc_pbx' ) {
my $format = '';
if ( $p->{inbound} ) {
$format = $cust_pkg->part_pkg->option('selfservice_inbound_format')
or return { 'error' => "unknown custnum $custnum" };
my $status = $cust_main->status;
+
+ my %order_pkg_options = ();
+ if ( $p->{locationnum} > 0 ) {
+ $order_pkg_options{locationnum} = delete($p->{locationnum});
+ } elsif ( $p->{address1} ) {
+ $order_pkg_options{'cust_location'} = new FS::cust_location {
+ map { $_ => $p->{$_} }
+ qw( address1 address2 city county state zip country )
+ };
+ }
+
#false laziness w/ClientAPI/Signup.pm
my $cust_pkg = new FS::cust_pkg ( {
- 'custnum' => $custnum,
- 'pkgpart' => $p->{'pkgpart'},
+ 'custnum' => $custnum,
+ 'pkgpart' => $p->{'pkgpart'},
+ 'quantity' => $p->{'quantity'} || 1,
} );
my $error = $cust_pkg->check;
return { 'error' => $error } if $error;
}
- use Tie::RefHash;
- tie my %hash, 'Tie::RefHash';
- %hash = ( $cust_pkg => \@svc );
- #msgcat
- $error = $cust_main->order_pkgs( \%hash, 'noexport' => 1 );
+ $error = $cust_main->order_pkg(
+ 'cust_pkg' => $cust_pkg,
+ 'svcs' => \@svc,
+ 'noexport' => 1,
+ %order_pkg_options,
+ );
return { 'error' => $error } if $error;
my $conf = new FS::Conf;
return { error=>"Can't change a suspended package", pkgnum=>$cust_pkg->pkgnum}
if $cust_pkg->status eq 'suspended';
- my @newpkg;
- my $error = FS::cust_pkg::order( $custnum,
- [$p->{pkgpart}],
- [$p->{pkgnum}],
- \@newpkg,
- );
+ my $err_or_cust_pkg = $cust_pkg->change( 'pkgpart' => $p->{'pkgpart'},
+ 'quantity' => $p->{'quantity'} || 1,
+ );
+
+ return { error=>$err_or_cust_pkg, pkgnum=>$cust_pkg->pkgnum }
+ unless ref($err_or_cust_pkg);
if ( $conf->exists('signup_server-realtime') ) {
my $bill_error = _do_bop_realtime( $cust_main, $status, 'no_credit'=>1 );
if ($bill_error) {
- $newpkg[0]->suspend;
+ $err_or_cust_pkg->suspend;
return $bill_error;
} else {
- $newpkg[0]->reexport;
+ $err_or_cust_pkg->reexport;
}
} else {
- $newpkg[0]->reexport;
+ $err_or_cust_pkg->reexport;
}
return { error => '', pkgnum => $cust_pkg->pkgnum };
}
sub provision_phone {
- my $p = shift;
- my @bulkdid;
- @bulkdid = @{$p->{'bulkdid'}} if $p->{'bulkdid'};
+ my $p = shift;
+ my @bulkdid;
+ @bulkdid = @{$p->{'bulkdid'}} if $p->{'bulkdid'};
- if($p->{'svcnum'} && $p->{'svcnum'} =~ /^\d+$/){
+ #editing an existing phone number
+ if ( $p->{'svcnum'} && $p->{'svcnum'} =~ /^\d+$/ ) {
my($context, $session, $custnum) = _custoragent_session_custnum($p);
return { 'error' => $session } if $context eq 'error';
return { 'error' => $svc_phone->replace };
}
-# single DID LNP
- unless($p->{'lnp'}) {
+ # single DID LNP
+ unless ( $p->{'lnp'} ) {
$p->{'lnp_desired_due_date'} = parse_datetime($p->{'lnp_desired_due_date'});
$p->{'lnp_status'} = "portingin";
return _provision( 'FS::svc_phone',
$p,
@_
);
- }
+ }
-# single DID order
- unless (scalar(@bulkdid)) {
+ # single DID order (the usual case)
+ unless (scalar(@bulkdid)) {
return _provision( 'FS::svc_phone',
[qw(phonenum countrycode)],
[qw(phonenum countrycode)],
$p,
@_
);
- }
+ }
-# bulk DID order case
+ # bulk DID order case
my $error;
foreach my $did ( @bulkdid ) {
$did =~ s/[^0-9]//g;
{ 'bulkdid' => [ @bulkdid ], 'svc' => $error->{'svc'} }
}
+sub provision_pbx {
+ my $p = shift;
+ warn "provision_pbx called\n"
+ if $DEBUG;
+
+ warn "provision_pbx calling _provision\n"
+ if $DEBUG;
+ _provision( 'FS::svc_pbx',
+ [qw(id title max_extensions max_simultaneous ip_addr)],
+ [qw(id title max_extensions max_simultaneous ip_addr)],
+ $p,
+ @_
+ );
+}
+
sub provision_acct {
my $p = shift;
warn "provision_acct called\n"
);
}
+sub provision_forward {
+ my $p = shift;
+ _provision( 'FS::svc_forward',
+ ['srcsvc','src','dstsvc','dst'],
+ [],
+ $p,
+ );
+}
+
sub _provision {
my( $class, $fields, $return_fields, $p ) = splice(@_, 0, 4);
warn "_provision called for $class\n"
my $part_svc = qsearchs('part_svc', { 'svcpart' => $p->{'svcpart'} } )
or return { 'error' => "unknown svcpart $p->{'svcpart'}" };
+ return { error=> 'svcpart '. $p->{'svcpart'}. " is not a $class definition" }
+ if $class ne 'FS::'. $part_svc->svcdb;
+
warn "creating $class record\n"
if $DEBUG;
my $svc_x = $class->new( {
'svcpart' => $p->{'svcpart'},
map { $_ => $p->{$_} } @$fields
} );
+
+ my %insert_args = ();
+ #i shouldn't be a special case here (pass an option or something)
+ if ( $class eq 'FS::svc_phone'
+ && grep length($p->{$_}), @location_editable_fields
+ )
+ {
+ $insert_args{'cust_location'} = new FS::cust_location {
+ map { $_ => $p->{$_} } @location_editable_fields
+ };
+ }
+
warn "inserting $class record\n"
if $DEBUG;
- my $error = $svc_x->insert;
+ my $error = $svc_x->insert(%insert_args);
unless ( $error ) {
warn "finding inserted record for svcnum ". $svc_x->svcnum. "\n"
}
}
+ if ($ret->{'svcdb'} eq 'svc_forward') {
+ $ret->{'forward_emails'} = {$cust_pkg->forward_emails()};
+ }
+
$ret;
}