diff options
Diffstat (limited to 'FS')
-rw-r--r-- | FS/FS/Record.pm | 11 | ||||
-rw-r--r-- | FS/FS/UID.pm | 7 | ||||
-rw-r--r-- | FS/FS/cust_main.pm | 101 |
3 files changed, 91 insertions, 28 deletions
diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm index 282c5ff16..dd8cc542c 100644 --- a/FS/FS/Record.pm +++ b/FS/FS/Record.pm @@ -176,7 +176,7 @@ sub qsearch { my $statement = "SELECT $select FROM $table"; if ( @fields ) { - $statement .= " WHERE ". join(' AND ', map { + $statement .= ' WHERE '. join(' AND ', map { if ( ! defined( $record->{$_} ) || $record->{$_} eq '' ) { if ( driver_name eq 'Pg' ) { "$_ IS NULL"; @@ -191,11 +191,13 @@ sub qsearch { $statement .= " $extra_sql" if defined($extra_sql); warn $statement if $DEBUG; - my $sth = $dbh->prepare_cached($statement) or croak $dbh->errstr; + my $sth = $dbh->prepare_cached($statement) + or croak "$dbh->errstr doing $statement"; $sth->execute( map $record->{$_}, grep defined( $record->{$_} ) && $record->{$_} ne '', @fields ) or croak $dbh->errstr; + $dbh->commit or croak $dbh->errstr if $FS::UID::AutoCommit; if ( eval 'scalar(@FS::'. $table. '::ISA);' ) { if ( eval 'FS::'. $table. '->can(\'new\')' eq \&new ) { @@ -387,6 +389,7 @@ sub insert { local $SIG{PIPE} = 'IGNORE'; $sth->execute or return $sth->errstr; + dbh->commit or croak dbh->errstr if $FS::UID::AutoCommit; ''; } @@ -436,6 +439,7 @@ sub delete { my $rc = $sth->execute or return $sth->errstr; #not portable #return "Record not found, statement:\n$statement" if $rc eq "0E0"; + dbh->commit or croak dbh->errstr if $FS::UID::AutoCommit; undef $self; #no need to keep object! @@ -507,6 +511,7 @@ sub replace { my $rc = $sth->execute or return $sth->errstr; #not portable #return "Record not found (or records identical)." if $rc eq "0E0"; + dbh->commit or croak dbh->errstr if $FS::UID::AutoCommit; ''; @@ -908,7 +913,7 @@ sub DESTROY { return; } =head1 VERSION -$Id: Record.pm,v 1.11 2000-12-06 10:21:13 ivan Exp $ +$Id: Record.pm,v 1.12 2001-02-03 14:03:49 ivan Exp $ =head1 BUGS diff --git a/FS/FS/UID.pm b/FS/FS/UID.pm index 88d733829..5cb5572af 100644 --- a/FS/FS/UID.pm +++ b/FS/FS/UID.pm @@ -4,6 +4,7 @@ use strict; use vars qw( @ISA @EXPORT_OK $cgi $dbh $freeside_uid $user $conf_dir $secrets $datasrc $db_user $db_pass %callback $driver_name + $AutoCommit ); use subs qw( getsecrets cgisetotaker @@ -21,6 +22,8 @@ $freeside_uid = scalar(getpwnam('freeside')); $conf_dir = "/usr/local/etc/freeside/"; +$AutoCommit = 1; #ours, not DBI + =head1 NAME FS::UID - Subroutines for database login and assorted other stuff @@ -76,7 +79,7 @@ sub adminsuidsetup { croak "Not running uid freeside!" unless checkeuid(); getsecrets; $dbh = DBI->connect($datasrc,$db_user,$db_pass, { - 'AutoCommit' => 'true', + 'AutoCommit' => 'false', 'ChopBlanks' => 'true', } ) or die "DBI->connect error: $DBI::errstr\n"; @@ -256,7 +259,7 @@ coderef into the hash %FS::UID::callback : =head1 VERSION -$Id: UID.pm,v 1.3 2000-06-23 12:25:59 ivan Exp $ +$Id: UID.pm,v 1.4 2001-02-03 14:03:49 ivan Exp $ =head1 BUGS diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index e50ea7198..7b75bea1e 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -15,7 +15,7 @@ use Date::Format; use Mail::Internet; use Mail::Header; use Business::CreditCard; -use FS::UID qw( getotaker ); +use FS::UID qw( getotaker dbh ); use FS::Record qw( qsearchs qsearch ); use FS::cust_pkg; use FS::cust_bill; @@ -183,17 +183,24 @@ sub table { 'cust_main'; } Adds this customer to the database. If there is an error, returns the error, otherwise returns false. +There is a special insert mode in which you pass a data structure to the insert +method containing FS::cust_pkg and FS::svc_I<tablename> objects. When +running under a transactional database, all records are inserted atomicly, or +the transaction is rolled back. 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->insert( \%hash ); + =cut sub insert { my $self = shift; - my $flag = 0; - if ( $self->payby eq 'PREPAY' ) { - $self->payby('BILL'); - $flag = 1; - } - local $SIG{HUP} = 'IGNORE'; local $SIG{INT} = 'IGNORE'; local $SIG{QUIT} = 'IGNORE'; @@ -201,30 +208,78 @@ sub insert { local $SIG{TSTP} = 'IGNORE'; local $SIG{PIPE} = 'IGNORE'; - my $error = $self->SUPER::insert; - return $error if $error; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; - if ( $flag ) { - my $prepay_credit = - qsearchs('prepay_credit', { 'identifier' => $self->payinfo } ); + my $amount = 0; + my $seconds = 0; + if ( $self->payby eq 'PREPAY' ) { + $self->payby('BILL'); + my $prepay_credit = qsearchs( + 'prepay_credit', + { 'identifier' => $self->payinfo }, + '', + 'FOR UPDATE' + ); warn "WARNING: can't find pre-found prepay_credit: ". $self->payinfo unless $prepay_credit; - my $amount = $prepay_credit->amount; + $amount = $prepay_credit->amount; + $seconds = $prepay_credit->seconds; my $error = $prepay_credit->delete; if ( $error ) { - warn "WARNING: can't delete prepay_credit: ". $self->payinfo; - } else { - my $cust_credit = new FS::cust_credit { - 'custnum' => $self->custnum, - 'amount' => $amount, - }; - my $error = $cust_credit->insert; - warn "WARNING: error inserting cust_credit for prepay_credit: $error" - if $error; + $dbh->rollback; + return $error; + } + } + + my $error = $self->SUPER::insert; + if ( $error ) { + $dbh->rollback; + return $error; + } + + if ( @_ ) { + my $cust_pkgs = shift; + foreach my $cust_pkg ( keys %$cust_pkgs ) { + $cust_pkg->custnum( $self->custnum ); + $error = $cust_pkg->insert; + if ( $error ) { + $dbh->rollback; + return $error; + } + foreach my $svc_something ( @{$cust_pkgs->{$cust_pkg}} ) { + $svc_something->pkgnum( $cust_pkg->pkgnum ); + if ( $seconds && $svc_something->isa('FS::svc_acct') ) { + $svc_something->seconds( $svc_something->seconds + $seconds ); + $seconds = 0; + } + $error = $svc_something->insert; + if ( $error ) { + $dbh->rollback; + return $error; + } + } } + } + + if ( $seconds ) { + $dbh->rollback; + return "No svc_acct record to apply pre-paid time"; + } + if ( $amount ) { + my $cust_credit = new FS::cust_credit { + 'custnum' => $self->custnum, + 'amount' => $amount, + }; + $error = $cust_credit->insert; + if ( $error ) { + $dbh->rollback; + return $error; + } } + $dbh->commit or die $dbh->errstr; ''; } @@ -999,7 +1054,7 @@ sub check_invoicing_list { =head1 VERSION -$Id: cust_main.pm,v 1.9 2001-01-31 07:21:00 ivan Exp $ +$Id: cust_main.pm,v 1.10 2001-02-03 14:03:50 ivan Exp $ =head1 BUGS |