+sub with_report_option {
+ my ($self, %opt) = @_;
+ # %opt can contain:
+ # - report_optionnum: a comma-separated list of numbers. Zero means to
+ # include packages with _no_ report classes.
+ # - not_report_optionnum: a comma-separated list. Packages that have
+ # any of these report options will be excluded from the result.
+ # Zero does nothing.
+ # - use_override: also matches line items that are add-ons to a package
+ # matching the report class.
+ # - all_report_options: returns only packages that have ALL of the
+ # report classes listed in $num. Otherwise, will return packages that
+ # have ANY of those classes.
+
+ my @num = ref($opt{'report_optionnum'})
+ ? @{ $opt{'report_optionnum'} }
+ : split(/\s*,\s*/, $opt{'report_optionnum'});
+ my @not_num = ref($opt{'not_report_optionnum'})
+ ? @{ $opt{'not_report_optionnum'} }
+ : split(/\s*,\s*/, $opt{'not_report_optionnum'});
+ my $null;
+ $null = 1 if ( grep {$_ == 0} @num );
+ @num = grep {$_ > 0} @num;
+ @not_num = grep {$_ > 0} @not_num;
+
+ # brute force
+ my $table = $opt{'use_override'} ? 'override' : 'part_pkg';
+ my $op = ' OR ';
+ if ( $opt{'all_report_options'} ) {
+ if ( @num and $null ) {
+ return 'false'; # mutually exclusive criteria, so just bail out
+ }
+ $op = ' AND ';
+ }
+ my @where_num = map {
+ "EXISTS(SELECT 1 FROM part_pkg_option ".
+ "WHERE optionname = 'report_option_$_' ".
+ "AND part_pkg_option.pkgpart = $table.pkgpart)"
+ } @num;
+ if ( $null ) {
+ push @where_num, "NOT EXISTS(SELECT 1 FROM part_pkg_option ".
+ "WHERE optionname LIKE 'report_option_%' ".
+ "AND part_pkg_option.pkgpart = $table.pkgpart)";
+ }
+ my @where_not_num = map {
+ "NOT EXISTS(SELECT 1 FROM part_pkg_option ".
+ "WHERE optionname = 'report_option_$_' ".
+ "AND part_pkg_option.pkgpart = $table.pkgpart)"
+ } @not_num;
+
+ my @where;
+ if (@where_num) {
+ push @where, '( '.join($op, @where_num).' )';
+ }
+ if (@where_not_num) {
+ push @where, '( '.join(' AND ', @where_not_num).' )';
+ }
+
+ return @where;
+ # this messes up totals
+ #if ( $opt{'use_override'} ) {
+ # # then also allow the non-override package to match
+ # delete $opt{'use_override'};
+ # $comparison = "( $comparison OR " . $self->with_report_option(%opt) . ")";
+ #}
+
+}
+
+sub with_cust_classnum {
+ my ($self, %opt) = @_;
+ if ( $opt{'cust_classnum'} ) {
+ my $classnums = $opt{'cust_classnum'};
+ $classnums = [ $classnums ] if !ref($classnums);
+ @$classnums = grep /^\d+$/, @$classnums;
+ return 'cust_main.classnum in('. join(',',@$classnums) .')'
+ if @$classnums;
+ }
+ ();
+}
+
+