X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2FReport%2FFCC_477.pm;h=20d402d7d19898014ed996538bf3c4ebaaf34d23;hb=fcb230261cbd138c1869f6db4a443ac7ae2a98a1;hp=86fa0a6165a9ea4b3b787e724f87dea35fa357c9;hpb=d7cf0d6bb3b81b1c91ef1bcc3252d56f96b65b0f;p=freeside.git diff --git a/FS/FS/Report/FCC_477.pm b/FS/FS/Report/FCC_477.pm index 86fa0a616..20d402d7d 100644 --- a/FS/FS/Report/FCC_477.pm +++ b/FS/FS/Report/FCC_477.pm @@ -4,14 +4,13 @@ use base qw( FS::Report ); use strict; use vars qw( @upload @download @technology @part2aoption @part2boption %states - $DEBUG ); use FS::Record qw( dbh ); use Tie::IxHash; use Storable; -$DEBUG = 1; +our $DEBUG = 0; =head1 NAME @@ -247,6 +246,17 @@ sub join_optionname_int { " ON (part_pkg.pkgpart = t_$name.pkgpart)"; } +sub dbaname { + # Returns an sql expression for the DBA name + "COALESCE( deploy_zone.dbaname, + (SELECT value FROM conf WHERE conf.name = 'company_name' + AND (conf.agentnum = deploy_zone.agentnum + OR conf.agentnum IS NULL) + ORDER BY conf.agentnum IS NOT NULL DESC + LIMIT 1) + ) AS dbaname" +} + sub active_on { # Returns a condition to limit packages to those that were setup before a # certain date, and not canceled before that date. @@ -259,17 +269,28 @@ sub active_on { } sub is_fixed_broadband { - "is_broadband::int = 1 AND technology::int IN(".join(',', - 10, 11, 12, 20, 30, 40, 41, 42, 50, 60, 70, 90, 0 - ).")"; + "is_broadband::int = 1 AND technology::int IN( 10, 11, 12, 20, 30, 40, 41, 42, 50, 60, 70, 90, 0 )" +} + +sub is_mobile_broadband { + "is_broadband::int = 1 AND technology::int IN( 80, 81, 82, 83, 84, 85, 86, 87, 88)" } =item report SECTION, OPTIONS Returns the report section SECTION (see the C method for section -name strings) as an arrayref of arrayrefs. OPTIONS may contain "date" -(a timestamp value to run the report as of this date) and "agentnum" -(to limit to a single agent). +name strings) as an arrayref of arrayrefs. OPTIONS may contain the following: + +- date: a timestamp value. Packages that were active on that date will be +counted. + +- agentnum: limit to packages with this agent. + +- detail: if true, the report will contain an additional column which contains +the keys of all objects aggregated in the row. + +- ignore_quantity: if true, package quantities will be ignored (only distinct +packages will be counted). =cut @@ -283,6 +304,7 @@ sub report { unless $class->can($method); my $statement = $class->$method(%opt); + warn $statement if $DEBUG; my $sth = dbh->prepare($statement); $sth->execute or die $sth->errstr; $sth->fetchall_arrayref; @@ -290,14 +312,13 @@ sub report { sub fbd_sql { my $class = shift; - my %opt = shift; + my %opt = @_; my $date = $opt{date} || time; - warn $date; my $agentnum = $opt{agentnum}; my @select = ( 'censusblock', - 'COALESCE(dbaname, agent.agent)', + dbaname(), 'technology', 'CASE WHEN is_consumer IS NOT NULL THEN 1 ELSE 0 END', 'adv_speed_down', @@ -306,8 +327,9 @@ sub fbd_sql { 'cir_speed_down', 'cir_speed_up', ); - my $from = - 'deploy_zone_block + push @select, 'blocknum' if $opt{detail}; + + my $from = 'deploy_zone_block JOIN deploy_zone USING (zonenum) JOIN agent USING (agentnum)'; my @where = ( @@ -317,7 +339,7 @@ sub fbd_sql { ); push @where, "agentnum = $agentnum" if $agentnum; - my $order_by = 'censusblock, dbaname, technology, is_consumer, is_business'; + my $order_by = 'censusblock, agentnum, technology, is_consumer, is_business'; "SELECT ".join(', ', @select) . " FROM $from @@ -328,18 +350,23 @@ sub fbd_sql { sub fbs_sql { my $class = shift; - my %opt = shift; + my %opt = @_; my $date = $opt{date} || time; my $agentnum = $opt{agentnum}; + my $q = $opt{ignore_quantity} ? '1' : 'COALESCE(cust_pkg.quantity, 1)'; + + my $censustract = "replace(cust_location.censustract, '.', '')"; my @select = ( - 'cust_location.censustract', + "$censustract AS censustract", 'technology', 'broadband_downstream', 'broadband_upstream', - 'COUNT(*)', - 'COUNT(is_consumer)', + "SUM($q)", + "SUM(COALESCE(is_consumer,0) * $q)", ); + push @select, "array_to_string(array_agg(pkgnum), ',')" if $opt{detail}; + my $from = 'cust_pkg JOIN cust_location ON (cust_pkg.locationnum = cust_location.locationnum) @@ -356,8 +383,7 @@ sub fbs_sql { is_fixed_broadband() ); push @where, "cust_main.agentnum = $agentnum" if $agentnum; - my $group_by = 'cust_location.censustract, technology, '. - 'broadband_downstream, broadband_upstream '; + my $group_by = "$censustract, technology, broadband_downstream, broadband_upstream "; my $order_by = $group_by; "SELECT ".join(', ', @select) . " @@ -371,19 +397,22 @@ sub fbs_sql { sub fvs_sql { my $class = shift; - my %opt = shift; + my %opt = @_; my $date = $opt{date} || time; my $agentnum = $opt{agentnum}; + my $q = $opt{ignore_quantity} ? '1' : 'COALESCE(cust_pkg.quantity, 1)'; + my $censustract = "replace(cust_location.censustract, '.', '')"; my @select = ( - 'cust_location.censustract', + "$censustract AS censustract", # VoIP indicator (0 for non-VoIP, 1 for VoIP) 'COALESCE(is_voip, 0)', # number of lines/subscriptions - 'SUM(CASE WHEN is_voip = 1 THEN 1 ELSE phone_lines END)', + "SUM($q * (CASE WHEN is_voip = 1 THEN 1 ELSE phone_lines END))", # consumer grade lines/subscriptions - 'SUM(CASE WHEN is_consumer = 1 THEN ( CASE WHEN is_voip = 1 THEN voip_sessions ELSE phone_lines END) ELSE 0 END)' + "SUM($q * COALESCE(is_consumer,0) * (CASE WHEN is_voip = 1 THEN voip_sessions ELSE phone_lines END))", ); + push @select, "array_to_string(array_agg(pkgnum), ',')" if $opt{detail}; my $from = 'cust_pkg JOIN cust_location ON (cust_pkg.locationnum = cust_location.locationnum) @@ -399,7 +428,7 @@ sub fvs_sql { "(is_voip = 1 OR is_phone = 1)", ); push @where, "cust_main.agentnum = $agentnum" if $agentnum; - my $group_by = 'cust_location.censustract, COALESCE(is_voip, 0)'; + my $group_by = "$censustract, COALESCE(is_voip, 0)"; my $order_by = $group_by; "SELECT ".join(', ', @select) . " @@ -413,27 +442,30 @@ sub fvs_sql { sub lts_sql { my $class = shift; - my %opt = shift; + my %opt = @_; my $date = $opt{date} || time; my $agentnum = $opt{agentnum}; + my $q = $opt{ignore_quantity} ? '1' : 'COALESCE(cust_pkg.quantity, 1)'; my @select = ( "state.fips", - "SUM(phone_vges)", - "SUM(phone_circuits)", - "SUM(phone_lines)", - "SUM(CASE WHEN is_broadband = 1 THEN phone_lines ELSE 0 END)", - "SUM(CASE WHEN is_consumer = 1 AND phone_longdistance IS NULL THEN phone_lines ELSE 0 END)", - "SUM(CASE WHEN is_consumer = 1 AND phone_longdistance = 1 THEN phone_lines ELSE 0 END)", - "SUM(CASE WHEN is_consumer IS NULL AND phone_longdistance IS NULL THEN phone_lines ELSE 0 END)", - "SUM(CASE WHEN is_consumer IS NULL AND phone_longdistance = 1 THEN phone_lines ELSE 0 END)", - "SUM(CASE WHEN phone_localloop = 'owned' THEN phone_lines ELSE 0 END)", - "SUM(CASE WHEN phone_localloop = 'leased' THEN phone_lines ELSE 0 END)", - "SUM(CASE WHEN phone_localloop = 'resale' THEN phone_lines ELSE 0 END)", - "SUM(CASE WHEN media = 'Fiber' THEN phone_lines ELSE 0 END)", - "SUM(CASE WHEN media = 'Cable Modem' THEN phone_lines ELSE 0 END)", - "SUM(CASE WHEN media = 'Fixed Wireless' THEN phone_lines ELSE 0 END)", + "SUM($q * phone_vges)", + "SUM($q * phone_circuits)", + "SUM($q * phone_lines)", + "SUM($q * (CASE WHEN is_broadband = 1 THEN phone_lines ELSE 0 END))", + "SUM($q * (CASE WHEN is_consumer = 1 AND phone_longdistance IS NULL THEN phone_lines ELSE 0 END))", + "SUM($q * (CASE WHEN is_consumer = 1 AND phone_longdistance = 1 THEN phone_lines ELSE 0 END))", + "SUM($q * (CASE WHEN is_consumer IS NULL AND phone_longdistance IS NULL THEN phone_lines ELSE 0 END))", + "SUM($q * (CASE WHEN is_consumer IS NULL AND phone_longdistance = 1 THEN phone_lines ELSE 0 END))", + "SUM($q * (CASE WHEN phone_localloop = 'owned' THEN phone_lines ELSE 0 END))", + "SUM($q * (CASE WHEN phone_localloop = 'leased' THEN phone_lines ELSE 0 END))", + "SUM($q * (CASE WHEN phone_localloop = 'resale' THEN phone_lines ELSE 0 END))", + "SUM($q * (CASE WHEN media = 'Fiber' THEN phone_lines ELSE 0 END))", + "SUM($q * (CASE WHEN media = 'Cable Modem' THEN phone_lines ELSE 0 END))", + "SUM($q * (CASE WHEN media = 'Fixed Wireless' THEN phone_lines ELSE 0 END))", ); + push @select, "array_to_string(array_agg(pkgnum),',')" if $opt{detail}; + my $from = 'cust_pkg JOIN cust_location ON (cust_pkg.locationnum = cust_location.locationnum) @@ -465,25 +497,27 @@ sub lts_sql { sub voip_sql { my $class = shift; - my %opt = shift; + my %opt = @_; my $date = $opt{date} || time; my $agentnum = $opt{agentnum}; + my $q = $opt{ignore_quantity} ? '1' : 'COALESCE(cust_pkg.quantity, 1)'; my @select = ( "state.fips", # OTT, OTT + consumer - "SUM(CASE WHEN (voip_lastmile IS NULL) THEN 1 ELSE 0 END)", - "SUM(CASE WHEN (voip_lastmile IS NULL AND is_consumer = 1) THEN 1 ELSE 0 END)", + "SUM($q * (CASE WHEN (voip_lastmile IS NULL) THEN 1 ELSE 0 END))", + "SUM($q * (CASE WHEN (voip_lastmile IS NULL AND is_consumer = 1) THEN 1 ELSE 0 END))", # non-OTT: total, consumer, broadband bundle, media types - "SUM(CASE WHEN (voip_lastmile = 1) THEN 1 ELSE 0 END)", - "SUM(CASE WHEN (voip_lastmile = 1 AND is_consumer = 1) THEN 1 ELSE 0 END)", - "SUM(CASE WHEN (voip_lastmile = 1 AND is_broadband = 1) THEN 1 ELSE 0 END)", - "SUM(CASE WHEN (voip_lastmile = 1 AND media = 'Copper') THEN 1 ELSE 0 END)", - "SUM(CASE WHEN (voip_lastmile = 1 AND media = 'Cable Modem') THEN 1 ELSE 0 END)", - "SUM(CASE WHEN (voip_lastmile = 1 AND media = 'Fiber') THEN 1 ELSE 0 END)", - "SUM(CASE WHEN (voip_lastmile = 1 AND media = 'Fixed Wireless') THEN 1 ELSE 0 END)", - "SUM(CASE WHEN (voip_lastmile = 1 AND media NOT IN('Copper', 'Fiber', 'Cable Modem', 'Fixed Wireless') ) THEN 1 ELSE 0 END)", + "SUM($q * (CASE WHEN (voip_lastmile = 1) THEN 1 ELSE 0 END))", + "SUM($q * (CASE WHEN (voip_lastmile = 1 AND is_consumer = 1) THEN 1 ELSE 0 END))", + "SUM($q * (CASE WHEN (voip_lastmile = 1 AND is_broadband = 1) THEN 1 ELSE 0 END))", + "SUM($q * (CASE WHEN (voip_lastmile = 1 AND media = 'Copper') THEN 1 ELSE 0 END))", + "SUM($q * (CASE WHEN (voip_lastmile = 1 AND media = 'Cable Modem') THEN 1 ELSE 0 END))", + "SUM($q * (CASE WHEN (voip_lastmile = 1 AND media = 'Fiber') THEN 1 ELSE 0 END))", + "SUM($q * (CASE WHEN (voip_lastmile = 1 AND media = 'Fixed Wireless') THEN 1 ELSE 0 END))", + "SUM($q * (CASE WHEN (voip_lastmile = 1 AND media NOT IN('Copper', 'Fiber', 'Cable Modem', 'Fixed Wireless') ) THEN 1 ELSE 0 END))", ); + push @select, "array_to_string(array_agg(pkgnum),',')" if $opt{detail}; my $from = 'cust_pkg @@ -510,7 +544,88 @@ sub voip_sql { GROUP BY $group_by ORDER BY $order_by "; +} + +sub mbs_sql { + my $class = shift; + my %opt = @_; + my $date = $opt{date} || time; + my $agentnum = $opt{agentnum}; + my $q = $opt{ignore_quantity} ? '1' : 'COALESCE(cust_pkg.quantity, 1)'; + + my @select = ( + 'state.fips', + 'broadband_downstream', + 'broadband_upstream', + "SUM($q)", + "SUM(COALESCE(is_consumer, 0) * $q)", + ); + push @select, "array_to_string(array_agg(pkgnum),',')" if $opt{detail}; + + my $from = + 'cust_pkg + JOIN cust_location ON (cust_pkg.locationnum = cust_location.locationnum) + JOIN state USING (country, state) + JOIN cust_main ON (cust_pkg.custnum = cust_main.custnum) + JOIN part_pkg USING (pkgpart) '. + join_optionnames_int(qw( + is_broadband technology + is_consumer + )). + join_optionnames(qw(broadband_downstream broadband_upstream)) + ; + my @where = ( + active_on($date), + is_mobile_broadband() + ); + push @where, "cust_main.agentnum = $agentnum" if $agentnum; + my $group_by = 'state.fips, broadband_downstream, broadband_upstream '; + my $order_by = $group_by; + + "SELECT ".join(', ', @select) . " + FROM $from + WHERE ".join(' AND ', @where)." + GROUP BY $group_by + ORDER BY $order_by + "; +} + +sub mvs_sql { + my $class = shift; + my %opt = @_; + my $date = $opt{date} || time; + my $agentnum = $opt{agentnum}; + my $q = $opt{ignore_quantity} ? '1' : 'COALESCE(cust_pkg.quantity, 1)'; + + my @select = ( + 'state.fips', + "SUM($q)", + "SUM($q * COALESCE(mobile_direct,0))", + ); + push @select, "array_to_string(array_agg(pkgnum),',')" if $opt{detail}; + + my $from = + 'cust_pkg + JOIN cust_location ON (cust_pkg.locationnum = cust_location.locationnum) + JOIN state USING (country, state) + JOIN cust_main ON (cust_pkg.custnum = cust_main.custnum) + JOIN part_pkg USING (pkgpart) '. + join_optionnames_int(qw( is_mobile mobile_direct) ) + ; + my @where = ( + active_on($date), + 'is_mobile = 1' + ); + push @where, "cust_main.agentnum = $agentnum" if $agentnum; + my $group_by = 'state.fips'; + my $order_by = $group_by; + "SELECT ".join(', ', @select) . " + FROM $from + WHERE ".join(' AND ', @where)." + GROUP BY $group_by + ORDER BY $order_by + "; } =item parts @@ -537,4 +652,22 @@ sub parts { Storable::dclone(\%parts); } +=item part_table SECTION + +Returns the name of the primary table that's aggregated in the report section +SECTION. The last column of the report returned by the L method is +a comma-separated list of record numbers, in this table, that are included in +the report line item. + +=cut + +sub part_table { + my ($class, $part) = @_; + if ($part eq 'fbd') { + return 'deploy_zone_block'; + } else { + return 'cust_pkg'; + } # add other cases as we add more of the deployment/availability reports +} + 1;