summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorivan <ivan>2004-06-29 04:02:45 +0000
committerivan <ivan>2004-06-29 04:02:45 +0000
commit157e8bdba110b7aac022bd2c2f7b377d3c5b2f85 (patch)
tree9dc49439d40ebbbeeea1db3f48fdd6ee7602cb34
parentf1e474e3ea4c658b9a1f84af108f09a65886055c (diff)
add cust_pay_refund table to refund payments
-rw-r--r--ANNOUNCE.1.5.010
-rw-r--r--FS/FS.pm6
-rw-r--r--FS/FS/cust_bill_pay.pm69
-rw-r--r--FS/FS/cust_credit_bill.pm2
-rw-r--r--FS/FS/cust_credit_refund.pm58
-rw-r--r--FS/FS/cust_pay.pm20
-rw-r--r--FS/FS/cust_pay_refund.pm187
-rw-r--r--FS/FS/cust_refund.pm105
-rw-r--r--FS/MANIFEST2
-rwxr-xr-xFS/bin/freeside-setup15
-rw-r--r--FS/t/cust_pay_refund.t5
-rw-r--r--README.1.5.0pre615
-rw-r--r--httemplate/docs/upgrade10.html20
-rwxr-xr-xhttemplate/edit/cust_bill_pay.cgi8
-rwxr-xr-xhttemplate/edit/process/cust_bill_pay.cgi24
-rwxr-xr-xhttemplate/view/cust_main.cgi40
16 files changed, 421 insertions, 165 deletions
diff --git a/ANNOUNCE.1.5.0 b/ANNOUNCE.1.5.0
new file mode 100644
index 0000000..d1c6f23
--- /dev/null
+++ b/ANNOUNCE.1.5.0
@@ -0,0 +1,10 @@
+- broadband (dsl/wireless) tracking, etc etc
+- Extended description on invoice for time/data charges
+- Multiple, named taxes
+- */*FIX
+- extended reported and graphing
+- integrated RT ticketing system
+- one-time payments (in signup server too). DCRD and DCHK on-demand payment types
+- credit report
+- reseller interface
+- cust_pay_refund and credit card refund w/supported processor
diff --git a/FS/FS.pm b/FS/FS.pm
index 6c560d9..67cb1f8 100644
--- a/FS/FS.pm
+++ b/FS/FS.pm
@@ -122,9 +122,11 @@ L<FS::cust_credit> - Credit class
L<FS::cust_refund> - Refund class
-L<FS::cust_credit_refund> - Refund application class
+L<FS::cust_credit_refund> - Refund application to credit class
-L<FS::cust_credit_bill> - Credit invoice application class
+L<FS::cust_credit_bill> - Credit application to invoice class
+
+L<FS::cust_pay_refund> - Refund application to payment class
L<FS::cust_pay_batch> - Credit card transaction queue class
diff --git a/FS/FS/cust_bill_pay.pm b/FS/FS/cust_bill_pay.pm
index c8b5525..f0cb132 100644
--- a/FS/FS/cust_bill_pay.pm
+++ b/FS/FS/cust_bill_pay.pm
@@ -74,60 +74,11 @@ otherwise returns false.
sub insert {
my $self = 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 $error = $self->check;
+ my $error = $self->SUPER::insert;
return $error if $error;
- $error = $self->SUPER::insert;
-
- my $cust_pay = qsearchs('cust_pay', { 'paynum' => $self->paynum } ) or do {
- $dbh->rollback if $oldAutoCommit;
- return "unknown cust_pay.paynum: ". $self->paynum;
- };
-
- my $pay_total = 0;
- $pay_total += $_ foreach map { $_->amount }
- qsearch('cust_bill_pay', { 'paynum' => $self->paynum } );
-
- if ( sprintf("%.2f", $pay_total) > sprintf("%.2f", $cust_pay->paid) ) {
- $dbh->rollback if $oldAutoCommit;
- return "total cust_bill_pay.amount $pay_total for paynum ". $self->paynum.
- " greater than cust_pay.paid ". $cust_pay->paid;
- }
-
- my $cust_bill = $self->cust_bill;
- unless ( $cust_bill ) {
- $dbh->rollback if $oldAutoCommit;
- return "unknown cust_bill.invnum: ". $self->invnum;
- };
-
- my $bill_total = 0;
- $bill_total += $_ foreach map { $_->amount }
- qsearch('cust_bill_pay', { 'invnum' => $self->invnum } );
- $bill_total += $_ foreach map { $_->amount }
- qsearch('cust_credit_bill', { 'invnum' => $self->invnum } );
- if ( sprintf("%.2f", $bill_total) > sprintf("%.2f", $cust_bill->charged) ) {
- $dbh->rollback if $oldAutoCommit;
- return "total cust_bill_pay.amount and cust_credit_bill.amount $bill_total".
- " for invnum ". $self->invnum.
- " greater than cust_bill.charged ". $cust_bill->charged;
- }
-
- $dbh->commit or die $dbh->errstr if $oldAutoCommit;
-
- if ( $conf->exists('invoice_send_receipts') ) {
- my $send_error = $cust_bill->send;
+ if ( $conf->exists('invoice_send_receipts') ) {
+ my $send_error = $self->cust_bill->send;
warn "Error sending receipt: $send_error\n" if $send_error;
}
@@ -178,9 +129,23 @@ sub check {
return $error if $error;
return "amount must be > 0" if $self->amount <= 0;
+
+ return "Unknown invoice"
+ unless my $cust_bill =
+ qsearchs( 'cust_bill', { 'invnum' => $self->invnum } );
+
+ return "Unknown payment"
+ unless my $cust_pay =
+ qsearchs( 'cust_pay', { 'paynum' => $self->paynum } );
$self->_date(time) unless $self->_date;
+ return "Cannot apply more than remaining value of invoice"
+ unless $self->amount <= $cust_bill->owed;
+
+ return "Cannot apply more than remaining value of payment"
+ unless $self->amount <= $cust_pay->unapplied;
+
$self->SUPER::check;
}
diff --git a/FS/FS/cust_credit_bill.pm b/FS/FS/cust_credit_bill.pm
index bd76c2e..0e5885f 100644
--- a/FS/FS/cust_credit_bill.pm
+++ b/FS/FS/cust_credit_bill.pm
@@ -38,7 +38,7 @@ FS::cust_credit_bill - Object methods for cust_credit_bill records
=head1 DESCRIPTION
An FS::cust_credit_bill object represents application of a credit (see
-L<FS::cust_credit>) to an invoice (see L<FS::cust_bill>). FS::cust_credit
+L<FS::cust_credit>) to an invoice (see L<FS::cust_bill>). FS::cust_credit_bill
inherits from FS::Record. The following fields are currently supported:
=over 4
diff --git a/FS/FS/cust_credit_refund.pm b/FS/FS/cust_credit_refund.pm
index d0deae2..ff2454d 100644
--- a/FS/FS/cust_credit_refund.pm
+++ b/FS/FS/cust_credit_refund.pm
@@ -70,43 +70,9 @@ otherwise returns false.
sub insert {
my $self = 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 $error = $self->check;
+ my $error = $self->SUPER::insert;
return $error if $error;
- $error = $self->SUPER::insert;
-
- my $cust_refund =
- qsearchs('cust_refund', { 'refundnum' => $self->refundnum } )
- or do {
- $dbh->rollback if $oldAutoCommit;
- return "unknown cust_refund.refundnum: ". $self->refundnum
- };
-
- my $refund_total = 0;
- $refund_total += $_ foreach map { $_->amount }
- qsearch('cust_credit_refund', { 'refundnum' => $self->refundnum } );
-
- if ( $refund_total > $cust_refund->refund ) {
- $dbh->rollback if $oldAutoCommit;
- return "total cust_credit_refund.amount $refund_total for refundnum ".
- $self->refundnum.
- " greater than cust_refund.refund ". $cust_refund->refund;
- }
-
- $dbh->commit or die $dbh->errstr if $oldAutoCommit;
-
'';
}
@@ -132,8 +98,9 @@ sub replace {
=item check
-Checks all fields to make sure this is a valid payment. If there is an error,
-returns the error, otherwise returns false. Called by the insert method.
+Checks all fields to make sure this is a valid refund application. If there is
+an error, returns the error, otherwise returns false. Called by the insert
+method.
=cut
@@ -151,10 +118,21 @@ sub check {
return "amount must be > 0" if $self->amount <= 0;
+ return "unknown cust_credit.crednum: ". $self->crednum
+ unless my $cust_credit =
+ qsearchs( 'cust_credit', { 'crednum' => $self->crednum } );
+
+ return "Unknown refund"
+ unless my $cust_refund =
+ qsearchs( 'cust_refund', { 'refundnum' => $self->refundnum } );
+
$self->_date(time) unless $self->_date;
- return "unknown cust_credit.crednum: ". $self->crednum
- unless qsearchs( 'cust_credit', { 'crednum' => $self->crednum } );
+ return "Cannot apply more than remaining value of credit"
+ unless $self->amount <= $cust_credit->credited;
+
+ return "Cannot apply more than remaining value of refund"
+ unless $self->amount <= $cust_refund->unapplied;
$self->SUPER::check;
}
@@ -185,7 +163,7 @@ sub cust_credit {
=head1 VERSION
-$Id: cust_credit_refund.pm,v 1.10 2003-08-05 00:20:41 khoff Exp $
+$Id: cust_credit_refund.pm,v 1.11 2004-06-29 04:02:44 ivan Exp $
=head1 BUGS
diff --git a/FS/FS/cust_pay.pm b/FS/FS/cust_pay.pm
index ba9924f..111de05 100644
--- a/FS/FS/cust_pay.pm
+++ b/FS/FS/cust_pay.pm
@@ -9,6 +9,7 @@ use FS::Record qw( dbh qsearch qsearchs dbh );
use FS::Misc qw(send_email);
use FS::cust_bill;
use FS::cust_bill_pay;
+use FS::cust_pay_refund;
use FS::cust_main;
@ISA = qw( FS::Record );
@@ -371,10 +372,26 @@ sub cust_bill_pay {
;
}
+=item cust_pay_refund
+
+Returns all applications of refunds (see L<FS::cust_pay_refund>) to this
+payment.
+
+=cut
+
+sub cust_pay_refund {
+ my $self = shift;
+ sort { $a->_date <=> $b->_date }
+ qsearch( 'cust_pay_refund', { 'paynum' => $self->paynum } )
+ ;
+}
+
+
=item unapplied
Returns the amount of this payment that is still unapplied; which is
-paid minus all payment applications (see L<FS::cust_bill_pay>).
+paid minus all payment applications (see L<FS::cust_bill_pay>) and refund
+applications (see L<FS::cust_pay_refund>).
=cut
@@ -382,6 +399,7 @@ sub unapplied {
my $self = shift;
my $amount = $self->paid;
$amount -= $_->amount foreach ( $self->cust_bill_pay );
+ $amount -= $_->amount foreach ( $self->cust_pay_refund );
sprintf("%.2f", $amount );
}
diff --git a/FS/FS/cust_pay_refund.pm b/FS/FS/cust_pay_refund.pm
new file mode 100644
index 0000000..55a5eb7
--- /dev/null
+++ b/FS/FS/cust_pay_refund.pm
@@ -0,0 +1,187 @@
+package FS::cust_pay_refund;
+
+use strict;
+use vars qw( @ISA ); #$conf );
+use FS::UID qw( getotaker );
+use FS::Record qw( qsearchs ); # qsearch );
+use FS::cust_main;
+use FS::cust_pay;
+use FS::cust_refund;
+
+@ISA = qw( FS::Record );
+
+#ask FS::UID to run this stuff for us later
+#FS::UID->install_callback( sub {
+# $conf = new FS::Conf;
+#} );
+
+=head1 NAME
+
+FS::cust_pay_refund - Object methods for cust_pay_refund records
+
+=head1 SYNOPSIS
+
+ use FS::cust_pay_refund;
+
+ $record = new FS::cust_pay_refund \%hash;
+ $record = new FS::cust_pay_refund { 'column' => 'value' };
+
+ $error = $record->insert;
+
+ $error = $new_record->replace($old_record);
+
+ $error = $record->delete;
+
+ $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::cust_pay_refund object represents application of a refund (see
+L<FS::cust_refund>) to an payment (see L<FS::cust_pay>). FS::cust_pay_refund
+inherits from FS::Record. The following fields are currently supported:
+
+=over 4
+
+=item payrefundnum - primary key
+
+=item paynum - credit being applied
+
+=item refundnum - invoice to which credit is applied (see L<FS::cust_bill>)
+
+=item amount - amount of the credit applied
+
+=item _date - specified as a UNIX timestamp; see L<perlfunc/"time">. Also see
+L<Time::Local> and L<Date::Parse> for conversion functions.
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new cust_pay_refund. To add the cust_pay_refund to the database,
+see L<"insert">.
+
+=cut
+
+sub table { 'cust_pay_refund'; }
+
+=item insert
+
+Adds this cust_pay_refund to the database. If there is an error, returns the
+error, otherwise returns false.
+
+=cut
+
+sub insert {
+ my $self = shift;
+ my $error = $self->SUPER::insert(@_);
+ return $error if $error;
+
+ '';
+}
+
+=item delete
+
+=cut
+
+sub delete {
+ my $self = shift;
+ return "Can't apply refund to closed payment"
+ if $self->cust_pay->closed =~ /^Y/i;
+ return "Can't apply closed refund"
+ if $self->cust_refund->closed =~ /^Y/i;
+ $self->SUPER::delete(@_);
+}
+
+=item replace OLD_RECORD
+
+Application of refunds to payments may not be modified.
+
+=cut
+
+sub replace {
+ return "Can't modify application of a refund to payment!"
+}
+
+=item check
+
+Checks all fields to make sure this is a valid refund application to a payment.
+If there is an error, returns the error, otherwise returns false. Called by
+the insert and replace methods.
+
+=cut
+
+sub check {
+ my $self = shift;
+
+ my $error =
+ $self->ut_numbern('payrefundnum')
+ || $self->ut_number('paynum')
+ || $self->ut_number('refundnum')
+ || $self->ut_numbern('_date')
+ || $self->ut_money('amount')
+ ;
+ return $error if $error;
+
+ return "amount must be > 0" if $self->amount <= 0;
+
+ return "Unknown payment"
+ unless my $cust_pay =
+ qsearchs( 'cust_pay', { 'paynum' => $self->paynum } );
+
+ return "Unknown refund"
+ unless my $cust_refund =
+ qsearchs( 'cust_refund', { 'refundnum' => $self->refundnum } );
+
+ $self->_date(time) unless $self->_date;
+
+ return 'Cannot apply ($'. $self->amount. ') more than'.
+ ' remaining value of refund ($'. $cust_refund->unapplied. ')'
+ unless $self->amount <= $cust_refund->unapplied;
+
+ return "Cannot apply more than remaining value of payment"
+ unless $self->amount <= $cust_pay->unapplied;
+
+ $self->SUPER::check;
+}
+
+=item sub cust_credit
+
+Returns the credit (see L<FS::cust_credit>)
+
+=cut
+
+sub cust_credit {
+ my $self = shift;
+ qsearchs( 'cust_credit', { 'crednum' => $self->crednum } );
+}
+
+=item cust_bill
+
+Returns the invoice (see L<FS::cust_bill>)
+
+=cut
+
+sub cust_bill {
+ my $self = shift;
+ qsearchs( 'cust_bill', { 'invnum' => $self->invnum } );
+}
+
+=back
+
+=head1 BUGS
+
+The delete method.
+
+=head1 SEE ALSO
+
+L<FS::Record>, L<FS::cust_refund>, L<FS::cust_bill>, L<FS::cust_credit>,
+schema.html from the base documentation.
+
+=cut
+
+1;
+
diff --git a/FS/FS/cust_refund.pm b/FS/FS/cust_refund.pm
index d60c010..b9f48db 100644
--- a/FS/FS/cust_refund.pm
+++ b/FS/FS/cust_refund.pm
@@ -3,10 +3,11 @@ package FS::cust_refund;
use strict;
use vars qw( @ISA );
use Business::CreditCard;
-use FS::Record qw( qsearchs dbh );
+use FS::Record qw( qsearch qsearchs dbh );
use FS::UID qw(getotaker);
use FS::cust_credit;
use FS::cust_credit_refund;
+use FS::cust_pay_refund;
use FS::cust_main;
@ISA = qw( FS::Record );
@@ -78,7 +79,9 @@ Adds this refund to the database.
For backwards-compatibility and convenience, if the additional field crednum is
defined, an FS::cust_credit_refund record for the full amount of the refund
-will be created. In this case, custnum is optional.
+will be created. Or (this time for convenience and consistancy), if the
+additional field paynum is defined, an FS::cust_pay_refund record for the full
+amount of the refund will be created. In both cases, custnum is optional.
=cut
@@ -103,6 +106,13 @@ sub insert {
return "Unknown cust_credit.crednum: ". $self->crednum;
};
$self->custnum($cust_credit->custnum);
+ } elsif ( $self->paynum ) {
+ my $cust_pay = qsearchs('cust_pay', { 'paynum' => $self->paynum } )
+ or do {
+ $dbh->rollback if $oldAutoCommit;
+ return "Unknown cust_pay.paynum: ". $self->paynum;
+ };
+ $self->custnum($cust_pay->custnum);
}
my $error = $self->check;
@@ -127,57 +137,20 @@ sub insert {
return $error;
}
#$self->custnum($cust_credit_refund->cust_credit->custnum);
- }
-
-
- $dbh->commit or die $dbh->errstr if $oldAutoCommit;
-
- '';
-
-}
-
-sub upgrade_replace { #1.3.x->1.4.x
- my $self = 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 $error = $self->check;
- return $error if $error;
-
- my %new = $self->hash;
- my $new = FS::cust_refund->new(\%new);
-
- if ( $self->crednum ) {
- my $cust_credit_refund = new FS::cust_credit_refund {
- 'crednum' => $self->crednum,
+ } elsif ( $self->paynum ) {
+ my $cust_pay_refund = new FS::cust_pay_refund {
+ 'paynum' => $self->paynum,
'refundnum' => $self->refundnum,
'amount' => $self->refund,
'_date' => $self->_date,
};
- $error = $cust_credit_refund->insert;
+ $error = $cust_pay_refund->insert;
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return $error;
}
- $new->custnum($cust_credit_refund->cust_credit->custnum);
- } else {
- die;
}
- $error = $new->SUPER::replace($self);
- if ( $error ) {
- $dbh->rollback if $oldAutoCommit;
- return $error;
- }
$dbh->commit or die $dbh->errstr if $oldAutoCommit;
@@ -263,6 +236,52 @@ sub check {
$self->SUPER::check;
}
+=item cust_credit_refund
+
+Returns all applications to credits (see L<FS::cust_credit_refund>) for this
+refund.
+
+=cut
+
+sub cust_credit_refund {
+ my $self = shift;
+ sort { $a->_date <=> $b->_date }
+ qsearch( 'cust_credit_refund', { 'refundnum' => $self->refundnum } )
+ ;
+}
+
+=item cust_pay_refund
+
+Returns all applications to payments (see L<FS::cust_pay_refund>) for this
+refund.
+
+=cut
+
+sub cust_pay_refund {
+ my $self = shift;
+ sort { $a->_date <=> $b->_date }
+ qsearch( 'cust_pay_refund', { 'refundnum' => $self->refundnum } )
+ ;
+}
+
+=item unapplied
+
+Returns the amount of this refund that is still unapplied; which is
+amount minus all credit applications (see L<FS::cust_credit_refund>) and
+payment applications (see L<FS::cust_pay_refund>).
+
+=cut
+
+sub unapplied {
+ my $self = shift;
+ my $amount = $self->refund;
+ $amount -= $_->amount foreach ( $self->cust_credit_refund );
+ $amount -= $_->amount foreach ( $self->cust_pay_refund );
+ sprintf("%.2f", $amount );
+}
+
+
+
=item payinfo_masked
Returns a "masked" payinfo field with all but the last four characters replaced
diff --git a/FS/MANIFEST b/FS/MANIFEST
index 24fc1d1..4e78e72 100644
--- a/FS/MANIFEST
+++ b/FS/MANIFEST
@@ -59,6 +59,7 @@ FS/cust_pay.pm
FS/cust_bill_event.pm
FS/cust_bill_pay.pm
FS/cust_pay_batch.pm
+FS/cust_pay_refund.pm
FS/cust_pkg.pm
FS/cust_refund.pm
FS/cust_credit_refund.pm
@@ -148,6 +149,7 @@ t/cust_main_county.t
t/cust_main_invoice.t
t/cust_pay.t
t/cust_pay_batch.t
+t/cust_pay_refund.t
t/cust_pkg.t
t/cust_refund.t
t/cust_svc.t
diff --git a/FS/bin/freeside-setup b/FS/bin/freeside-setup
index 522c0a1..33b3465 100755
--- a/FS/bin/freeside-setup
+++ b/FS/bin/freeside-setup
@@ -1115,6 +1115,21 @@ sub tables_hash_hack {
'index' => [],
},
+ 'cust_pay_refund' => {
+ 'columns' => [
+ 'payrefundnum', 'serial', '', '',
+ 'paynum', 'int', '', '',
+ 'refundnum', 'int', '', '',
+ '_date', @date_type,
+ 'amount', @money_type,
+ ],
+ 'primary_key' => 'payrefundnum',
+ 'unique' => [],
+ 'index' => [ ['paynum'], ['refundnum'] ],
+ },
+
+
+
);
%tables;
diff --git a/FS/t/cust_pay_refund.t b/FS/t/cust_pay_refund.t
new file mode 100644
index 0000000..85d6c23
--- /dev/null
+++ b/FS/t/cust_pay_refund.t
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::cust_pay_refund;
+$loaded=1;
+print "ok 1\n";
diff --git a/README.1.5.0pre6 b/README.1.5.0pre6
new file mode 100644
index 0000000..ba9129f
--- /dev/null
+++ b/README.1.5.0pre6
@@ -0,0 +1,15 @@
+CREATE TABLE cust_pay_refund (
+ payrefundnum serial NOT NULL,
+ paynum int NOT NULL,
+ refundnum int NOT NULL,
+ _date int NOT NULL,
+ amount decimal(10,2) NOT NULL,
+ PRIMARY KEY (payrefundnum)
+);
+CREATE INDEX cust_pay_refund1 ON cust_pay_refund(paynum);
+CREATE INDEX cust_pay_refund2 ON cust_pay_refund(refundnum);
+
+dbdef-create username
+create-history-tables username cust_pay_refund
+dbdef-create username
+
diff --git a/httemplate/docs/upgrade10.html b/httemplate/docs/upgrade10.html
index c2b88be..1d09964 100644
--- a/httemplate/docs/upgrade10.html
+++ b/httemplate/docs/upgrade10.html
@@ -113,8 +113,8 @@ select setval('public.part_pkg_temp_pkgpart_seq', ( select max(pkgpart) from par
Or on Pg versions that don't support DROP CONSTRAINT and ADD PRIMARY KEY (tested on 7.1 and 7.2 so far):
DROP INDEX part_pkg_temp_pkey;
CREATE UNIQUE INDEX part_pkg_pkey ON part_pkg (pkgpart);
-7.1?: select setval('part_pkg_temp_pkgpart_seq', ( select max(pkgpart) from part_pkg) );
-7.2: select setval('part_pkg_pkgpart_seq', ( select max(pkgpart) from part_pkg) );
+probably this one?: select setval('part_pkg_temp_pkgpart_seq', ( select max(pkgpart) from part_pkg) );
+probably not this one?: select setval('part_pkg_pkgpart_seq', ( select max(pkgpart) from part_pkg) );
CREATE TABLE h_part_pkg_temp (
historynum serial NOT NULL,
@@ -148,9 +148,19 @@ select setval('public.h_part_pkg_temp_historynum_seq', ( select max(historynum)
Or on Pg versions that don't support DROP CONSTRAINT and ADD PRIMARY KEY (tested on 7.1 and 7.2 so far):
DROP INDEX h_part_pkg_temp_pkey;
CREATE UNIQUE INDEX h_part_pkg_pkey ON h_part_pkg (historynum);
-7.1?: select setval('h_part_pkg_temp_historynum_seq', ( select max(historynum) from h_part_pkg) );
-7.2: select setval('h_part_pkg_historynum_seq', ( select max(historynum) from h_part_pkg) );
-
+probably this one?: select setval('h_part_pkg_temp_historynum_seq', ( select max(historynum) from h_part_pkg) );
+probably not this one?: select setval('h_part_pkg_historynum_seq', ( select max(historynum) from h_part_pkg) );
+
+CREATE TABLE cust_pay_refund (
+ payrefundnum serial NOT NULL,
+ paynum int NOT NULL,
+ refundnum int NOT NULL,
+ _date int NOT NULL,
+ amount decimal(10,2) NOT NULL,
+ PRIMARY KEY (payrefundnum)
+);
+CREATE INDEX cust_pay_refund1 ON cust_pay_refund(paynum);
+CREATE INDEX cust_pay_refund2 ON cust_pay_refund(refundnum);
DROP INDEX cust_bill_pkg1;
diff --git a/httemplate/edit/cust_bill_pay.cgi b/httemplate/edit/cust_bill_pay.cgi
index 8cdf450..24bce30 100755
--- a/httemplate/edit/cust_bill_pay.cgi
+++ b/httemplate/edit/cust_bill_pay.cgi
@@ -59,10 +59,10 @@ foreach my $cust_bill ( @cust_bill ) {
END
}
-# if ( cust_bill == "Refund" ) {
-# what.form.amount.value = "$credited";
-# }
print <<END;
+ if ( cust_bill == "Refund" ) {
+ what.form.amount.value = "$unapplied";
+ }
}
</SCRIPT>
END
@@ -75,7 +75,7 @@ foreach my $cust_bill ( @cust_bill ) {
' - '. time2str("%D",$cust_bill->_date).
' - $'. $cust_bill->owed;
}
-#print qq!<OPTION VALUE="Refund">Refund!;
+print qq!<OPTION VALUE="Refund">Refund!;
print "</SELECT>";
print qq!<BR>Amount \$<INPUT TYPE="text" NAME="amount" VALUE="$amount" SIZE=8 MAXLENGTH=8>!;
diff --git a/httemplate/edit/process/cust_bill_pay.cgi b/httemplate/edit/process/cust_bill_pay.cgi
index 0c33506..0025b16 100755
--- a/httemplate/edit/process/cust_bill_pay.cgi
+++ b/httemplate/edit/process/cust_bill_pay.cgi
@@ -11,12 +11,24 @@ my $cust_main = qsearchs('cust_main', { 'custnum' => $cust_pay->custnum } )
my $custnum = $cust_main->custnum;
-my $new = new FS::cust_bill_pay ( {
- map {
- $_, scalar($cgi->param($_));
- #} qw(custnum _date amount invnum)
- } fields('cust_bill_pay')
-} );
+my $new;
+if ($cgi->param('invnum') =~ /^Refund$/) {
+ $new = new FS::cust_refund ( {
+ 'reason' => 'Refunding payment', #enter reason in UI
+ 'refund' => $cgi->param('amount'),
+ 'payby' => 'BILL',
+ #'_date' => $cgi->param('_date'),
+ 'payinfo' => 'Cash', #enter payinfo in UI
+ 'paynum' => $paynum,
+ } );
+} else {
+ $new = new FS::cust_bill_pay ( {
+ map {
+ $_, scalar($cgi->param($_));
+ #} qw(custnum _date amount invnum)
+ } fields('cust_bill_pay')
+ } );
+}
my $error = $new->insert;
diff --git a/httemplate/view/cust_main.cgi b/httemplate/view/cust_main.cgi
index cf899d0..125c51a 100755
--- a/httemplate/view/cust_main.cgi
+++ b/httemplate/view/cust_main.cgi
@@ -604,6 +604,7 @@ function cust_credit_areyousure(href) {
? $cust_pay->payinfo_masked
: $cust_pay->payinfo;
my @cust_bill_pay = $cust_pay->cust_bill_pay;
+ my @cust_pay_refund = $cust_pay->cust_pay_refund;
my $target = "$payby$payinfo";
$payby =~ s/^BILL$/Check #/ if $payinfo;
@@ -612,25 +613,42 @@ function cust_credit_areyousure(href) {
my $info = $payby ? " ($payby$payinfo)" : '';
my( $pre, $post, $desc, $apply, $ext ) = ( '', '', '', '', '' );
- if ( scalar(@cust_bill_pay) == 0 ) {
+ if ( scalar(@cust_bill_pay) == 0
+ && scalar(@cust_pay_refund) == 0 ) {
#completely unapplied
$pre = '<B><FONT COLOR="#FF0000">Unapplied ';
$post = '</FONT></B>';
$apply = qq! (<A HREF="${p}edit/cust_bill_pay.cgi?!.
$cust_pay->paynum. '">apply</A>)';
- } elsif ( scalar(@cust_bill_pay) == 1 && $cust_pay->unapplied == 0 ) {
- #applied to one invoice
+ } elsif ( scalar(@cust_bill_pay) == 1
+ && scalar(@cust_pay_refund) == 0
+ && $cust_pay->unapplied == 0 ) {
+ #applied to one invoice, the usual situation
$desc = ' applied to Invoice #'. $cust_bill_pay[0]->invnum;
+ } elsif ( scalar(@cust_bill_pay) == 0
+ && scalar(@cust_pay_refund) == 1
+ && $cust_pay->unapplied == 0 ) {
+ #applied to one refund
+ $desc = ' refunded on '. time2str("%D", $cust_pay_refund[0]->_date);
} else {
#complicated
$desc = '<BR>';
- foreach my $cust_bill_pay (@cust_bill_pay) {
- $desc .= '&nbsp;&nbsp;'.
- '$'. $cust_bill_pay->amount.
- ' applied to Invoice #'. $cust_bill_pay->invnum.
- '<BR>';
- #' on '. time2str("%D", $cust_bill_pay->_date).
-
+ foreach my $app ( sort { $a->_date <=> $b->_date }
+ ( @cust_bill_pay, @cust_pay_refund ) ) {
+ if ( $app->isa('FS::cust_bill_pay') ) {
+ $desc .= '&nbsp;&nbsp;'.
+ '$'. $app->amount.
+ ' applied to Invoice #'. $app->invnum.
+ '<BR>';
+ #' on '. time2str("%D", $cust_bill_pay->_date).
+ } elsif ( $app->isa('FS::cust_pay_refund') ) {
+ $desc .= '&nbsp;&nbsp;'.
+ '$'. $app->amount.
+ ' refunded on'. time2str("%D", $app->_date).
+ '<BR>';
+ } else {
+ die "$app is not a FS::cust_bill_pay or FS::cust_pay_refund";
+ }
}
if ( $cust_pay->unapplied > 0 ) {
$desc .= '&nbsp;&nbsp;'.
@@ -684,7 +702,7 @@ function cust_credit_areyousure(href) {
} elsif ( scalar(@cust_credit_bill) == 1
&& scalar(@cust_credit_refund) == 0
&& $cust_credit->credited == 0 ) {
- #applied to one invoice
+ #applied to one invoice, the usual situation
$desc = ' applied to Invoice #'. $cust_credit_bill[0]->invnum;
} elsif ( scalar(@cust_credit_bill) == 0
&& scalar(@cust_credit_refund) == 1