'';
}
+=item check_options
+
+For a passed I<$options> hashref, validates any options that
+have 'validate' subroutines defined in the info hash,
+then validates the entire hashref if the price plan has
+its own 'validate' subroutine defined in the info hash
+(I<$options> values might be altered.)
+
+Returns error message, or empty string if valid.
+
+Invoked by L</insert> and L</replace> via the equivalent
+methods in L<FS::option_Common>.
+
+=cut
+
+sub check_options {
+ my ($self,$options) = @_;
+ foreach my $option (keys %$options) {
+ if (exists $plans{ $self->plan }->{fields}->{$option}) {
+ if (exists($plans{$self->plan}->{fields}->{$option}->{'validate'})) {
+ # pass option name for use in error message
+ # pass a reference to the $options value, so it can be cleaned up
+ my $error = &{$plans{$self->plan}->{fields}->{$option}->{'validate'}}($option,\($options->{$option}));
+ return $error if $error;
+ }
+ } # else "option does not exist" error?
+ }
+ if (exists($plans{$self->plan}->{'validate'})) {
+ my $error = &{$plans{$self->plan}->{'validate'}}($options);
+ return $error if $error;
+ }
+ return '';
+}
+
=item check_pkg_svc
Checks pkg_svc records as a whole (for part_svc_link dependencies).
=item calc_units CUST_PKG
This returns the number of provisioned svc_phone records, or, of the package
-count_available_phones option is set, the number available to be provisoined
+count_available_phones option is set, the number available to be provisioned
in the package.
=cut
-#fallback that returns 0 for old legacy packages with no plan
-sub calc_units { 0; }
+sub calc_units {
+ my($self, $cust_pkg ) = @_;
+ my $count = 0;
+ if ( $self->option('count_available_phones', 1)) {
+ foreach my $pkg_svc ($cust_pkg->part_pkg->pkg_svc) {
+ if ($pkg_svc->part_svc->svcdb eq 'svc_phone') { # svc_pbx?
+ $count += $pkg_svc->quantity || 0;
+ }
+ }
+ $count *= $cust_pkg->quantity;
+ } else {
+ $count =
+ scalar(grep { $_->part_svc->svcdb eq 'svc_phone' } $cust_pkg->cust_svc);
+ }
+ $count;
+}
#fallback for everything not based on flat.pm
sub recur_temporality { 'upcoming'; }
$self->base_recur_permonth(@_) - $self->recur_cost_permonth(@_);
}
+=item intro_end PACKAGE
+
+Takes an L<FS::cust_pkg> object. If this plan has an introductory rate,
+returns the expected date the intro period will end. If there is no intro
+rate, returns zero.
+
+=cut
+
+sub intro_end {
+ 0;
+}
+
=item format OPTION DATA
Returns data formatted according to the function 'format' described