X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=httemplate%2Fview%2Fcust_main.cgi;h=9aa00896988f46d24652610535b6be0eb19a91cb;hp=6057017533a09d41cf731ae1cfde6235b49932eb;hb=6fe8172b11d0369d0b1274d6825ec0c57afe8001;hpb=6db0053308daae19135066c5bf4d20e82f0a5780
diff --git a/httemplate/view/cust_main.cgi b/httemplate/view/cust_main.cgi
index 605701753..9aa008969 100755
--- a/httemplate/view/cust_main.cgi
+++ b/httemplate/view/cust_main.cgi
@@ -3,7 +3,6 @@
my $conf = new FS::Conf;
-#false laziness with view/cust_pkg.cgi, but i'm trying to make that go away so
my %uiview = ();
my %uiadd = ();
foreach my $part_svc ( qsearch('part_svc',{}) ) {
@@ -37,15 +36,15 @@ print qq!Edit this customer!;
%>
<%
-print qq! | !.
+print qq! | !.
'Cancel this customer'
if $cust_main->ncancelled_pkgs;
@@ -236,8 +235,7 @@ if ( $conf->config('payby-default') ne 'HIDE' ) {
;
if ( $cust_main->payby eq 'CARD' || $cust_main->payby eq 'DCRD' ) {
- my $payinfo = $cust_main->payinfo;
- $payinfo = 'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4));
+ my $payinfo = $cust_main->payinfo_masked;
print 'Credit card ',
( $cust_main->payby eq 'CARD' ? '(automatic)' : '(on-demand)' ),
'',
@@ -302,13 +300,25 @@ if ( defined $cust_main->dbdef_table->column('comments')
'';
}
-print '';
+%>
+
+
-print '
'.
- '
';
+<%
if ( $conf->config('payby-default') ne 'HIDE' ) {
@@ -351,21 +363,6 @@ if ( $conf->config('payby-default') ne 'HIDE' ) {
}
-%>
-
-
-
-<%
-
print qq!Packages !,
qq!( Order and cancel packages (preserves services) )!,
;
@@ -401,7 +398,7 @@ foreach my $pkg (sort pkgsort_pkgnum_cancel @$packages) {
>
- <%=$pkg->{pkgnum}%>:
+ <%=$pkg->{pkgnum}%>:
<%=$pkg->{pkg}%> - <%=$pkg->{comment}%>
<% unless ($pkg->{cancel}) { %>
( <%=pkg_change_link($pkg)%> )
@@ -414,27 +411,13 @@ foreach my $pkg (sort pkgsort_pkgnum_cancel @$packages) {
#}
print " | ". &itable('');
- sub freq {
-
- #false laziness w/edit/part_pkg.cgi
- my %freq = ( #move this
- '1d' => 'daily',
- '1w' => 'weekly',
- '2w' => 'biweekly (every 2 weeks)',
- '1' => 'monthly',
- '2' => 'bimonthly (every 2 months)',
- '3' => 'quarterly (every 3 months)',
- '6' => 'semiannually (every 6 months)',
- '12' => 'annually',
- '24' => 'biannually (every 2 years)',
- );
-
- my $freq = shift;
- exists $freq{$freq} ? $freq{$freq} : "every $freq months";
+ sub myfreq {
+ my $part_pkg = shift;
+ my $freq = $part_pkg->freq_pretty;
+ $freq =~ s/ / /g;
+ $freq;
}
- #eomove
-
if ( $pkg->{cancel} ) { #status: cancelled
print ' |
Cancelled | '.
@@ -483,7 +466,7 @@ foreach my $pkg (sort pkgsort_pkgnum_cancel @$packages) {
print '
( '. pkg_cancel_link($pkg).
' ) | ';
} else {
- print 'billed '. freq($pkg->{freq}). ')
';
+ print 'billed '. myfreq($pkg->{part_pkg}). ')';
}
} else { #setup
@@ -494,7 +477,7 @@ foreach my $pkg (sort pkgsort_pkgnum_cancel @$packages) {
pkg_datestr($pkg,'setup',$conf). '';
} else {
print 'Active'.
- ', billed '. freq($pkg->{freq}). ' |
'.
+ ', billed '. myfreq($pkg->{part_pkg}). ''.
'Setup | '.
pkg_datestr($pkg, 'setup',$conf). ' |
';
}
@@ -546,34 +529,14 @@ print '';
#end display packages
%>
-
-
<% if ( $conf->config('payby-default') ne 'HIDE' ) { %>
-
Payment History
- (Post payment
- | Post credit)
+
Payment History
+ Post cash/check payment
+ | Process credit card payment
+ | Process electronic check (ACH) payment
+
Post credit
+
<%
#get payment history
@@ -599,37 +562,56 @@ function cust_credit_areyousure(href) {
foreach my $cust_pay ($cust_main->cust_pay) {
my $payby = $cust_pay->payby;
- my $payinfo = $cust_pay->payinfo;
+ my $payinfo = $payby eq 'CARD'
+ ? $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;
- $payinfo = 'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4))
- if $payby eq 'CARD';
my $target = "$payby$payinfo";
$payby =~ s/^BILL$/Check #/ if $payinfo;
+ $payby =~ s/^CHEK$/Electronic check /;
$payby =~ s/^BILL$//;
$payby =~ s/^(CARD|COMP)$/$1 /;
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 = 'Unapplied ';
$post = '';
$apply = qq! (apply)';
- } 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 = '
';
- foreach my $cust_bill_pay (@cust_bill_pay) {
- $desc .= ' '.
- '$'. $cust_bill_pay->amount.
- ' applied to Invoice #'. $cust_bill_pay->invnum.
- '
';
- #' 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 .= ' '.
+ '$'. $app->amount.
+ ' applied to Invoice #'. $app->invnum.
+ '
';
+ #' on '. time2str("%D", $cust_bill_pay->_date).
+ } elsif ( $app->isa('FS::cust_pay_refund') ) {
+ $desc .= ' '.
+ '$'. $app->amount.
+ ' refunded on'. time2str("%D", $app->_date).
+ '
';
+ } else {
+ die "$app is not a FS::cust_bill_pay or FS::cust_pay_refund";
+ }
}
if ( $cust_pay->unapplied > 0 ) {
$desc .= ' '.
@@ -641,31 +623,78 @@ function cust_credit_areyousure(href) {
}
}
+ my $refund = '';
+ my $refund_days = $conf->config('card_refund-days') || 120;
+ if ( $cust_pay->closed !~ /^Y/i
+ && $cust_pay->payby =~ /^(CARD|CHEK)$/
+ && time-$cust_pay->_date < $refund_days*86400
+ && $cust_pay->unrefunded > 0
+ ) {
+ $refund = qq! (refund)!;
+ }
+
+ my $void = '';
+ if ( $cust_pay->closed !~ /^Y/i
+ && $cust_pay->payby !~ /^(CARD|CHEK)$/
+ ) {
+ $void = qq! (!.
+ qq!void)!;
+ }
+
my $delete = '';
if ( $cust_pay->closed !~ /^Y/i && $conf->exists('deletepayments') ) {
- $delete = qq! (paynum.
- qq!')">delete)!;
+ qq!', 'Are you sure you want to delete this payment?')">!.
+ qq!delete)!;
}
my $unapply = '';
if ( $cust_pay->closed !~ /^Y/i
&& $conf->exists('unapplypayments')
&& scalar(@cust_bill_pay) ) {
- $unapply = qq! (paynum.
- qq!')">unapply)!;
+ qq!', 'Are you sure you want to unapply this payment?')">!.
+ qq!unapply)!;
}
push @history, {
'date' => $cust_pay->_date,
'desc' => $pre. "Payment$post$info$desc".
- "$apply$delete$unapply",
+ "$apply$refund$void$delete$unapply",
'payment' => $cust_pay->paid,
'target' => $target,
};
}
+ #voided payments
+ foreach my $cust_pay_void ($cust_main->cust_pay_void) {
+
+ my $payby = $cust_pay_void->payby;
+ my $payinfo = $payby eq 'CARD'
+ ? $cust_pay_void->payinfo_masked
+ : $cust_pay_void->payinfo;
+
+ $payby =~ s/^BILL$/Check #/ if $payinfo;
+ $payby =~ s/^CHEK$/Electronic check /;
+ $payby =~ s/^BILL$//;
+ $payby =~ s/^(CARD|COMP)$/$1 /;
+ my $info = $payby ? " ($payby$payinfo)" : '';
+
+ push @history, {
+ 'date' => $cust_pay_void->_date,
+ 'desc' => "Payment $info voided ".
+ time2str("%D", $cust_pay_void->void_date).
+ " by ". $cust_pay_void->otaker. '',
+ 'void_payment' => $cust_pay_void->paid,
+ };
+
+ }
+
#credits (some false laziness w/payments)
foreach my $cust_credit ($cust_main->cust_credit) {
@@ -683,7 +712,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
@@ -711,28 +740,30 @@ function cust_credit_areyousure(href) {
}
}
if ( $cust_credit->credited > 0 ) {
- $desc .= ' - $'.
- $cust_credit->unapplied. ' unapplied'.
+ $desc .= ' $'.
+ $cust_credit->credited. ' unapplied'.
qq! (apply'.
+ $cust_credit->crednum. '">apply)'.
'
';
}
}
#
my $delete = '';
if ( $cust_credit->closed !~ /^Y/i && $conf->exists('deletecredits') ) {
- $delete = qq! (crednum.
- qq!')">delete)!;
+ qq!', 'Are you sure you want to delete this credit?')">!.
+ qq!delete)!;
}
my $unapply = '';
if ( $cust_credit->closed !~ /^Y/i
&& $conf->exists('unapplycredits')
&& scalar(@cust_credit_bill) ) {
- $unapply = qq! (crednum.
- qq!')">unapply)!;
+ qq!', 'Are you sure you want to unapply this credit?')">!.
+ qq!unapply)!;
}
push @history, {
@@ -749,11 +780,12 @@ function cust_credit_areyousure(href) {
foreach my $cust_refund ($cust_main->cust_refund) {
my $payby = $cust_refund->payby;
- my $payinfo = $cust_refund->payinfo;
+ my $payinfo = $payby eq 'CARD'
+ ? $cust_refund->payinfo_masked
+ : $cust_refund->payinfo;
- $payinfo = 'x'x(length($payinfo)-4). substr($payinfo,(length($payinfo)-4))
- if $payby eq 'CARD';
$payby =~ s/^BILL$/Check #/ if $payinfo;
+ $payby =~ s/^CHEK$/Electronic check /;
$payby =~ s/^(CARD|COMP)$/$1 /;
push @history, {
@@ -790,6 +822,8 @@ function cust_credit_areyousure(href) {
my $payment = exists($item->{'payment'})
? sprintf('- $%.2f', $item->{'payment'})
: '';
+ $payment ||= sprintf('- $%.2f', $item->{'void_payment'})
+ if exists($item->{'void_payment'});
my $credit = exists($item->{'credit'})
? sprintf('- $%.2f', $item->{'credit'})
: '';
@@ -852,8 +886,13 @@ sub get_packages {
) {
my $part_pkg = $cust_pkg->part_pkg;
-
+
my %pkg = ();
+
+ #to get back to the original object... should use it in the first place!!
+ $pkg{cust_pkg} = $cust_pkg;
+ $pkg{part_pkg} = $part_pkg;
+
$pkg{pkgnum} = $cust_pkg->pkgnum;
$pkg{pkg} = $part_pkg->pkg;
$pkg{pkgpart} = $part_pkg->pkgpart;
@@ -865,39 +904,19 @@ sub get_packages {
$pkg{susp} = $cust_pkg->getfield('susp');
$pkg{expire} = $cust_pkg->getfield('expire');
$pkg{cancel} = $cust_pkg->getfield('cancel');
-
- my %svcparts = ();
- foreach my $pkg_svc (
- qsearch('pkg_svc', { 'pkgpart' => $part_pkg->pkgpart })
- ) {
- next if ($pkg_svc->quantity == 0);
-
- my $part_svc = qsearchs('part_svc', { 'svcpart' => $pkg_svc->svcpart });
-
- my $svcpart = {};
- $svcpart->{svcpart} = $part_svc->svcpart;
- $svcpart->{svc} = $part_svc->svc;
- $svcpart->{svcdb} = $part_svc->svcdb;
- $svcpart->{quantity} = $pkg_svc->quantity;
- $svcpart->{count} = 0;
-
- $svcpart->{services} = [];
-
- $svcparts{$svcpart->{svcpart}} = $svcpart;
-
- }
-
- foreach my $cust_svc (
- qsearch( 'cust_svc', {
- 'pkgnum' => $cust_pkg->pkgnum,
- #'svcpart' => $part_svc->svcpart,
- }
- )
- ) {
-
- warn "svcnum ". $cust_svc->svcnum. " / svcpart ". $cust_svc->svcpart. "\n";
+ my %svcparts = map {
+ $_->svcpart => {
+ $_->part_svc->hash,
+ 'quantity' => $_->quantity,
+ 'count' => $cust_pkg->num_cust_svc($_->svcpart),
+ #'services' => [],
+ };
+ } $part_pkg->pkg_svc;
+
+ foreach my $cust_svc ( $cust_pkg->cust_svc ) {
+ #warn "svcnum ". $cust_svc->svcnum. " / svcpart ". $cust_svc->svcpart. "\n";
my $svc = {
'svcnum' => $cust_svc->svcnum,
'label' => ($cust_svc->label)[1],
@@ -906,18 +925,14 @@ sub get_packages {
#false laziness with above, to catch extraneous services. whole
#damn thing should be OO...
my $svcpart = ( $svcparts{$cust_svc->svcpart} ||= {
- 'svcpart' => $cust_svc->svcpart,
- 'svc' => $cust_svc->part_svc->svc,
- 'svcdb' => $cust_svc->part_svc->svcdb,
+ $cust_svc->part_svc->hash,
'quantity' => 0,
- 'count' => 0,
- 'services' => [],
+ 'count' => $cust_pkg->num_cust_svc($cust_svc->svcpart),
+ #'services' => [],
} );
push @{$svcpart->{services}}, $svc;
- $svcpart->{count}++;
-
}
$pkg{svcparts} = [ values %svcparts ];
@@ -947,11 +962,21 @@ sub svc_label_link {
sub svc_provision_link {
my ($pkg, $svcpart, $conf) = @_;
( my $svc_nbsp = $svcpart->{svc} ) =~ s/\s+/ /g;
- my $pkgnum_svcpart = "pkgnum$pkg->{pkgnum}-svcpart$svcpart->{svcpart}";
my $num_left = $svcpart->{quantity} - $svcpart->{count};
+ my $pkgnum_svcpart = "pkgnum$pkg->{pkgnum}-svcpart$svcpart->{svcpart}";
- my $link = qq!!.
+ my $url;
+ if ( $svcpart->{svcdb} eq 'svc_external'
+ && $conf->exists('svc_external-skip_manual')
+ ) {
+ $url = "${p}edit/process/$svcpart->{svcdb}.cgi?".
+ "pkgnum=$pkg->{pkgnum}&".
+ "svcpart=$svcpart->{svcpart}";
+ } else {
+ $url = "${p}edit/$svcpart->{svcdb}.cgi?$pkgnum_svcpart";
+ }
+
+ my $link = qq!!.
"Provision $svc_nbsp ($num_left)";
if ( $conf->exists('legacy_link') ) {
$link .= '
'.
@@ -964,7 +989,8 @@ sub svc_provision_link {
sub svc_unprovision_link {
my $svc = shift or return '';
- return qq!Unprovision!;
+ qq!Unprovision!;
}
# This should be generalized to use config options to determine order.
@@ -990,14 +1016,10 @@ sub pkg_datestr {
$strip;
}
-#sub pkg_details_link {
-# my $pkg = shift or return '';
-# return qq!Details!;
-#}
-
sub pkg_change_link {
my $pkg = shift or return '';
- return qq!Change package!;
+ return qq!!.
+ qq!Change package!;
}
sub pkg_suspend_link {
@@ -1012,19 +1034,22 @@ sub pkg_unsuspend_link {
sub pkg_cancel_link {
my $pkg = shift or return '';
- qq!Cancel now | !.
+ qq!!.
+ qq!Cancel now | !.
qq!Cancel later!;
}
sub pkg_dates_link {
my $pkg = shift or return '';
- return qq!Edit dates!;
+ qq!Edit dates!;
}
sub pkg_customize_link {
my $pkg = shift or return '';
my $custnum = shift;
- return qq!Customize!;
+ qq!Customize!;
}
%>