+ return $next_number-1;
+}
+
+=head2 bug_filter
+
+ bug_filter
+
+Allows filtering bugs on commonly used criteria
+
+
+
+=cut
+
+sub bug_filter {
+ my %param = validate_with(params => \@_,
+ spec => {bug => {type => ARRAYREF|SCALAR,
+ optional => 1,
+ },
+ status => {type => HASHREF|ARRAYREF,
+ optional => 1,
+ },
+ seen_merged => {type => HASHREF,
+ optional => 1,
+ },
+ repeat_merged => {type => BOOLEAN,
+ default => 1,
+ },
+ include => {type => HASHREF,
+ optional => 1,
+ },
+ exclude => {type => HASHREF,
+ optional => 1,
+ },
+ min_days => {type => SCALAR,
+ optional => 1,
+ },
+ max_days => {type => SCALAR,
+ optional => 1,
+ },
+ },
+ );
+ if (exists $param{repeat_merged} and
+ not $param{repeat_merged} and
+ not defined $param{seen_merged}) {
+ croak "repeat_merged false requires seen_merged to be passed";
+ }
+ if (not exists $param{bug} and not exists $param{status}) {
+ croak "one of bug or status must be passed";
+ }
+
+ if (not exists $param{status}) {
+ my $location = getbuglocation($param{bug}, 'summary');
+ return 0 if not defined $location or not length $location;
+ $param{status} = readbug( $param{bug}, $location );
+ return 0 if not defined $param{status};
+ }
+
+ if (exists $param{include}) {
+ return 1 if (!__bug_matches($param{include}, $param{status}));
+ }
+ if (exists $param{exclude}) {
+ return 1 if (__bug_matches($param{exclude}, $param{status}));
+ }
+ if (exists $param{repeat_merged} and not $param{repeat_merged}) {
+ my @merged = sort {$a<=>$b} $param{bug}, split(/ /, $param{status}{mergedwith});
+ return 1 if first {defined $_} @{$param{seen_merged}}{@merged};
+ @{$param{seen_merged}}{@merged} = (1) x @merged;
+ }
+ my $daysold = int((time - $param{status}{date}) / 86400); # seconds to days
+ if (exists $param{min_days}) {
+ return 1 unless $param{min_days} <= $daysold;
+ }
+ if (exists $param{max_days}) {
+ return 1 unless $param{max_days} == -1 or
+ $param{max_days} >= $daysold;
+ }
+ return 0;