X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_credit.pm;h=96789343ab0732a51e04028b36d25dbc0686b773;hb=6422e165313ee8d67790007581821217240734fb;hp=7741bbee299e5cd09ef5c91eb42fe0f2aa1a9a92;hpb=95cef2cea4c98d8fde7f58bacce3cf1da955c1a0;p=freeside.git diff --git a/FS/FS/cust_credit.pm b/FS/FS/cust_credit.pm index 7741bbee2..96789343a 100644 --- a/FS/FS/cust_credit.pm +++ b/FS/FS/cust_credit.pm @@ -7,7 +7,7 @@ use vars qw( $conf $unsuspendauto $me $DEBUG ); use List::Util qw( min ); use Date::Format; -use FS::UID qw( dbh getotaker ); +use FS::UID qw( dbh ); use FS::Misc qw(send_email); use FS::Record qw( qsearch qsearchs dbdef ); use FS::CurrentUser; @@ -19,6 +19,9 @@ use FS::part_pkg; use FS::reason_type; use FS::reason; use FS::cust_event; +use FS::agent; +use FS::sales; +use FS::cust_credit_void; $me = '[ FS::cust_credit ]'; $DEBUG = 0; @@ -201,6 +204,8 @@ the void method instead to leave a record of the deleted credit. # very similar to FS::cust_pay::delete sub delete { my $self = shift; + my %opt = @_; + return "Can't delete closed credit" if $self->closed =~ /^Y/i; local $SIG{HUP} = 'IGNORE'; @@ -236,7 +241,7 @@ sub delete { return $error; } - if ( $conf->config('deletecredits') ne '' ) { + if ( !$opt{void} and $conf->config('deletecredits') ne '' ) { my $cust_main = $self->cust_main; @@ -311,6 +316,9 @@ sub check { || $self->ut_enum('closed', [ '', 'Y' ]) || $self->ut_foreign_keyn('pkgnum', 'cust_pkg', 'pkgnum') || $self->ut_foreign_keyn('eventnum', 'cust_event', 'eventnum') + || $self->ut_foreign_keyn('commission_agentnum', 'agent', 'agentnum') + || $self->ut_foreign_keyn('commission_salesnum', 'sales', 'salesnum') + || $self->ut_foreign_keyn('commission_pkgnum', 'cust_pkg', 'pkgnum') ; return $error if $error; @@ -331,6 +339,53 @@ sub check { $self->SUPER::check; } +=item void [ REASON ] + +Voids this credit: deletes the credit and all associated applications and +adds a record of the voided credit to the cust_credit_void table. + +=cut + +# yes, false laziness with cust_pay and cust_bill +# but frankly I don't have time to fix it now + +sub void { + my $self = shift; + my $reason = 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; + + my $cust_credit_void = new FS::cust_credit_void ( { + map { $_ => $self->get($_) } $self->fields + } ); + $cust_credit_void->set('void_reason', $reason); + my $error = $cust_credit_void->insert; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + $error = $self->delete(void => 1); # suppress deletecredits warning + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + + ''; + +} + =item cust_credit_refund Returns all refund applications (see L) for this credit. @@ -717,6 +772,7 @@ sub credit_lineitems { my %cust_bill_pkg = (); my %cust_credit_bill_pkg = (); my %taxlisthash = (); + my %unapplied_payments = (); #invoice numbers, and then billpaynums foreach my $billpkgnum ( @{$arg{billpkgnums}} ) { my $setuprecur = shift @{$arg{setuprecurs}}; my $amount = shift @{$arg{amounts}}; @@ -744,7 +800,6 @@ sub credit_lineitems { push @{$cust_bill_pkg{$invnum}}, $cust_bill_pkg; - my %unapplied_payments; # billpaynum => amount #unapply any payments applied to this line item (other credits too?) foreach my $cust_bill_pay_pkg ( $cust_bill_pkg->cust_bill_pay_pkg($setuprecur) ) { $error = $cust_bill_pay_pkg->delete; @@ -752,31 +807,9 @@ sub credit_lineitems { $dbh->rollback if $oldAutoCommit; return "Error unapplying payment: $error"; } - $unapplied_payments{$cust_bill_pay_pkg->billpaynum} + $unapplied_payments{$invnum}{$cust_bill_pay_pkg->billpaynum} += $cust_bill_pay_pkg->amount; } - # also unapply that amount from the invoice so it doesn't screw up - # application of the credit - foreach my $billpaynum (keys %unapplied_payments) { - my $cust_bill_pay = FS::cust_bill_pay->by_key($billpaynum) - or die "broken payment application $billpaynum"; - $error = $cust_bill_pay->delete; # can't replace - - my $new_cust_bill_pay = FS::cust_bill_pay->new({ - $cust_bill_pay->hash, - billpaynum => '', - amount => sprintf('%.2f', - $cust_bill_pay->amount - $unapplied_payments{$billpaynum}), - }); - - if ( $new_cust_bill_pay->amount > 0 ) { - $error ||= $new_cust_bill_pay->insert; - } - if ( $error ) { - $dbh->rollback if $oldAutoCommit; - return "Error unapplying payment: $error"; - } - } #$subtotal += $amount; $cust_credit_bill{$invnum} += $amount; @@ -904,8 +937,53 @@ sub credit_lineitems { }; } # if $amount > 0 + + #unapply any payments applied to the tax + foreach my $cust_bill_pay_pkg + ( $tax_item->cust_bill_pay_pkg('setup') ) + { + $error = $cust_bill_pay_pkg->delete; + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error unapplying payment: $error"; + } + $unapplied_payments{$invnum}{$cust_bill_pay_pkg->billpaynum} + += $cust_bill_pay_pkg->amount; + } } #foreach $taxline + # if we unapplied any payments from line items, also unapply that + # amount from the invoice + foreach my $billpaynum (keys %{$unapplied_payments{$invnum}}) { + my $cust_bill_pay = FS::cust_bill_pay->by_key($billpaynum) + or die "broken payment application $billpaynum"; + my @subapps = $cust_bill_pay->lineitem_applications; + $error = $cust_bill_pay->delete; # can't replace + + my $new_cust_bill_pay = FS::cust_bill_pay->new({ + $cust_bill_pay->hash, + billpaynum => '', + amount => sprintf('%.2f', + $cust_bill_pay->amount + - $unapplied_payments{$invnum}{$billpaynum}), + }); + + if ( $new_cust_bill_pay->amount > 0 ) { + $error ||= $new_cust_bill_pay->insert; + # Also reapply it to everything it was applied to before. + # Note that we've already deleted cust_bill_pay_pkg records for the + # items we're crediting, so they aren't on this list. + foreach my $cust_bill_pay_pkg (@subapps) { + $cust_bill_pay_pkg->billpaypkgnum(''); + $cust_bill_pay_pkg->billpaynum($new_cust_bill_pay->billpaynum); + $error ||= $cust_bill_pay_pkg->insert; + } + } + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return "Error unapplying payment: $error"; + } + } #insert cust_credit_bill my $cust_credit_bill = new FS::cust_credit_bill {