X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=httemplate%2Fview%2Fcust_main.cgi;h=9aa00896988f46d24652610535b6be0eb19a91cb;hp=cc36006417e5f9ce3c0263a1d1624f81be6c4b43;hb=6fe8172b11d0369d0b1274d6825ec0c57afe8001;hpb=e3f327b2af9e6a591bae41d315fda731ec7f5128 diff --git a/httemplate/view/cust_main.cgi b/httemplate/view/cust_main.cgi index cc3600641..9aa008969 100755 --- a/httemplate/view/cust_main.cgi +++ b/httemplate/view/cust_main.cgi @@ -36,15 +36,15 @@ print qq!Edit this customer!; %> <% -print qq! | !. +print qq! | !. 'Cancel this customer' if $cust_main->ncancelled_pkgs; @@ -235,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)' ), '', @@ -301,13 +300,25 @@ if ( defined $cust_main->dbdef_table->column('comments') ''; } -print ''; +%> + + -print '
'. - '
'. - qq!!. - ' +

'; +
+ +<% if ( $conf->config('payby-default') ne 'HIDE' ) { @@ -350,21 +363,6 @@ if ( $conf->config('payby-default') ne 'HIDE' ) { } -%> - - - -<% - print qq!Packages !, qq!( Order and cancel packages (preserves services) )!, ; @@ -413,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 '. @@ -482,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 @@ -493,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). ''; } @@ -545,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 @@ -598,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 .= '  '. @@ -640,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) { @@ -682,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 @@ -710,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, { @@ -748,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, { @@ -789,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'}) : ''; @@ -851,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; @@ -864,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], @@ -905,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 ]; @@ -946,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 .= '
'. @@ -963,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. @@ -991,7 +1018,8 @@ sub pkg_datestr { sub pkg_change_link { my $pkg = shift or return ''; - return qq!Change package!; + return qq!!. + qq!Change package!; } sub pkg_suspend_link { @@ -1006,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!; } %>