summaryrefslogtreecommitdiff
path: root/FS/FS/cust_pay.pm
diff options
context:
space:
mode:
authorjeff <jeff>2010-09-22 19:16:20 +0000
committerjeff <jeff>2010-09-22 19:16:20 +0000
commit5250c44bd7f282c7d782bf0e8349af12376929df (patch)
treeb2afcd8e47270c6f5b78cff378849168d17ed765 /FS/FS/cust_pay.pm
parent60ee9af0e885def0dd61f4a5506ac0e55d779e89 (diff)
prepayment discounts rt#5318
Diffstat (limited to 'FS/FS/cust_pay.pm')
-rw-r--r--FS/FS/cust_pay.pm53
1 files changed, 53 insertions, 0 deletions
diff --git a/FS/FS/cust_pay.pm b/FS/FS/cust_pay.pm
index 9985f59..e0c99f8 100644
--- a/FS/FS/cust_pay.pm
+++ b/FS/FS/cust_pay.pm
@@ -141,6 +141,10 @@ For backwards-compatibility and convenience, if the additional field invnum
is defined, an FS::cust_bill_pay record for the full amount of the payment
will be created. In this case, custnum is optional.
+If the additional field discount_term is defined then a prepayment discount
+is taken for that length of time. It is an error for the customer to owe
+after this payment is made.
+
A hash of optional arguments may be passed. Currently "manual" is supported.
If true, a payment receipt is sent instead of a statement when
'payment_receipt_email' configuration option is set.
@@ -183,6 +187,51 @@ sub insert {
return "error inserting cust_pay: $error";
}
+ if ( my $credit_type = $conf->config('prepayment_discounts-credit_type') ) {
+ if ( my $months = $self->discount_term ) {
+ #hmmm... error handling
+ my ($credit, $savings, $total) =
+ $cust_main->discount_term_values($months);
+ my $cust_credit = new FS::cust_credit {
+ 'custnum' => $self->custnum,
+ 'amount' => $credit,
+ 'reason' => 'customer chose to prepay for discount',
+ };
+ $error = $cust_credit->insert('reason_type' => $credit_type);
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "error inserting cust_pay: $error";
+ }
+ my @pkgs = $cust_main->_discount_pkgs_and_bill;
+ my $cust_bill = shift(@pkgs);
+ @pkgs = &FS::cust_main::Billing::_discountable_pkgs_at_term($months, @pkgs);
+ $_->bill($_->last_bill) foreach @pkgs;
+ $error = $cust_main->bill(
+ 'recurring_only' => 1,
+ 'time' => $cust_bill->invoice_date,
+ 'no_usage_reset' => 1,
+ 'pkg_list' => \@pkgs,
+ 'freq_override' => $months,
+ );
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "error inserting cust_pay: $error";
+ }
+ $error = $cust_main->apply_payments_and_credits;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "error inserting cust_pay: $error";
+ }
+ my $new_balance = $cust_main->balance;
+ if ($new_balance > 0) {
+ $dbh->rollback if $oldAutoCommit;
+ return "balance after prepay discount attempt: $new_balance";
+ }
+
+ }
+
+ }
+
if ( $self->invnum ) {
my $cust_bill_pay = new FS::cust_bill_pay {
'invnum' => $self->invnum,
@@ -388,6 +437,7 @@ sub check {
|| $self->ut_enum('closed', [ '', 'Y' ])
|| $self->ut_foreign_keyn('pkgnum', 'cust_pkg', 'pkgnum')
|| $self->payinfo_check()
+ || $self->ut_numbern('discount_term')
;
return $error if $error;
@@ -399,6 +449,9 @@ sub check {
$self->_date(time) unless $self->_date;
+ return "invalid discount_term"
+ if ($self->discount_term && $self->discount_term < 2);
+
#i guess not now, with cust_pay_pending, if we actually make it here, we _do_ want to record it
# # UNIQUE index should catch this too, without race conditions, but this
# # should give a better error message the other 99.9% of the time...