1 % if ( $opt{'type'} eq 'xml' ) {
2 %# container element <Part_IA_$tech> is in 477.html
4 % foreach ( @summary_row ) {
5 % my $el = $xml_prefix . $col . '1'; # PartIA_Aa1, PartIA_Ab1, etc.
6 <<% $el %>><% $_ %><<% "/$el" %>>
9 % foreach my $col_data ( @data ) {
11 % foreach my $cell ( @$col_data ) {
12 % my $el = $xml_prefix . $col . $row; # PartIA_Af1, PartIA_Af2...
13 % if ( $cell->[0] > 0 ) {
14 <<% $el %>><% $cell->[0] %><<% "/$el" %>>
15 % if ( $percentages ) {
16 % $el = $xml_percent . $col . $row; # Part_p_IA_Af1, ...
17 <<% $el %>><% $cell->[1] %><<% "/$el" %>>
23 % } # foreach $col_data
26 <H2><% $title %> totals</H2>
27 <& /elements/table-grid.html &>
29 % foreach ( 'Total Connections',
31 % '% billed to end users',
33 % '% residential > 200 kbps') {
34 <TH WIDTH="20%"><% $_ |h %></TH>
38 % foreach ( @summary_row ) {
43 <H2><% $title %> breakdown by speed</H2>
44 <TABLE CLASS="grid" CELLSPACING=0>
47 % for (my $col = 0; $col < scalar(@download_option); $col++) {
49 <% $FS::Report::FCC_477::download[$col] |h %>
53 % for (my $row = 0; $row < scalar(@upload_option); $row++) {
54 <TR CLASS="row<% $row % 2%>">
55 <TD STYLE="text-align: left; font-weight: bold">
56 % if ( $asymmetric ) {
57 <% $FS::Report::FCC_477::upload[$row] |h %>
60 % for (my $col = 0; $col < scalar(@download_option); $col++) {
62 % if ( $data[$col][$row][0] > 0 ) {
63 <% $data[$col][$row][0] %>
64 % if ( $percentages ) {
65 <BR><% $data[$col][$row][1] %>
76 my $curuser = $FS::CurrentUser::CurrentUser;
79 unless $curuser->access_right('List packages');
84 for ( qw(agentnum state) ) {
85 $search_hash{$_} = $cgi->param($_) if $cgi->param($_);
86 } # note that separation by state is no longer required after July 2014
87 $search_hash{'country'} = 'US';
88 $search_hash{'classnum'} = [ $cgi->param('classnum') ];
90 my $info = FS::part_pkg_fcc_option->info;
94 # arrays of report_option_ numbers, running parallel to
95 # the download and upload speed arrays
96 my @download_option = $cgi->param('part1_column_option');
97 my @upload_option = $cgi->param('part1_row_option');
99 my @technology_option = &FS::Report::FCC_477::parse_technology_option($cgi);
102 my $total_residential = 0;
104 my $tech_code = $opt{tech_code};
105 my $technology = $FS::Report::FCC_477::technology[$tech_code] || 'unknown';
106 my $title = "Part IA $technology";
107 my $xml_prefix = 'PartIA_'. chr(65 + $tech_code);
108 my $xml_percent = 'Part_p_IA_'. chr(65 + $tech_code); # yes, seriously
110 # whether to show the results as a matrix (upload speeds in rows) or a single
113 if ( $technology eq 'Symmetric xDSL' or $technology eq 'Other Wireline' ) {
115 @upload_option = ( undef );
117 # whether to show residential percentages in each cell of the matrix
118 my $percentages = ($technology eq 'Terrestrial Mobile Wireless');
121 # FCC 477 instructions: "Only count connections that are in service."
122 # So we count packages that were in active status as of the specified date,
123 # not over any sort of range.
124 $search_hash{'active'} = [ $opt{date}, $opt{date} ];
126 my $query = FS::cust_pkg->search(\%search_hash);
127 my $count_query = $query->{'count_query'};
129 my $is_residential = " AND COALESCE(cust_main.company, '') = ''";
130 my $has_option = sub {
131 my $optionnum = shift;
132 $optionnum =~ /^\d+$/ ?
134 SELECT 1 FROM part_pkg_option
135 WHERE part_pkg_option.pkgpart = part_pkg.pkgpart
136 AND optionname = 'report_option_$optionnum'
137 AND optionvalue = '1'
141 # limit to those that have technology option $tech_code
142 $count_query .= $has_option->($technology_option[$tech_code]);
145 for ( my $row = 0; $row < scalar @upload_option; $row++ ) {
146 for ( my $col = 0; $col < scalar @download_option; $col++ ) {
148 my $this_count_query = $count_query .
149 $has_option->($upload_option[$row]) .
150 $has_option->($download_option[$col]);
152 my $count = FS::Record->scalar_sql($this_count_query);
153 my $residential = FS::Record->scalar_sql($this_count_query . $is_residential);
155 my $percent = sprintf('%.3f', $count ? 100 * $residential / $count : 0);
156 $data[$col][$row] = [ $count, $percent ];
158 $total_count += $count;
159 $total_residential += $residential;
160 $above_200 += $residential if $row > 0 or !$asymmetric;
164 my $total_percentage =
165 sprintf("%.3f", $total_count ? 100*$total_residential/$total_count : 0);
167 my $above_200_percentage =
168 sprintf("%.3f", $total_count ? 100*$above_200/$total_count : 0);
172 100.00, # own local loop--consistent with previous practice, but probably wrong
173 100.00, # billed to end user--also wrong
174 $total_percentage, # residential percentage
175 $above_200_percentage,