Merge branch 'master' of git.freeside.biz:/home/git/freeside
authorIvan Kohler <ivan@freeside.biz>
Tue, 17 Oct 2017 21:22:19 +0000 (14:22 -0700)
committerIvan Kohler <ivan@freeside.biz>
Tue, 17 Oct 2017 21:22:19 +0000 (14:22 -0700)
20 files changed:
FS/FS/ClientAPI/MyAccount.pm
FS/FS/Report/Table.pm
FS/FS/Schema.pm
FS/FS/TaxEngine/compliance_solutions.pm
FS/FS/cust_payby.pm
FS/FS/h_cust_pkg.pm
fs_selfservice/FS-SelfService/cgi/change_check_pay.html [new file with mode: 0644]
fs_selfservice/FS-SelfService/cgi/change_creditcard_pay.html [new file with mode: 0644]
fs_selfservice/FS-SelfService/cgi/process_change_check_pay.html [new file with mode: 0644]
fs_selfservice/FS-SelfService/cgi/process_change_creditcard_pay.html [new file with mode: 0644]
fs_selfservice/FS-SelfService/cgi/selfservice.cgi
httemplate/docs/license.html
httemplate/elements/header-logo.html [new file with mode: 0644]
httemplate/graph/cust_pkg.html
httemplate/graph/elements/monthly.html
httemplate/graph/elements/report.html
httemplate/misc/confirm-censustract.html
httemplate/misc/openmap.html
httemplate/view/cust_bill-taxengine_request.html [new file with mode: 0644]
httemplate/view/cust_bill.cgi

index 30ab96b..ce887ef 100644 (file)
@@ -1675,14 +1675,15 @@ sub insert_payby {
 
   #XXX payinfo1 + payinfo2 for CHEK?
   #or take the opportunity to use separate, more well- named fields?
-  # my $payinfo;
-  # $p->{'payinfo1'} =~ /^([\dx]+)$/
-  #   or return { 'error' => "illegal account number ". $p->{'payinfo1'} };
-  # my $payinfo1 = $1;
-  #  $p->{'payinfo2'} =~ /^([\dx\.]+)$/ # . turned on by echeck-country CA ?
-  #   or return { 'error' => "illegal ABA/routing number ". $p->{'payinfo2'} };
-  # my $payinfo2 = $1;
-  # $payinfo = $payinfo1. '@'. $payinfo2;
+   if ($p->{'payby'} eq 'CHEK') {
+     $p->{'payinfo1'} =~ /^([\dx]+)$/
+       or return { 'error' => "illegal account number ". $p->{'payinfo1'} };
+     my $payinfo1 = $1;
+      $p->{'payinfo2'} =~ /^([\dx\.]+)$/ # . turned on by echeck-country CA ?
+       or return { 'error' => "illegal ABA/routing number ". $p->{'payinfo2'} };
+     my $payinfo2 = $1;
+     $p->{'payinfo'} = $payinfo1. '@'. $payinfo2;
+   }
 
   my $cust_payby = new FS::cust_payby {
     'custnum' => $custnum,
@@ -1706,6 +1707,16 @@ sub update_payby {
   my($context, $session, $custnum) = _custoragent_session_custnum($p);
   return { 'error' => $session } if $context eq 'error';
 
+  if ($p->{'payby'} eq 'CHEK') {
+     $p->{'payinfo1'} =~ /^([\dx]+)$/
+       or return { 'error' => "illegal account number ". $p->{'payinfo1'} };
+     my $payinfo1 = $1;
+      $p->{'payinfo2'} =~ /^([\dx\.]+)$/ # . turned on by echeck-country CA ?
+       or return { 'error' => "illegal ABA/routing number ". $p->{'payinfo2'} };
+     my $payinfo2 = $1;
+     $p->{'payinfo'} = $payinfo1. '@'. $payinfo2;
+   }
+
   my $cust_payby = qsearchs('cust_payby', {
                               'custnum'      => $custnum,
                               'custpaybynum' => $p->{'custpaybynum'},
index 5fb5640..e3e0854 100644 (file)
@@ -863,6 +863,54 @@ sub unsusp_pkg {
   $self->churn_pkg('unsusp', @_);
 }
 
+sub total_revenue_pkg {
+  my $self = shift;
+  my $active_revenue = $self->revenue_pkg('active', @_);
+  my $setup_revenue = $self->revenue_pkg('setup', @_);
+  my $return = sprintf("%.2f", $active_revenue + $setup_revenue);
+
+  return $return;
+}
+
+sub revenue_pkg {
+  my $self = shift;
+  my ( $status, $speriod, $eperiod, $agentnum, %opt ) = @_;
+  my $totalrevenue;
+
+  my ($from, @where) =
+    FS::h_cust_pkg->churn_fromwhere_sql( $status, $speriod, $eperiod);
+
+  push @where, $self->pkg_where(%opt, 'agentnum' => $agentnum);
+
+  my $sql;
+
+  if ($status eq "active") {
+    $sql = "SELECT DISTINCT ON (revenue.pkgnum) revenue.pkgnum AS pkgnum, revenue.recur AS revenue
+      FROM $from
+      JOIN part_pkg ON (cust_pkg.pkgpart = part_pkg.pkgpart)
+      JOIN cust_main ON (cust_pkg.custnum = cust_main.custnum)
+      JOIN h_cust_bill_pkg AS revenue ON (cust_pkg.pkgnum = revenue.pkgnum AND cust_pkg.history_date + 5 > revenue.history_date)
+    ";
+  }
+  elsif ($status eq "setup") {
+    $sql = "SELECT DISTINCT ON (revenue.pkgnum) revenue.pkgnum AS pkgnum, revenue.setup AS revenue
+      FROM $from
+      JOIN part_pkg ON (cust_pkg.pkgpart = part_pkg.pkgpart)
+      JOIN cust_main ON (cust_pkg.custnum = cust_main.custnum)
+      JOIN h_cust_bill_pkg AS revenue ON (cust_pkg.pkgnum = revenue.pkgnum AND cust_pkg.setup + 15 > revenue.history_date)
+    ";
+  }
+
+  $sql .= ' WHERE '.join(' AND ', @where)
+    if scalar(@where);
+
+  $sql .= "ORDER BY revenue.pkgnum ASC, revenue.history_date DESC";
+
+  my $revenue_sql = "SELECT sum(rev.revenue) AS total_revenue FROM ( $sql ) AS rev";
+
+  $self->scalar_sql($revenue_sql);
+}
+
 sub churn_pkg {
   my $self = shift;
   my ( $status, $speriod, $eperiod, $agentnum, %opt ) = @_;
index d347c06..6d7520b 100644 (file)
@@ -695,6 +695,7 @@ sub tables_hashref {
         'statementnum', 'int', 'NULL', '', '', '', #invoice aggregate statements
         'agent_invid',  'int', 'NULL', '', '', '', #(varchar?) importing legacy
         'promised_date', @date_type,       '', '',
+        'taxengine_request', 'text', 'NULL', '', '', '',
         
         'pending',     'char', 'NULL',  1, '', '',
       ],
@@ -732,6 +733,7 @@ sub tables_hashref {
         'statementnum', 'int', 'NULL', '', '', '', #invoice aggregate statements
         'agent_invid',  'int', 'NULL', '', '', '', #(varchar?) importing legacy
         'promised_date', @date_type,       '', '',
+        'taxengine_request', 'text', 'NULL', '', '', '',
 
         #void fields
         'void_date', @date_type, '', '', 
index 1f0c166..33b6a3e 100644 (file)
@@ -226,6 +226,7 @@ sub make_taxlines {
     }
   );
   warn $request_json if $DEBUG > 1;
+  $cust_bill->taxengine_request($request_json);
 
   my $soap = SOAP::Lite->service("http://tcms1.csilongwood.com/cgi-bin/taxcalc.wsdl");
 
index fd90597..704741f 100644 (file)
@@ -159,8 +159,9 @@ sub insert {
   local $FS::UID::AutoCommit = 0;
   my $dbh = dbh;
 
-  my $error =  $self->check_payinfo_cardtype
-            || $self->SUPER::insert;
+  my $error =  $self->check_payinfo_cardtype if $self->payby =~/^(CARD|DCRD)$/;
+  $self->SUPER::insert unless $error;
+
   if ( $error ) {
     $dbh->rollback if $oldAutoCommit;
     return $error;
index 423b442..f074647 100644 (file)
@@ -140,9 +140,9 @@ sub churn_fromwhere_sql {
     # XXX or should we include if they were created by a pkgpart change?
     $from = "cust_pkg";
     @where = (
-      "setup >= $speriod",
-      "setup < $eperiod",
-      "change_pkgnum IS NULL"
+      "cust_pkg.setup >= $speriod",
+      "cust_pkg.setup < $eperiod",
+      "cust_pkg.change_pkgnum IS NULL"
     );
   } elsif ( $status eq 'cancel' ) {
     # also simple, because packages should only be canceled once
diff --git a/fs_selfservice/FS-SelfService/cgi/change_check_pay.html b/fs_selfservice/FS-SelfService/cgi/change_check_pay.html
new file mode 100644 (file)
index 0000000..7dd2583
--- /dev/null
@@ -0,0 +1,23 @@
+<%= include('header', 'Change ach payment information') %>
+
+<%= if ( $error ) { 
+  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">Error: $error</FONT><BR><BR>!;
+  }  ''; %>
+
+<FORM NAME="OneTrueForm" METHOD="POST" ACTION="<%=$selfurl%>" onSubmit="document.OneTrueForm.process.disabled=true">
+
+  <TABLE BGCOLOR="#cccccc">
+    <INPUT TYPE="hidden" NAME="payby" VALUE="CHEK">
+    <%= include('check') %>
+    <TR><TD COLSPAN=3>
+      <INPUT TYPE="checkbox" NAME="auto" VALUE="1">Charge future payments to this card automatically
+    </TD></TR>
+  </TABLE>
+
+  <INPUT TYPE="hidden" NAME="action" VALUE="process_change_check_pay">
+  <INPUT TYPE="hidden" NAME="custpaybynum" VALUE="<%=$custpaybynum%>">
+  <BR>
+  <!-- onClick="this.disabled=true"> -->
+  <INPUT TYPE="submit" NAME="process" VALUE="Save payment information">
+
+<%= include('footer') %>
\ No newline at end of file
diff --git a/fs_selfservice/FS-SelfService/cgi/change_creditcard_pay.html b/fs_selfservice/FS-SelfService/cgi/change_creditcard_pay.html
new file mode 100644 (file)
index 0000000..cce5559
--- /dev/null
@@ -0,0 +1,23 @@
+<%= include('header', 'Change credit card payment information') %>
+
+<%= if ( $error ) { 
+  $OUT .= qq!<FONT SIZE="+1" COLOR="#ff0000">Error: $error</FONT><BR><BR>!;
+  }  ''; %>
+
+<FORM NAME="OneTrueForm" METHOD="POST" ACTION="<%=$selfurl%>" onSubmit="document.OneTrueForm.process.disabled=true">
+
+  <TABLE BGCOLOR="#cccccc">
+    <INPUT TYPE="hidden" NAME="payby" VALUE="CARD">
+    <%= include('card') %>
+    <TR><TD COLSPAN=3>
+      <INPUT TYPE="checkbox" NAME="auto" VALUE="1">Charge future payments to this card automatically
+    </TD></TR>
+  </TABLE>
+
+  <INPUT TYPE="hidden" NAME="action" VALUE="process_change_creditcard_pay">
+  <INPUT TYPE="hidden" NAME="custpaybynum" VALUE="<%=$custpaybynum%>">
+  <BR>
+  <!-- onClick="this.disabled=true"> -->
+  <INPUT TYPE="submit" NAME="process" VALUE="Save payment information">
+
+<%= include('footer') %>
\ No newline at end of file
diff --git a/fs_selfservice/FS-SelfService/cgi/process_change_check_pay.html b/fs_selfservice/FS-SelfService/cgi/process_change_check_pay.html
new file mode 100644 (file)
index 0000000..a1ad60c
--- /dev/null
@@ -0,0 +1,3 @@
+<%= include('header', 'ACH information updated successfully' ) %>
+<FONT SIZE=4>Ach information updated successfully.</FONT>
+<%= include('footer') %>
\ No newline at end of file
diff --git a/fs_selfservice/FS-SelfService/cgi/process_change_creditcard_pay.html b/fs_selfservice/FS-SelfService/cgi/process_change_creditcard_pay.html
new file mode 100644 (file)
index 0000000..c95e09a
--- /dev/null
@@ -0,0 +1,3 @@
+<%= include('header', 'Information updated successfully' ) %>
+<FONT SIZE=4>Information updated successfully.</FONT>
+<%= include('footer') %>
\ No newline at end of file
index f194746..6cf264c 100755 (executable)
@@ -337,6 +337,32 @@ sub _process_change_payby {
   }
 }
 
+sub _process_insert_payby {
+  my ($erroraction, @fields) = @_;
+
+  my $results = '';
+
+  $results ||= insert_payby (
+    'session_id' => $session_id,
+    map { ($_ => $cgi->param($_)) } grep { defined($cgi->param($_)) } @fields,
+  );
+
+  ## check error
+
+
+  if ( $results->{'error'} ) {
+    no strict 'refs';
+    $action = $erroraction;
+    return {
+      $cgi->Vars,
+      %{&$action()},
+      'error' => '<FONT COLOR="#FF0000">'. $results->{'error'}. '</FONT>',
+    };
+  } else {
+    return $results;
+  }
+}
+
 sub process_change_bill {
         _process_change_info( 'change_bill', 
           qw( first last company address1 address2 city state
@@ -389,20 +415,20 @@ sub process_change_creditcard_pay {
               address1 address2 city county state zip country auto paytype
               paystate ss stateid stateid_state invoicing_list
             );
-
-        _process_change_payby( 'change_creditcard_pay', @list );
+        if ($cgi->param( 'custpaybynum' )) { _process_change_payby( 'change_creditcard_pay', @list ); }
+        else { _process_insert_payby( 'change_creditcard_pay', @list ); }
 }
 
 sub process_change_check_pay {
         my $payby  = $cgi->param( 'payby' );
-        $cgi->param('paydate', $cgi->param('year') . '-' . $cgi->param('month') . '-01');
+        #$cgi->param('paydate', '2039-12-01');
         my @list =
           qw( payby payinfo payinfo1 payinfo2 paydate payname custpaybynum 
               address1 address2 city county state zip country auto paytype
               paystate ss stateid stateid_state invoicing_list
             );
-
-        _process_change_payby( 'change_check_pay', @list );
+        if ($cgi->param( 'custpaybynum' )) { _process_change_payby( 'change_check_pay', @list ); }
+        else { _process_insert_payby( 'change_check_pay', @list ); }
 }
 
 sub view_invoice {
index 4ab596d..570f503 100644 (file)
@@ -36,7 +36,9 @@ All rights reserved<BR>
     option) any later version.
 
 <P>
-    At your option, you may also redistribute and/or modify the
+    At your option, you may also redistribute and/or modify the files in 
+    fs_selfservice/drupal/ fs_selfservice/wordpress/ fs_selfservice/perl/ and
+    fs_selfservice/java/ directories and the
     fs_selfservice/php/freeside.class.php file (but not the rest of the
     software) under the terms of the GNU Lesser General Public License as
     published by the Free Software Foundation, either version 3 of the License,
@@ -146,6 +148,10 @@ under the terms of the MIT license.
 Contains the form validation jQuery plugin <a href="https://jqueryvalidation.org/">jQuery Validation</a>  by Jörn Zaefferer, 
 licensed under the terms of MIT License.
 
+<P>
+Contains the leaflet JavaScript library <a href="http://leafletjs.com/">Leaflet JS</a>  by Vladimir Agafonkin,
+licensed under the terms of MIT License.
+
 <!-- artwork -->
 
 <P>
diff --git a/httemplate/elements/header-logo.html b/httemplate/elements/header-logo.html
new file mode 100644 (file)
index 0000000..f272c56
--- /dev/null
@@ -0,0 +1,114 @@
+<%doc>
+
+Example:
+
+  <& /elements/header-logo.html',
+       {
+         'title'     => 'Title',
+         'menubar'   => \@menubar,
+         'etc'       => '', #included in <BODY> tag, for things like onLoad=
+         'head'      => '', #included before closing </HEAD> tag
+         'nobr'      => 0,  #1 for no <BR><BR> after the title
+         'no_jquery' => #for use from RT, which loads its own
+       }
+  &>
+
+</%doc>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+%#<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+%# above is what RT declares, should we switch now? hopefully no glitches result
+%# or just fuck it, XHTML died anyway, HTML 5 or bust?
+<HTML>
+  <HEAD>
+    <TITLE>
+      <% encode_entities($title) || $title_noescape |n %>
+    </TITLE>
+    <!-- per RT, to prevent IE compatibility mode -->
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <!-- The X-UA-Compatible <meta> tag above must be very early in <head> -->
+    <META HTTP-Equiv="Cache-Control" Content="no-cache">
+    <META HTTP-Equiv="Pragma" Content="no-cache">
+    <META HTTP-Equiv="Expires" Content="0"> 
+% if ( $mobile ) {
+    <META NAME="viewport" content="width=device-width height=device-height user-scalable=yes">
+% }
+
+% unless ( $nocss ) {
+  <link href="<%$fsurl%>elements/freeside.css" type="text/css" rel="stylesheet">
+  <link href="<%$fsurl%>elements/freeside-print.css" type="text/css" rel="stylesheet" media="print">
+% }
+
+%   unless ( $no_jquery ) {
+      <link rel="stylesheet" href="<% $fsurl %>elements/jquery-ui.min.css">
+      <SCRIPT SRC="<% $fsurl %>elements/jquery.js"></SCRIPT>
+      <SCRIPT SRC="<% $fsurl %>elements/jquery-ui.min.js"></SCRIPT>
+      <SCRIPT SRC="<% $fsurl %>elements/jquery.validate.min.js"></SCRIPT>
+%     if ( $FS::CurrentUser::CurrentUser->option('printtofit') ) {
+      <SCRIPT SRC="<% $fsurl %>elements/printtofit.js"></SCRIPT>
+%     }
+%   }
+    <% include('init_overlib.html') |n %>
+    <% include('rs_init_object.html') |n %>
+    <script type="text/javascript" src="<% $fsurl %>elements/topreload.js"></script>
+    <% $head |n %>
+
+%# announce our base path, and the Mason comp path of this page
+  <script type="text/javascript">
+  window.fsurl = <% $fsurl |js_string %>;
+  window.request_comp_path = <% $m->request_comp->path |js_string %>;
+  </script>
+
+  </HEAD>
+  <BODY BGCOLOR="#f8f8f8" <% $etc |n %> STYLE="margin-top:0; margin-bottom:0; margin-left:0px; margin-right:0px">
+    <table width="100%" CELLPADDING=0 CELLSPACING=0 STYLE="padding-left:0px; padding-right:4px" CLASS="fshead">
+      <tr>
+        <td BGCOLOR="#ffffff"><% $company_url ? qq(<A HREF="$company_url">) : '' |n %><IMG BORDER=0 ALT="freeside" HEIGHT="36" SRC="<%$fsurl%>view/REAL_logo.cgi"><% $company_url ? '</A>' : '' |n %></td>
+        <td align=left BGCOLOR="#ffffff"> <!-- valign="top" -->
+          <font size=6><% $company_name || 'ExampleCo' %></font>
+        </td>
+      </tr>
+    </table>
+
+<%init>
+
+my( $title, $title_noescape, $menubar, $etc, $head ) = ( '', '', '', '', '' );
+my( $nobr, $nocss, $no_jquery ) = ( 0, 0, 0 );
+
+my $mobile;
+
+my $opt = shift;
+$title   = $opt->{title};
+$title_noescape = $opt->{title_noescape};
+$menubar    = $opt->{menubar};
+$etc        = $opt->{etc};
+$head       = $opt->{head};
+$nobr       = $opt->{nobr};
+$nocss      = $opt->{nocss};
+$mobile     = $opt->{mobile};
+$no_jquery  = $opt->{no_jquery};
+
+my $conf = new FS::Conf;
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+
+my $menu_position = $curuser->option('menu_position')
+                    || 'top'; #new default for 1.9
+
+if ( !defined($mobile) ) {
+  $mobile = $curuser->option('mobile_menu',1) && FS::UI::Web::is_mobile();
+}
+if ( $cgi->param('mobile') =~ /^(\d)$/ ) { # allow client to override
+  $mobile = $1;
+}
+
+my($company_name, $company_url);
+my @agentnums = $curuser->agentnums;
+if ( scalar(@agentnums) == 1 ) {
+  $company_name = $conf->config('company_name', $agentnums[0] );
+  $company_url  = $conf->config('company_url',  $agentnums[0] );
+} else {
+  $company_name = $conf->config('company_name');
+  $company_url  = $conf->config('company_url');
+}
+
+</%init>
\ No newline at end of file
index 3b6552b..68c5b21 100644 (file)
@@ -7,12 +7,13 @@
   'links'         => \@links,
   'params'        => \@params,
   'agentnum'      => $agentnum,
-  'sprintf'       => ( $normalize ? '%0.1f%%' : '%u'), 
+  'sprintf'       => ( $normalize ? '%0.1f%%' : '%u'),
+  'sprintf_fields' => $sprintf_fields,
   'normalize'     => ( $normalize ? 0 : undef ),
   'disable_money' => 1,
   'remove_empty'  => (scalar(@group_keys) > 1 ? 1 : 0),
   'nototal'       => 1,
-  'no_graph'      => [ 1, 0, 0, 0, 0 ], # don't graph 'active'
+  'no_graph'      => [ 1, 0, 0, 0, 0, 1 ], # don't graph 'active, total_revenue'
 &>
 <%init>
 
@@ -33,7 +34,7 @@ if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) {
 
 my $agentname = $agent ? $agent->agent.' ' : '';
 
-my @base_items = qw( active_pkg setup_pkg susp_pkg unsusp_pkg cancel_pkg );
+my @base_items = qw( active_pkg setup_pkg susp_pkg unsusp_pkg cancel_pkg total_revenue_pkg );
 
 my %base_labels = (
   'active_pkg' => 'Active packages',
@@ -41,6 +42,7 @@ my %base_labels = (
   'susp_pkg'   => 'Suspensions',
   'unsusp_pkg' => 'Unsuspensions',
   'cancel_pkg' => 'Cancellations',
+  'total_revenue_pkg' => 'Total Revenue'
 );
 
 my %base_colors = (
@@ -49,8 +51,13 @@ my %base_colors = (
   'susp_pkg'    => 'ff9900', #yellow
   'unsusp_pkg'  => '44ff44', #light green
   'cancel_pkg'  => 'cc0000', #red 
+  'total_revenue_pkg'  => '0000ff', #blue
 );
 
+my $sprintf_fields = {
+  'total_revenue_pkg' => '%.2f', #format to 2 decimal places
+};
+
 my %base_links;
 foreach my $status (qw(active setup cancel susp unsusp)) {
   $base_links{$status.'_pkg'} =
index 1a94281..cfe5a3c 100644 (file)
@@ -59,6 +59,7 @@ Example:
             'no_graph'      => \@no_graph,
             'bottom_link'   => \@bottom_link,
             'transpose'     => $opt{'daily'},
+            'sprintf_fields' => $sprintf_fields,
             map { $_, $opt{$_} } (qw(title
                                     nototal
                                     graph_type
@@ -79,6 +80,7 @@ my $fromparam = $opt{'link_fromparam'} || 'begin';
 my $toparam   = $opt{'link_toparam'} || 'end';
 
 my @items = @{ $opt{'items'} };
+my $sprintf_fields = $opt{'sprintf_fields'};
 
 foreach my $other (qw( labels graph_labels colors links )) {
   if ( ref($opt{$other}) eq 'HASH' ) {
index b5d2148..70c3a9e 100644 (file)
@@ -249,7 +249,7 @@ any delimiter and linked from the elements in @data.
 %   my $e = 0;
 %   foreach ( @$data_row ) {
 %     my $entry = $_;
-%     $entry = $money_char . sprintf($sprintf, $entry);
+%     $entry = $money_char . sprintf($sprintf_fields->{$row} ? $sprintf_fields->{$row} : $sprintf, $entry);
 %     $entry = $link_prefix . shift(@$links) . "\">$entry</A>" if $link_prefix;
 %     push @{$cell[$i]}, $entry;
 %     $bottom_total[$e++] += $_ unless $opt{no_graph}[$i-1];
@@ -343,6 +343,7 @@ my $conf = new FS::Conf;
 my $money_char = $opt{'disable_money'} ? '' : $conf->config('money_char');
 
 my @items = @{ $opt{'items'} };
+my $sprintf_fields = $opt{'sprintf_fields'};
 
 foreach my $other (qw( col_labels row_labels graph_labels axis_labels colors links )) {
   if ( ref($opt{$other}) eq 'HASH' ) {
index b491d49..0f115e5 100644 (file)
@@ -16,7 +16,7 @@ Confirm census tract
 <% $location{address1} |h %> <% $location{address2} |h %><BR>
 <% $location{city} |h %>, <% $location{state} |h %> <% $location{zip} |h %><BR>
 <BR>
-% my $querystring = "census_year=$year&address=$location{address1}, $location{address2}, $location{city}, $location{state}, $location{zip}";
+% my $querystring = "census_year=$year&address=$location{address1}, $location{address2}, $location{city}, $location{state}";
 <A HREF="<%$p%>misc/openmap.html?<% $querystring %>"
    TARGET="_blank">Map service module location</A><BR>
 % $querystring = "census_year=$year&pre=$pre&zip_code=" . $cache->get('zip');
index 6ccc724..73f1071 100644 (file)
@@ -1,11 +1,7 @@
-<html>
-<head>
-  <title>Find Census Tract Map</title>
-  <link rel="stylesheet" href="elements/leaflet/leaflet.css"/>
-  <script src="elements/leaflet/leaflet.js"></script>
-</head>
-<body>
-  <h1>Please select your location on the map</h1>
+<& /elements/header-logo.html, { title => 'Find Census Tract Map', head =>  $head, } &>
+
+<P><h1>Please select your location on the map</h1></P>
+<P>&nbsp;</P>
   <table>
    <tr>
    <td valign=top>
@@ -79,6 +75,11 @@ local $SIG{__DIE__}; #disable Mason error trap
 
 my $DEBUG = 0;
 
+my $head = '
+  <link rel="stylesheet" href="elements/leaflet/leaflet.css"/>
+  <script src="elements/leaflet/leaflet.js"></script>
+';
+
 my $census_year = $cgi->param('census_year');
 my $pre         = $cgi->param('pre');
 my $zip_code    = $cgi->param('zip_code');
diff --git a/httemplate/view/cust_bill-taxengine_request.html b/httemplate/view/cust_bill-taxengine_request.html
new file mode 100644 (file)
index 0000000..991e65f
--- /dev/null
@@ -0,0 +1,14 @@
+<& /elements/header-popup.html &>
+<% $cust_bill->taxengine_request |h %>
+<& /elements/footer-popup.html &>
+<%init>
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+
+die "access denied"
+  unless $curuser->access_right('View invoices');
+
+my $invnum = $cgi->param('invnum');
+my $cust_bill = qsearchs('cust_bill', { invnum=>$invnum });
+
+</%init>
index e35d7f1..762eec0 100755 (executable)
@@ -171,6 +171,18 @@ function change_invoice_mode(obj) {
 &>
 %   $br++;
 % }
+% if ( $cust_bill->taxengine_request ) { # inefficient
+<% $br ? '|' : '' %>
+<& /elements/popup_link.html,
+  'action'      => 'cust_bill-taxengine_request.html?invnum=' . $cust_bill->invnum,
+  'label'       => mt('View raw tax engine request'),
+  'actionlabel' => mt('Tax engine request'),
+  'width'       => 1050,
+  'height'      => 600,
+  'title'       => emt('Tax engine request'),
+&>
+%   $br++;
+% }
 
 <BR><BR>