package import w/bulk phone number ranges, RT#39127
[freeside.git] / FS / FS / cust_pkg / Search.pm
index 5091236..89809de 100644 (file)
@@ -118,6 +118,15 @@ Limit to packages associated with a svc_broadband, associated with a sector,
 associated with this towernum (or any of these, if it's an arrayref) (or NO
 towernum, if it's zero). This is an extreme niche case.
 
+=item 477part, 477rownum, date
+
+Limit to packages included in a specific row of one of the FCC 477 reports.
+'477part' is the section name (see L<FS::Report::FCC_477> methods), 'date'
+is the report as-of date (completely unrelated to the package setup/bill/
+other date fields), and '477rownum' is the row number of the report starting
+with zero. Row numbers have no inherent meaning, so this is useful only 
+for explaining a 477 report you've already run.
+
 =back
 
 =cut
@@ -272,6 +281,21 @@ sub search {
   }
 
   ###
+  # parse refnum (advertising source)
+  ###
+
+  if ( exists($params->{'refnum'}) ) {
+    my @refnum;
+    if (ref $params->{'refnum'}) {
+      @refnum = @{ $params->{'refnum'} };
+    } else {
+      @refnum = ( $params->{'refnum'} );
+    }
+    my $in = join(',', grep /^\d+$/, @refnum);
+    push @where, "refnum IN($in)" if length $in;
+  }
+
+  ###
   # parse package report options
   ###
 
@@ -288,10 +312,10 @@ sub search {
   if (@report_option) {
     # this will result in the empty set for the dangling comma case as it should
     push @where, 
-      map{ "0 < ( SELECT count(*) FROM part_pkg_option
-                    WHERE part_pkg_option.pkgpart = part_pkg.pkgpart
-                    AND optionname = 'report_option_$_'
-                    AND optionvalue = '1' )"
+      map{ "EXISTS ( SELECT 1 FROM part_pkg_option
+                       WHERE part_pkg_option.pkgpart = part_pkg.pkgpart
+                       AND optionname = 'report_option_$_'
+                       AND optionvalue = '1' )"
          } @report_option;
   }
 
@@ -307,10 +331,10 @@ sub search {
     if (@report_option_any) {
       # this will result in the empty set for the dangling comma case as it should
       push @where, ' ( '. join(' OR ',
-        map{ "0 < ( SELECT count(*) FROM part_pkg_option
-                      WHERE part_pkg_option.pkgpart = part_pkg.pkgpart
-                      AND optionname = 'report_option_$_'
-                      AND optionvalue = '1' )"
+        map{ "EXISTS ( SELECT 1 FROM part_pkg_option
+                         WHERE part_pkg_option.pkgpart = part_pkg.pkgpart
+                         AND optionname = 'report_option_$_'
+                         AND optionvalue = '1' )"
            } @report_option_any
       ). ' ) ';
     }
@@ -540,6 +564,39 @@ sub search {
   }
 
   ##
+  # parse the 477 report drill-down options
+  ##
+
+  if ($params->{'477part'} =~ /^([a-z]+)$/) {
+    my $section = $1;
+    my ($date, $rownum, $agentnum);
+    if ($params->{'date'} =~ /^(\d+)$/) {
+      $date = $1;
+    }
+    if ($params->{'477rownum'} =~ /^(\d+)$/) {
+      $rownum = $1;
+    }
+    if ($params->{'agentnum'} =~ /^(\d+)$/) {
+      $agentnum = $1;
+    }
+    if ($date and defined($rownum)) {
+      my $report = FS::Report::FCC_477->report($section,
+        'date'      => $date,
+        'agentnum'  => $agentnum,
+        'detail'    => 1
+      );
+      my $pkgnums = $report->{detail}->[$rownum]
+        or die "row $rownum is past the end of the report";
+        # '0' so that if there are no pkgnums (empty string) it will create
+        # a valid query that returns nothing
+      warn "PKGNUMS:\n$pkgnums\n\n"; # XXX debug
+
+      # and this overrides everything
+      @where = ( "cust_pkg.pkgnum IN($pkgnums)" );
+    } # else we're missing some params, ignore the whole business
+  }
+
+  ##
   # setup queries, links, subs, etc. for the search
   ##