}
$cust_pkg->locationnum($opt->{'cust_location'}->locationnum);
- } else {
+ } elsif ( ! $cust_pkg->locationnum ) {
$cust_pkg->locationnum($self->ship_locationnum);
}
-=item suspended_pkgs
+=item suspended_pkgs OPTION => VALUE ...
Returns all suspended packages (see L<FS::cust_pkg>) for this customer.
+Currently supports one option, I<reason_type>, which if set to a typenum,
+limits the results to packages which were suspended for reasons of this type.
+(Does not currently work in scalar context; i.e. when just asking for a count.)
+
=cut
sub suspended_pkgs {
my $self = shift;
- return $self->num_suspended_pkgs unless wantarray;
- grep { $_->susp } $self->ncancelled_pkgs;
+ my %opt = @_;
+
+ return $self->num_suspended_pkgs unless wantarray; #XXX opt in scalar context
+
+ my @pkgs = grep { $_->susp } $self->ncancelled_pkgs;
+
+ if ( $opt{reason_type} ) {
+ @pkgs = grep { my $r = $_->last_reason('susp');
+ $r && $r->reason_type == $opt{reason_type};
+ }
+ @pkgs;
+ }
+
+ @pkgs;
}
=item unsuspended_pkgs
=cut
+#recurring_pkgs? different from cust_pkg idea of "active" which has
+# a setup vs not_yet_billed which doesn't
sub active_pkgs {
my $self = shift;
grep { my $part_pkg = $_->part_pkg;
=cut
+#ncancelled_recurring_pkgs? different from cust_pkg idea of "active" which has
+# a setup vs not_yet_billed which doesn't
sub ncancelled_active_pkgs {
my $self = shift;
grep { my $part_pkg = $_->part_pkg;
$self->num_pkgs($opt);
}
+=item num_ncancelled_pkgs
+
+Returns the number of packages that have not been cancelled (see L<FS::cust_pkg>) for this
+customer.
+
+=cut
+
sub num_ncancelled_pkgs {
my $self = shift;
my $opt = shift || {};
$self->num_pkgs($opt);
}
+=item num_billing_pkgs
+
+Returns the number of packages that have not been cancelled
+and have a non-zero billing frequency (see L<FS::cust_pkg>)
+for this customer.
+
+=cut
+
+sub num_billing_pkgs {
+ my $self = shift;
+ my $opt = shift || {};
+ $opt->{addl_from} .= ' LEFT JOIN part_pkg USING (pkgpart)';
+ $opt->{extra_sql} .= ' AND ' if $opt->{extra_sql};
+ $opt->{extra_sql} .= "freq IS NOT NULL AND freq != '0'";
+ $self->num_ncancelled_pkgs($opt);
+}
+
sub num_suspended_pkgs {
my $self = shift;
my $opt = shift || {};
$sth->fetchrow_arrayref->[0];
}
+=item num_usage_pkgs
+
+Returns the number of packages for this customer that have services that
+can have RADIUS usage statistics.
+
+=cut
+
+sub num_usage_pkgs {
+ my $self = shift;
+ # have to enumerate exportnums but it's not bad
+ my @exportnums = map { $_->exportnum }
+ grep { $_->can('usage_sessions') }
+ qsearch('part_export');
+ return 0 if !@exportnums;
+ my $in_exportnums = join(',', @exportnums);
+ my $sql = "SELECT COUNT(DISTINCT pkgnum) FROM cust_pkg
+ JOIN cust_svc USING (pkgnum)
+ JOIN export_svc USING (svcpart)
+ WHERE exportnum IN( $in_exportnums ) AND custnum = ?";
+ FS::Record->scalar_sql($sql, $self->custnum);
+}
+
=item display_recurring
Returns an array of hash references, one for each recurring freq
my $discount = $cust_pkg_discount->discount;
#and only one of these for each
$pkg_amount -= $discount->amount;
- $pkg_amount -= $amount * $discount->percent/100;
+ $pkg_amount -= $pkg_amount * $discount->percent/100;
}
$pkg_amount *= ( $cust_pkg->quantity || 1 );