[freeside-commits] branch master updated. 0be54958813c9a4a5e24e32707b92e49881c7c0a

Mark Wells mark at 420.am
Fri Apr 15 18:28:35 PDT 2016


The branch, master has been updated
       via  0be54958813c9a4a5e24e32707b92e49881c7c0a (commit)
      from  fbb0b4a9c32444f89e0b5aacfebdf883070c3b21 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 0be54958813c9a4a5e24e32707b92e49881c7c0a
Author: Mark Wells <mark at freeside.biz>
Date:   Fri Apr 15 18:21:17 2016 -0700

    tax report showing all taxes, #41656

diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm
index aa9d3be..7b4db99 100644
--- a/FS/FS/Mason.pm
+++ b/FS/FS/Mason.pm
@@ -146,7 +146,8 @@ if ( -e $addl_handler_use_file ) {
   use FS::Report::Table;
   use FS::Report::Table::Monthly;
   use FS::Report::Table::Daily;
-  use FS::Report::Tax;
+  use FS::Report::Tax::ByName;
+  use FS::Report::Tax::All;
   use FS::TicketSystem;
   use FS::NetworkMonitoringSystem;
   use FS::Tron qw( tron_lint );
diff --git a/FS/FS/Report/Tax/All.pm b/FS/FS/Report/Tax/All.pm
new file mode 100644
index 0000000..26dbf5f
--- /dev/null
+++ b/FS/FS/Report/Tax/All.pm
@@ -0,0 +1,110 @@
+package FS::Report::Tax::All;
+
+use strict;
+use vars qw($DEBUG);
+use FS::Record qw(dbh qsearch qsearchs group_concat_sql);
+use FS::Report::Tax::ByName;
+use Date::Format qw( time2str );
+
+use Data::Dumper;
+
+$DEBUG = 0;
+
+=item report OPTIONS
+
+Constructor. Generates a tax report using the internal tax rate system,
+showing all taxes, broken down by tax name and country.
+
+Required parameters:
+- beginning, ending: the date range as Unix timestamps.
+
+Optional parameters:
+- debug: sets the debug level.  1 will warn the data collected for the report;
+2 will also warn all of the SQL statements.
+
+=cut
+
+# because there's not yet a "DBIx::DBSchema::View"...
+
+sub report {
+  my $class = shift;
+  my %opt = @_;
+
+  $DEBUG ||= $opt{debug};
+
+  my($beginning, $ending) = @opt{'beginning', 'ending'};
+
+  # figure out which reports we need to run
+  my @taxname_and_country = qsearch({
+      table     => 'cust_main_county',
+      select    => 'country, taxname',
+      hashref   => {
+        tax => { op => '>', value => '0' }
+      },
+      order_by  => 'GROUP BY country, taxname ORDER BY country, taxname',
+  });
+  my @table;
+  foreach (@taxname_and_country) {
+    my $taxname = $_->taxname || 'Tax';
+    my $country = $_->country;
+    my $report = FS::Report::Tax::ByName->report(
+      %opt,
+      taxname     => $taxname,
+      country     => $country,
+      total_only  => 1,
+    );
+    # will have only one total row (should be only one row at all)
+    my ($total_row) = grep { $_->{total} } $report->table;
+    $total_row->{total} = 0; # but in this context it's a detail row
+    $total_row->{taxname} = $taxname;
+    $total_row->{country} = $country;
+    $total_row->{label} = "$country - $taxname";
+    push @table, $total_row;
+  }
+  my $self = bless {
+    'opt'   => \%opt,
+    'table' => \@table,
+  }, $class;
+
+  $self;
+}
+
+sub opt {
+  my $self = shift;
+  $self->{opt};
+}
+
+sub data {
+  my $self = shift;
+  $self->{data};
+}
+
+# sub fetchall_array...
+
+sub table {
+  my $self = shift;
+  @{ $self->{table} };
+}
+
+sub title {
+  my $self = shift;
+  my $string = '';
+  if ( $self->{opt}->{agentnum} ) {
+    my $agent = qsearchs('agent', { agentnum => $self->{opt}->{agentnum} });
+    $string .= $agent->agent . ' ';
+  }
+  $string .= 'Tax Report: '; # XXX localization
+  if ( $self->{opt}->{beginning} ) {
+    $string .= time2str('%h %o %Y ', $self->{opt}->{beginning});
+  }
+  $string .= 'through ';
+  if ( $self->{opt}->{ending} and $self->{opt}->{ending} < 4294967295 ) {
+    $string .= time2str('%h %o %Y', $self->{opt}->{ending});
+  } else {
+    $string .= 'now';
+  }
+  $string .= ' - all taxes';
+  return $string;
+}
+
+1;
diff --git a/FS/FS/Report/Tax.pm b/FS/FS/Report/Tax/ByName.pm
similarity index 97%
rename from FS/FS/Report/Tax.pm
rename to FS/FS/Report/Tax/ByName.pm
index f1f6be3..88695b9 100644
--- a/FS/FS/Report/Tax.pm
+++ b/FS/FS/Report/Tax/ByName.pm
@@ -1,4 +1,4 @@
-package FS::Report::Tax;
+package FS::Report::Tax::ByName;
 
 use strict;
 use vars qw($DEBUG);
@@ -9,10 +9,12 @@ use Data::Dumper;
 
 $DEBUG = 0;
 
-=item report_internal OPTIONS
+=item report OPTIONS
 
 Constructor.  Generates a tax report using the internal tax rate system 
-(L<FS::cust_main_county>).
+(L<FS::cust_main_county>), showing all taxes with a specified tax name,
+broken down by state/county. Optionally, the taxes can be broken down further
+by city/district, tax class, or package class.
 
 Required parameters:
 
@@ -22,21 +24,22 @@ Required parameters:
 
 Optional parameters:
 - agentnum: limit to this agentnum.num.
-- breakdown: hashref of the fields to group by.  Keys can be 'city', 'district',
-  'pkgclass', or 'taxclass'; values should be true.
+- breakdown: hashref of the fields to group by.  Keys can be 'city',
+'district', 'pkgclass', or 'taxclass'; values should be true.
+- total_only: don't run the tax group queries, only the totals queries.
+Returns one row, except in the unlikely event you're using breakdown by
+package class.
 - debug: sets the debug level.  1 will warn the data collected for the report;
-  2 will also warn all of the SQL statements.
+2 will also warn all of the SQL statements.
 
 =cut
 
-sub report_internal {
+sub report {
   my $class = shift;
   my %opt = @_;
 
   $DEBUG ||= $opt{debug};
 
-  my $conf = new FS::Conf;
-
   my($beginning, $ending) = @opt{'beginning', 'ending'};
 
   my ($taxname, $country, %breakdown);
diff --git a/FS/MANIFEST b/FS/MANIFEST
index d0bf99b..83359f1 100644
--- a/FS/MANIFEST
+++ b/FS/MANIFEST
@@ -56,6 +56,8 @@ FS/Report.pm
 FS/Report/FCC_477.pm
 FS/Report/Table.pm
 FS/Report/Table/Monthly.pm
+FS/Report/Tax/All.pm
+FS/Report/Tax/ByName.pm
 FS/SearchCache.pm
 FS/UI/Web.pm
 FS/UID.pm
diff --git a/httemplate/search/report_tax-xls.cgi b/httemplate/search/report_tax-xls.cgi
index c914d5a..30b32e8 100755
--- a/httemplate/search/report_tax-xls.cgi
+++ b/httemplate/search/report_tax-xls.cgi
@@ -13,9 +13,7 @@ my %params = (
   beginning => $beginning,
   ending    => $ending,
 );
-$params{country} = $cgi->param('country');
 $params{debug}   = $DEBUG;
-$params{breakdown} = { map { $_ => 1 } $cgi->param('breakdown') };
 
 my $agentname;
 if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) {
@@ -24,15 +22,38 @@ if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) {
   $agentname = $agent->agentname;
 }
 
-# allow anything in here; FS::Report::Tax will treat it as unsafe
-if ( length($cgi->param('taxname')) ) {
-  $params{taxname} = $cgi->param('taxname');
+# credit date behavior: limit by the date of the credit application, or
+# the invoice?
+if ( $cgi->param('credit_date') eq 'cust_credit_bill' ) {
+  $params{credit_date} = 'cust_credit_bill';
 } else {
-  die "taxname required";
+  $params{credit_date} = 'cust_bill';
+}
+
+my $all = $cgi->param('all');
+my $report_class;
+
+if ( $all ) {
+  $report_class = 'FS::Report::Tax::All';
+} else {
+  $report_class = 'FS::Report::Tax::ByName';
+  $params{country} = $cgi->param('country');
+  $params{breakdown} = { map { $_ => 1 } $cgi->param('breakdown') };
+
+  # allow anything in here; FS::Report::Tax will treat it as unsafe
+  if ( length($cgi->param('taxname')) ) {
+    $params{taxname} = $cgi->param('taxname');
+  } else {
+    die "taxname required";
+  }
+}
+
+if ($DEBUG) {
+  warn "REPORT: $report_class\nPARAMS:\n".Dumper(\%params)."\n\n";
 }
 
 # generate the report
-my $report = FS::Report::Tax->report_internal(%params);
+my $report = $report_class->report(%params);
 my @rows = $report->table; # array of hashrefs
 
 my %pkgclass_name = map { $_->classnum, $_->classname } qsearch('pkg_class');
diff --git a/httemplate/search/report_tax.cgi b/httemplate/search/report_tax.cgi
index bbb3bc1..410fe46 100644
--- a/httemplate/search/report_tax.cgi
+++ b/httemplate/search/report_tax.cgi
@@ -78,14 +78,6 @@ TD.rowhead { font-weight: bold; text-align: left; padding: 0px 3px }
 %   # cust_bill_pkg.cgi wants a list of specific taxnums (and package class)
 %   # cust_credit_bill_pkg.html wants a geographic scope (and package class)
 %   my $rowlink = ';taxnum=' . $row->{taxnums};
-% # DON'T EVER USE THIS
-% #  my $rowregion = ';country=' . $cgi->param('country');
-% #  foreach my $loc (qw(state county city district)) {
-% #    if ( $row->{$loc} ) {
-% #      $rowregion .= ";$loc=" . uri_escape($row->{$loc});
-% #    }
-% #  }
-%   # and also the package class, if we're limiting package class
 %   if ( $params{breakdown}->{pkgclass} ) {
 %     $rowlink .= ';classnum=' . ($row->{pkgclass} || 0);
 % #    $rowregion .= ';classnum=' . ($row->{pkgclass} || 0);
@@ -96,7 +88,26 @@ TD.rowhead { font-weight: bold; text-align: left; padding: 0px 3px }
 %   }
   <TR CLASS="row<% $rownum % 2 %>">
 %   # Row label
-    <TD CLASS="rowhead"><% $row->{label} |h %></TD>
+%   # Special: If this report is showing all taxes, link the row label to
+%   # the detailed tax report for that taxname/country.
+    <TD CLASS="rowhead">
+%   if ( $all ) {
+%     my $newcgi = CGI->new($cgi);
+%     $newcgi->delete('all');
+%     $newcgi->param('country', $row->{country});
+%     $newcgi->param('taxname', $row->{taxname});
+%     $newcgi->param('breakdown', qw(city district));
+
+      <A HREF="<% encode_entities( $newcgi->self_url ) %>">
+        <% $row->{label} |h %>
+      </A>
+
+%   } else { # on the per-taxname report, just show the label with no link
+
+        <% $row->{label} |h %>
+
+%   }
+    </TD>
     <TD>
 %   # Total sales
       <A HREF="<% $saleslink . $rowlink %>">
@@ -167,7 +178,8 @@ TD.rowhead { font-weight: bold; text-align: left; padding: 0px 3px }
 % } # foreach my $row
 % # at the end of everything
   </TBODY>
-% if ( $report->{out_sales} > 0 ) {
+% # the all-taxes report doesn't have "out of region"
+% if ( !$all and $report->{out_sales} > 0 ) {
   <TBODY CLASS="total" STYLE="background-color: #cccccc; line-height: 3">
     <TR>
       <TD CLASS="rowhead">
@@ -175,7 +187,7 @@ TD.rowhead { font-weight: bold; text-align: left; padding: 0px 3px }
       </TD>
       <TD STYLE="text-align: right">
         <A HREF="<% $saleslink %>;out=1;taxname=<% encode_entities($params{'taxname'}) %>">
-          <% $money_sprintf->( $report->{out_sales } ) %>
+          <% $money_sprintf->( $report->{out_sales} ) %>
         </A>
       </TD>
       <TD COLSPAN=0></TD>
@@ -254,7 +266,7 @@ TD.rowhead { font-weight: bold; text-align: left; padding: 0px 3px }
 %   $prev_row = $row;
 % } # foreach my $row
 % # "out of taxable region" for credits (there is a need for it)
-% if ( $report->{out_credit} > 0 ) {
+% if ( !$all and $report->{out_credit} > 0 ) {
 %   my $creditlink = "cust_credit_bill_pkg.html?out=1;$dateagentlink";
 %   if ( $params{'credit_date'} eq 'cust_credit_bill' ) {
 %     $creditlink =~ s/begin/credit_begin/;
@@ -268,7 +280,7 @@ TD.rowhead { font-weight: bold; text-align: left; padding: 0px 3px }
       </TD>
       <TD STYLE="text-align: right">
         <A HREF="<% $creditlink %>">
-          <% $money_sprintf->( $report->{out_credit } ) %>
+          <% $money_sprintf->( $report->{out_credit} ) %>
         </A>
       </TD>
       <TD COLSPAN=0></TD>
@@ -295,33 +307,48 @@ my %params = (
   beginning => $beginning,
   ending    => $ending,
 );
-$params{country} = $cgi->param('country');
 $params{debug}   = $DEBUG;
-$params{breakdown} = { map { $_ => 1 } $cgi->param('breakdown') };
-
 my $agentname;
+
+# filter by agentnum
 if ( $cgi->param('agentnum') =~ /^(\d+)$/ ) {
   my $agent = FS::agent->by_key($1) or die "unknown agentnum $1";
   $params{agentnum} = $1;
   $agentname = $agent->agentname;
 }
 
-# allow anything in here; FS::Report::Tax will treat it as unsafe
-if ( length($cgi->param('taxname')) ) {
-  $params{taxname} = $cgi->param('taxname');
-} else {
-  die "taxname required";
-}
-
+# credit date behavior: limit by the date of the credit application, or
+# the invoice?
 if ( $cgi->param('credit_date') eq 'cust_credit_bill' ) {
   $params{credit_date} = 'cust_credit_bill';
 } else {
   $params{credit_date} = 'cust_bill';
 }
 
-warn "PARAMS:\n".Dumper(\%params)."\n\n" if $DEBUG;
+my $all = $cgi->param('all');
+my $report_class;
+
+if ( $all ) {
+  # then show the master report, no country, no taxname, no breakdown
+  $report_class = 'FS::Report::Tax::All';
+} else {
+  $report_class = 'FS::Report::Tax::ByName';
+  $params{country} = $cgi->param('country');
+  $params{breakdown} = { map { $_ => 1 } $cgi->param('breakdown') };
+
+  # allow anything in here; FS::Report::Tax will treat it as unsafe
+  if ( length($cgi->param('taxname')) ) {
+    $params{taxname} = $cgi->param('taxname');
+  } else {
+    die "taxname required";
+  }
+}
+
+if ($DEBUG) {
+  warn "REPORT: $report_class\nPARAMS:\n".Dumper(\%params)."\n\n";
+}
 
-my $report = FS::Report::Tax->report_internal(%params);
+my $report = $report_class->report(%params);
 my @rows = $report->table; # array of hashrefs
 
 my $money_char = $conf->config('money_char') || '$';
diff --git a/httemplate/search/report_tax.html b/httemplate/search/report_tax.html
index 8d8d108..f920adb 100755
--- a/httemplate/search/report_tax.html
+++ b/httemplate/search/report_tax.html
@@ -8,6 +8,20 @@
 
   <& /elements/tr-input-beginning_ending.html &>
 
+  <tr>
+    <td></td>
+    <td colspan=2 style="font-weight: bold">
+      <& /elements/radio.html,
+        'field' => 'all',
+        'value' => 1,
+        'curr_value' => 1,
+      &> All taxes
+      <& /elements/radio.html,
+        'field' => 'all',
+        'value' => 0,
+      &> A specific tax
+    </td>
+  </tr>
   <& /elements/tr-select.html,
     'label'         => 'Country',
     'field'         => 'country',
@@ -49,6 +63,21 @@
 
 </FORM>
 
+<script>
+$(document).ready(function() {
+  $('[name=all]').on('change', function(ev) {
+    // disable country/taxname/breakdown if 'all' = 1
+    if (this.checked) {
+      var disabled = (this.value == 1);
+      $('[name=country').prop('disabled', disabled);
+      $('[name=taxname').prop('disabled', disabled);
+      $('[name=breakdown').prop('disabled', disabled);
+    }
+  });
+  $('[name=all]').change();
+});
+</script>
+
 <% include('/elements/footer.html') %>
 <%init>
 
diff --git a/httemplate/search/tax_sales.cgi b/httemplate/search/tax_sales.cgi
index 4b28c93..91abd1b 100644
--- a/httemplate/search/tax_sales.cgi
+++ b/httemplate/search/tax_sales.cgi
@@ -113,7 +113,7 @@ while ($countdate < $enddate) {
   # run a report for each tax name
   foreach my $taxname (@taxnames) {
     $params{'taxname'} = $taxname;
-    my $report = FS::Report::Tax->report_internal(%params);
+    my $report = FS::Report::Tax::ByName->report(%params);
 
     # extract totals from report, kinda awkward
     my $pkgclass = ''; # this will get more complicated if we breakdown by pkgclass

-----------------------------------------------------------------------

Summary of changes:
 FS/FS/Mason.pm                         |    3 +-
 FS/FS/Report/Tax/All.pm                |  110 ++++++++++++++++++++++++++++++++
 FS/FS/Report/{Tax.pm => Tax/ByName.pm} |   21 +++---
 FS/MANIFEST                            |    2 +
 httemplate/search/report_tax-xls.cgi   |   35 ++++++++--
 httemplate/search/report_tax.cgi       |   77 ++++++++++++++--------
 httemplate/search/report_tax.html      |   29 +++++++++
 httemplate/search/tax_sales.cgi        |    2 +-
 8 files changed, 236 insertions(+), 43 deletions(-)
 create mode 100644 FS/FS/Report/Tax/All.pm
 rename FS/FS/Report/{Tax.pm => Tax/ByName.pm} (97%)




More information about the freeside-commits mailing list