diff options
Diffstat (limited to 'httemplate/misc')
35 files changed, 891 insertions, 349 deletions
diff --git a/httemplate/misc/bulk_change_pkg.cgi b/httemplate/misc/bulk_change_pkg.cgi index 9334985..7f47a84 100755 --- a/httemplate/misc/bulk_change_pkg.cgi +++ b/httemplate/misc/bulk_change_pkg.cgi @@ -7,17 +7,23 @@ <FORM ACTION="<% $p %>misc/process/bulk_change_pkg.cgi" METHOD=POST> -<INPUT TYPE="hidden" NAME="query" VALUE="<% $cgi->keywords %>"> -% for my $param (qw(agentnum magic status classnum pkgpart)) { -<INPUT TYPE="hidden" NAME="<% $param %>" VALUE="<% $cgi->param($param) %>"> +%# some false laziness w/search/cust_pkg.cgi + +<INPUT TYPE="hidden" NAME="query" VALUE="<% $cgi->keywords |h %>"> +% for my $param (qw(agentnum magic status classnum custom censustract)) { +<INPUT TYPE="hidden" NAME="<% $param %>" VALUE="<% $cgi->param($param) |h %>"> % } % +% foreach my $pkgpart ($cgi->param('pkgpart')) { +<INPUT TYPE="hidden" NAME="pkgpart" VALUE="<% $pkgpart |h %>"> +% } +% % foreach my $field (qw( setup last_bill bill adjourn susp expire cancel )) { % - <INPUT TYPE="hidden" NAME="<% $field %>begin" VALUE="<% $cgi->param("${field}.begin") %>"> - <INPUT TYPE="hidden" NAME="<% $field %>beginning" VALUE="<% $cgi->param("${field}beginning") %>"> - <INPUT TYPE="hidden" NAME="<% $field %>end" VALUE="<% $cgi->param("${field}.end") %>"> - <INPUT TYPE="hidden" NAME="<% $field %>ending" VALUE="<% $cgi->param("${field}.ending") %>"> + <INPUT TYPE="hidden" NAME="<% $field %>begin" VALUE="<% $cgi->param("${field}.begin") |h %>"> + <INPUT TYPE="hidden" NAME="<% $field %>beginning" VALUE="<% $cgi->param("${field}beginning") |h %>"> + <INPUT TYPE="hidden" NAME="<% $field %>end" VALUE="<% $cgi->param("${field}.end") |h %>"> + <INPUT TYPE="hidden" NAME="<% $field %>ending" VALUE="<% $cgi->param("${field}.ending") |h %>"> % } <% ntable('#cccccc') %> @@ -28,10 +34,7 @@ 'table' => 'part_pkg', 'name_col' => 'pkg', 'empty_label' => 'Select package', - 'label_callback' => sub { $_[0]->pkgpart. ': '. - $_[0]->pkg. ' - '. - $_[0]->comment; - }, + 'label_callback' => sub { $_[0]->pkg_comment }, 'element_name' => 'new_pkgpart', 'curr_value' => ( $cgi->param('error') ? scalar($cgi->param('new_pkgpart')) diff --git a/httemplate/misc/cancel_pkg.html b/httemplate/misc/cancel_pkg.html index e0e5fd1..607ce13 100755 --- a/httemplate/misc/cancel_pkg.html +++ b/httemplate/misc/cancel_pkg.html @@ -17,7 +17,7 @@ <BR><BR> -<% ucfirst($method) . " $pkgnum: " .$part_pkg->pkg. ' - ' .$part_pkg->comment %> +<% ucfirst($method) %> <% $part_pkg->pkg_comment %> <% ntable("#cccccc", 2) %> % if ($method eq 'expire' || $method eq 'adjourn') { diff --git a/httemplate/misc/change_pkg.cgi b/httemplate/misc/change_pkg.cgi index c4dfca2..16b7071 100755 --- a/httemplate/misc/change_pkg.cgi +++ b/httemplate/misc/change_pkg.cgi @@ -13,19 +13,15 @@ <% $curuser->option('show_pkgnum') ? $cust_pkg->pkgnum.': ' : '' %><B><% $part_pkg->pkg |h %></B> - <% $part_pkg->comment |h %> </TD> </TR> - - <TR> - <TH ALIGN="right">New package</TH> - <TD COLSPAN=7> - <% include('/elements/select-cust-part_pkg.html', - 'cust_main' => $cust_main, - 'element_name' => 'pkgpart', - #'extra_sql' => ' AND pkgpart != '. $cust_pkg->pkgpart, - 'curr_value' => scalar($cgi->param('pkgpart')), - ) - %> - </TD> - </TR> + + <% include('/elements/tr-select-cust-part_pkg.html', + 'pre_label' => 'New', + 'curr_value' => scalar($cgi->param('pkgpart')), + 'classnum' => $part_pkg->classnum, + 'cust_main' => $cust_main, + #'extra_sql' => ' AND pkgpart != '. $cust_pkg->pkgpart, + ) + %> <% include('/elements/tr-select-cust_location.html', 'cgi' => $cgi, diff --git a/httemplate/misc/cust-part_pkg.cgi b/httemplate/misc/cust-part_pkg.cgi new file mode 100644 index 0000000..a249f03 --- /dev/null +++ b/httemplate/misc/cust-part_pkg.cgi @@ -0,0 +1,29 @@ +<% objToJson( \@return ) %> +<%init> + +my( $custnum, $classnum ) = $cgi->param('arg'); + +#XXX i guess i should be agent-virtualized. cause "packages a customer can +#order" is such a huge deal +my $cust_main = qsearchs('cust_main', { 'custnum' => $custnum } ); + +my %hash = ( 'disabled' => '' ); +if ( $classnum > 0 ) { + $hash{'classnum'} = $classnum; +} elsif ( $classnum eq '' || $classnum == 0 ) { + $hash{'classnum'} = ''; +} #else -1, all classes, so don't set classnum + +my @part_pkg = qsearch({ + 'table' => 'part_pkg', + 'hashref' => \%hash, + 'extra_sql' => + ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql( 'null'=>1 ). + ' AND '. FS::part_pkg->agent_pkgs_sql( $cust_main->agent ), +}); + +my @return = map { $_->pkgpart => $_->pkg_comment } + sort { $a->pkg_comment cmp $b->pkg_comment } + @part_pkg; + +</%init> diff --git a/httemplate/misc/cust_main-import.cgi b/httemplate/misc/cust_main-import.cgi index b822c5d..9c1f984 100644 --- a/httemplate/misc/cust_main-import.cgi +++ b/httemplate/misc/cust_main-import.cgi @@ -56,7 +56,7 @@ Import a file containing customer records. <SELECT NAME="pkgpart"><OPTION VALUE="">(none)</OPTION> % foreach my $part_pkg ( qsearch('part_pkg',{'disabled'=>'' }) ) { - <OPTION VALUE="<% $part_pkg->pkgpart %>"><% $part_pkg->pkg. ' - '. $part_pkg->comment %></OPTION> + <OPTION VALUE="<% $part_pkg->pkgpart %>"><% $part_pkg->pkg_comment %></OPTION> % } </SELECT> diff --git a/httemplate/misc/delay_susp_pkg.html b/httemplate/misc/delay_susp_pkg.html index 1158a35..d4a6da1 100755 --- a/httemplate/misc/delay_susp_pkg.html +++ b/httemplate/misc/delay_susp_pkg.html @@ -12,7 +12,7 @@ <INPUT TYPE="hidden" NAME="pkgnum" VALUE="<% $pkgnum %>"> <BR><BR> -<% "Delay automatic suspension of $pkgnum: " .$part_pkg->pkg. ' - ' .$part_pkg->comment %> +<% "Delay automatic suspension of " .$part_pkg->pkg_comment %> <% ntable("#cccccc", 2) %> <TR> diff --git a/httemplate/misc/delete-cust_bill.html b/httemplate/misc/delete-cust_bill.html new file mode 100644 index 0000000..3a642b0 --- /dev/null +++ b/httemplate/misc/delete-cust_bill.html @@ -0,0 +1,21 @@ +% if ( $error ) { +% errorpage($error); +% } else { +<% $cgi->redirect($p. "view/cust_main.cgi?". $custnum) %> +% } +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Delete invoices'); + +#untaint invnum +my($query) = $cgi->keywords; +$query =~ /^(\d+)$/ || die "Illegal crednum"; +my $invnum = $1; + +my $cust_bill = qsearchs('cust_bill',{'invnum'=>$invnum}); +my $custnum = $cust_bill->custnum; + +my $error = $cust_bill->delete; + +</%init> diff --git a/httemplate/misc/delete-phone_device.html b/httemplate/misc/delete-phone_device.html new file mode 100755 index 0000000..7220c41 --- /dev/null +++ b/httemplate/misc/delete-phone_device.html @@ -0,0 +1,23 @@ +% if ( $error ) { +% errorpage($error); +% } else { +<% $cgi->redirect($p. "view/svc_phone.cgi?". $svcnum) %> +% } +<%init> + +# :/ needs agent-virt so you can't futz with arbitrary devices + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Provision customer service'); #something else more specific? + +#untaint devicenum +my($query) = $cgi->keywords; +$query =~ /^(\d+)$/ || die "Illegal devicenum"; +my $devicenum = $1; + +my $phone_device = qsearchs('phone_device', { 'devicenum' => $devicenum } ); +my $svcnum = $phone_device->svcnum; + +my $error = $phone_device->delete; + +</%init> diff --git a/httemplate/misc/download-batch.cgi b/httemplate/misc/download-batch.cgi index 57905da..01bf5d2 100644 --- a/httemplate/misc/download-batch.cgi +++ b/httemplate/misc/download-batch.cgi @@ -1,146 +1,9 @@ -%if ($format eq "BoM") { -% -% my($origid,$datacenter,$typecode,$shortname,$longname,$mybank,$myacct) = -% $conf->config("batchconfig-$format"); -% -<% sprintf( "A%10s%04u%06u%05u%54s\n",$origid,$pay_batch->batchnum,$jdate,$datacenter,""). - sprintf( "XD%03u%06u%-15s%-30s%09u%-12s \n",$typecode,$jdate,$shortname,$longname,$mybank,$myacct ) - %> -% -%}elsif ($format eq "PAP"){ -% -% my($origid,$datacenter,$typecode,$shortname,$longname,$mybank,$myacct) = -% $conf->config("batchconfig-$format"); -% -<% sprintf( "H%10sD%3s%06u%-15s%09u%-12s%04u%19s\n",$origid,$typecode,$cdate,$shortname,$mybank,$myacct,$pay_batch->batchnum,"") %> -% -% -%}elsif ($format eq "csv-td_canada_trust-merchant_pc_batch"){ -%# 1; -%}elsif ($format eq "csv-chase_canada-E-xactBatch"){ -% -% my($origid) = $conf->config("batchconfig-$format"); -<% sprintf( '$$E-xactBatchFileV1.0$$%s:%03u$$%s',$sdate,$pay_batch->batchnum, $origid) - %> -% -%}elsif ($format eq "ach-spiritone"){ -%# 1; -%}else{ -% die "Unknown format for batch in batchconfig. \n"; -%} -% -% -%for my $cust_pay_batch ( sort { $a->paybatchnum <=> $b->paybatchnum } -% qsearch('cust_pay_batch', -% {'batchnum'=>$pay_batch->batchnum} ) -%) { -% -% $cust_pay_batch->exp =~ /^\d{2}(\d{2})[\/\-](\d+)[\/\-]\d+$/; -% my( $mon, $y ) = ( $2, $1 ); -% if ( $conf->exists('batch-increment_expiration') ) { -% my( $curmon, $curyear ) = (localtime(time))[4,5]; -% $curmon++; $curyear-=100; -% $y++ while $y < $curyear || ( $y == $curyear && $mon < $curmon ); -% } -% $mon = "0$mon" if $mon =~ /^\d$/; -% $y = "0$y" if $y =~ /^\d$/; -% my $exp = "$mon$y"; -% -% if ( $first_download ) { -% my $balance = $cust_pay_batch->cust_main->balance; -% if ( $balance <= 0 ) { -% my $error = $cust_pay_batch->delete; -% if ( $error ) { -% $dbh->rollback or die $dbh->errstr if $oldAutoCommit; -% die $error; -% } -% next; -% } elsif ( $balance < $cust_pay_batch->amount ) { -% $cust_pay_batch->amount($balance); -% my $error = $cust_pay_batch->replace; -% if ( $error ) { -% $dbh->rollback or die $dbh->errstr if $oldAutoCommit; -% die $error; -% } -% #} elsif ( $balance > $cust_pay_batch->amount ) { -% } -% } -% -% $batchcount++; -% $batchtotal += $cust_pay_batch->amount; -% -% if ($format eq "BoM") { -% -% my( $account, $aba ) = split( '@', $cust_pay_batch->payinfo ); -% -<% sprintf( "D%010.0f%09u%-12s%-29s%-19s\n",$cust_pay_batch->amount*100,$aba,$account,$cust_pay_batch->payname,$cust_pay_batch->paybatchnum) %> -% -% -% } elsif ($format eq "PAP"){ -% -% my( $account, $aba ) = split( '@', $cust_pay_batch->payinfo ); -% -<% sprintf( "D%-23s%06u%-19s%09u%-12s%010.0f\n",$cust_pay_batch->payname,$cdate,$cust_pay_batch->paybatchnum,$aba,$account,$cust_pay_batch->amount*100) %> -% -% -% } elsif ($format eq "csv-td_canada_trust-merchant_pc_batch") { -% -% -,,,,<% $cust_pay_batch->payinfo %>,<% $exp %>,<% $cust_pay_batch->amount %>,<% $cust_pay_batch->paybatchnum %> -% -% -% } elsif ($format eq "csv-chase_canada-E-xactBatch"){ -% -% my $payname=$cust_pay_batch->payname; $payname =~ tr/",/ /; #payinfo too? :P -<% $cust_pay_batch->paybatchnum %>,<% $cust_pay_batch->custnum %>,<% $cust_pay_batch->invnum %>,"<% $payname %>",00,<% $cust_pay_batch->payinfo %>,<% $cust_pay_batch->amount %>,<% $exp %>,, -% -% -% }elsif ($format eq "ach-spiritone"){ -% -% my( $account, $aba ) = split( '@', $cust_pay_batch->payinfo ); -% my $payname=$cust_pay_batch->first. " ". $cust_pay_batch->last; -% $payname =~ tr/",/ /; #payinfo too? -% my $batchline = qq!"$payname","!.$cust_pay_batch->paybatchnum. -% qq!","$aba","$account","27","!.$cust_pay_batch->amount. -% qq!","27","0.00"!; -% push @batchlines, $batchline; -<% $batchline %> -% -% } else { -% die "I'm already dead, but you did not know that.\n"; -% } -% -%} -% -%if ($format eq "BoM") { -% -% -<% sprintf( "YD%08u%014.0f%56s\n",$batchcount,$batchtotal*100,"" ). - sprintf( "Z%014u%05u%014u%05u%41s\n",$batchtotal*100,$batchcount,"0","0","" ) %> -% -% -%} elsif ($format eq "PAP"){ -% -% -<% sprintf( "T%08u%014.0f%57s\n",$batchcount,$batchtotal*100,"" ) %> -% -% -%} elsif ($format eq "csv-td_canada_trust-merchant_pc_batch"){ -% #1; -%} elsif ($format eq "csv-chase_canada-E-xactBatch"){ -% #1; -%} elsif ($format eq "ach-spiritone"){ -% #1; -%} else { -% die "I'm already dead (again), but you did not know that.\n"; -%} -% -<%init> +<% $pay_batch->export_batch($format) %> -my $conf=new FS::Conf; +<%init> #http_header('Content-Type' => 'text/comma-separated-values' ); #IE chokes -http_header('Content-Type' => 'text/plain' ); +http_header('Content-Type' => 'text/plain' ); # not necessarily correct... my $batchnum; if ( $cgi->param('batchnum') =~ /^(\d+)$/ ) { @@ -152,62 +15,9 @@ if ( $cgi->param('batchnum') =~ /^(\d+)$/ ) { my $format; if ( $cgi->param('format') =~ /^([\w\- ]+)$/ ) { $format = $1; -} else { - $format = $conf->config('batch-default_format'); -} - -my $autopost; -if ( $format eq 'ach-spiritone' ) { - $autopost = 1; -}else{ - $autopost = 0; -} - -my $oldAutoCommit = $FS::UID::AutoCommit; -local $FS::UID::AutoCommit = 0; -my $dbh = dbh; - -my $pay_batch = qsearchs('pay_batch', {'batchnum'=>$batchnum, 'status'=>'O'} ); -my $first_download = 1; -unless ($pay_batch) { - $pay_batch = qsearchs('pay_batch', {'batchnum'=>$batchnum, 'status'=>'I'} ) - if $FS::CurrentUser::CurrentUser->access_right('Reprocess batches'); - $first_download = 0; } -die "No pending batch. \n" unless $pay_batch; -my $error = $pay_batch->set_status('I'); -die "error updating batch status: $error\n" if $error; +my $pay_batch = qsearchs('pay_batch', { batchnum => $batchnum } ); +die "Batch not found: '$batchnum'" if !$pay_batch; -my $batchtotal=0; -my $batchcount=0; - -my (@date)=localtime($pay_batch->download); -my $jdate = sprintf("%03d", $date[5] % 100).sprintf("%03d", $date[7] + 1); -my $cdate = sprintf("%02d", $date[3]).sprintf("%02d", $date[4] + 1). - sprintf("%02d", $date[5] % 100); -my $sdate = sprintf("%02d", $date[5] % 100).'/'.sprintf("%02d", $date[4] + 1). - '/'.sprintf("%02d", $date[3]); - -my @batchlines = (); </%init> -<%cleanup> -if ($autopost) { - my $dir = $FS::UID::conf_dir. "/cache.". $FS::UID::datasrc; - my $fh = new File::Temp( - TEMPLATE => 'paybatch.'. $batchnum .'.XXXXXXXX', - DIR => $dir, - ) or die "can't open temp file: $!\n"; - - print $fh map{ "$_\n" } @batchlines; - seek $fh, 0, 0; - - $error = $pay_batch->import_results( 'filehandle' => $fh, - 'format' => $format, - ); - die $error if $error; -} - -$dbh->commit or die $dbh->errstr if $oldAutoCommit; - -</%cleanup> diff --git a/httemplate/misc/email-customers.html b/httemplate/misc/email-customers.html index 0d3d622..f644db9 100644 --- a/httemplate/misc/email-customers.html +++ b/httemplate/misc/email-customers.html @@ -126,7 +126,7 @@ die "access denied" my %search = $cgi->Vars; delete $search{$_} for qw( magic from subject html_body text_body ); $search{$_} = [ split(/\0/, $search{$_}) ] - foreach grep $search{$_} =~ /\0/, keys %search; + foreach grep { $_ eq 'payby' || $search{$_} =~ /\0/ } keys %search; my $title = 'Bulk send customer notices'; diff --git a/httemplate/misc/link.cgi b/httemplate/misc/link.cgi index 748eaa1..f37f769 100755 --- a/httemplate/misc/link.cgi +++ b/httemplate/misc/link.cgi @@ -58,6 +58,7 @@ die "access denied" my %link_field = ( 'svc_acct' => 'username', 'svc_domain' => 'domain', + 'svc_phone' => 'phonenum', ); my %link_field2 = ( diff --git a/httemplate/misc/meta-import.cgi b/httemplate/misc/meta-import.cgi index 5b3470c..8c158bd 100644 --- a/httemplate/misc/meta-import.cgi +++ b/httemplate/misc/meta-import.cgi @@ -46,7 +46,7 @@ Import data from a DBI data source<BR><BR> First package: <SELECT NAME="pkgpart"><OPTION VALUE="">(none)</OPTION> % foreach my $part_pkg ( qsearch('part_pkg',{'disabled'=>'' }) ) { - <OPTION VALUE="<% $part_pkg->pkgpart %>"><% $part_pkg->pkg. ' - '. $part_pkg->comment %></OPTION> + <OPTION VALUE="<% $part_pkg->pkgpart %>"><% $part_pkg->pkg_comment %></OPTION> % } </SELECT><BR><BR> diff --git a/httemplate/misc/order_pkg.html b/httemplate/misc/order_pkg.html index 2c83351..a7571ca 100644 --- a/httemplate/misc/order_pkg.html +++ b/httemplate/misc/order_pkg.html @@ -1,5 +1,10 @@ <% include('/elements/header-popup.html', 'Order new package' ) %> +<LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2"> +<SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT> +<SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT> + <SCRIPT TYPE="text/javascript"> function enable_order_pkg () { @@ -19,18 +24,42 @@ <INPUT TYPE="hidden" NAME="custnum" VALUE="<% $cust_main->custnum %>"> <% ntable("#cccccc", 2) %> +<% include('/elements/tr-select-cust-part_pkg.html', + 'curr_value' => $pkgpart, + 'classnum' => -1, + 'cust_main' => $cust_main, + 'onchange' => 'enable_order_pkg', + ) +%> + +%# false laziness w/edit/quick-charge.html <TR> - <TH ALIGN="right">Package</TH> - <TD COLSPAN=7> - <% include('/elements/select-cust-part_pkg.html', - 'curr_value' => $pkgpart, - 'cust_main' => $cust_main, - 'onchange' => 'enable_order_pkg', - ) - %> + <TH ALIGN="right">Start date </TD> + <TD COLSPAN=6> + <INPUT TYPE = "text" + NAME = "start_date" + SIZE = 32 + ID = "start_date_text" + VALUE = "<% $start_date %>" + > + <IMG SRC = "../images/calendar.png" + ID = "start_date_button" + STYLE = "cursor: pointer" + TITLE = "Select date" + > + <FONT SIZE=-1>(leave blank to start immediately)</FONT> </TD> </TR> +<SCRIPT TYPE="text/javascript"> + Calendar.setup({ + inputField: "start_date_text", + ifFormat: "%m/%d/%Y", + button: "start_date_button", + align: "BR" + }); +</SCRIPT> + % if ( $conf->exists('pkg_referral') ) { <% include('/elements/tr-select-part_referral.html', 'curr_value' => scalar( $cgi->param('refnum') ), #get rid of empty_label first# || $cust_main->refnum, @@ -72,4 +101,8 @@ my $cust_main = qsearchs({ my $pkgpart = scalar($cgi->param('pkgpart')); +my $format = "%m/%d/%Y %T %z (%Z)"; #false laziness w/REAL_cust_pkg.cgi? +my $start_date = $cust_main->next_bill_date; +$start_date = $start_date ? time2str($format, $start_date) : ''; + </%init> diff --git a/httemplate/misc/part_device-import.html b/httemplate/misc/part_device-import.html new file mode 100644 index 0000000..7bd6404 --- /dev/null +++ b/httemplate/misc/part_device-import.html @@ -0,0 +1,53 @@ +<% include("/elements/header.html", 'Import device types') %> + +Import a file containing phone device types, one per line. +<BR><BR> + +<% include( '/elements/form-file_upload.html', + 'name' => 'PartDeviceImportForm', + 'action' => 'process/part_device-import.html', + 'num_files' => 1, + 'fields' => [ 'format', ], + 'message' => 'Device type import successful', + 'url' => $p.'browse/part_device.html', + ) +%> + +<% &ntable("#cccccc", 2) %> + + <INPUT TYPE="hidden" NAME="format" VALUE="default"> + + <% include( '/elements/file-upload.html', + 'field' => 'file', + 'label' => 'Filename', + ) + %> + + <TR> + <TD COLSPAN=2 ALIGN="center" STYLE="padding-top:6px"> + <INPUT TYPE = "submit" + ID = "submit" + VALUE = "Import file" + onClick = "document.PartDeviceImportForm.submit.disabled=true;" + > + </TD> + </TR> + +</TABLE> + +</FORM> + +<BR> + +Upload file can be a text file or Excel spreadsheet. If an Excel spreadsheet, + should have an .XLS extension. +<BR><BR> + +<% include('/elements/footer.html') %> + +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Import'); + +</%init> diff --git a/httemplate/misc/part_svc-columns.cgi b/httemplate/misc/part_svc-columns.cgi new file mode 100644 index 0000000..0602561 --- /dev/null +++ b/httemplate/misc/part_svc-columns.cgi @@ -0,0 +1,13 @@ +<% objToJson(\@output) %> +<%init> + +my $conf = new FS::Conf; + +my $pkgpart_svcpart = $cgi->param('arg'); +$pkgpart_svcpart =~ /^\d+_(\d+)$/; +my $part_svc = qsearchs('part_svc', { 'svcpart' => $1 }) if $1; + +my @output = map { ( $_->columnname, $_->columnflag, $_->columnvalue ) } + $part_svc->all_part_svc_column; + +</%init> diff --git a/httemplate/misc/payment.cgi b/httemplate/misc/payment.cgi index 0047004..813b560 100644 --- a/httemplate/misc/payment.cgi +++ b/httemplate/misc/payment.cgi @@ -12,23 +12,66 @@ <% ntable('#cccccc') %> <TR> - <TD ALIGN="right">Payment amount</TD> - <TD> + <TH ALIGN="right">Payment amount</TH> + <TD COLSPAN=7> <TABLE><TR><TD BGCOLOR="#ffffff"> - $<INPUT TYPE="text" NAME="amount" SIZE=8 VALUE="<% $balance > 0 ? sprintf("%.2f", $balance) : '' %>"> + <% $money_char %><INPUT NAME = "amount" + TYPE = "text" + VALUE = "<% $amount %>" + SIZE = 8 + STYLE = "text-align:right;" +% if ( $fee ) { + onChange = "amount_changed(this)" + onKeyDown = "amount_changed(this)" + onKeyUp = "amount_changed(this)" + onKeyPress = "amount_changed(this)" +% } + > + </TD><TD BGCOLOR="#cccccc"> +% if ( $fee ) { + <INPUT TYPE="hidden" NAME="fee_pkgpart" VALUE="<% $fee_pkg->pkgpart %>"> + <INPUT TYPE="hidden" NAME="fee" VALUE="<% $fee_display eq 'add' ? $fee : '' %>"> + <B><FONT SIZE='+1'><% $fee_op %></FONT> + <% $money_char . $fee %> + </B> + <% $fee_pkg->pkg |h %> + <B><FONT SIZE='+1'>=</FONT></B> + </TD><TD ID="ajax_total_cell" BGCOLOR="#dddddd" STYLE="border:1px solid blue"> + <FONT SIZE="+1"><% length($amount) ? $money_char. sprintf('%.2f', ($fee_display eq 'add') ? $amount + $fee : $amount - $fee ) : '' %> <% $fee_display eq 'add' ? 'TOTAL' : 'AVAILABLE' %></FONT> + +% } </TD></TR></TABLE> </TD> </TR> +% if ( $fee ) { + + <SCRIPT TYPE="text/javascript"> + + function amount_changed(what) { + + + var total = ''; + if ( what.value.length ) { + total = parseFloat(what.value) <% $fee_op %> <% $fee %>; + /* total = Math.round(total*100)/100; */ + total = '<% $money_char %>' + total.toFixed(2); + } + + var total_cell = document.getElementById('ajax_total_cell'); + total_cell.innerHTML = '<FONT SIZE="+1">' + total + ' <% $fee_display eq 'add' ? 'TOTAL' : 'AVAILABLE' %></FONT>'; + + } + + </SCRIPT> + +% } + + % if ( $payby eq 'CARD' ) { % % my( $payinfo, $paycvv, $month, $year ) = ( '', '', '', '' ); % my $payname = $cust_main->first. ' '. $cust_main->getfield('last'); -% my $address1 = $cust_main->address1; -% my $address2 = $cust_main->address2; -% my $city = $cust_main->city; -% my $state = $cust_main->state; -% my $zip = $cust_main->zip; % if ( $cust_main->payby =~ /^(CARD|DCRD)$/ ) { % $payinfo = $cust_main->paymask; % $paycvv = $cust_main->paycvv; @@ -37,13 +80,13 @@ % } <TR> - <TD ALIGN="right">Card number</TD> - <TD> + <TH ALIGN="right">Card number</TH> + <TD COLSPAN=7> <TABLE> <TR> <TD> <INPUT TYPE="text" NAME="payinfo" SIZE=20 MAXLENGTH=19 VALUE="<%$payinfo%>"> </TD> - <TD>Exp.</TD> + <TH>Exp.</TH> <TD> <SELECT NAME="month"> % for ( ( map "0$_", 1 .. 9 ), 10 .. 12 ) { @@ -68,51 +111,23 @@ </TD> </TR> <TR> - <TD ALIGN="right">CVV2</TD> + <TH ALIGN="right">CVV2</TH> <TD><INPUT TYPE="text" NAME="paycvv" VALUE="<% $paycvv %>" SIZE=4 MAXLENGTH=4> (<A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('../docs/cvv2.html', 480, 352, 'cvv2_popup' ), CAPTION, 'CVV2 Help', STICKY, AUTOSTATUSCAP, CLOSECLICK, DRAGGABLE ); return false;">help</A>) </TD> </TR> <TR> - <TD ALIGN="right">Exact name on card</TD> + <TH ALIGN="right">Exact name on card</TH> <TD><INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="payname" VALUE="<%$payname%>"></TD> - </TR><TR> - <TD ALIGN="right">Card billing address</TD> - <TD> - <INPUT TYPE="text" SIZE=40 MAXLENGTH=80 NAME="address1" VALUE="<%$address1%>"> - </TD> - </TR><TR> - <TD ALIGN="right">Address line 2</TD> - <TD> - <INPUT TYPE="text" SIZE=40 MAXLENGTH=80 NAME="address2" VALUE="<%$address2%>"> - </TD> - </TR><TR> - <TD ALIGN="right">City</TD> - <TD> - <TABLE> - <TR> - <TD> - <INPUT TYPE="text" NAME="city" SIZE="12" MAXLENGTH=80 VALUE="<%$city%>"> - </TD> - <TD>State</TD> - <TD> - <SELECT NAME="state"> -% for ( @states ) { - - <OPTION<% $_ eq $state ? ' SELECTED' : '' %>><% $_ %> -% } - - </SELECT> - </TD> - <TD>Zip</TD> - <TD> - <INPUT TYPE="text" NAME="zip" SIZE=11 MAXLENGTH=10 VALUE="<%$zip%>"> - </TD> - </TR> - </TABLE> - </TD> </TR> + <% include( '/elements/location.html', + 'object' => $cust_main, #XXX errors??? + 'no_asterisks' => 1, + 'address1_label' => 'Card billing address', + ) + %> + % } elsif ( $payby eq 'CHEK' ) { % % my( $payinfo1, $payinfo2, $payname, $ss, $paytype, $paystate, @@ -270,16 +285,51 @@ my $balance = $cust_main->balance; my $payinfo = ''; -#false laziness w/selfservice make_payment.html shortcut for one-country my $conf = new FS::Conf; + +my $money_char = $conf->config('money_char') || '$'; + +#false laziness w/selfservice make_payment.html shortcut for one-country my %states = map { $_->state => 1 } qsearch('cust_main_county', { 'country' => $conf->config('countrydefault') || 'US' } ); my @states = sort { $a cmp $b } keys %states; +my $fee = ''; +my $fee_pkg = ''; +my $fee_display = ''; +my $fee_op = ''; +my $num_payments = scalar($cust_main->cust_pay); +#handle old cust_main.pm (remove...) +$num_payments = scalar( @{ [ $cust_main->cust_pay ] } ) + unless defined $num_payments; +if ( $conf->config('manual_process-pkgpart') + and ! $conf->exists('manual_process-skip_first') || $num_payments + ) +{ + + $fee_display = $conf->config('manual_process-display') || 'add'; + $fee_op = $fee_display eq 'add' ? '+' : '-'; + + $fee_pkg = + qsearchs('part_pkg', { pkgpart=>$conf->config('manual_process-pkgpart') } ); + + #well ->unit_setup or ->calc_setup both call for a $cust_pkg + # (though ->unit_setup doesn't use it...) + $fee = $fee_pkg->option('setup_fee') + if $fee_pkg; #in case.. better than dying with a perl traceback + +} + +my $amount = ''; +if ( $balance > 0 ) { + $amount = $balance; + $amount += $fee + if $fee && $fee_display eq 'subtract'; + $amount = sprintf("%.2f", $amount); +} + my $payunique = "webui-payment-". time. "-$$-". rand() * 2**32; </%init> - - diff --git a/httemplate/misc/ping.html b/httemplate/misc/ping.html new file mode 100644 index 0000000..4f0360e --- /dev/null +++ b/httemplate/misc/ping.html @@ -0,0 +1,102 @@ +<% include('/elements/header-popup.html', "Ping $ip" ) %> + +<% include('/elements/xmlhttp.html', + 'url' => $p. 'misc/xmlhttp-ping.html', + 'subs' => [ 'ping' ], + ) +%> + +%# <img src="<%$p%>images/bullet_red.png" border=0> + + +<%ntable("#cccccc", 2)%> + +<TR> + <TD>Status</TD> + <TD BGCOLOR="#ffffff" ID="ping_status">Checking...</TD> +</TR> +<TR> + <TD>Packet loss</TD> + <TD BGCOLOR="#ffffff" ID="ping_packetloss"></TD> +</TR> +<TR> + <TD>Latency</TD> + <TD BGCOLOR="#ffffff" ID="ping_latency"></TD> +</TR> +<TR> + <TD>Packets</TD> + <TD BGCOLOR="#ffffff" ID="ping_packets"></TD> +</TR> + +</TABLE> + +<BR> +<CENTER> +<INPUT TYPE="button" VALUE="Close" onClick="parent.nd(1);"> +</CENTER> + +<SCRIPT TYPE="text/javascript"> + + var fails = 0; + var pongs = 0; + var totaltime = 0; + var avg = 0; + + function ping_update ( updatetext ) { + var pingArray = eval('(' + updatetext + ')'); + var status = pingArray[0]; + var rtt = pingArray[1]; + + if ( status == 0 ) { + fails++; + } else if ( status == 1 ) { + pongs++; + totaltime = totaltime + rtt; + avg = totaltime / pongs; + } + + var loss = 100 * fails / ( fails + pongs ); + + var statusCell = document.getElementById('ping_status'); + var packetlossCell = document.getElementById('ping_packetloss'); + var latencyCell = document.getElementById('ping_latency'); + var packetsCell = document.getElementById('ping_packets'); + + var status = ''; + // red conditions + if ( loss == 100 ) { + status = '<FONT COLOR="#ff0000">Unreachable</FONT>'; + } else + // yellow conditions + if ( loss > 50 ) { + status = '<FONT COLOR="#ff9900">High packet loss</FONT>'; + } else + if ( avg > 1 ) { + status = '<FONT COLOR="#ff9900">High latency</FONT>'; + } else { + status = '<FONT COLOR="#00cc00">Up</FONT>'; + } + + statusCell.innerHTML = '<B>' + status + '</B>'; + packetlossCell.innerHTML = '<B>' + Math.round(loss) + '%</B>'; + if ( avg > 0 ) { + latencyCell.innerHTML = '<B>' + Math.round( avg*1000 ) + 'ms</B>'; + } + var packets = fails + pongs; + packetsCell.innerHTML = '<B>' + packets + '</B>'; + + setTimeout( "ping('<%$ip%>', ping_update)", 1000 ); + + } + + ping( '<%$ip%>', ping_update ); + +</SCRIPT> + +<%init> + +my($query) = $cgi->keywords; +$query =~ /^([\d\.]+)$/ or die 'Illegal IP'; +my $ip = $1; + +</%init> diff --git a/httemplate/misc/process/link.cgi b/httemplate/misc/process/link.cgi index df15dca..77546f3 100755 --- a/httemplate/misc/process/link.cgi +++ b/httemplate/misc/process/link.cgi @@ -1,14 +1,20 @@ %unless ($error) { % #no errors, so let's view this customer. % my $custnum = $new->cust_pkg->custnum; -<% $cgi->redirect(popurl(3). "view/cust_main.cgi?$custnum#cust_pkg$pkgnum" ) %> +% my $show = $curuser->default_customer_view =~ /^(jumbo|packages)$/ +% ? '' +% : ';show=packages'; +% my $frag = "cust_pkg$pkgnum"; #hack for IE ignoring real #fragment +<% $cgi->redirect(popurl(3). "view/cust_main.cgi?custnum=$custnum$show;fragment=$frag#$frag" ) %> %} else { % errorpage($error); %} <%init> +my $curuser = $FS::CurrentUser::CurrentUser; + die "access denied" - unless $FS::CurrentUser::CurrentUser->access_right('View/link unlinked services'); + unless $curuser->access_right('View/link unlinked services'); my $DEBUG = 0; diff --git a/httemplate/misc/process/part_device-import.html b/httemplate/misc/process/part_device-import.html new file mode 100644 index 0000000..eac111a --- /dev/null +++ b/httemplate/misc/process/part_device-import.html @@ -0,0 +1,9 @@ +<% $server->process %> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Import'); + +my $server = new FS::UI::Web::JSRPC 'FS::part_device::process_batch_import', $cgi; + +</%init> diff --git a/httemplate/misc/process/payment.cgi b/httemplate/misc/process/payment.cgi index 2baca1e..1e9501d 100644 --- a/httemplate/misc/process/payment.cgi +++ b/httemplate/misc/process/payment.cgi @@ -32,6 +32,11 @@ $cgi->param('amount') =~ /^\s*(\d*(\.\d\d)?)\s*$/ my $amount = $1; errorpage("amount <= 0") unless $amount > 0; +if ( $cgi->param('fee') =~ /^\s*(\d*(\.\d\d)?)\s*$/ ) { + my $fee = $1; + $amount = sprintf('%.2f', $amount + $fee); +} + $cgi->param('year') =~ /^(\d+)$/ or errorpage("illegal year ". $cgi->param('year')); my $year = $1; @@ -44,7 +49,7 @@ $cgi->param('payby') =~ /^(CARD|CHEK)$/ or errorpage("illegal payby ". $cgi->param('payby')); my $payby = $1; my %payby2fields = ( - 'CARD' => [ qw( address1 address2 city state zip ) ], + 'CARD' => [ qw( address1 address2 city county state zip country ) ], 'CHEK' => [ qw( ss paytype paystate stateid stateid_state ) ], ); my %type = ( 'CARD' => 'credit card', @@ -143,6 +148,22 @@ if ( $cgi->param('batch') ) { ); errorpage($error) if $error; + #no error, so order the fee package if applicable... + if ( $cgi->param('fee_pkgpart') =~ /^(\d+)$/ ) { + + my $cust_pkg = new FS::cust_pkg { 'pkgpart' => $1 }; + + my $error = $cust_main->order_pkg( 'cust_pkg' => $cust_pkg ); + errorpage("payment processed successfully, but error ordering fee: $error") + if $error; + + #and generate an invoice for it now too + $error = $cust_main->bill( 'pkg_list' => [ $cust_pkg ] ); + errorpage("payment processed and fee ordered sucessfully, but error billing fee: $error") + if $error; + + } + $cust_main->apply_payments; } diff --git a/httemplate/misc/process/rate_edit_excel.html b/httemplate/misc/process/rate_edit_excel.html new file mode 100644 index 0000000..acd5f49 --- /dev/null +++ b/httemplate/misc/process/rate_edit_excel.html @@ -0,0 +1,10 @@ +<% $server->process %> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $server = new FS::UI::Web::JSRPC 'FS::rate_detail::process_edit_import', $cgi; + +</%init> + diff --git a/httemplate/misc/process/recharge_svc.html b/httemplate/misc/process/recharge_svc.html index 147b953..5f68bf1 100755 --- a/httemplate/misc/process/recharge_svc.html +++ b/httemplate/misc/process/recharge_svc.html @@ -1,62 +1,13 @@ -%unless ($error) { -% -% my ($amount, $seconds, $up, $down, $total) = (0, 0, 0, 0, 0); -% #should probably use payby.pm but whatever -% if ($payby eq 'PREP') { -% $error = $cust_main->get_prepay($prepaid, \$amount, \$seconds, \$up, \$down, \$total) -% || $svc_acct->increment_seconds($seconds) -% || $svc_acct->increment_upbytes($up) -% || $svc_acct->increment_downbytes($down) -% || $svc_acct->increment_totalbytes($total) -% || $cust_main->insert_cust_pay_prepay( $amount, $prepaid ); -% } elsif ( $payby =~ /^(CARD|DCRD|CHEK|DCHK|LECB|BILL|COMP)$/ ) { -% my $part_pkg = $svc_acct->cust_svc->cust_pkg->part_pkg; -% $amount = $part_pkg->option('recharge_amount', 1); -% my %rhash = map { $_ =~ /^recharge_(.*)$/; $1, $part_pkg->option($_) } -% grep { $part_pkg->option($_, 1) } -% qw ( recharge_seconds recharge_upbytes recharge_downbytes -% recharge_totalbytes ); -% -% my $description = "Recharge"; -% $description .= " $rhash{seconds}s" if $rhash{seconds}; -% $description .= " $rhash{upbytes} up" if $rhash{upbytes}; -% $description .= " $rhash{downbytes} down" if $rhash{downbytes}; -% $description .= " $rhash{totalbytes} total" if $rhash{totalbytes}; -% -% $error = $cust_main->charge($amount, "Recharge " . $svc_acct->label, -% $description, $part_pkg->taxclass); -% -% if ($part_pkg->option('recharge_reset', 1)) { -% $error ||= $svc_acct->set_usage(\%rhash); -% }else{ -% $error ||= $svc_acct->recharge(\%rhash); -% } -% -% my $old_balance = $cust_main->balance; -% $error ||= $cust_main->bill; -% $error ||= $cust_main->apply_payments_and_credits; -% my $bill_error = $cust_main->collect('realtime' => 1) unless $error; -% $error ||= "Failed to collect - $bill_error" -% if $cust_main->balance > $old_balance && $cust_main->balance > 0 -% && $payby ne 'BILL'; -% -% } else { -% $error = "fatal error - unknown payby: $payby"; -% } -%} -% %if ($error) { % $cgi->param('error', $error); -% $dbh->rollback if $oldAutoCommit; -% print $cgi->redirect(popurl(2). "recharge_svc.html?". $cgi->query_string ); -%} -%$dbh->commit or die $dbh->errstr if $oldAutoCommit; -% +<% $cgi->redirect(popurl(2). "recharge_svc.html?". $cgi->query_string ) %> +%} else { <% header("Package recharged") %> <SCRIPT TYPE="text/javascript"> window.top.location.reload(); </SCRIPT> </BODY></HTML> +%} <%init> my $conf = new FS::Conf; @@ -89,4 +40,52 @@ my $oldAutoCommit = $FS::UID::AutoCommit; local $FS::UID::AutoCommit = 0; my $dbh = dbh; +unless ($error) { + + #should probably use payby.pm but whatever + if ($payby eq 'PREP') { + $error = $cust_main->recharge_prepay( $prepaid ); + } elsif ( $payby =~ /^(CARD|DCRD|CHEK|DCHK|LECB|BILL|COMP)$/ ) { + my $part_pkg = $svc_acct->cust_svc->cust_pkg->part_pkg; + my $amount = $part_pkg->option('recharge_amount', 1); + my %rhash = map { $_ =~ /^recharge_(.*)$/; $1, $part_pkg->option($_) } + grep { $part_pkg->option($_, 1) } + qw ( recharge_seconds recharge_upbytes recharge_downbytes + recharge_totalbytes ); + + my $description = "Recharge"; + $description .= " $rhash{seconds}s" if $rhash{seconds}; + $description .= " $rhash{upbytes} up" if $rhash{upbytes}; + $description .= " $rhash{downbytes} down" if $rhash{downbytes}; + $description .= " $rhash{totalbytes} total" if $rhash{totalbytes}; + + $error = $cust_main->charge($amount, "Recharge " . $svc_acct->label, + $description, $part_pkg->taxclass); + + if ($part_pkg->option('recharge_reset', 1)) { + $error ||= $svc_acct->set_usage(\%rhash, 'null' => 1); + }else{ + $error ||= $svc_acct->recharge(\%rhash); + } + + my $old_balance = $cust_main->balance; + $error ||= $cust_main->bill; + $error ||= $cust_main->apply_payments_and_credits; + my $bill_error = $cust_main->collect('realtime' => 1) unless $error; + $error ||= "Failed to collect - $bill_error" + if $cust_main->balance > $old_balance && $cust_main->balance > 0 + && $payby ne 'BILL'; + + } else { + $error = "fatal error - unknown payby: $payby"; + } + +} + +if ($error) { + $dbh->rollback if $oldAutoCommit; +} else { + $dbh->commit or die $dbh->errstr if $oldAutoCommit; +} + </%init> diff --git a/httemplate/misc/process/tax-fetch_and_import.cgi b/httemplate/misc/process/tax-fetch_and_import.cgi new file mode 100644 index 0000000..553c755 --- /dev/null +++ b/httemplate/misc/process/tax-fetch_and_import.cgi @@ -0,0 +1,9 @@ +<% $server->process %> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $server = new FS::UI::Web::JSRPC 'FS::tax_rate::process_download_and_update', $cgi; + +</%init> diff --git a/httemplate/misc/process/tax-fetch_and_replace.cgi b/httemplate/misc/process/tax-fetch_and_replace.cgi new file mode 100644 index 0000000..1a9b626 --- /dev/null +++ b/httemplate/misc/process/tax-fetch_and_replace.cgi @@ -0,0 +1,9 @@ +<% $server->process %> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $server = new FS::UI::Web::JSRPC 'FS::tax_rate::process_download_and_reload', $cgi; + +</%init> diff --git a/httemplate/misc/process/tax-import.cgi b/httemplate/misc/process/tax-import.cgi index 016d4b6..f800dbd 100644 --- a/httemplate/misc/process/tax-import.cgi +++ b/httemplate/misc/process/tax-import.cgi @@ -2,7 +2,7 @@ <%init> die "access denied" - unless $FS::CurrentUser::CurrentUser->access_right('Resend invoices'); + unless $FS::CurrentUser::CurrentUser->access_right('Import'); my $server = new FS::UI::Web::JSRPC 'FS::tax_rate::process_batch_import', $cgi; diff --git a/httemplate/misc/rate_edit_excel.html b/httemplate/misc/rate_edit_excel.html new file mode 100644 index 0000000..e73133c --- /dev/null +++ b/httemplate/misc/rate_edit_excel.html @@ -0,0 +1,61 @@ +<% include('/elements/header.html', 'Edit rates with Excel' ) %> + +<% include( '/elements/form-file_upload.html', + 'name' => 'RateImportForm', + 'action' => 'process/rate_edit_excel.html', + 'num_files' => 1, + 'fields' => [ 'format' ], + 'message' => 'Rate edit successful', + 'url' => $p."browse/rate_region.html", + ) +%> + +<% &ntable("#cccccc", 2) %> + + <TR> + <TH ALIGN="left">1. Download current rates:</TH> + <TD> + <A HREF="<%$p%>/browse/rate_region.html?show_rates=1;_type=regions.xls">Download rate spreadsheet</A> + </TD> + </TR> + + <TR> + <TH ALIGN="left" COLSPAN=2>2. Edit rates with Excel (or other .XLS-compatible application)</TH> + </TR> + + <TR> + <TD ALIGN="left" COLSPAN=2> + - To add rates, add four columns like an existing rate, with headers starting with "NEW: Rate Name" or "Rate Name".<BR> + - <FONT SIZE="-2"><I>For rate addition, protection can be turned off in Excel via the Tools->Protection->Unprotect Sheet menu command. Note that only new rates can be added; modified grayed out cells will not be imported.</I></FONT> + </TD> + </TR> + + <% include( '/elements/file-upload.html', + 'field' => 'file', + 'label' => '3. Upload edited rate file: ', + 'label_align' => 'left', + ) + %> + + <INPUT TYPE="hidden" NAME="format" VALUE="default"> + + <TR> + <TD COLSPAN=2 ALIGN="center" STYLE="padding-top:6px"> + <INPUT TYPE = "submit" + ID = "submit" + VALUE = "Upload" + onClick = "document.RateImportForm.submit.disabled=true;" + > + </TD> + </TR> + + +</TABLE> + +<% include('/elements/footer.html') %> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +</%init> diff --git a/httemplate/misc/send-invoice.cgi b/httemplate/misc/send-invoice.cgi new file mode 100644 index 0000000..32dfe27 --- /dev/null +++ b/httemplate/misc/send-invoice.cgi @@ -0,0 +1,30 @@ +<% $cgi->redirect("${p}view/cust_main.cgi?$custnum") %> +<%once> + +my %method = ( map { $_=>1 } qw( email print fax_invoice ) ); + +</%once> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Resend invoices'); + +my $invnum = $cgi->param('invnum'); +my $template = $cgi->param('template'); +my $notice_name = $cgi->param('notice_name') if $cgi->param('notice_name'); +my $method = $cgi->param('method'); + +$method .= '_invoice' if $method eq 'fax'; #! + +die "unknown method $method" unless $method{$method}; + +my $cust_bill = qsearchs('cust_bill',{'invnum'=>$invnum}); +die "Can't find invoice!\n" unless $cust_bill; + +$cust_bill->$method({ 'template' => $template, + 'notice_name' => $notice_name, + }); + +my $custnum = $cust_bill->getfield('custnum'); + +</%init> diff --git a/httemplate/misc/send-statement.cgi b/httemplate/misc/send-statement.cgi new file mode 100755 index 0000000..e363fbd --- /dev/null +++ b/httemplate/misc/send-statement.cgi @@ -0,0 +1,28 @@ +<% $cgi->redirect("${p}view/cust_main.cgi?$custnum") %> +<%once> + +my %method = map { $_=>1 } qw( email print fax_invoice ); + +</%once> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Resend invoices'); + +my $statementnum = $cgi->param('statementnum'); +my $template = $cgi->param('template') || 'statement'; #XXX configure... via event?? eh.. +my $notice_name = $cgi->param('notice_name') if $cgi->param('notice_name'); +my $method = $cgi->param('method'); + +$method .= '_invoice' if $method eq 'fax'; #! + +die "unknown method $method" unless $method{$method}; + +my $cust_statement = qsearchs('cust_statement',{'statementnum'=>$statementnum}); +die "Can't find statement!\n" unless $cust_statement; + +$cust_statement->$method({ 'template' => $template }); + +my $custnum = $cust_statement->getfield('custnum'); + +</%init> diff --git a/httemplate/misc/states.cgi b/httemplate/misc/states.cgi index cf2b46e..02b7be4 100644 --- a/httemplate/misc/states.cgi +++ b/httemplate/misc/states.cgi @@ -1,7 +1,7 @@ -% -% -% my $country = $cgi->param('arg'); -% my @output = states_hash($country); -% -% [ <% join(', ', map { qq("$_") } @output) %> ] +<%init> + +my $country = $cgi->param('arg'); +my @output = states_hash($country); + +</%init> diff --git a/httemplate/misc/tax-fetch_and_import.cgi b/httemplate/misc/tax-fetch_and_import.cgi new file mode 100644 index 0000000..33a6c9b --- /dev/null +++ b/httemplate/misc/tax-fetch_and_import.cgi @@ -0,0 +1,48 @@ +<% include("/elements/header.html",'Tax Rate Download and Import') %> + +Import a tax data update. +<BR><BR> + +<% include( '/elements/progress-init.html', 'TaxRateImport',[ 'format', ], + 'process/tax-fetch_and_import.cgi', { 'message' => 'Tax rates imported' }, + ) +%> + +<FORM NAME="TaxRateImport" ACTION="javascript:void()" METHOD="POST"> +<% &ntable("#cccccc", 2) %> + + <TR> + <TH ALIGN="right">Format</TH> + <TD> + <SELECT NAME="format"> + <OPTION VALUE="cch">CCH import + </SELECT> + </TD> + </TR> + <TR> + <TH ALIGN="right">Update Password</TH> + <TD> + <INPUT TYPE="text" NAME="password"> + </TD> + </TR> + + <TR> + <TD COLSPAN=2 ALIGN="center" STYLE="padding-top:6px"> + <INPUT TYPE = "submit" + VALUE = "Download and Import" + onClick = "document.TaxRateImport.submit.disabled=true; process();" + > + </TD> + </TR> + +</TABLE> + +</FORM> + +<% include('/elements/footer.html') %> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Import'); + +</%init> diff --git a/httemplate/misc/tax-fetch_and_replace.cgi b/httemplate/misc/tax-fetch_and_replace.cgi new file mode 100644 index 0000000..3290a3c --- /dev/null +++ b/httemplate/misc/tax-fetch_and_replace.cgi @@ -0,0 +1,48 @@ +<% include("/elements/header.html",'Tax Rate Download and Import') %> + +Replace tax data. +<BR><BR> + +<% include( '/elements/progress-init.html', 'TaxRateImport',[ 'format', ], + 'process/tax-fetch_and_replace.cgi', { 'message' => 'Tax rates replaced' }, + ) +%> + +<FORM NAME="TaxRateImport" ACTION="javascript:void()" METHOD="POST"> +<% &ntable("#cccccc", 2) %> + + <TR> + <TH ALIGN="right">Format</TH> + <TD> + <SELECT NAME="format"> + <OPTION VALUE="cch">CCH import + </SELECT> + </TD> + </TR> + <TR> + <TH ALIGN="right">Update Password</TH> + <TD> + <INPUT TYPE="text" NAME="password"> + </TD> + </TR> + + <TR> + <TD COLSPAN=2 ALIGN="center" STYLE="padding-top:6px"> + <INPUT TYPE = "submit" + VALUE = "Download and Import" + onClick = "document.TaxRateImport.submit.disabled=true; process();" + > + </TD> + </TR> + +</TABLE> + +</FORM> + +<% include('/elements/footer.html') %> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Import'); + +</%init> diff --git a/httemplate/misc/tax-import.cgi b/httemplate/misc/tax-import.cgi index a695e97..5116e54 100644 --- a/httemplate/misc/tax-import.cgi +++ b/httemplate/misc/tax-import.cgi @@ -6,7 +6,7 @@ Import a CSV file set containing tax rate records. <% include( '/elements/form-file_upload.html', 'name' => 'TaxRateUpload', 'action' => 'process/tax-import.cgi', - 'num_files' => 5, + 'num_files' => 6, 'fields' => [ 'format', ], 'message' => 'Tax rates imported', ) @@ -27,13 +27,15 @@ Import a CSV file set containing tax rate records. </TR> <% include( '/elements/file-upload.html', - 'field' => [ 'codefile', + 'field' => [ 'geofile', + 'codefile', 'plus4file', 'zipfile', 'txmatrix', 'detail', ], - 'label' => [ 'code filename', + 'label' => [ 'geocode filename', + 'code filename', 'plus4 filename', 'zip filename', 'txmatrix filename', diff --git a/httemplate/misc/xmlhttp-cust_main-address_standardize.html b/httemplate/misc/xmlhttp-cust_main-address_standardize.html index 72fa4a4..3b9e142 100644 --- a/httemplate/misc/xmlhttp-cust_main-address_standardize.html +++ b/httemplate/misc/xmlhttp-cust_main-address_standardize.html @@ -50,6 +50,9 @@ if ( $sub eq 'address_standardize' ) { unless ( $verifier->is_error ) { + my $zip = $hash->{Zip5}; + $zip .= '-'. $hash->{Zip4} if $hash->{Zip4} =~ /\d/; + $return = { %$return, "new_$pre".'company' => $hash->{FirmName}, @@ -57,7 +60,7 @@ if ( $sub eq 'address_standardize' ) { "new_$pre".'address2' => $hash->{Address1}, "new_$pre".'city' => $hash->{City}, "new_$pre".'state' => $hash->{State}, - "new_$pre".'zip' => $hash->{Zip5}. '-'. $hash->{Zip4}, + "new_$pre".'zip' => $zip, }; my @fields = (qw( company address1 address2 city state zip )); #hmm diff --git a/httemplate/misc/xmlhttp-cust_main-censustract.html b/httemplate/misc/xmlhttp-cust_main-censustract.html new file mode 100644 index 0000000..9d588d7 --- /dev/null +++ b/httemplate/misc/xmlhttp-cust_main-censustract.html @@ -0,0 +1,105 @@ +<% objToJson($return) %> +<%init> + +my $DEBUG = 0; + +my $url='http://www.ffiec.gov/Geocode/default.aspx'; + +my $sub = $cgi->param('sub'); + +my $return = {}; +my $error = ''; + +use LWP::UserAgent; +use HTTP::Request; +use HTTP::Request::Common qw( GET POST ); +use HTML::TokeParser; + +if ( $sub eq 'censustract' ) { + + my %arg = $cgi->param('arg'); + warn join('', map "$_: $arg{$_}\n", keys %arg ) + if $DEBUG; + + my $ua = new LWP::UserAgent; + my $res = $ua->request( GET( $url ) ); + + warn $res->as_string + if $DEBUG > 1; + + unless ($res->code eq '200') { + + $error = $res->message; + + } else { + + my $content = $res->content; + my $p = new HTML::TokeParser \$content; + my $viewstate; + while (my $token = $p->get_tag('input') ) { + next unless $token->[1]->{name} eq '__VIEWSTATE'; + $viewstate = $token->[1]->{value}; + last; + } + + unless ($viewstate) { + + $error = "no __VIEWSTATE found"; + + } else { + + my($zip5, $zip4) = split('-',$arg{zip}); + + my @ffiec_args = ( + __VIEWSTATE => $viewstate, + ddlbYear => $arg{year}, + txtAddress => $arg{address}, + txtCity => $arg{city}, + ddlbState => $arg{state}, + txtZipCode => $zip5, + btnSearch => 'Search', + ); + warn join("\n", @ffiec_args ) + if $DEBUG; + + $res = $ua->request( POST( $url, \@ffiec_args ) ); + warn $res->as_string + if $DEBUG > 1; + + unless ($res->code eq '200') { + + $error = $res->message; + + } else { + + my @id = qw( MSACode StateCode CountyCode TractCode ); + $content = $res->content; + $p = new HTML::TokeParser \$content; + my $prefix = 'UcGeoResult11_lb'; + my $compare = + sub { my $t=shift; scalar( grep { lc($t) eq lc("$prefix$_")} @id ) }; + + while (my $token = $p->get_tag('span') ) { + next unless ( $token->[1]->{id} && &$compare( $token->[1]->{id} ) ); + $token->[1]->{id} =~ /^$prefix(\w+)$/; + $return->{lc($1)} = $p->get_trimmed_text("/span"); + } + + $error = "No census tract found" unless $return->{tractcode}; + $return->{tractcode} .= ' ' + unless $error || $JSON::VERSION >= 2; #broken JSON 1 workaround + + } #unless ($res->code eq '200') + + } #unless ($viewstate) + + } #unless ($res->code eq '200') + + $error = "FFIEC Geocoding error: $error" if $error; + $return->{'error'} = $error; + + $return; + +} + +</%init> diff --git a/httemplate/misc/xmlhttp-ping.html b/httemplate/misc/xmlhttp-ping.html new file mode 100644 index 0000000..e993032 --- /dev/null +++ b/httemplate/misc/xmlhttp-ping.html @@ -0,0 +1,20 @@ +<% objToJson($return) %> +<%init> + +my $conf = new FS::Conf; + +my $sub = $cgi->param('sub'); + +die "$sub not supported" unless $sub eq 'ping'; + +my $ip = $cgi->param('arg'); + +my $ping = new Net::Ping('external', 5); +$ping->hires(1); +#my $a=time; warn "pinging\n"; +my ($ret, $duration, $ip2) = $ping->ping($ip); +#warn "done pinging (". int(time-$a). "s)\n"; + +my $return = [ $ret, $duration ]; + +</%init> |