diff options
| -rw-r--r-- | FS/FS/ClientAPI/MyAccount.pm | 124 | ||||
| -rw-r--r-- | FS/FS/cust_main.pm | 35 | 
2 files changed, 148 insertions, 11 deletions
| diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm index fda4bc28f..8ac1b8de5 100644 --- a/FS/FS/ClientAPI/MyAccount.pm +++ b/FS/FS/ClientAPI/MyAccount.pm @@ -12,13 +12,17 @@ use FS::svc_acct;  use FS::svc_domain;  use FS::cust_main;  use FS::cust_bill; +use FS::cust_pkg;  use FS::ClientAPI; #hmm  FS::ClientAPI->register_handlers( -  'MyAccount/login'         => \&login, -  'MyAccount/customer_info' => \&customer_info, -  'MyAccount/invoice'       => \&invoice, -  'MyAccount/cancel'        => \&cancel, +  'MyAccount/login'            => \&login, +  'MyAccount/customer_info'    => \&customer_info, +  'MyAccount/invoice'          => \&invoice, +  'MyAccount/cancel'           => \&cancel, +  'MyAccount/list_pkgs'        => \&list_pkgs, +  'MyAccount/order_pkg'        => \&order_pkg, +  'MyAccount/cancel_pkg'       => \&cancel_pkg,  );  #store in db? @@ -152,5 +156,117 @@ sub cancel {  } +sub list_pkgs { +  my $p = shift; +  my $session = $cache->get($p->{'session_id'}) +    or return { 'error' => "Can't resume session" }; #better error message + +  my $custnum = $session->{'custnum'}; + +  my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ) +    or return { 'error' => "unknown custnum $custnum" }; + +  return { 'cust_pkg' => [ map { $_->hashref } $cust_main->ncancelled_pkgs ] }; + +} + +sub order_pkg { +  my $p = shift; +  my $session = $cache->get($p->{'session_id'}) +    or return { 'error' => "Can't resume session" }; #better error message + +  my $custnum = $session->{'custnum'}; + +  my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ) +    or return { 'error' => "unknown custnum $custnum" }; + +  #false laziness w/ClientAPI/Signup.pm + +  my $cust_pkg = new FS::cust_pkg ( { +    'custnum' => $custnum, +    'pkgpart' => $p->{'pkgpart'}, +  } ); +  my $error = $cust_pkg->check; +  return { 'error' => $error } if $error; + +  my $svc_acct = new FS::svc_acct ( { +    'svcpart'   => $p->{'svcpart'} || $cust_pkg->part_pkg->svcpart('svc_acct'), +    map { $_ => $p->{$_} } +      qw( username _password sec_phrase popnum ), +  } ); + +  my @acct_snarf; +  my $snarfnum = 1; +  while ( length($p->{"snarf_machine$snarfnum"}) ) { +    my $acct_snarf = new FS::acct_snarf ( { +      'machine'   => $p->{"snarf_machine$snarfnum"}, +      'protocol'  => $p->{"snarf_protocol$snarfnum"}, +      'username'  => $p->{"snarf_username$snarfnum"}, +      '_password' => $p->{"snarf_password$snarfnum"}, +    } ); +    $snarfnum++; +    push @acct_snarf, $acct_snarf; +  } +  $svc_acct->child_objects( \@acct_snarf ); + +  my $y = $svc_acct->setdefault; # arguably should be in new method +  return { 'error' => $y } if $y && !ref($y); + +  $error = $svc_acct->check; +  return { 'error' => $error } if $error; + +  use Tie::RefHash; +  tie my %hash, 'Tie::RefHash'; +  %hash = ( $cust_pkg => [ $svc_acct ] ); +  #msgcat +  $error = $cust_main->order_pkgs( \%hash, '', 'noexport' => 1 ); +  return { 'error' => $error } if $error; + +  my $conf = new FS::Conf; +  if ( $conf->exists('signup_server-realtime') ) { + +    my $old_balance = $cust_main->balance; + +    my $bill_error = $cust_main->bill; +    $cust_main->apply_payments; +    $cust_main->apply_credits; +    $bill_error = $cust_main->collect; + +    if ( $cust_main->balance > $old_balance ) { +      $cust_pkg->cancel('quiet'=>1); +      return { 'error' => '_decline' }; +    } else { +      $cust_pkg->reexport; +    } + +  } else { +    $cust_pkg->reexport; +  } + +  return { error => '' }; + +} + +sub cancel_pkg { +  my $p = shift; +  my $session = $cache->get($p->{'session_id'}) +    or return { 'error' => "Can't resume session" }; #better error message + +  my $custnum = $session->{'custnum'}; + +  my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ) +    or return { 'error' => "unknown custnum $custnum" }; + +  my $pkgnum = $session->{'pkgnum'}; + +  my $cust_pkg = qsearchs('cust_pkg', { 'custnum' => $custnum, +                                        'pkgnum'  => $pkgnum,   } ) +    or return { 'error' => "unknown pkgnum $pkgnum" }; + +  my $error = $cust_main->cancel( 'quiet'=>1 ); +  return { 'error' => $error }; + +} +  1; diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index 9c0e36e18..5bea9fe26 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -285,8 +285,8 @@ sub insert {    }    # packages -  local $FS::svc_Common::noexport_hack = 1 if $options{'noexport'}; -  $error = $self->order_pkgs($cust_pkgs, \$seconds); +  #local $FS::svc_Common::noexport_hack = 1 if $options{'noexport'}; +  $error = $self->order_pkgs($cust_pkgs, \$seconds, %options);    if ( $error ) {      $dbh->rollback if $oldAutoCommit;      return $error; @@ -320,9 +320,27 @@ sub insert {  } -=item order_pkgs +=item order_pkgs HASHREF, [ , OPTION => VALUE ... ] ] + +Like the insert method on an existing record, this method orders a package +and included services atomicaly.  Pass a Tie::RefHash data structure to this +method containing FS::cust_pkg and FS::svc_I<tablename> objects.  There should +be a better explanation of this, but until then, here's an example: + +  use Tie::RefHash; +  tie %hash, 'Tie::RefHash'; #this part is important +  %hash = ( +    $cust_pkg => [ $svc_acct ], +    ... +  ); +  $cust_main->order_pkgs( \%hash, 'noexport'=>1 ); -document me.  like ->insert(%cust_pkg) on an existing record +Currently available options are: I<noexport> + +If I<noexport> is set true, no provisioning jobs (exports) are scheduled. +(You can schedule them later with the B<reexport> method for each +cust_pkg object.  Using the B<reexport> method on the cust_main object is not +recommended, as existing services will also be reexported.)  =cut @@ -330,6 +348,7 @@ sub order_pkgs {    my $self = shift;    my $cust_pkgs = shift;    my $seconds = shift; +  my %options = @_;    local $SIG{HUP} = 'IGNORE';    local $SIG{INT} = 'IGNORE'; @@ -342,6 +361,8 @@ sub order_pkgs {    local $FS::UID::AutoCommit = 0;    my $dbh = dbh; +  local $FS::svc_Common::noexport_hack = 1 if $options{'noexport'}; +    foreach my $cust_pkg ( keys %$cust_pkgs ) {      $cust_pkg->custnum( $self->custnum );      my $error = $cust_pkg->insert; @@ -370,9 +391,9 @@ sub order_pkgs {  =item reexport -document me.  Re-schedules all exports by calling the B<reexport> method -of all associated packages (see L<FS::cust_pkg>).  If there is an error, -returns the error; otherwise returns false. +Re-schedules all exports by calling the B<reexport> method of all associated +packages (see L<FS::cust_pkg>).  If there is an error, returns the error; +otherwise returns false.  =cut | 
