use vars qw( @ISA $conf $Debug $import );
use Safe;
use Carp;
-use Time::Local;
+use Time::Local qw(timelocal_nocheck);
use Date::Format;
#use Date::Manip;
use Business::CreditCard;
$import = 0;
#ask FS::UID to run this stuff for us later
-$FS::UID::callback{'FS::cust_main'} = sub {
+#$FS::UID::callback{'FS::cust_main'} = sub {
+install_callback FS::UID sub {
$conf = new FS::Conf;
#yes, need it for stuff below (prolly should be cached)
};
=item ship_fax - phone (optional)
-=item payby - `CARD' (credit cards), `CHEK' (electronic check), `LECB' (Phone bill billing), `BILL' (billing), `COMP' (free), or `PREPAY' (special billing type: applies a credit - see L<FS::prepay_credit> and sets billing type to BILL)
+=item payby - I<CARD> (credit card - automatic), I<DCRD> (credit card - on-demand), I<CHEK> (electronic check - automatic), I<DCHK> (electronic check - on-demand), I<LECB> (Phone bill billing), I<BILL> (billing), I<COMP> (free), or I<PREPAY> (special billing type: applies a credit - see L<FS::prepay_credit> and sets billing type to I<BILL>)
=item payinfo - card number, P.O., comp issuer (4-8 lowercase alphanumerics; think username) or prepayment identifier (see L<FS::prepay_credit>)
}
# packages
- foreach my $cust_pkg ( keys %$cust_pkgs ) {
- $cust_pkg->custnum( $self->custnum );
- $error = $cust_pkg->insert;
- if ( $error ) {
- $dbh->rollback if $oldAutoCommit;
- return "inserting cust_pkg (transaction rolled back): $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 if $oldAutoCommit;
- #return "inserting svc_ (transaction rolled back): $error";
- return $error;
- }
- }
+ $error = $self->order_pkgs($cust_pkgs, \$seconds);
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
}
if ( $seconds ) {
}
+=item order_pkgs
+
+document me. like ->insert(%cust_pkg) on an existing record
+
+=cut
+
+sub order_pkgs {
+ my $self = shift;
+ my $cust_pkgs = shift;
+ my $seconds = shift;
+
+ local $SIG{HUP} = 'IGNORE';
+ local $SIG{INT} = 'IGNORE';
+ local $SIG{QUIT} = 'IGNORE';
+ local $SIG{TERM} = 'IGNORE';
+ local $SIG{TSTP} = 'IGNORE';
+ local $SIG{PIPE} = 'IGNORE';
+
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
+ foreach my $cust_pkg ( keys %$cust_pkgs ) {
+ $cust_pkg->custnum( $self->custnum );
+ my $error = $cust_pkg->insert;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "inserting cust_pkg (transaction rolled back): $error";
+ }
+ foreach my $svc_something ( @{$cust_pkgs->{$cust_pkg}} ) {
+ $svc_something->pkgnum( $cust_pkg->pkgnum );
+ if ( $seconds && $$seconds && $svc_something->isa('FS::svc_acct') ) {
+ $svc_something->seconds( $svc_something->seconds + $$seconds );
+ $$seconds = 0;
+ }
+ $error = $svc_something->insert;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ #return "inserting svc_ (transaction rolled back): $error";
+ return $error;
+ }
+ }
+ }
+
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+ ''; #no error
+}
+
=item delete NEW_CUSTNUM
This deletes the customer. If there is an error, returns the error, otherwise
}
}
- $self->payby =~ /^(CARD|CHEK|LECB|BILL|COMP|PREPAY)$/
+ $self->payby =~ /^(CARD|DCRD|CHEK|DCHK|LECB|BILL|COMP|PREPAY)$/
or return "Illegal payby: ". $self->payby;
$self->payby($1);
- if ( $self->payby eq 'CARD' ) {
+ if ( $self->payby eq 'CARD' || $self->payby eq 'DCRD' ) {
my $payinfo = $self->payinfo;
$payinfo =~ s/\D//g;
return gettext('unknown_card_type')
if cardtype($self->payinfo) eq "Unknown";
- } elsif ( $self->payby eq 'CHEK' ) {
+ } elsif ( $self->payby eq 'CHEK' || $self->payby eq 'DCHK' ) {
my $payinfo = $self->payinfo;
$payinfo =~ s/[^\d\@]//g;
}
if ( $self->payname eq '' && $self->payby ne 'CHEK' &&
- ( ! $conf->exists('require_cardname') || $self->payby ne 'CARD' ) ) {
+ ( ! $conf->exists('require_cardname')
+ || $self->payby !~ /^(CARD|DCRD)$/ )
+ ) {
$self->payname( $self->first. " ". $self->getfield('last') );
} else {
$self->payname =~ /^([\w \,\.\-\']+)$/
my %hash = $cust_pkg->hash;
my $old_cust_pkg = new FS::cust_pkg \%hash;
+ my @details = ();
+
# bill setup
my $setup = 0;
unless ( $cust_pkg->setup ) {
": $setup_prog";
};
$setup_prog = $1;
+ $setup_prog = '0' if $setup_prog =~ /^\s*$/;
#my $cpt = new Safe;
##$cpt->permit(); #what is necessary?
my $sdate;
if ( $part_pkg->getfield('freq') > 0 &&
! $cust_pkg->getfield('susp') &&
- ( $cust_pkg->getfield('bill') || 0 ) < $time
+ ( $cust_pkg->getfield('bill') || 0 ) <= $time
) {
my $recur_prog = $part_pkg->getfield('recur');
$recur_prog =~ /^(.*)$/ or do {
": $recur_prog";
};
$recur_prog = $1;
+ $recur_prog = '0' if $recur_prog =~ /^\s*$/;
# shared with $recur_prog
$sdate = $cust_pkg->bill || $cust_pkg->setup || $time;
# only for figuring next bill date, nothing else, so, reset $sdate again
# here
$sdate = $cust_pkg->bill || $cust_pkg->setup || $time;
+ $cust_pkg->last_bill($sdate)
+ if $cust_pkg->dbdef_table->column('last_bill');
$mon += $part_pkg->freq;
until ( $mon < 12 ) { $mon -= 12; $year++; }
$cust_pkg->setfield('bill',
- timelocal($sec,$min,$hour,$mday,$mon,$year));
+ timelocal_nocheck($sec,$min,$hour,$mday,$mon,$year));
$cust_pkg_mod_flag = 1;
}
}
if ( $setup > 0 || $recur > 0 ) {
my $cust_bill_pkg = new FS::cust_bill_pkg ({
- 'pkgnum' => $cust_pkg->pkgnum,
- 'setup' => $setup,
- 'recur' => $recur,
- 'sdate' => $sdate,
- 'edate' => $cust_pkg->bill,
+ 'pkgnum' => $cust_pkg->pkgnum,
+ 'setup' => $setup,
+ 'recur' => $recur,
+ 'sdate' => $sdate,
+ 'edate' => $cust_pkg->bill,
+ 'details' => \@details,
});
push @cust_bill_pkg, $cust_bill_pkg;
$total_setup += $setup;
(Attempt to) collect money for this customer's outstanding invoices (see
L<FS::cust_bill>). Usually used after the bill method.
-Depending on the value of `payby', this may print an invoice (`BILL'), charge
-a credit card (`CARD'), or just add any necessary (pseudo-)payment (`COMP').
+Depending on the value of `payby', this may print or email an invoice (I<BILL>,
+I<DCRD>, or I<DCHK>), charge a credit card (I<CARD>), charge via electronic
+check/ACH (I<CHEK>), or just add any necessary (pseudo-)payment (I<COMP>).
Most actions are now triggered by invoice events; see L<FS::part_bill_event>
and the invoice events web interface.