Adds this package definition to the database. If there is an error,
returns the error, otherwise returns false.
-Currently available options are: I<pkg_svc>, I<primary_svc>, I<cust_pkg> and
-I<custnum_ref>.
+Currently available options are: I<pkg_svc>, I<primary_svc>, I<cust_pkg>,
+I<custnum_ref> and I<options>.
If I<pkg_svc> is set to a hashref with svcparts as keys and quantities as
values, appropriate FS::pkg_svc records will be inserted.
In conjunction with I<cust_pkg>, if I<custnum_ref> is set to a scalar reference,
the scalar will be updated with the custnum value from the cust_pkg record.
+If I<options> is set to a hashref of options, appropriate FS::part_pkg_option
+records will be inserted.
+
=cut
sub insert {
my $self = shift;
my %options = @_;
- warn "FS::part_pkg::insert called on $self with options %options" if $DEBUG;
+ warn "FS::part_pkg::insert called on $self with options ".
+ join(', ', map "$_=>$options{$_}", keys %options)
+ if $DEBUG;
local $SIG{HUP} = 'IGNORE';
local $SIG{INT} = 'IGNORE';
}
if ( $plandata ) {
- warn " inserting part_pkg_option records for plandata" if $DEBUG;
+
+ warn " inserting part_pkg_option records for plandata" if $DEBUG;
foreach my $part_pkg_option (
map { /^(\w+)=(.*)$/ or do { $dbh->rollback if $oldAutoCommit;
return "illegal plandata: $plandata";
return $error;
}
}
+
+ } elsif ( $options{'options'} ) {
+
+ warn " inserting part_pkg_option records for options hashref" if $DEBUG;
+ foreach my $optionname ( keys %{$options{'options'}} ) {
+
+ my $part_pkg_option =
+ new FS::part_pkg_option {
+ 'pkgpart' => $self->pkgpart,
+ 'optionname' => $optionname,
+ 'optionvalue' => $options{'options'}->{$optionname},
+ };
+
+ my $error = $part_pkg_option->insert;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+
+ }
+
}
my $conf = new FS::Conf;
my $pkg_svc = $options{'pkg_svc'} || {};
foreach my $part_svc ( qsearch('part_svc', {} ) ) {
my $quantity = $pkg_svc->{$part_svc->svcpart} || 0;
- my $primary_svc = $options{'primary_svc'} == $part_svc->svcpart ? 'Y' : '';
+ my $primary_svc =
+ ( $options{'primary_svc'} && $options{'primary_svc'}==$part_svc->svcpart )
+ ? 'Y'
+ : '';
my $pkg_svc = new FS::pkg_svc( {
'pkgpart' => $self->pkgpart,
Returns a list of the acceptable payment types for this package. Eventually
this should come out of a database table and be editable, but currently has the
-following logic instead;
+following logic instead:
-If the package has B<0> setup and B<0> recur, the single item B<BILL> is
+If the package is free, the single item B<BILL> is
returned, otherwise, the single item B<CARD> is returned.
(CHEK? LEC? Probably shouldn't accept those by default, prone to abuse)
sub payby {
my $self = shift;
- #if ( $self->setup == 0 && $self->recur == 0 ) {
- if ( $self->setup =~ /^\s*0+(\.0*)?\s*$/
- && $self->recur =~ /^\s*0+(\.0*)?\s*$/ ) {
+ if ( $self->is_free ) {
( 'BILL' );
} else {
( 'CARD' );
}
}
+=item is_free
+
+Returns true if this package is free.
+
+=cut
+
+sub is_free {
+ my $self = shift;
+ unless ( $self->plan ) {
+ $self->setup =~ /^\s*0+(\.0*)?\s*$/
+ && $self->recur =~ /^\s*0+(\.0*)?\s*$/;
+ } elsif ( $self->can('is_free_options') ) {
+ not grep { $_ !~ /^\s*0*(\.0*)?\s*$/ }
+ map { $self->option($_) }
+ $self->is_free_options;
+ } else {
+ warn "FS::part_pkg::is_free: FS::part_pkg::". $self->plan. " subclass ".
+ "provides neither is_free_options nor is_free method; returning false";
+ 0;
+ }
+}
+
=item freq_pretty
Returns an english representation of the I<freq> field, such as "monthly",
'6' => 'semiannually (every 6 months)',
'12' => 'annually',
'24' => 'biannually (every 2 years)',
+ '36' => 'triannually (every 3 years)',
+ '48' => '(every 4 years)',
+ '60' => '(every 5 years)',
+ '120' => '(every 10 years)',
;
sub freq_pretty {
=cut
sub option {
- my( $self, $opt ) = @_;
+ my( $self, $opt, $ornull ) = @_;
my $part_pkg_option =
qsearchs('part_pkg_option', {
pkgpart => $self->pkgpart,
my %plandata = map { /^(\w+)=(.*)$/; ( $1 => $2 ); }
split("\n", $self->get('plandata') );
return $plandata{$opt} if exists $plandata{$opt};
- cluck "Package definition option $opt not found in options or plandata!\n";
+ cluck "Package definition option $opt not found in options or plandata!\n"
+ unless $ornull;
'';
}
$value;
}
+#fallback that return 0 for old legacy packages with no plan
+
+sub calc_remain { 0; }
+sub calc_cancel { 0; }
+
=back
=head1 SUBROUTINES