[freeside-commits] freeside/FS/FS/ClientAPI Bulk.pm,NONE,1.1
Jeff Finucane,420,,
jeff at wavetail.420.am
Wed May 27 00:50:42 PDT 2009
- Previous message: [freeside-commits] freeside/fs_selfservice/FS-SelfService/cgi overlibmws_crossframe.js, NONE, 1.1 overlibmws_draggable.js, NONE, 1.1 overlibmws_iframe.js, NONE, 1.1 overlibmws.js, NONE, 1.1 iframecontentmws.js, NONE, 1.1
- Next message: [freeside-commits] freeside/FS/FS cust_recon.pm, NONE, 1.1 Conf.pm, 1.285, 1.286 Schema.pm, 1.140, 1.141 cust_main.pm, 1.425, 1.426 cust_pkg.pm, 1.127, 1.128 svc_acct.pm, 1.258, 1.259
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /home/cvs/cvsroot/freeside/FS/FS/ClientAPI
In directory wavetail.420.am:/tmp/cvs-serv12160/FS/FS/ClientAPI
Added Files:
Bulk.pm
Log Message:
bulk provisioning via ftp and SOAP #5202
--- NEW FILE: Bulk.pm ---
package FS::ClientAPI::Bulk;
use strict;
use vars qw( $DEBUG $cache );
use Date::Parse;
use FS::Record qw( qsearchs );
use FS::Conf;
use FS::ClientAPI_SessionCache;
use FS::cust_main;
use FS::cust_pkg;
use FS::cust_svc;
use FS::svc_acct;
use FS::svc_external;
use FS::cust_recon;
use Data::Dumper;
$DEBUG = 1;
sub _cache {
$cache ||= new FS::ClientAPI_SessionCache ( {
'namespace' => 'FS::ClientAPI::Agent', #yes, share session_ids
} );
}
sub _izoom_ftp_row_fixup {
my $hash = shift;
my @addr_fields = qw( address1 address2 city state zip );
my @fields = ( qw( agent_custid username _password first last ),
@addr_fields,
map { "ship_$_" } @addr_fields );
$hash->{$_} =~ s/[&\/\*'"]/_/g foreach @fields;
#$hash->{action} = '' if $hash->{action} eq 'R'; #unsupported for ftp
$hash->{refnum} = 1; #ahem
$hash->{country} = 'US';
$hash->{ship_country} = 'US';
$hash->{payby} = 'LECB';
$hash->{payinfo} = $hash->{daytime};
$hash->{ship_fax} = '' if ( !$hash->{sms} || $hash->{sms} eq 'F' );
my $has_ship =
grep { $hash->{"ship_$_"} &&
(! $hash->{$_} || $hash->{"ship_$_"} ne $hash->{$_} )
}
( @addr_fields, 'fax' );
if ( $has_ship ) {
foreach ( @addr_fields, qw( first last ) ) {
$hash->{"ship_$_"} = $hash->{$_} unless $hash->{"ship_$_"};
}
}
delete $hash->{sms};
'';
};
sub _izoom_ftp_result {
my ($hash, $error) = @_;
my $cust_main =
qsearchs( 'cust_main', { 'agent_custid' => $hash->{agent_custid},
'agentnum' => $hash->{agentnum}
}
);
my $custnum = $cust_main ? $cust_main->custnum : '';
my @response = ( $hash->{action}, $hash->{agent_custid}, $custnum );
if ( $error ) {
push @response, ( 'ERROR', $error );
} else {
push @response, ( 'OK', 'OK' );
}
join( ',', @response );
}
sub _izoom_ftp_badaction {
"Invalid action: $_[0] record: @_ ";
}
sub _izoom_soap_row_fixup { _izoom_ftp_row_fixup(@_) };
sub _izoom_soap_result {
my ($hash, $error) = @_;
if ( $hash->{action} eq 'R' ) {
if ( $error ) {
return "Please check errors:\n $error"; # odd extra space
} else {
return join(' ', "Everything ok.", $hash->{pkg}, $hash->{adjourn} );
}
}
my $pkg = $hash->{pkg} || $hash->{saved_pkg} || '';
if ( $error ) {
return join(' ', $hash->{agent_custid}, $error );
} else {
return join(' ', $hash->{agent_custid}, $pkg, $hash->{adjourn} );
}
}
sub _izoom_soap_badaction {
"Unknown action '$_[13]' ";
}
my %format = (
'izoom-ftp' => {
'fields' => [ qw ( action agent_custid username _password
daytime ship_fax sms first last
address1 address2 city state zip
pkg adjourn ship_address1 ship_address2
ship_city ship_state ship_zip ) ],
'fixup' => sub { _izoom_ftp_row_fixup(@_) },
'result' => sub { _izoom_ftp_result(@_) },
'action' => sub { _izoom_ftp_badaction(@_) },
},
'izoom-soap' => {
'fields' => [ qw ( agent_custid username _password
daytime first last address1 address2
city state zip pkg action adjourn
ship_fax sms ship_address1 ship_address2
ship_city ship_state ship_zip ) ],
'fixup' => sub { _izoom_soap_row_fixup(@_) },
'result' => sub { _izoom_soap_result(@_) },
'action' => sub { _izoom_soap_badaction(@_) },
},
);
sub processrow {
my $p = shift;
my $session = _cache->get($p->{'session_id'})
or return { 'error' => "Can't resume session" }; #better error message
my $conf = new FS::Conf;
my $format = $conf->config('selfservice-bulk_format', $session->{agentnum})
|| 'izoom-soap';
my ( @row ) = @{ $p->{row} };
warn "processrow called with '". join("' '", @row). "'\n" if $DEBUG;
return { 'error' => "unknown format: $format" }
unless exists $format{$format};
return { 'error' => "Invalid record record length: ". scalar(@row).
"record: @row " #sic
}
unless scalar(@row) == scalar(@{$format{$format}{fields}});
my %hash = ( 'agentnum' => $session->{agentnum} );
my $error;
foreach my $field ( @{ $format{ $format }{ fields } } ) {
$hash{$field} = shift @row;
}
$error ||= &{ $format{ $format }{ fixup } }( \%hash );
# put in the fixup routine?
if ( 'R' eq $hash{action} ) {
warn "processing reconciliation\n" if $DEBUG;
$error ||= process_recon($hash{agentnum}, $hash{agent_custid});
} elsif ( 'P' eq $hash{action} ) {
# do nothing
} elsif( 'D' eq $hash{action} ) {
$hash{promo_pkg} = 'disk-1-'. $session->{agent};
} elsif ( 'S' eq $hash{action} ) {
$hash{promo_pkg} = 'disk-2-'. $session->{agent};
$hash{saved_pkg} = $hash{pkg};
$hash{pkg} = '';
} else {
$error ||= &{ $format{ $format }{ action } }( @row );
}
warn "processing provision\n" if ($DEBUG && !$error && $hash{action} ne 'R');
$error ||= provision( %hash ) unless $hash{action} eq 'R';
my $result = &{ $format{ $format }{ result } }( \%hash, $error );
warn "processrow returning '". join("' '", $result, $error). "'\n"
if $DEBUG;
return { 'error' => $error, 'message' => $result };
}
sub provision {
my %args = ( @_ );
delete $args{action};
my $cust_main =
qsearchs( 'cust_main',
{ map { $_ => $args{$_} } qw ( agent_custid agentnum ) },
);
unless ( $cust_main ) {
$cust_main = new FS::cust_main { %args };
my $error = $cust_main->insert;
return $error if $error;
}
my @pkgs = grep { $_->part_pkg->freq } $cust_main->ncancelled_pkgs;
if ( scalar(@pkgs) > 1 ) {
return "Invalid account, should not be more then one active package ". #sic
"but found: ". scalar(@pkgs). " packages.";
}
my $part_pkg = qsearchs( 'part_pkg', { 'pkg' => $args{pkg} } )
or return "Unknown pkgpart: $args{pkg}"
if $args{pkg};
my $create_package = $args{pkg};
if ( scalar(@pkgs) && $create_package ) {
my $pkg = pop(@pkgs);
if ( $part_pkg->pkgpart != $pkg->pkgpart ) {
my @cust_bill_pkg = $pkg->cust_bill_pkg();
if ( 1 == scalar(@cust_bill_pkg) ) {
my $cbp= pop(@cust_bill_pkg);
my $cust_bill = $cbp->cust_bill;
$cust_bill->delete(); #really? wouldn't a credit be better?
}
$pkg->cancel();
} else {
$create_package = '';
$pkg->setfield('adjourn', str2time($args{adjourn}));
my $error = $pkg->replace();
return $error if $error;
}
}
if ( $create_package ) {
my $cust_pkg = new FS::cust_pkg ( {
'pkgpart' => $part_pkg->pkgpart,
'adjourn' => str2time( $args{adjourn} ),
} );
my $svcpart = $part_pkg->svcpart('svc_acct');
my $svc_acct = new FS::svc_acct ( {
'svcpart' => $svcpart,
'username' => $args{username},
'_password' => $args{_password},
} );
my $error = $cust_main->order_pkg( cust_pkg => $cust_pkg,
svcs => [ $svc_acct ],
);
return $error if $error;
}
if ( $args{promo_pkg} ) {
my $part_pkg =
qsearchs( 'part_pkg', { 'promo_code' => $args{promo_pkg} } )
or return "unknown pkgpart: $args{promo_pkg}";
my $svcpart = $part_pkg->svcpart('svc_external')
or return "unknown svcpart: svc_external";
my $cust_pkg = new FS::cust_pkg ( {
'svcpart' => $svcpart,
'pkgpart' => $part_pkg->pkgpart,
} );
my $svc_ext = new FS::svc_external ( { 'svcpart' => $svcpart } );
my $ticket_subject = 'Send setup disk to customer '. $cust_main->custnum;
my $error = $cust_main->order_pkg ( cust_pkg => $cust_pkg,
svcs => [ $svc_ext ],
noexport => 1,
ticket_subject => $ticket_subject,
ticket_queue => "disk-$args{agentnum}",
);
return $error if $error;
}
my $error = $cust_main->bill();
return $error if $error;
}
sub process_recon {
my ( $agentnum, $id ) = @_;
my @recs = split /;/, $id;
my $err = '';
foreach my $rec ( @recs ) {
my @record = split /,/, $rec;
my $result = process_recon_record(@record, $agentnum);
$err .= "$result\n" if $result;
}
return $err;
}
sub process_recon_record {
my ( $agent_custid, $username, $_password, $daytime, $first, $last, $address1, $address2, $city, $state, $zip, $pkg, $adjourn, $agentnum) = @_;
warn "process_recon_record called with '". join("','", @_). "'\n" if $DEBUG;
my ($cust_pkg, $package);
my $cust_main =
qsearchs( 'cust_main',
{ 'agent_custid' => $agent_custid, 'agentnum' => $agentnum },
);
my $comments = '';
if ( $cust_main ) {
my @cust_pkg = grep { $_->part_pkg->freq } $cust_main->ncancelled_pkgs;
if ( scalar(@cust_pkg) == 1) {
$cust_pkg = pop(@cust_pkg);
$package = $cust_pkg->part_pkg->pkg;
$comments = "$agent_custid wrong package, expected: $pkg found: $package"
if ( $pkg ne $package );
} else {
$comments = "invalid account, should be one active package but found: ".
scalar(@cust_pkg). " packages.";
}
} else {
$comments =
"Customer not found agent_custid=$agent_custid, agentnum=$agentnum";
}
my $cust_recon = new FS::cust_recon( {
'recondate' => time,
'agentnum' => $agentnum,
'first' => $first,
'last' => $last,
'address1' => $address1,
'address2' => $address2,
'city' => $city,
'state' => $state,
'zip' => $zip,
'custnum' => $cust_main ? $cust_main->custnum : '', #really?
'status' => $cust_main ? $cust_main->status : '',
'pkg' => $package,
'adjourn' => $cust_pkg ? $cust_pkg->adjourn : '',
'agent_custid' => $agent_custid, # redundant?
'agent_pkg' => $pkg,
'agent_adjourn' => str2time($adjourn),
'comments' => $comments,
} );
warn Dumper($cust_recon) if $DEBUG;
my $error = $cust_recon->insert;
return $error if $error;
warn "process_recon_record returning $comments\n" if $DEBUG;
$comments;
}
sub check_username {
my $p = shift;
my $session = _cache->get($p->{'session_id'})
or return { 'error' => "Can't resume session" }; #better error message
my $svc_domain = qsearchs( 'svc_domain', { 'domain' => $p->{domain} } )
or return { 'error' => 'Unknown domain '. $p->{domain} };
my $svc_acct = qsearchs( 'svc_acct', { 'username' => $p->{user},
'domsvc' => $svc_domain->svcnum,
},
);
return { 'error' => $p->{user}. '@'. $p->{domain}. " alerady in use" } # sic
if $svc_acct;
return { 'error' => '',
'message' => $p->{user}. '@'. $p->{domain}. " is free"
};
}
1;
- Previous message: [freeside-commits] freeside/fs_selfservice/FS-SelfService/cgi overlibmws_crossframe.js, NONE, 1.1 overlibmws_draggable.js, NONE, 1.1 overlibmws_iframe.js, NONE, 1.1 overlibmws.js, NONE, 1.1 iframecontentmws.js, NONE, 1.1
- Next message: [freeside-commits] freeside/FS/FS cust_recon.pm, NONE, 1.1 Conf.pm, 1.285, 1.286 Schema.pm, 1.140, 1.141 cust_main.pm, 1.425, 1.426 cust_pkg.pm, 1.127, 1.128 svc_acct.pm, 1.258, 1.259
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the freeside-commits
mailing list