From 72a65ceaa28155e8c1c3c1328dd76587b35e089a Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 17 Mar 2004 21:47:56 +0000 Subject: proper self-service login supporting plaintext, crypt and MD5 passwords --- httemplate/docs/install.html | 1 + httemplate/docs/upgrade-1.4.2.html | 1 + 2 files changed, 2 insertions(+) (limited to 'httemplate') diff --git a/httemplate/docs/install.html b/httemplate/docs/install.html index ed306f2d3..0217c9085 100644 --- a/httemplate/docs/install.html +++ b/httemplate/docs/install.html @@ -56,6 +56,7 @@ Before installing, you need:
  • NetAddr-IP
  • Chart +
  • Crypt::PasswdMD5
  • Apache::DBI (optional but recommended for better webinterface performance) diff --git a/httemplate/docs/upgrade-1.4.2.html b/httemplate/docs/upgrade-1.4.2.html index 3c9ac9c6d..b8c5fcf7e 100644 --- a/httemplate/docs/upgrade-1.4.2.html +++ b/httemplate/docs/upgrade-1.4.2.html @@ -13,6 +13,7 @@
  • Install DBD::Pg 1.32.
  • Install Cache::Cache.
  • Install Net::SSH 0.08. +
  • Install Crypt::PasswdMD5
  • CGI.pm minimum version 2.47 is required. You will probably need to install a current CGI.pm from CPAN if you are using Perl 5.005 or earlier.
  • If using Apache::ASP, add PerlSetVar RequestBinaryRead Off to your Apache configuration and make sure you are using Apache::ASP minimum version 2.55.
  • Run make aspdocs or make masondocs. -- cgit v1.2.1 From 5a5242465520ef7a64a715496c31a3c17c95cc57 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 22 Mar 2004 02:59:39 +0000 Subject: much easier to understand listing of credits/payments that get split up, closes: Bug#773, 762 --- httemplate/view/cust_main.cgi | 451 +++++++++++++++++++++++------------------- 1 file changed, 250 insertions(+), 201 deletions(-) (limited to 'httemplate') diff --git a/httemplate/view/cust_main.cgi b/httemplate/view/cust_main.cgi index c41d2d894..229362e6c 100755 --- a/httemplate/view/cust_main.cgi +++ b/httemplate/view/cust_main.cgi @@ -15,14 +15,16 @@ print header("Customer View", menubar( 'Main Menu' => popurl(2) )); -print < + -END + +<% die "No customer specified (bad URL)!" unless $cgi->keywords; my($query) = $cgi->keywords; # needs parens with my, ->keywords returns array @@ -33,14 +35,16 @@ die "Customer not found!" unless $cust_main; print qq!Edit this customer!; -print < + -END + +<% print qq! | !. 'Cancel this customer' @@ -348,7 +352,8 @@ if ( $conf->config('payby-default') ne 'HIDE' ) { } -print < + -END + +<% print qq!
    Packages !, # qq!
    Click on package number to view/edit package.!, @@ -536,13 +542,12 @@ foreach my $pkg (sort pkgsort_pkgnum_cancel @$packages) { } } } -print '' +print ''; } #end display packages +%> - -print < function cust_pay_areyousure(href) { if (confirm("Are you sure you want to delete this payment?") @@ -565,169 +570,205 @@ function cust_credit_areyousure(href) { window.location.href = href; } -END -if ( $conf->config('payby-default') ne 'HIDE' ) { - - #formatting - print qq!

    Payment History!. - qq! ( !. - qq!!. - qq!Post payment | !. - qq!!. - qq!Post credit )!; +<% if ( $conf->config('payby-default') ne 'HIDE' ) { %> +

    Payment History + (Post payment + | Post credit) + + <% #get payment history - # - # major problem: this whole thing is way too sloppy. - # minor problem: the description lines need better formatting. - - my @history = (); #needed for mod_perl :) - - my %target = (); - - my @bills = qsearch('cust_bill',{'custnum'=>$custnum}); - foreach my $bill (@bills) { - my($bref)=$bill->hashref; - my $bpre = ( $bill->owed > 0 ) - ? ' Open ' - : ''; - my $bpost = ( $bill->owed > 0 ) ? '' : ''; - push @history, - $bref->{_date} . qq!\t${bpre}Invoice #! . $bref->{invnum} . - qq! (Balance \$! . $bill->owed . qq!)$bpost\t! . - $bref->{charged} . qq!\t\t\t!; - - my(@cust_bill_pay)=qsearch('cust_bill_pay',{'invnum'=> $bref->{invnum} } ); - # my(@payments)=qsearch('cust_pay',{'invnum'=> $bref->{invnum} } ); - # my($payment); - foreach my $cust_bill_pay (@cust_bill_pay) { - my $payment = $cust_bill_pay->cust_pay; - my($date,$invnum,$payby,$payinfo,$paid)=($payment->_date, - $cust_bill_pay->invnum, - $payment->payby, - $payment->payinfo, - $cust_bill_pay->amount, - ); - $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/^(CARD|COMP)$/$1 /; - my $delete = $payment->closed !~ /^Y/i && $conf->exists('deletepayments') - ? qq! (delete)! - : ''; - my $unapply = - $payment->closed !~ /^Y/i && $conf->exists('unapplypayments') - ? qq! (unapply)! - : ''; - push @history, - "$date\tPayment, Invoice #$invnum ($payby$payinfo)$delete$unapply\t\t$paid\t\t\t$target"; + my @history = (); + + #invoices + foreach my $cust_bill ($cust_main->cust_bill) { + my $pre = ( $cust_bill->owed > 0 ) + ? 'Open ' + : ''; + my $post = ( $cust_bill->owed > 0 ) ? '' : ''; + my $invnum = $cust_bill->invnum; + push @history, { + 'date' => $cust_bill->_date, + 'desc' => qq!!. $pre. + "Invoice #$invnum (Balance \$". $cust_bill->owed. ')'. + $post. '', + 'charge' => $cust_bill->charged, + }; + } + + #payments (some false laziness w/credits) + foreach my $cust_pay ($cust_main->cust_pay) { + + my $payby = $cust_pay->payby; + my $payinfo = $cust_pay->payinfo; + my @cust_bill_pay = $cust_pay->cust_bill_pay; + + $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/^BILL$//; + $payby =~ s/^(CARD|COMP)$/$1 /; + my $info = $payby ? " ($payby$payinfo)" : ''; + + my( $pre, $post, $desc, $apply, $ext ) = ( '', '', '', '', '' ); + if ( scalar(@cust_bill_pay) == 0 ) { + #completely unapplied + $pre = 'Unapplied '; + $post = ''; + $apply = qq! (apply)'; + } elsif ( scalar(@cust_bill_pay) == 1 && $cust_pay->unapplied == 0 ) { + #applied to one invoice + $desc = ' applied to Invoice #'. $cust_bill_pay[0]->invnum; + } 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). + + } + if ( $cust_pay->unapplied > 0 ) { + $desc .= '  '. + '$'. + $cust_pay->unapplied. ' unapplied'. + qq! (apply)'. + '
    '; + } } - - my(@cust_credit_bill)= - qsearch('cust_credit_bill', { 'invnum'=> $bref->{invnum} } ); - foreach my $cust_credit_bill (@cust_credit_bill) { - my $cust_credit = $cust_credit_bill->cust_credit; - my($date, $invnum, $crednum, $amount, $reason, $app_date ) = ( - $cust_credit->_date, - $cust_credit_bill->invnum, - $cust_credit_bill->crednum, - $cust_credit_bill->amount, - $cust_credit->reason, - time2str("%D", $cust_credit_bill->_date), - ); - my $delete = - $cust_credit->closed !~ /^Y/i && $conf->exists('deletecredits') - ? qq! (delete)! - : ''; - my $unapply = - $cust_credit->closed !~ /^Y/i && $conf->exists('unapplycredits') - ? qq! (unapply)! - : ''; - push @history, - "$date\tCredit #$crednum: $reason
    ". - "(applied to invoice #$invnum on $app_date)$delete$unapply\t\t\t$amount\t"; + + my $delete = ''; + if ( $cust_pay->closed !~ /^Y/i && $conf->exists('deletepayments') ) { + $delete = qq! (delete)!; } - } - - my @credits = grep { scalar(my @array = $_->cust_credit_refund) } - qsearch('cust_credit',{'custnum'=>$custnum}); - foreach my $credit (@credits) { - my($cref)=$credit->hashref; - my(@cust_credit_refund)= - qsearch('cust_credit_refund', { 'crednum'=> $cref->{crednum} } ); - foreach my $cust_credit_refund (@cust_credit_refund) { - my $cust_refund = $cust_credit_refund->cust_credit; - my($date, $crednum, $amount, $reason, $app_date ) = ( - $credit->_date, - $credit->crednum, - $cust_credit_refund->amount, - $credit->reason, - time2str("%D", $cust_credit_refund->_date), - ); - push @history, - "$date\tCredit #$crednum: $reason
    ". - "(applied to refund on $app_date)\t\t\t$amount\t"; + + my $unapply = ''; + if ( $cust_pay->closed !~ /^Y/i + && $conf->exists('unapplypayments') + && scalar(@cust_bill_pay) ) { + $unapply = qq! (unapply)!; } + + push @history, { + 'date' => $cust_pay->_date, + 'desc' => $pre. "Payment$post$info$desc". + "$apply$delete$unapply", + 'payment' => $cust_pay->paid, + 'target' => $target, + }; } - - @credits = grep { $_->credited > 0 } - qsearch('cust_credit',{'custnum'=>$custnum}); - foreach my $credit (@credits) { - my($cref)=$credit->hashref; - my $delete = - $credit->closed !~ /^Y/i && $conf->exists('deletecredits') - ? qq! (delete)! - : ''; - push @history, - $cref->{_date} . "\t" . - qq!!. - 'Unapplied credit #' . - $cref->{crednum} . ": ". - $cref->{reason} . "$delete\t\t\t" . $credit->credited . "\t"; - } - - my(@refunds)=qsearch('cust_refund',{'custnum'=> $custnum } ); - foreach my $refund (@refunds) { - my($rref)=$refund->hashref; - my($refundnum) = ( - $refund->refundnum, - ); - - push @history, - $rref->{_date} . "\tRefund #$refundnum, (" . - $rref->{payby} . " " . $rref->{payinfo} . ") by " . - $rref->{otaker} . " - ". $rref->{reason} . "\t\t\t\t" . - $rref->{refund}; + + #credits (some false laziness w/payments) + foreach my $cust_credit ($cust_main->cust_credit) { + + my @cust_credit_bill = $cust_credit->cust_credit_bill; + my @cust_credit_refund = $cust_credit->cust_credit_refund; + + my( $pre, $post, $desc, $apply, $ext ) = ( '', '', '', '', '' ); + if ( scalar(@cust_credit_bill) == 0 + && scalar(@cust_credit_refund) == 0 ) { + #completely unapplied + $pre = 'Unapplied '; + $post = ''; + $apply = qq! (apply)'; + } elsif ( scalar(@cust_credit_bill) == 1 + && scalar(@cust_credit_refund) == 0 + && $cust_credit->credited == 0 ) { + #applied to one invoice + $desc = ' applied to Invoice #'. $cust_credit_bill[0]->invnum; + } elsif ( scalar(@cust_credit_bill) == 0 + && scalar(@cust_credit_refund) == 1 + && $cust_credit->credited == 0 ) { + #applied to one refund + $desc = ' refunded on '. time2str("%D", $cust_credit_refund[0]->_date); + } else { + #complicated + $desc = '
    '; + foreach my $app ( sort { $a->_date <=> $b->_date } + ( @cust_credit_bill, @cust_credit_refund ) ) { + if ( $app->isa('FS::cust_credit_bill') ) { + $desc .= '  '. + '$'. $app->amount. + ' applied to Invoice #'. $app->invnum. + '
    '; + #' on '. time2str("%D", $app->_date). + } elsif ( $app->isa('FS::cust_credit_refund') ) { + $desc .= '  '. + '$'. $app->amount. + ' refunded on'. time2str("%D", $app->_date). + '
    '; + } else { + die "$app is not a FS::cust_credit_bill or a FS::cust_credit_refund"; + } + } + if ( $cust_credit->credited > 0 ) { + $desc .= ' - $'. + $cust_credit->unapplied. ' unapplied'. + qq! (apply'. + '
    '; + } + } +# + my $delete = ''; + if ( $cust_credit->closed !~ /^Y/i && $conf->exists('deletecredits') ) { + $delete = qq! (delete)!; + } + + my $unapply = ''; + if ( $cust_credit->closed !~ /^Y/i + && $conf->exists('unapplycredits') + && scalar(@cust_credit_bill) ) { + $unapply = qq! (unapply)!; + } + + push @history, { + 'date' => $cust_credit->_date, + 'desc' => $pre. "Credit$post by ". $cust_credit->otaker. + ' ('. $cust_credit->reason. ')'. + "$desc$apply$delete$unapply", + 'credit' => $cust_credit->amount, + }; + } - - my @unapplied_payments = - grep { $_->unapplied > 0 } qsearch('cust_pay', { 'custnum' => $custnum } ); - foreach my $payment (@unapplied_payments) { - my $payby = $payment->payby; - my $payinfo = $payment->payinfo; - #false laziness w/above + + #refunds + foreach my $cust_refund ($cust_main->cust_refund) { + + my $payby = $cust_refund->payby; + my $payinfo = $cust_refund->payinfo; + $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/^(CARD|COMP)$/$1 /; - my $delete = $payment->closed !~ /^Y/i && $conf->exists('deletepayments') - ? qq! (delete)! - : ''; - push @history, - $payment->_date. "\t". - 'Unapplied payment #' . - $payment->paynum . " ($payby$payinfo) ". - '('. - "apply)$delete". - "\t\t" . $payment->unapplied . "\t\t\t$target"; + + push @history, { + 'date' => $cust_refund->_date, + 'desc' => "Refund ($payby$payinfo) by ". $cust_refund->otaker, + 'refund' => $cust_refund->refund, + }; + } - #formatting - print &table(), < + + <%= table() %> Date Description @@ -737,59 +778,67 @@ if ( $conf->config('payby-default') ne 'HIDE' ) { Refund Balance -END - + + <% #display payment history - + + my %target; my $balance = 0; - foreach my $item (sort keyfield_numerically @history) { - my($date,$desc,$charge,$payment,$credit,$refund,$target)=split(/\t/,$item); - $charge ||= 0; - $payment ||= 0; - $credit ||= 0; - $refund ||= 0; - $balance += $charge - $payment; - $balance -= $credit - $refund; + foreach my $item ( sort { $a->{'date'} <=> $b->{'date'} } @history ) { + + my $charge = exists($item->{'charge'}) + ? sprintf('$%.2f', $item->{'charge'}) + : ''; + my $payment = exists($item->{'payment'}) + ? sprintf('- $%.2f', $item->{'payment'}) + : ''; + my $credit = exists($item->{'credit'}) + ? sprintf('- $%.2f', $item->{'credit'}) + : ''; + my $refund = exists($item->{'refund'}) + ? sprintf('$%.2f', $item->{'refund'}) + : ''; + + my $target = exists($item->{'target'}) ? $item->{'target'} : ''; + + $balance += $item->{'charge'} if exists $item->{'charge'}; + $balance -= $item->{'payment'} if exists $item->{'payment'}; + $balance -= $item->{'credit'} if exists $item->{'credit'}; + $balance += $item->{'refund'} if exists $item->{'refund'}; $balance = sprintf("%.2f", $balance); $balance =~ s/^\-0\.00$/0.00/; #yay ieee fp - $target = '' unless defined $target; + + %> - print ""; - print qq!! unless $target && $target{$target}++; - print time2str("%D",$date); - print '' if $target && $target{$target} == 1; - print "", - "$desc", - "", - ( $charge ? "\$".sprintf("%.2f",$charge) : '' ), - "", - "", - ( $payment ? "- \$".sprintf("%.2f",$payment) : '' ), - "", - "", - ( $credit ? "- \$".sprintf("%.2f",$credit) : '' ), - "", - "", - ( $refund ? "\$".sprintf("%.2f",$refund) : '' ), - "", - "\$" . $balance, - "", - "\n"; - } + + + <% unless ( !$target || $target{$target}++ ) { %> + + <% } %> + <%= time2str("%D",$item->{'date'}) %> + <% if ( $target && $target{$target} == 1 ) { %> + + <% } %> + + + <%= $item->{'desc'} %> + <%= $charge %> + <%= $payment %> + <%= $credit %> + <%= $refund %> + $<%= $balance %> + + + <% } %> - print ""; - -} + -print ''; - -#subroutiens -sub keyfield_numerically { (split(/\t/,$a))[0] <=> (split(/\t/,$b))[0]; } +<% } %> -%> + <% - +#subroutines sub get_packages { my $cust_main = shift or return undef; -- cgit v1.2.1 From 351b0af13ba6c449151c1bec2303294051c073d1 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 22 Mar 2004 10:16:43 +0000 Subject: yay! remove package view entirely (closes: Bug#569) --- httemplate/misc/expire_pkg.cgi | 64 +++++++++++++++++++++++++--------- httemplate/misc/process/expire_pkg.cgi | 25 +++++++++++++ httemplate/view/cust_main.cgi | 40 ++++++++++++--------- 3 files changed, 96 insertions(+), 33 deletions(-) create mode 100755 httemplate/misc/process/expire_pkg.cgi (limited to 'httemplate') diff --git a/httemplate/misc/expire_pkg.cgi b/httemplate/misc/expire_pkg.cgi index 9e4ce8b62..b59674a69 100755 --- a/httemplate/misc/expire_pkg.cgi +++ b/httemplate/misc/expire_pkg.cgi @@ -1,25 +1,55 @@ + <% -#untaint date & pkgnum - -my $date; -if ( $cgi->param('date') ) { - str2time($cgi->param('date')) =~ /^(\d+)$/ or die "Illegal date"; - $date=$1; -} else { - $date=''; -} - -$cgi->param('pkgnum') =~ /^(\d+)$/ or die "Illegal pkgnum"; +my($query) = $cgi->keywords; +$query =~ /^(\d+)$/; my $pkgnum = $1; +#get package record my $cust_pkg = qsearchs('cust_pkg',{'pkgnum'=>$pkgnum}); -my %hash = $cust_pkg->hash; -$hash{expire}=$date; -my $new = new FS::cust_pkg ( \%hash ); -my $error = $new->replace($cust_pkg); -&eidiot($error) if $error; +die "Unknown pkgnum $pkgnum" unless $cust_pkg; +my $part_pkg = $cust_pkg->part_pkg; + +my $custnum = $cust_pkg->getfield('custnum'); -print $cgi->redirect(popurl(2). "view/cust_main.cgi?".$cust_pkg->getfield('custnum')); +my $date = $cust_pkg->expire ? time2str('%D', $cust_pkg->expire) : ''; %> + +<%= header('Expire package', menubar( + "View this customer (#$custnum)" => "${p}view/cust_main.cgi?$custnum", + 'Main Menu' => popurl(2) +)) %> + + + + + + +<%= $pkgnum %>: <%= $part_pkg->pkg. ' - '. $part_pkg->comment %> + +
    + + + + + + +
    Cancel package on + +
    m/d/y +
    + + + + +
    + + diff --git a/httemplate/misc/process/expire_pkg.cgi b/httemplate/misc/process/expire_pkg.cgi new file mode 100755 index 000000000..dc35592ce --- /dev/null +++ b/httemplate/misc/process/expire_pkg.cgi @@ -0,0 +1,25 @@ +<% + +#untaint date & pkgnum + +my $date; +if ( $cgi->param('date') ) { + str2time($cgi->param('date')) =~ /^(\d+)$/ or die "Illegal date"; + $date=$1; +} else { + $date=''; +} + +$cgi->param('pkgnum') =~ /^(\d+)$/ or die "Illegal pkgnum"; +my $pkgnum = $1; + +my $cust_pkg = qsearchs('cust_pkg',{'pkgnum'=>$pkgnum}); +my %hash = $cust_pkg->hash; +$hash{expire}=$date; +my $new = new FS::cust_pkg ( \%hash ); +my $error = $new->replace($cust_pkg); +&eidiot($error) if $error; + +print $cgi->redirect(popurl(3). "view/cust_main.cgi?".$cust_pkg->getfield('custnum')); + +%> diff --git a/httemplate/view/cust_main.cgi b/httemplate/view/cust_main.cgi index 229362e6c..8d8af63d6 100755 --- a/httemplate/view/cust_main.cgi +++ b/httemplate/view/cust_main.cgi @@ -20,7 +20,6 @@ print header("Customer View", menubar( @@ -382,7 +381,7 @@ if ( @$packages ) { %> - + @@ -402,9 +401,9 @@ foreach my $pkg (sort pkgsort_pkgnum_cancel @$packages) { %> - \n! if ($cnt > 0); - print qq! \n\n!; + print qq! \n\n!; } } } @@ -946,13 +945,21 @@ sub svc_label_link { } sub svc_provision_link { - my ($pkg, $svcpart) = (shift,shift) or return ''; + my ($pkg, $svcpart, $conf) = @_; ( my $svc_nbsp = $svcpart->{svc} ) =~ s/\s+/ /g; - return qq!! . - "Provision $svc_nbsp (". - ($svcpart->{quantity} - $svcpart->{count}). - ')'; + my $pkgnum_svcpart = "pkgnum$pkg->{pkgnum}-svcpart$svcpart->{svcpart}"; + my $num_left = $svcpart->{quantity} - $svcpart->{count}; + + my $link = qq!!. + "Provision $svc_nbsp ($num_left)"; + if ( $conf->exists('legacy_link') ) { + $link .= '
    '. + qq!!. + "Link to legacy $svc_nbsp ($num_left)"; + } + $link; } sub svc_unprovision_link { @@ -983,10 +990,10 @@ sub pkg_datestr { $strip; } -sub pkg_details_link { - my $pkg = shift or return ''; - return qq!Details!; -} +#sub pkg_details_link { +# my $pkg = shift or return ''; +# return qq!Details!; +#} sub pkg_change_link { my $pkg = shift or return ''; @@ -1005,7 +1012,8 @@ sub pkg_unsuspend_link { sub pkg_cancel_link { my $pkg = shift or return ''; - return qq!Cancel!; + qq!Cancel now | !. + qq!Cancel later!; } sub pkg_dates_link { -- cgit v1.2.1
    PackagePackage Status Services
    CLASS="pkgnum"><%=$pkg->{pkgnum}%> > - <%=$pkg->{pkg}%> - <%=$pkg->{comment}%> ( <%=pkg_details_link($pkg)%> )
    + <%=$pkg->{pkgnum}%>: + <%=$pkg->{pkg}%> - <%=$pkg->{comment}%>
    <% unless ($pkg->{cancel}) { %> ( <%=pkg_change_link($pkg)%> ) ( <%=pkg_dates_link($pkg)%> | <%=pkg_customize_link($pkg,$custnum)%> ) @@ -538,7 +537,7 @@ foreach my $pkg (sort pkgsort_pkgnum_cancel @$packages) { } if ($svcpart->{count} < $svcpart->{quantity}) { print qq!
    !.svc_provision_link($pkg,$svcpart).qq!
    !.svc_provision_link($pkg, $svcpart, $conf).qq!