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 $partname (@partnames) {
+% my $this_part = $parts{$partname};
% $cgi->param('parts', $partname);
% $cgi->param('type', 'csv');
<table class="fcc477part">
<caption>
- <span class="parttitle"><% $parttitle{$partname} %></span>
+ <span class="parttitle"><% $part_titles->{$partname} %></span>
+% if ( $this_part->{num_errors} > 0 ) {
+% # disable downloading while it contains errors
+ <span class="errortitle">
+ <% emt('This section contains [quant,_1,error].', $this_part->{num_errors}) %>
+ </span>
+% } else {
<a class="download" href="<% $cgi->self_url %>">Download</a>
+% }
</caption>
% my $header = ".header_$partname";
-% my $data = $parts{$partname};
+% my $data = $this_part->{data};
+% my $error = $this_part->{error};
<thead>
<& $header &>
</thead>
+% 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 $partname
<& /elements/footer.html &>
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+)$/ ) {
}
my $date = parse_datetime($cgi->param('date')) || time;
my @partnames = grep /^\w+$/, $cgi->param('parts');
+my $ignore_quantity = ($cgi->param('ignore_quantity') ? 1 : 0);
+
foreach my $partname (@partnames) {
- my $method = "report_$partname";
- $parts{$partname} ||= FS::Report::FCC_477->$method(
- date => $date,
- agentnum => $agentnum
- );
+ $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');
if ( $cgi->param('type') eq 'csv' ) {
my $partname = $partnames[0]; # ignore any beyond the first
- my $data = $parts{$partname};
+ my $data = $parts{$partname}->{data};
my $csv = Text::CSV_XS->new({ eol => "\r\n" }); # i think
my $filename = time2str('%Y-%m-%d', $date) . '-'. $partname . '.csv';
$m->abort;
}
+my $part_titles = FS::Report::FCC_477->parts;
+
</%init>
-<%def .header_fixed_broadband>
+<%def .header_fbd>
+ <TR CLASS="head">
+ <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>
+ <TD COLSPAN=2>Contractual Speed (Mbps)</TD>
+ </TR>
+ <TR CLASS="subhead">
+ <TD>Down</TD>
+ <TD>Up</TD>
+ <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>Consumer</TD>
</TR>
</%def>
-<%def .header_fixed_voice>
+<%def .header_fvs>
<TR CLASS="head">
<TD ROWSPAN=2>Census Tract</TD>
<TD ROWSPAN=2>VoIP?</TD>
<TD>Consumer</TD>
</TR>
</%def>
-<%def .header_local_phone>
+<%def .header_lts>
<TR CLASS="head">
<TD ROWSPAN=3>State</TD>
<TD COLSPAN=2>Wholesale</TD>
</%def>
<%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>
<TD>Other</TD>
</TR>
</%def>
-<%def .header_mobile_broadband>
+<%def .header_mbs>
%# unimplemented
<TR CLASS="head">
<TD ROWSPAN=2>State</TD>
<TD>Consumer</TD>
</TR>
</%def>
-<%def .header_mobile_voice>
+<%def .header_mvs>
%# unimplemented
<TR CLASS="head">
<TD ROWSPAN=2>State</TD>