default to a session cookie instead of setting an explicit timeout, weird timezone...
[freeside.git] / httemplate / search / 477.html
index 6849337..9a41261 100644 (file)
@@ -32,39 +32,87 @@ table.fcc477part thead tr.subhead {
   font-size: large;
   float: left;
 }
+.errortitle {
+  font-weight: bold;
+  color: #ff0000;
+}
+tr.error td {
+  background-color: #ffdddd;
+}
+tr.error td.error {
+  text-align: left;
+  border: none;
+}
+tr.error ul {
+  margin: 0px;
+  list-style-image: url("<% $fsurl %>images/cross.png");
+}
 a.download {
   float: right;
 }
 </STYLE>
-% foreach my $partnum (@partnums) {
-%   $cgi->param('parts', $partnum);
+% foreach my $partname (@partnames) {
+%   my $this_part = $parts{$partname};
+%   $cgi->param('parts', $partname);
 %   $cgi->param('type', 'csv');
 <table class="fcc477part">
   <caption>
-    <span class="parttitle">Part <% $partnum %></span>
+    <span class="parttitle"><% $part_titles->{$partname} %></span>
+%   if ( $this_part->{num_errors} > 0 ) {
+%     # show error heading while it contains errors
+      <span class="errortitle">
+        <% emt('This section contains [quant,_1,error].', $this_part->{num_errors}) %>
+      </span>
+%   }
     <a class="download" href="<% $cgi->self_url %>">Download</a>
   </caption>
-%   my $header = ".header$partnum";
-%   my $data = $parts{$partnum};
+%   my $header = ".header_$partname";
+%   $header .= '_old' if $partname eq 'fbd' && $date < 1569826800; #9/30/2019
+%              # ( halfway between the two filing "as of" dates when it changed
+
+%   my $data = $this_part->{data};
+%   my $error = $this_part->{error};
   <thead>
     <& $header &>
   </thead>
-%   #XXX column headings
+%   my $rownum = 0;
 %   foreach my $row (@$data) {
-  <tr>
+%     my %eh; # error hash
+%     if ( $error->[$rownum] ) {
+%       %eh = %{ $error->[$rownum] };
+%     }
+  <tr<% keys(%eh) ? ' class="error"' : ''%>>
+%     my $first = 1;
 %     foreach my $item (@$row) {
-    <td><% $item %></td>
+    <td>
+%     if ($first and $part_link{$partname}) {
+      <a href="<% $part_link{$partname} . "477rownum=$rownum" %>"><% $item || '(empty)' %></a>
+%       $first = 0;
+%     } else {
+      <% $item %>
 %     }
+    </td>
+%   } #foreach $item
+%   # display errors
+%   if ( keys %eh ) {
+    <td class="error"><ul>
+%     foreach my $key (sort keys %eh) {
+      <li><% $eh{$key} %></li>
+%     }
+    </ul></td>
+%   } # if there are errors
   </tr>
-%   }
+%   $rownum++;
+%   } #foreach $row
 </table>
-% } # foreach $partnum
+% } # foreach $partname
 <& /elements/footer.html &>
 <%init>
 die "access denied"
   unless $FS::CurrentUser::CurrentUser->access_right('List packages');
 
 my %parts;
+my %part_link;
 # load from cache if possible
 my $session;
 if ( $cgi->param('session') =~ /^(\d+)$/ ) {
@@ -80,24 +128,34 @@ if ($cgi->param('agentnum') =~ /^(\d+)$/ ) {
   $agentnum = $1;
 }
 my $date = parse_datetime($cgi->param('date')) || time;
-my @partnums = grep /^\d+$/, $cgi->param('parts');
-foreach my $partnum (@partnums) {
-  my $method = "part$partnum";
-  $parts{$partnum} ||= FS::Report::FCC_477->$method(
-    date      => $date,
-    agentnum  => $agentnum
-  );
+my @partnames = grep /^\w+$/, $cgi->param('parts');
+my $ignore_quantity = ($cgi->param('ignore_quantity') ? 1 : 0);
+
+foreach my $partname (@partnames) {
+  $parts{$partname} ||= FS::Report::FCC_477->report( $partname,
+    date            => $date,
+    agentnum        => $agentnum,
+    ignore_quantity => $ignore_quantity,
+  ); # includes error, detail, and data parts
+  my $detail_table = FS::Report::FCC_477->part_table($partname);
+  if ($detail_table eq 'cust_pkg') {
+    my $link = popurl(1).'477_cust_pkg.html?477part='.$partname.";date=$date;";
+    if ($agentnum) {
+      $link .= "agentnum=$agentnum;";
+    }
+    $part_link{$partname} = $link;
+  } # don't include detail links to deploy_blocks, that's pointless
 }
 $m->cache->set($session, \%parts, '1h');
 
 my $title = 'FCC Form 477 Data - ' . time2str('%b %o, %Y', $date);
 
 if ( $cgi->param('type') eq 'csv' ) {
-  my $partnum = $partnums[0]; # ignore any beyond the first
-  my $data = $parts{$partnum};
+  my $partname = $partnames[0]; # ignore any beyond the first
+  my $data = $parts{$partname}->{data};
   my $csv = Text::CSV_XS->new({ eol => "\r\n" }); # i think
 
-  my $filename = time2str('%Y-%m-%d', $date) . '-part' . $partnum . '.csv';
+  my $filename = time2str('%Y-%m-%d', $date) . '-'. $partname . '.csv';
   http_header('Content-Type' => 'text/csv');
   http_header('Content-Disposition' => qq(attachment;filename="$filename"));
 
@@ -110,24 +168,44 @@ if ( $cgi->param('type') eq 'csv' ) {
   $m->abort;
 }
 
+my $part_titles = FS::Report::FCC_477->parts;
+
 </%init>
-<%def .header6>
+<%def .header_fbd_old>
   <TR CLASS="head">
-    <TD ROWSPAN=2>Census Tract</TD>
+    <TD ROWSPAN=2>Census Block</TD>
+    <TD ROWSPAN=2>DBA Name</TD>
     <TD ROWSPAN=2>Technology</TD>
-    <TD COLSPAN=2>Speed (Mbps)</TD>
-    <TD COLSPAN=2>Subscriptions</TD>
+    <TD ROWSPAN=2>Consumer?</TD>
+    <TD COLSPAN=2>Advertised Speed (Mbps)</TD>
+    <TD ROWSPAN=2>Business?</TD>
+    <TD COLSPAN=2>Contractual Speed (Mbps)</TD>
   </TR>
   <TR CLASS="subhead">
     <TD>Down</TD>
     <TD>Up</TD>
-    <TD>Total</TD>
-    <TD>Consumer</TD>
+    <TD>Down</TD>
+    <TD>Up</TD>
   </TR>
 </%def>
-<%def .header7>
+<%def .header_fbd>
   <TR CLASS="head">
-    <TD ROWSPAN=2>State</TD>
+    <TD ROWSPAN=2>Census Block</TD>
+    <TD ROWSPAN=2>DBA Name</TD>
+    <TD ROWSPAN=2>Technology</TD>
+    <TD ROWSPAN=2>Consumer?</TD>
+    <TD COLSPAN=2>Advertised Speed (Mbps)</TD>
+    <TD ROWSPAN=2>Business?</TD>
+  </TR>
+  <TR CLASS="subhead">
+    <TD>Down</TD>
+    <TD>Up</TD>
+  </TR>
+</%def>
+<%def .header_fbs>
+  <TR CLASS="head">
+    <TD ROWSPAN=2>Census Tract</TD>
+    <TD ROWSPAN=2>Technology</TD>
     <TD COLSPAN=2>Speed (Mbps)</TD>
     <TD COLSPAN=2>Subscriptions</TD>
   </TR>
@@ -138,17 +216,18 @@ if ( $cgi->param('type') eq 'csv' ) {
     <TD>Consumer</TD>
   </TR>
 </%def>
-<%def .header8>
+<%def .header_fvs>
   <TR CLASS="head">
-    <TD ROWSPAN=2>State</TD>
-    <TD COLSPAN=2>Subscriptions</TD>
+    <TD ROWSPAN=2>Census Tract</TD>
+    <TD ROWSPAN=2>VoIP?</TD>
+    <TD COLSPAN=2>Lines/Subscriptions</TD>
   </TR>
   <TR CLASS="subhead">
     <TD>Total</TD>
-    <TD>Direct</TD>
+    <TD>Consumer</TD>
   </TR>
 </%def>
-<%def .header9>
+<%def .header_lts>
   <TR CLASS="head">
     <TD ROWSPAN=3>State</TD>
     <TD COLSPAN=2>Wholesale</TD>
@@ -183,9 +262,9 @@ if ( $cgi->param('type') eq 'csv' ) {
     <TD>Wireless</TD>
   </TR>
 </%def>
-<%def .header10>
+<%def .header_voip>
   <TR CLASS="head">
-    <TD ROWSPAN=2>State</TD>
+    <TD ROWSPAN=3>State</TD>
     <TD COLSPAN=2>VoIP OTT</TD>
     <TD COLSPAN=8>VoIP Non-OTT</TD>
   </TR>
@@ -206,14 +285,29 @@ if ( $cgi->param('type') eq 'csv' ) {
     <TD>Other</TD>
   </TR>
 </%def>
-<%def .header11>
+<%def .header_mbs>
+%# unimplemented
   <TR CLASS="head">
-    <TD ROWSPAN=2>Census Tract</TD>
-    <TD ROWSPAN=2>VoIP?</TD>
-    <TD COLSPAN=2>Lines/Subscriptions</TD>
+    <TD ROWSPAN=2>State</TD>
+    <TD COLSPAN=2>Speed (Mbps)</TD>
+    <TD COLSPAN=2>Subscriptions</TD>
   </TR>
   <TR CLASS="subhead">
+    <TD>Down</TD>
+    <TD>Up</TD>
     <TD>Total</TD>
     <TD>Consumer</TD>
   </TR>
 </%def>
+<%def .header_mvs>
+%# unimplemented
+  <TR CLASS="head">
+    <TD ROWSPAN=2>State</TD>
+    <TD COLSPAN=2>Subscriptions</TD>
+  </TR>
+  <TR CLASS="subhead">
+    <TD>Total</TD>
+    <TD>Direct</TD>
+  </TR>
+</%def>
+