$self->invoicing_list( $invoicing_list );
}
+ if ( $conf->config('cust_main-skeleton_tables')
+ && $conf->config('cust_main-skeleton_custnum') ) {
+
+ warn " inserting skeleton records\n"
+ if $DEBUG > 1;
+
+ my $error = $self->start_copy_skel;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+
+ }
+
warn " ordering packages\n"
if $DEBUG > 1;
}
+sub start_copy_skel {
+ my $self = shift;
+
+ #'mg_user_preference' => {},
+ #'mg_user_indicator_profile' => { 'mg_profile_indicator' => { 'mg_profile_details' }, },
+ #'mg_watchlist_header' => { 'mg_watchlist_details' },
+ #'mg_user_grid_header' => { 'mg_user_grid_details' },
+ #'mg_portfolio_header' => { 'mg_portfolio_trades' => { 'mg_portfolio_trades_positions' } },
+ my @tables = eval($conf->config('cust_main-skeleton_tables'));
+ die $@ if $@;
+
+ _copy_skel( 'cust_main', #tablename
+ $conf->config('cust_main-skeleton_custnum'), #sourceid
+ $self->custnum, #destid
+ @tables, #child tables
+ );
+}
+
+#recursive subroutine, not a method
+sub _copy_skel {
+ my( $table, $sourceid, $destid, %child_tables ) = @_;
+
+ my $dbdef_table = dbdef->table($table);
+ my $primary_key = $dbdef_table->primary_key
+ or return "$table has no primary key".
+ " (or do you need to run dbdef-create?)";
+
+ foreach my $child_table ( keys %child_tables ) {
+
+ my $child_pkey = dbdef->table($child_table)->primary_key;
+ # or return "$table has no primary key".
+ # " (or do you need to run dbdef-create?)\n";
+ my $sequence = '';
+ if ( keys %{ $child_tables{$child_table} } ) {
+
+ return "$child_table has no primary key\n" unless $child_pkey;
+
+ #false laziness w/Record::insert and only works on Pg
+ #refactor the proper last-inserted-id stuff out of Record::insert if this
+ # ever gets use for anything besides a quick kludge for one customer
+ my $default = dbdef->table($child_table)->column($child_pkey)->default;
+ $default =~ /^nextval\(\(?'"?([\w\.]+)"?'/i
+ or return "can't parse $child_table.$child_pkey default value ".
+ " for sequence name: $default";
+ $sequence = $1;
+
+ }
+
+ my @sel_columns = grep { $_ ne $primary_key } dbdef->table($table)->columns;
+ my $sel_columns = ' ( '. join(', ', @sel_columns ). ' ) ';
+
+ my @ins_columns = grep { $_ ne $child_pkey } @sel_columns;
+ my $ins_columns = ' ( ', join(', ', $primary_key, @ins_columns ). ' ) ',
+ my $placeholders = ' ( ?, '. join(', ', map '?', @ins_columns ). ' ) ';
+
+ my $sel_sth = dbh->prepare( "SELECT $sel_columns FROM $child_table".
+ " WHERE $primary_key = $sourceid")
+ or return dbh->errstr;
+
+ $sel_sth->execute or return $sel_sth->errstr;
+
+ while ( my $row = $sel_sth->fetchrow_hashref ) {
+
+ my $ins_sth =
+ dbh->prepare("INSERT INTO $child_table $ins_columns".
+ " VALUES $placeholders")
+ or return dbh->errstr;
+ $ins_sth->execute( $destid, map $row->{$_}, @ins_columns )
+ or return $ins_sth->errstr;
+
+ #next unless keys %{ $child_tables{$child_table} };
+ next unless $sequence;
+
+ #another section of that laziness
+ my $seq_sql = "SELECT currval('$sequence')";
+ my $seq_sth = dbh->prepare($seq_sql) or return dbh->errstr;
+ $seq_sth->execute or return $seq_sth->errstr;
+ my $insertid = $seq_sth->fetchrow_arrayref->[0];
+
+ # don't drink soap! recurse! recurse! okay!
+ my $error =
+ _copy_skel( $child_table,
+ $row->{$child_pkey}, #sourceid
+ $insertid, #destid
+ %{ $child_tables{$child_table} },
+ );
+ return $error if $error;
+
+ }
+
+ }
+
+ return '';
+
+}
+
=item order_pkgs HASHREF, [ SECONDSREF, [ , OPTION => VALUE ... ] ]
Like the insert method on an existing record, this method orders a package
my $dbh = dbh;
my $queue = new FS::queue { 'job' => 'FS::cust_main::append_fuzzyfiles' };
- my $error = $queue->insert($self->getfield('last'), $self->company);
+ my $error = $queue->insert( map $self->getfield($_),
+ qw(first last company)
+ );
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return "queueing job (transaction rolled back): $error";
}
- if ( defined $self->dbdef_table->column('ship_last') && $self->ship_last ) {
+ if ( $self->ship_last ) {
$queue = new FS::queue { 'job' => 'FS::cust_main::append_fuzzyfiles' };
- $error = $queue->insert($self->getfield('ship_last'), $self->ship_company);
+ $error = $queue->insert( map $self->getfield("ship_$_"),
+ qw(first last company)
+ );
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return "queueing job (transaction rolled back): $error";
or die "can't open $dir/cust_main.$fuzzy: $!";
flock(LOCK,LOCK_EX)
or die "can't lock $dir/cust_main.$fuzzy: $!";
-
- my @all = map $_->getfield($fuzzy), qsearch('cust_main', {});
- push @all,
- grep $_, map $_->getfield("ship_$fuzzy"), qsearch('cust_main',{});
-
+
open (CACHE,">$dir/cust_main.$fuzzy.tmp")
or die "can't open $dir/cust_main.$fuzzy.tmp: $!";
- print CACHE join("\n", @all), "\n";
+
+ foreach my $field ( $fuzzy, "ship_$fuzzy" ) {
+ my $sth = dbh->prepare("SELECT $field FROM cust_main".
+ " WHERE $field != '' AND $field IS NOT NULL");
+ $sth->execute or die $sth->errstr;
+
+ while ( my $row = $sth->fetchrow_arrayref ) {
+ print CACHE $row->[0]. "\n";
+ }
+
+ }
+
close CACHE or die "can't close $dir/cust_main.$fuzzy.tmp: $!";
rename "$dir/cust_main.$fuzzy.tmp", "$dir/cust_main.$fuzzy";
=cut
sub append_fuzzyfiles {
- my( $last, $company ) = @_;
+ #my( $first, $last, $company ) = @_;
&check_and_rebuild_fuzzyfiles;
my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc;
- if ( $last ) {
-
- open(LAST,">>$dir/cust_main.last")
- or die "can't open $dir/cust_main.last: $!";
- flock(LAST,LOCK_EX)
- or die "can't lock $dir/cust_main.last: $!";
-
- print LAST "$last\n";
-
- flock(LAST,LOCK_UN)
- or die "can't unlock $dir/cust_main.last: $!";
- close LAST;
- }
+ foreach my $field (qw( first last company )) {
+ my $value = shift;
- if ( $company ) {
+ if ( $value ) {
- open(COMPANY,">>$dir/cust_main.company")
- or die "can't open $dir/cust_main.company: $!";
- flock(COMPANY,LOCK_EX)
- or die "can't lock $dir/cust_main.company: $!";
+ open(CACHE,">>$dir/cust_main.$field")
+ or die "can't open $dir/cust_main.$field: $!";
+ flock(CACHE,LOCK_EX)
+ or die "can't lock $dir/cust_main.$field: $!";
- print COMPANY "$company\n";
+ print CACHE "$value\n";
- flock(COMPANY,LOCK_UN)
- or die "can't unlock $dir/cust_main.company: $!";
+ flock(CACHE,LOCK_UN)
+ or die "can't unlock $dir/cust_main.$field: $!";
+ close CACHE;
+ }
- close COMPANY;
}
1;
#warn join('-',keys %$param);
my $fh = $param->{filehandle};
my $agentnum = $param->{agentnum};
+
my $refnum = $param->{refnum};
my $pkgpart = $param->{pkgpart};
- my @fields = @{$param->{fields}};
+
+ #my @fields = @{$param->{fields}};
+ my $format = $param->{'format'};
+ my @fields;
+ my $payby;
+ if ( $format eq 'simple' ) {
+ @fields = qw( cust_pkg.setup dayphone first last
+ address1 address2 city state zip comments );
+ $payby = 'BILL';
+ } elsif ( $format eq 'extended' ) {
+ @fields = qw( agent_custid refnum
+ last first address1 address2 city state zip country
+ daytime night
+ ship_last ship_first ship_address1 ship_address2
+ ship_city ship_state ship_zip ship_country
+ payinfo paycvv paydate
+ invoicing_list
+ cust_pkg.pkgpart
+ svc_acct.username svc_acct._password
+ );
+ $payby = 'CARD';
+ } else {
+ die "unknown format $format";
+ }
eval "use Text::CSV_XS;";
die $@ if $@;
agentnum => $agentnum,
refnum => $refnum,
country => $conf->config('countrydefault') || 'US',
- payby => 'BILL', #default
+ payby => $payby, #default
paydate => '12/2037', #default
);
my $billtime = time;
my %cust_pkg = ( pkgpart => $pkgpart );
+ my %svc_acct = ();
foreach my $field ( @fields ) {
- if ( $field =~ /^cust_pkg\.(setup|bill|susp|expire|cancel)$/ ) {
+
+ if ( $field =~ /^cust_pkg\.(pkgpart|setup|bill|susp|expire|cancel)$/ ) {
+
#$cust_pkg{$1} = str2time( shift @$columns );
- if ( $1 eq 'setup' ) {
+ if ( $1 eq 'pkgpart' ) {
+ $cust_pkg{$1} = shift @columns;
+ } elsif ( $1 eq 'setup' ) {
$billtime = str2time(shift @columns);
} else {
$cust_pkg{$1} = str2time( shift @columns );
- }
+ }
+
+ } elsif ( $field =~ /^svc_acct\.(username|_password)$/ ) {
+
+ $svc_acct{$1} = shift @columns;
+
} else {
+
+ #refnum interception
+ if ( $field eq 'refnum' && $columns[0] !~ /^\s*(\d+)\s*$/ ) {
+
+ my $referral = $columns[0];
+ my $part_referral = new FS::part_referral {
+ 'referral' => $referral,
+ 'agentnum' => $agentnum,
+ };
+
+ my $error = $part_referral->insert;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "can't auto-insert advertising source: $referral: $error";
+ }
+ $columns[0] = $part_referral->refnum;
+ }
+
#$cust_main{$field} = shift @$columns;
$cust_main{$field} = shift @columns;
}
}
- my $cust_pkg = new FS::cust_pkg ( \%cust_pkg ) if $pkgpart;
+ my $invoicing_list = $cust_main{'invoicing_list'}
+ ? [ delete $cust_main{'invoicing_list'} ]
+ : [];
+
my $cust_main = new FS::cust_main ( \%cust_main );
+
use Tie::RefHash;
tie my %hash, 'Tie::RefHash'; #this part is important
- $hash{$cust_pkg} = [] if $pkgpart;
- my $error = $cust_main->insert( \%hash );
- if ( $error ) {
- $dbh->rollback if $oldAutoCommit;
- return "can't insert customer for $line: $error";
+ if ( $cust_pkg{'pkgpart'} ) {
+ my $cust_pkg = new FS::cust_pkg ( \%cust_pkg );
+
+ my @svc_acct = ();
+ if ( $svc_acct{'username'} ) {
+ $svc_acct{svcpart} = $cust_pkg->part_pkg->svcpart( 'svc_acct' );
+ push @svc_acct, new FS::svc_acct ( \%svc_acct )
+ }
+
+ $hash{$cust_pkg} = \@svc_acct;
}
- #false laziness w/bill.cgi
- $error = $cust_main->bill( 'time' => $billtime );
+ my $error = $cust_main->insert( \%hash, $invoicing_list );
+
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
- return "can't bill customer for $line: $error";
+ return "can't insert customer for $line: $error";
}
- $cust_main->apply_payments;
- $cust_main->apply_credits;
+ if ( $format eq 'simple' ) {
+
+ #false laziness w/bill.cgi
+ $error = $cust_main->bill( 'time' => $billtime );
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "can't bill customer for $line: $error";
+ }
+
+ $cust_main->apply_payments;
+ $cust_main->apply_credits;
+
+ $error = $cust_main->collect();
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "can't collect customer for $line: $error";
+ }
- $error = $cust_main->collect();
- if ( $error ) {
- $dbh->rollback if $oldAutoCommit;
- return "can't collect customer for $line: $error";
}
$imported++;