From 55f003404af6a2416571138356d11c5ad3755e58 Mon Sep 17 00:00:00 2001 From: jeff Date: Mon, 29 Jun 2009 13:53:25 +0000 Subject: [PATCH] FCC form 477 reporting #4912 --- FS/FS.pm | 6 +- FS/FS/Conf.pm | 7 + FS/FS/Schema.pm | 12 ++ FS/FS/cust_main.pm | 7 + FS/FS/cust_pkg.pm | 32 ++++ FS/FS/part_pkg_report_option.pm | 125 ++++++++++++++ FS/MANIFEST | 2 + FS/t/part_pkg_report_option.t | 5 + httemplate/browse/part_pkg_report_option.html | 28 ++++ httemplate/edit/cust_main/bottomfixup.html | 7 + httemplate/edit/cust_main/bottomfixup.js | 179 ++++++++++++++++----- httemplate/edit/cust_main/choose_tax_location.html | 2 +- httemplate/edit/cust_main/contact.html | 1 + httemplate/edit/part_pkg.cgi | 28 ++++ httemplate/edit/part_pkg_report_option.html | 23 +++ httemplate/edit/process/part_pkg.cgi | 5 + .../edit/process/part_pkg_report_option.html | 11 ++ httemplate/elements/location.html | 3 + httemplate/elements/menu.html | 5 +- httemplate/misc/xmlhttp-cust_main-censustract.html | 103 ++++++++++++ httemplate/search/cust_main.html | 7 +- httemplate/search/report_cust_main.html | 11 ++ httemplate/search/report_cust_pkg.html | 14 ++ 23 files changed, 577 insertions(+), 46 deletions(-) create mode 100644 FS/FS/part_pkg_report_option.pm create mode 100644 FS/t/part_pkg_report_option.t create mode 100644 httemplate/browse/part_pkg_report_option.html create mode 100644 httemplate/edit/part_pkg_report_option.html create mode 100644 httemplate/edit/process/part_pkg_report_option.html create mode 100644 httemplate/misc/xmlhttp-cust_main-censustract.html diff --git a/FS/FS.pm b/FS/FS.pm index 1477e985f..c3148735b 100644 --- a/FS/FS.pm +++ b/FS/FS.pm @@ -167,9 +167,9 @@ L - External provisioning export class L - Export option class -L - Package category class +L - Package category class (invoice oriented) -L - Package class class +L - Package class class (tax oriented) L - Package definition class @@ -179,6 +179,8 @@ L - Tax class class L - Package definition option class +L - Package reporting classification class + L - Class linking package definitions (see L) with service definitions (see L) diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index b45cdd797..12d6075b8 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -2576,6 +2576,13 @@ worry that config_items is freeside-specific and icky. }, { + 'key' => 'cust_main-require_censustract', + 'section' => 'UI', + 'description' => 'Customer is required to have a census tract. Useful for FCC form 477 reports. See also: cust_main-auto_standardize_address', + 'type' => 'checkbox', + }, + + { 'key' => 'disable_acl_changes', 'section' => '', 'description' => 'Disable all ACL changes, for demos.', diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index aed8d6079..61cd17e06 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -686,6 +686,7 @@ sub tables_hashref { 'paytype', 'varchar', 'NULL', $char_d, '', '', 'payip', 'varchar', 'NULL', 15, '', '', 'geocode', 'varchar', 'NULL', 20, '', '', + 'censustract', 'varchar', 'NULL', 20, '', '', # 7 to save space? 'tax', 'char', 'NULL', 1, '', '', 'otaker', 'varchar', '', 32, '', '', 'refnum', 'int', '', '', '', '', @@ -1850,6 +1851,17 @@ sub tables_hashref { 'index' => [ [ 'pkgpart' ], [ 'optionname' ] ], }, + 'part_pkg_report_option' => { + 'columns' => [ + 'num', 'serial', '', '', '', '', + 'name', 'varchar', '', $char_d, '', '', + 'disabled', 'char', 'NULL', 1, '', '', + ], + 'primary_key' => 'num', + 'unique' => [ [ 'name' ] ], + 'index' => [ [ 'disabled' ] ], + }, + 'rate' => { 'columns' => [ 'ratenum', 'serial', '', '', '', '', diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index 3f23346db..e5f289ca3 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -7573,6 +7573,13 @@ sub search_sql { unless $params->{'cancelled_pkgs'}; ## + # parse without census tract checkbox + ## + + push @where, "(censustract = '' or censustract is null)" + if $params->{'no_censustract'}; + + ## # dates ## diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm index a510c5245..881e005de 100644 --- a/FS/FS/cust_pkg.pm +++ b/FS/FS/cust_pkg.pm @@ -2325,12 +2325,44 @@ sub search_sql { #eslaf ### + # parse package report options + ### + + my @report_option = (); + if ( exists($params->{'report_option'}) + && $params->{'report_option'} =~ /^([,\d]*)$/ + ) + { + @report_option = split(',', $1); + } + + if (@report_option) { + # this will result in the empty set for the dangling comma case as it should + push @where, + map{ "0 < ( SELECT count(*) FROM part_pkg_option + WHERE part_pkg_option.pkgpart = part_pkg.pkgpart + AND optionname = 'report_option_$_' + AND optionvalue = '1' )" + } @report_option; + } + + #eslaf + + ### # parse custom ### push @where, "part_pkg.custom = 'Y'" if $params->{custom}; ### + # parse censustract + ### + + if ( $params->{'censustract'} =~ /^([.\d]+)$/ and $1 ) { + push @where, "cust_main.censustract = '". $params->{censustract}. "'"; + } + + ### # parse part_pkg ### diff --git a/FS/FS/part_pkg_report_option.pm b/FS/FS/part_pkg_report_option.pm new file mode 100644 index 000000000..16a4c9864 --- /dev/null +++ b/FS/FS/part_pkg_report_option.pm @@ -0,0 +1,125 @@ +package FS::part_pkg_report_option; + +use strict; +use base qw( FS::Record ); +use FS::Record qw( qsearch qsearchs ); + +=head1 NAME + +FS::part_pkg_report_option - Object methods for part_pkg_report_option records + +=head1 SYNOPSIS + + use FS::part_pkg_report_option; + + $record = new FS::part_pkg_report_option \%hash; + $record = new FS::part_pkg_report_option { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::part_pkg_report_option object represents a package definition optional +reporting classification. FS::part_pkg_report_option inherits from +FS::Record. The following fields are currently supported: + +=over 4 + +=item num + +primary key + +=item name + +name - The name associated with the reporting option + +=item disabled + +disabled - set to 'Y' to prevent addition to new packages + + +=back + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new report option. To add the option to the database, see L<"insert">. + +Note that this stores the hash reference, not a distinct copy of the hash it +points to. You can ask the object for a copy with the I method. + +=cut + +sub table { 'part_pkg_report_option'; } + +=item insert + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +=cut + +=item delete + +Delete this record from the database. + +=cut + +sub delete { + return "Can't delete part_pkg_report_option records!"; +} + +=item replace OLD_RECORD + +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. + +=cut + +=item check + +Checks all fields to make sure this is a valid example. If there is +an error, returns the error, otherwise returns false. Called by the insert +and replace methods. + +=cut + +# the check method should currently be supplied - FS::Record contains some +# data checking routines + +sub check { + my $self = shift; + + my $error = + $self->ut_numbern('num') + || $self->ut_text('name') + || $self->ut_enum('disabled', [ '', 'Y' ]) + ; + return $error if $error; + + $self->SUPER::check; +} + +=back + +=head1 BUGS + +Overlaps somewhat with pkg_class and pkg_category + +=head1 SEE ALSO + +L, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/MANIFEST b/FS/MANIFEST index 70287a3d9..7def8dffd 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -439,6 +439,8 @@ FS/cust_bill_pkg_tax_rate_location.pm t/cust_bill_pkg_tax_rate_location.t FS/cust_recon.pm t/cust_recon.t +FS/part_pkg_report_option.pm +t/part_pkg_report_option.t FS/cust_main_exemption.pm t/cust_main_exemption.t FS/cust_tax_adjustment.pm diff --git a/FS/t/part_pkg_report_option.t b/FS/t/part_pkg_report_option.t new file mode 100644 index 000000000..622bb3872 --- /dev/null +++ b/FS/t/part_pkg_report_option.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::part_pkg_report_option; +$loaded=1; +print "ok 1\n"; diff --git a/httemplate/browse/part_pkg_report_option.html b/httemplate/browse/part_pkg_report_option.html new file mode 100644 index 000000000..90540bca2 --- /dev/null +++ b/httemplate/browse/part_pkg_report_option.html @@ -0,0 +1,28 @@ +<% include( 'elements/browse.html', + 'title' => 'Package optional report classes', + 'html_init' => $html_init, + 'name' => 'package optional report classes', + 'disableable' => 1, + 'disabled_statuspos' => 2, + 'query' => { 'table' => 'part_pkg_report_option', + 'hashref' => {}, + 'extra_sql' => 'ORDER BY name', + }, + 'count_query' => 'SELECT COUNT(*) FROM part_pkg_report_option', + 'header' => [ '#', 'Class' ], + 'fields' => [ 'num', 'name' ], + 'links' => [ $link, $link ], + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + +my $html_init = + 'Package optional report classes define groups of packages, for reporting purposes.'. + qq!

Add a class

!; + +my $link = [ $p.'edit/part_pkg_report_option.html?', 'num' ]; + + diff --git a/httemplate/edit/cust_main/bottomfixup.html b/httemplate/edit/cust_main/bottomfixup.html index 3eb43e0e5..1b29c671a 100644 --- a/httemplate/edit/cust_main/bottomfixup.html +++ b/httemplate/edit/cust_main/bottomfixup.html @@ -7,6 +7,13 @@ ) %> +<% include( '/elements/xmlhttp.html', + 'url' => $p.'misc/xmlhttp-cust_main-censustract.html', + 'subs' => [ 'censustract' ], + #'method' => 'POST', #could get too long? + ) +%> + diff --git a/httemplate/edit/cust_main/bottomfixup.js b/httemplate/edit/cust_main/bottomfixup.js index ae4aafb70..822f98d39 100644 --- a/httemplate/edit/cust_main/bottomfixup.js +++ b/httemplate/edit/cust_main/bottomfixup.js @@ -86,52 +86,17 @@ function update_address(arg) { cf.elements['ship_zip'].value = argsHash['new_ship_zip']; } - } - - var cf = document.CustomerForm; - -% if ( $conf->exists('enable_taxproducts') ) { - - if ( <% $taxpre %>error || - new String(argsHash['new_<% $taxpre %>zip']).length < 10 ) - { - - var country_el = cf.elements['<% $taxpre %>country']; - var country = country_el.options[ country_el.selectedIndex ].value; - - if ( country == 'CA' || country == 'US' ) { - - var state_el = cf.elements['<% $taxpre %>state']; - var state = state_el.options[ state_el.selectedIndex ].value; - - var url = "cust_main/choose_tax_location.html" + - "?data_vendor=cch-zip" + - ";city=" + cf.elements['<% $taxpre %>city'].value + - ";state=" + state + - ";zip=" + cf.elements['<% $taxpre %>zip'].value + - ";country=" + country + - ";"; - - // popup a chooser - OLgetAJAX( url, update_geocode, 300 ); - - } else { - - cf.elements['geocode'].value = 'DEFAULT'; - cf.submit(); + post_standardization(); - } + } - } else -% } if ( changed || ship_changed ) { % if ( $conf->exists('cust_main-auto_standardize_address') ) { standardize_address(); - cf.submit(); % } else { @@ -198,9 +163,9 @@ function update_address(arg) { confirm_change = confirm_change + '' + - '' + + '' + '' + - '' + + '' + '' + '' + '' + @@ -213,10 +178,85 @@ function update_address(arg) { } else { - cf.submit(); + post_standardization(); + + } + + +} + +function post_standardization() { + + var cf = document.CustomerForm; + +% if ( $conf->exists('enable_taxproducts') ) { + + if ( new String(cf.elements['<% $taxpre %>zip'].value).length < 10 ) + { + + var country_el = cf.elements['<% $taxpre %>country']; + var country = country_el.options[ country_el.selectedIndex ].value; + + if ( country == 'CA' || country == 'US' ) { + + var state_el = cf.elements['<% $taxpre %>state']; + var state = state_el.options[ state_el.selectedIndex ].value; + + var url = "cust_main/choose_tax_location.html" + + "?data_vendor=cch-zip" + + ";city=" + cf.elements['<% $taxpre %>city'].value + + ";state=" + state + + ";zip=" + cf.elements['<% $taxpre %>zip'].value + + ";country=" + country + + ";"; + + // popup a chooser + OLgetAJAX( url, update_geocode, 300 ); + + } else { + + cf.elements['geocode'].value = 'DEFAULT'; + post_geocode(); + + } + + } else { + + post_geocode(); } +% } else { + + post_geocode(); + +% } + +} + +function post_geocode() { + +% if ( $conf->exists('cust_main-require_censustract') ) { + + //alert('fetch census tract data'); + var cf = document.CustomerForm; + var state_el = cf.elements['ship_state']; + var census_data = new Array( + 'year', '2008', // from config value? + 'address', cf.elements['ship_address1'].value, + 'city', cf.elements['ship_city'].value, + 'state', state_el.options[ state_el.selectedIndex ].value, + 'zip', cf.elements['ship_zip'].value + ); + + censustract( census_data, update_censustract ); + +% }else{ + + document.CustomerForm.submit(); + +% } + } function update_geocode() { @@ -232,6 +272,7 @@ function update_geocode() { setselect(cf.elements['<% $taxpre %>state'], argsHash['state']); cf.elements['<% $taxpre %>zip'].value = argsHash['zip']; cf.elements['geocode'].value = argsHash['geocode']; + post_geocode(); } @@ -241,6 +282,64 @@ function update_geocode() { } +var set_censustract; + +function update_censustract(arg) { + + var argsHash = eval('(' + arg + ')'); + + var cf = document.CustomerForm; + + var msacode = argsHash['msacode']; + var statecode = argsHash['statecode']; + var countycode = argsHash['countycode']; + var tractcode = argsHash['tractcode']; + var error = argsHash['error']; + + set_censustract = function () { + + cf.elements['censustract'].value = + document.forms.popupcensustract.elements.censustract.value; + cf.submit(); + + } + + if (error) { + // popup an entry dialog + + var choose_censustract = + '

Enter census tract

' + + '
' + + ''; + + choose_censustract = choose_censustract + + '' + + '' + + '' + + ''; + + choose_censustract = choose_censustract + + '' + + '
Census Tract:
  
' + + '' + + '' + + '
'; + + overlib( choose_censustract, CAPTION, 'Choose a census tract', STICKY, AUTOSTATUSCAP, CLOSETEXT, '', MIDX, 0, MIDY, 0, DRAGGABLE, WIDTH, 576, HEIGHT, 268, BGCOLOR, '#333399', CGCOLOR, '#333399', TEXTSIZE, 3 ); + + setTimeout("document.forms.popupcensustract.elements.censustract.focus()",1); + } else { + + cf.elements['censustract'].value = + new String(statecode) + + new String(countycode) + + new String(tractcode); + cf.submit(); + + } + +} + function copyelement(from, to) { if ( from == undefined ) { to.value = ''; diff --git a/httemplate/edit/cust_main/choose_tax_location.html b/httemplate/edit/cust_main/choose_tax_location.html index 2a4192632..be93a5de8 100644 --- a/httemplate/edit/cust_main/choose_tax_location.html +++ b/httemplate/edit/cust_main/choose_tax_location.html @@ -26,7 +26,7 @@

- +
diff --git a/httemplate/edit/cust_main/contact.html b/httemplate/edit/cust_main/contact.html index 27dd38516..2691da652 100644 --- a/httemplate/edit/cust_main/contact.html +++ b/httemplate/edit/cust_main/contact.html @@ -32,6 +32,7 @@ 'disabled' => $disabled, 'same_checked' => $opt{'same_checked'}, 'geocode' => $opt{'geocode'}, + 'censustract' => $opt{'censustract'}, ) %> diff --git a/httemplate/edit/part_pkg.cgi b/httemplate/edit/part_pkg.cgi index 0934f501a..a78aa87d8 100755 --- a/httemplate/edit/part_pkg.cgi +++ b/httemplate/edit/part_pkg.cgi @@ -46,6 +46,7 @@ 'recur_fee' => 'Recurring fee', 'bill_dst_pkgpart' => 'Include line item(s) from package', 'svc_dst_pkgpart' => 'Include services of package', + 'report_option' => 'Report classes', }, 'fields' => [ @@ -161,6 +162,19 @@ { type => 'columnend' }, + { 'type' => $census ? 'tablebreak-tr-title' + : 'hidden', + 'value' => 'Optional report classes', + 'field' => 'census_title', + }, + { 'field' => 'report_option', + 'type' => $census ? 'select-table' : 'hidden', + 'table' => 'part_pkg_report_option', + 'name_col' => 'name', + 'multiple' => 1, + }, + + { 'type' => 'tablebreak-tr-title', 'value' => 'Pricing add-ons', }, @@ -224,6 +238,7 @@ my $agent_clone_extra_sql = my $conf = new FS::Conf; my $taxproducts = $conf->exists('enable_taxproducts'); +my $census = scalar( qsearch( 'part_pkg_report_option', {} ) ); #XXX # - tr-part_pkg_freq: month_increments_only (from price plans) @@ -301,14 +316,27 @@ my $edit_callback = sub { (@agent_type) = map {$_->typenum} qsearch('type_pkgs',{'pkgpart'=>$1}); + my @report_option = (); foreach ($object->options) { /^usage_taxproductnum_(\d+)$/ && ($taxproductnums{$1} = 1); + /^report_option_(\d+)$/ && (push @report_option, $1); } foreach ($object->part_pkg_taxoverride) { $taxproductnums{$_->usage_class} = 1 if $_->usage_class; } + $cgi->param('report_option', join(',', @report_option)); + foreach my $field ( @$fields ) { + next unless ( + ref($field) eq 'HASH' && + $field->{field} && + $field->{field} eq 'report_option' + ); + #$field->{curr_value} = join(',', @report_option); + $field->{value} = join(',', @report_option); + } + %options = $object->options; $object->set($_ => $object->option($_)) diff --git a/httemplate/edit/part_pkg_report_option.html b/httemplate/edit/part_pkg_report_option.html new file mode 100644 index 000000000..a6f8e57b7 --- /dev/null +++ b/httemplate/edit/part_pkg_report_option.html @@ -0,0 +1,23 @@ +<% include( 'elements/edit.html', + 'name' => 'Package optional report class', + 'table' => 'part_pkg_report_option', + 'fields' => [ + 'name', + { field=>'num', type=>'hidden' }, + { field=>'disabled', type=>'checkbox', value=>'Y', }, + ], + 'labels' => { + 'num' => 'Class number', + 'name' => 'Class name', + 'disabled' => 'Disable class', + }, + 'viewall_dir' => 'browse', + ) + +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + + diff --git a/httemplate/edit/process/part_pkg.cgi b/httemplate/edit/process/part_pkg.cgi index 3116b7b28..107d45972 100755 --- a/httemplate/edit/process/part_pkg.cgi +++ b/httemplate/edit/process/part_pkg.cgi @@ -102,6 +102,11 @@ my $args_callback = sub { $options{"usage_taxproductnum_$_"} = $value; } + foreach ( split(',', $cgi->param('report_option') ) ) { + $error ||= "Illegal optional report class: $_" unless ( $_ =~ /^\d*$/ ); + $options{"report_option_$_"} = 1; + } + $options{$_} = scalar( $cgi->param($_) ) for (qw( setup_fee recur_fee )); diff --git a/httemplate/edit/process/part_pkg_report_option.html b/httemplate/edit/process/part_pkg_report_option.html new file mode 100644 index 000000000..052aabd72 --- /dev/null +++ b/httemplate/edit/process/part_pkg_report_option.html @@ -0,0 +1,11 @@ +<% include( 'elements/process.html', + 'table' => 'part_pkg_report_option', + 'viewall_dir' => 'browse', + ) +%> +<%init> + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('Configuration'); + + diff --git a/httemplate/elements/location.html b/httemplate/elements/location.html index dbc567d4d..1bdbf9604 100644 --- a/httemplate/elements/location.html +++ b/httemplate/elements/location.html @@ -9,6 +9,7 @@ Example: 'disabled' => $disabled, 'same_checked' => $same_checked, 'geocode' => $geocode, #passed through + 'censustract' => $censustract, #passed through 'no_asterisks' => 0, #set true to disable the red asterisks next #to required fields 'address1_label' => 'Address', #label for address @@ -85,6 +86,8 @@ Example: % if ( !$pre ) { +% } else { + % } <%init> diff --git a/httemplate/elements/menu.html b/httemplate/elements/menu.html index 5789a8a3f..cda1efcae 100644 --- a/httemplate/elements/menu.html +++ b/httemplate/elements/menu.html @@ -170,6 +170,8 @@ if ( $curuser->access_right('Financial reports') ) { $report_packages{'All customer packages'} = [ $fsurl.'search/cust_pkg.cgi?pkgnum', 'List all customer packages', ]; $report_packages{'Suspended customer packages'} = [ $fsurl.'search/cust_pkg.cgi?magic=suspended', 'List suspended packages' ]; $report_packages{'Customer packages with unconfigured services'} = [ $fsurl.'search/cust_pkg.cgi?APKG_pkgnum', 'List packages which have provisionable services' ]; +$report_packages{'FCC Form 477 packages'} = [ $fsurl.'search/report_477.html', 'Summarize packages by census tract for particular types' ] + if $conf->exists('cust_main-require_censustract'); $report_packages{'Advanced package reports'} = [ $fsurl.'search/report_cust_pkg.html', 'by agent, date range, status, package definition' ]; tie my %report_rating, 'Tie::IxHash', @@ -284,7 +286,8 @@ $config_export_svc_pkg{'View/Edit package definitions'} = [ $fsurl.'browse/part_ || $curuser->access_right('Edit global package definitions'); if ( $curuser->access_right('Configuration') ) { $config_export_svc_pkg{'View/Edit package categories'} = [ $fsurl.'browse/pkg_category.html', 'Package categories define groups of package classes, for reporting and convenience purposes.' ]; - $config_export_svc_pkg{'View/Edit package classes'} = [ $fsurl.'browse/pkg_class.html', 'Package classes define groups of packages, for reporting and convenience purposes.' ]; + $config_export_svc_pkg{'View/Edit package tax classes'} = [ $fsurl.'browse/pkg_class.html', 'Package classes define groups of packages, for taxes, reporting and convenience purposes.' ]; + $config_export_svc_pkg{'View/Edit package report classes'} = [ $fsurl.'browse/part_pkg_report_option.html', 'Package classes define groups of packages for reporting purposes.' ]; $config_export_svc_pkg{'View/Edit cancel reason types'} = [ $fsurl.'browse/reason_type.html?class=C', 'Cancel reason types define groups of reasons, for reporting and convenience purposes.' ]; $config_export_svc_pkg{'View/Edit cancel reasons'} = [ $fsurl.'browse/reason.html?class=C', 'Cancel reasons explain why a service was cancelled.' ]; $config_export_svc_pkg{'View/Edit suspend reason types'} = [ $fsurl.'browse/reason_type.html?class=S', 'Suspend reason types define groups of reasons, for reporting and convenience purposes.' ]; diff --git a/httemplate/misc/xmlhttp-cust_main-censustract.html b/httemplate/misc/xmlhttp-cust_main-censustract.html new file mode 100644 index 000000000..05636d3fb --- /dev/null +++ b/httemplate/misc/xmlhttp-cust_main-censustract.html @@ -0,0 +1,103 @@ +<% 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}; + + } #unless ($res->code eq '200') + + } #unless ($viewstate) + + } #unless ($res->code eq '200') + + $error = "FFIEC Geocoding error: $error" if $error; + $return->{'error'} = $error; + + $return; + +} + + diff --git a/httemplate/search/cust_main.html b/httemplate/search/cust_main.html index 0625a125a..f098fd3a6 100755 --- a/httemplate/search/cust_main.html +++ b/httemplate/search/cust_main.html @@ -43,9 +43,12 @@ my %search_hash = (); #$search_hash{'query'} = $cgi->keywords; #scalars -for my $param (qw( +my @scalars = qw ( agentnum status cancelled_pkgs cust_fields flattened_pkgs custbatch -)) { + no_censustract +); + +for my $param ( @scalars ) { $search_hash{$param} = scalar( $cgi->param($param) ) if $cgi->param($param); } diff --git a/httemplate/search/report_cust_main.html b/httemplate/search/report_cust_main.html index b0c5fde86..f139d4bb5 100755 --- a/httemplate/search/report_cust_main.html +++ b/httemplate/search/report_cust_main.html @@ -56,6 +56,15 @@ +% if ( $conf->exists('cust_main-require_censustract') ) { + + + Without census tract + + + +% } +   @@ -84,6 +93,8 @@ die "access denied" $FS::CurrentUser::CurrentUser->access_right('List packages') );; +my $conf = new FS::Conf; + <%once> diff --git a/httemplate/search/report_cust_pkg.html b/httemplate/search/report_cust_pkg.html index 3840663cf..66dd7d15e 100755 --- a/httemplate/search/report_cust_pkg.html +++ b/httemplate/search/report_cust_pkg.html @@ -72,6 +72,20 @@ ) %> +% if ( scalar( qsearch( 'part_pkg_report_option', { 'disabled' => '' } ) ) ) { + + <% include( '/elements/tr-select-table.html', + 'label' => 'Report classes', + 'table' => 'part_pkg_report_option', + 'name_col' => 'name', + 'hashref' => { 'disabled' => '' }, + 'element_name' => 'report_option', + 'multiple' => 'multiple', + ) + %> + +% } + % foreach my $field (qw( setup last_bill bill adjourn susp expire cancel )) { -- 2.11.0