+ $extra_sql .= " AND part_pkg.classnum = $classnum ";
+ }
+}
+
+if ( $cgi->param('status') =~ /^([\w ]+)$/ ) {
+ my $status = $1;
+ $extra_sql .= ' AND '. FS::cust_pkg->status_sql. " = '$status' ";
+}
+
+if ( $cgi->param('locationnum') =~ /^(\d+)$/ ) {
+ my $locationnum = $1;
+ $extra_sql .= " AND cust_pkg.locationnum = $locationnum ";
+}
+
+my $total_pkgs = $cust_main->all_pkgs;
+
+my $method = $hide_cancelled ? 'ncancelled_pkgs' : 'all_pkgs';
+my $num_pkgs = $cust_main->$method({
+ 'addl_from' => $addl_from,
+ 'extra_sql' => $extra_sql,
+});
+
+my $maxrecords = $conf->config('cust_main-packages-num_per_page') || 10;
+my $offset = $cgi->param('offset') =~ /^(\d+)$/ ? $1 : 0;
+$cgi->delete('offset');
+
+my @packages = $cust_main->$method( {
+ 'select' => "$cust_pkg_fields, $part_pkg_fields, $num_svcs",
+ 'addl_from' => $addl_from. "
+ LEFT JOIN part_pkg_option AS setup_option
+ ON ( cust_pkg.pkgpart = setup_option.pkgpart
+ AND setup_option.optionname = 'setup_fee' )
+ LEFT JOIN part_pkg_option AS recur_option
+ ON ( cust_pkg.pkgpart = recur_option.pkgpart
+ AND recur_option.optionname = 'recur_fee' )
+ ",
+ 'extra_sql' => $extra_sql,
+ 'order_by' => "ORDER BY pkgnum ASC LIMIT $maxrecords OFFSET $offset",
+} );
+
+foreach my $cust_pkg ( @packages ) {
+
+ my %hash = $cust_pkg->hash;
+ my %part_pkg = map { /^part_pkg_(.+)$/ or die; ( $1 => $hash{$_} ); }
+ grep { /^part_pkg_/ } keys %hash;
+ $cust_pkg->{'_pkgpart'} = new FS::part_pkg \%part_pkg;
+
+ #arrayref of supplementals
+ $cust_pkg->set('_supplemental', [
+ qsearch('cust_pkg', { main_pkgnum=>$cust_pkg->pkgnum })
+ ] );
+
+ #for future changes
+ if ( $cust_pkg->change_to_pkgnum ) {
+ my $change_to =
+ qsearchs('cust_pkg', { pkgnum=>$cust_pkg->change_to_pkgnum });
+ $cust_pkg->set('change_to_pkg', $change_to);
+ $change_to->set('change_from_pkg', $cust_pkg);