1 <& /elements/header.html, $title &>
2 <STYLE TYPE="text/css">
4 border-collapse: collapse;
5 border: 1px #777 solid;
10 border-left: 1px #777 solid;
11 border-right: 1px #777 solid;
13 table.fcc477part tbody td {
16 table.fcc477part thead tr.head {
20 border-top: 1px #777 solid;
21 border-bottom: 1px #777 solid;
23 table.fcc477part thead tr.subhead {
27 border-top: 1px #777 solid;
28 border-bottom: 1px #777 solid;
40 background-color: #ffdddd;
48 list-style-image: url("<% $fsurl %>images/cross.png");
54 % foreach my $partname (@partnames) {
55 % my $this_part = $parts{$partname};
56 % $cgi->param('parts', $partname);
57 % $cgi->param('type', 'csv');
58 <table class="fcc477part">
60 <span class="parttitle"><% $part_titles->{$partname} %></span>
61 % if ( $this_part->{num_errors} > 0 ) {
62 % # disable downloading while it contains errors
63 <span class="errortitle">
64 <% emt('This section contains [quant,_1,error].', $this_part->{num_errors}) %>
67 <a class="download" href="<% $cgi->self_url %>">Download</a>
70 % my $header = ".header_$partname";
71 % my $data = $this_part->{data};
72 % my $error = $this_part->{error};
77 % foreach my $row (@$data) {
78 % my %eh; # error hash
79 % if ( $error->[$rownum] ) {
80 % %eh = %{ $error->[$rownum] };
82 <tr<% keys(%eh) ? ' class="error"' : ''%>>
84 % foreach my $item (@$row) {
86 % if ($first and $part_link{$partname}) {
87 <a href="<% $part_link{$partname} . "477rownum=$rownum" %>"><% $item || '(empty)' %></a>
96 <td class="error"><ul>
97 % foreach my $key (sort keys %eh) {
98 <li><% $eh{$key} %></li>
101 % } # if there are errors
106 % } # foreach $partname
107 <& /elements/footer.html &>
110 unless $FS::CurrentUser::CurrentUser->access_right('List packages');
114 # load from cache if possible
116 if ( $cgi->param('session') =~ /^(\d+)$/ ) {
118 %parts = %{ $m->cache->get($session) };
120 $session = sprintf('%010d%06d', time, int(rand(1000000)));
121 $cgi->param('session', $session);
125 if ($cgi->param('agentnum') =~ /^(\d+)$/ ) {
128 my $date = parse_datetime($cgi->param('date')) || time;
129 my @partnames = grep /^\w+$/, $cgi->param('parts');
130 my $ignore_quantity = ($cgi->param('ignore_quantity') ? 1 : 0);
132 foreach my $partname (@partnames) {
133 $parts{$partname} ||= FS::Report::FCC_477->report( $partname,
135 agentnum => $agentnum,
136 ignore_quantity => $ignore_quantity,
137 ); # includes error, detail, and data parts
138 my $detail_table = FS::Report::FCC_477->part_table($partname);
139 if ($detail_table eq 'cust_pkg') {
140 my $link = popurl(1).'477_cust_pkg.html?477part='.$partname.";date=$date;";
142 $link .= "agentnum=$agentnum;";
144 $part_link{$partname} = $link;
145 } # don't include detail links to deploy_blocks, that's pointless
147 $m->cache->set($session, \%parts, '1h');
149 my $title = 'FCC Form 477 Data - ' . time2str('%b %o, %Y', $date);
151 if ( $cgi->param('type') eq 'csv' ) {
152 my $partname = $partnames[0]; # ignore any beyond the first
153 my $data = $parts{$partname}->{data};
154 my $csv = Text::CSV_XS->new({ eol => "\r\n" }); # i think
156 my $filename = time2str('%Y-%m-%d', $date) . '-'. $partname . '.csv';
157 http_header('Content-Type' => 'text/csv');
158 http_header('Content-Disposition' => qq(attachment;filename="$filename"));
162 foreach my $row (@$data) {
163 $csv->combine(@$row);
164 $m->print($csv->string);
169 my $part_titles = FS::Report::FCC_477->parts;
174 <TD ROWSPAN=2>Census Block</TD>
175 <TD ROWSPAN=2>DBA Name</TD>
176 <TD ROWSPAN=2>Technology</TD>
177 <TD ROWSPAN=2>Consumer?</TD>
178 <TD COLSPAN=2>Advertised Speed (Mbps)</TD>
179 <TD ROWSPAN=2>Business?</TD>
180 <TD COLSPAN=2>Contractual Speed (Mbps)</TD>
191 <TD ROWSPAN=2>Census Tract</TD>
192 <TD ROWSPAN=2>Technology</TD>
193 <TD COLSPAN=2>Speed (Mbps)</TD>
194 <TD COLSPAN=2>Subscriptions</TD>
205 <TD ROWSPAN=2>Census Tract</TD>
206 <TD ROWSPAN=2>VoIP?</TD>
207 <TD COLSPAN=2>Lines/Subscriptions</TD>
216 <TD ROWSPAN=3>State</TD>
217 <TD COLSPAN=2>Wholesale</TD>
218 <TD COLSPAN=12>End User Lines</TD>
221 <TD ROWSPAN=2>VGEs</TD>
222 <TD ROWSPAN=2>UNE-Ls</TD>
224 <TD ROWSPAN=2>Total</TD>
225 <TD ROWSPAN=2>With Broadband</TD>
226 <TD COLSPAN=2>Consumer</TD>
227 <TD COLSPAN=2>Business</TD>
229 <TD COLSPAN=3>Local Loop</TD>
231 <TD COLSPAN=3>Special Media</TD>
251 <TD ROWSPAN=3>State</TD>
252 <TD COLSPAN=2>VoIP OTT</TD>
253 <TD COLSPAN=8>VoIP Non-OTT</TD>
256 <TD ROWSPAN=2>Total</TD>
257 <TD ROWSPAN=2>Consumer</TD>
259 <TD ROWSPAN=2>Total</TD>
260 <TD ROWSPAN=2>Consumer</TD>
261 <TD ROWSPAN=2>Bundled</TD>
262 <TD COLSPAN=5>Media Type</TD>
275 <TD ROWSPAN=2>State</TD>
276 <TD COLSPAN=2>Speed (Mbps)</TD>
277 <TD COLSPAN=2>Subscriptions</TD>
289 <TD ROWSPAN=2>State</TD>
290 <TD COLSPAN=2>Subscriptions</TD>