X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=FS%2FFS%2Fpart_pkg.pm;h=98bb74cab60e35cccf78c87a1ca1077615e1586c;hp=08c9b87f91d15d910600983a726455182790a5b7;hb=ff92fba056c2b61753d464c84ecede6ec2f57258;hpb=e078ca418dcf3c7b92efcd371ce761df3314c369 diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm index 08c9b87f9..98bb74cab 100644 --- a/FS/FS/part_pkg.pm +++ b/FS/FS/part_pkg.pm @@ -16,9 +16,11 @@ use FS::type_pkgs; use FS::part_pkg_option; use FS::pkg_class; use FS::agent; +use FS::part_pkg_taxrate; use FS::part_pkg_taxoverride; use FS::part_pkg_taxproduct; use FS::part_pkg_link; +use FS::part_pkg_discount; @ISA = qw( FS::m2m_Common FS::option_Common ); $DEBUG = 0; @@ -98,6 +100,8 @@ inherits from FS::Record. The following fields are currently supported: =item agentnum - Optional agentnum (see L) +=item fcc_ds0s - Optional DS0 equivalency number for FCC form 477 + =back =head1 METHODS @@ -140,7 +144,9 @@ Currently available options are: I, I, I, I and I. If I is set to a hashref with svcparts as keys and quantities as -values, appropriate FS::pkg_svc records will be inserted. +values, appropriate FS::pkg_svc records will be inserted. I can +be set to a hashref of svcparts and flag values ('Y' or '') to set the +'hidden' field in these records. If I is set to the svcpart of the primary service, the appropriate FS::pkg_svc record will be updated. @@ -226,6 +232,7 @@ sub insert { warn " inserting pkg_svc records" if $DEBUG; my $pkg_svc = $options{'pkg_svc'} || {}; + my $hidden_svc = $options{'hidden_svc'} || {}; foreach my $part_svc ( qsearch('part_svc', {} ) ) { my $quantity = $pkg_svc->{$part_svc->svcpart} || 0; my $primary_svc = @@ -238,6 +245,7 @@ sub insert { 'svcpart' => $part_svc->svcpart, 'quantity' => $quantity, 'primary_svc' => $primary_svc, + 'hidden' => $hidden_svc->{$part_svc->svcpart}, } ); my $error = $pkg_svc->insert; if ( $error ) { @@ -289,10 +297,13 @@ sub delete { Replaces OLD_RECORD with this one in the database. If there is an error, returns the error, otherwise returns false. -Currently available options are: I, I and I +Currently available options are: I, I, I +and I If I is set to a hashref with svcparts as keys and quantities as -values, the appropriate FS::pkg_svc records will be replaced. +values, the appropriate FS::pkg_svc records will be replaced. I +can be set to a hashref of svcparts and flag values ('Y' or '') to set the +'hidden' field in these records. If I is set to the svcpart of the primary service, the appropriate FS::pkg_svc record will be updated. @@ -375,8 +386,10 @@ sub replace { warn " replacing pkg_svc records" if $DEBUG; my $pkg_svc = $options->{'pkg_svc'} || {}; + my $hidden_svc = $options->{'hidden_svc'} || {}; foreach my $part_svc ( qsearch('part_svc', {} ) ) { my $quantity = $pkg_svc->{$part_svc->svcpart} || 0; + my $hidden = $hidden_svc->{$part_svc->svcpart} || ''; my $primary_svc = ( defined($options->{'primary_svc'}) && $options->{'primary_svc'} && $options->{'primary_svc'} == $part_svc->svcpart @@ -384,17 +397,24 @@ sub replace { ? 'Y' : ''; - my $old_pkg_svc = qsearchs('pkg_svc', { - 'pkgpart' => $old->pkgpart, - 'svcpart' => $part_svc->svcpart, - } ); - my $old_quantity = $old_pkg_svc ? $old_pkg_svc->quantity : 0; - my $old_primary_svc = - ( $old_pkg_svc && $old_pkg_svc->dbdef_table->column('primary_svc') ) - ? $old_pkg_svc->primary_svc - : ''; - next unless $old_quantity != $quantity || $old_primary_svc ne $primary_svc; + 'pkgpart' => $old->pkgpart, + 'svcpart' => $part_svc->svcpart, + } + ); + my $old_quantity = 0; + my $old_primary_svc = ''; + my $old_hidden = ''; + if ( $old_pkg_svc ) { + $old_quantity = $old_pkg_svc->quantity; + $old_primary_svc = $old_pkg_svc->primary_svc + if $old_pkg_svc->dbdef_table->column('primary_svc'); # is this needed? + $old_hidden = $old_pkg_svc->hidden; + } + + next unless $old_quantity != $quantity || + $old_primary_svc ne $primary_svc || + $old_hidden ne $hidden; my $new_pkg_svc = new FS::pkg_svc( { 'pkgsvcnum' => ( $old_pkg_svc ? $old_pkg_svc->pkgsvcnum : '' ), @@ -402,6 +422,7 @@ sub replace { 'svcpart' => $part_svc->svcpart, 'quantity' => $quantity, 'primary_svc' => $primary_svc, + 'hidden' => $hidden, } ); my $error = $old_pkg_svc ? $new_pkg_svc->replace($old_pkg_svc) @@ -480,6 +501,7 @@ sub check { ? $self->ut_foreign_keyn('agentnum', 'agent', 'agentnum' ) : $self->ut_agentnum_acl('agentnum', \@null_agentnum_right) ) + || $self->ut_numbern('fcc_ds0s') || $self->SUPER::check ; return $error if $error; @@ -771,34 +793,9 @@ sub is_free { sub can_discount { 0; } sub freqs_href { - #method, class method or sub? #my $self = shift; - - tie my %freq, 'Tie::IxHash', - '0' => '(no recurring fee)', - '1h' => 'hourly', - '1d' => 'daily', - '2d' => 'every two days', - '3d' => 'every three days', - '1w' => 'weekly', - '2w' => 'biweekly (every 2 weeks)', - '1' => 'monthly', - '45d' => 'every 45 days', - '2' => 'bimonthly (every 2 months)', - '3' => 'quarterly (every 3 months)', - '4' => 'every 4 months', - '137d' => 'every 4 1/2 months (137 days)', - '6' => 'semiannually (every 6 months)', - '12' => 'annually', - '13' => 'every 13 months (annually +1 month)', - '24' => 'biannually (every 2 years)', - '36' => 'triannually (every 3 years)', - '48' => '(every 4 years)', - '60' => '(every 5 years)', - '120' => '(every 10 years)', - ; - - \%freq; - + # moved to FS::Misc to make this accessible to other packages + # at initialization + FS::Misc::pkg_freqs(); } =item freq_pretty @@ -831,32 +828,34 @@ sub freq_pretty { } } -=item add_freq TIMESTAMP +=item add_freq TIMESTAMP [ FREQ ] -Adds the frequency of this package to the provided timestamp and returns -the resulting timestamp, or -1 if the frequency of this package could not be -parsed (shouldn't happen). +Adds a billing period of some frequency to the provided timestamp and +returns the resulting timestamp, or -1 if the frequency could not be +parsed (shouldn't happen). By default, the frequency of this package +will be used; to override this, pass a different frequency as a second +argument. =cut sub add_freq { - my( $self, $date ) = @_; - my $freq = $self->freq; + my( $self, $date, $freq ) = @_; + $freq = $self->freq unless $freq; #change this bit to use Date::Manip? CAREFUL with timezones (see # mailing list archive) my ($sec,$min,$hour,$mday,$mon,$year) = (localtime($date) )[0,1,2,3,4,5]; - if ( $self->freq =~ /^\d+$/ ) { - $mon += $self->freq; + if ( $freq =~ /^\d+$/ ) { + $mon += $freq; until ( $mon < 12 ) { $mon -= 12; $year++; } - } elsif ( $self->freq =~ /^(\d+)w$/ ) { + } elsif ( $freq =~ /^(\d+)w$/ ) { my $weeks = $1; $mday += $weeks * 7; - } elsif ( $self->freq =~ /^(\d+)d$/ ) { + } elsif ( $freq =~ /^(\d+)d$/ ) { my $days = $1; $mday += $days; - } elsif ( $self->freq =~ /^(\d+)h$/ ) { + } elsif ( $freq =~ /^(\d+)h$/ ) { my $hours = $1; $hour += $hours; } else { @@ -959,6 +958,8 @@ sub _part_pkg_link { qsearch({ table => 'part_pkg_link', hashref => { 'src_pkgpart' => $self->pkgpart, 'link_type' => $type, + #protection against infinite recursive links + 'dst_pkgpart' => { op=>'!=', value=> $self->pkgpart }, }, order_by => "ORDER BY hidden", }); @@ -1145,6 +1146,18 @@ sub part_pkg_taxrate { } ); } +=item part_pkg_discount + +Returns the package to discount m2m records (see L) +for this package. + +=cut + +sub part_pkg_discount { + my $self = shift; + qsearch('part_pkg_discount', { 'pkgpart' => $self->pkgpart }); +} + =item _rebless Reblesses the object into the FS::part_pkg::PLAN class (if available), where @@ -1209,6 +1222,18 @@ sub calc_units { 0; } #fallback for everything except bulk.pm sub hide_svc_detail { 0; } +=item recur_cost_permonth CUST_PKG + +recur_cost divided by freq (only supported for monthly and longer frequencies) + +=cut + +sub recur_cost_permonth { + my($self, $cust_pkg) = @_; + return 0 unless $self->freq =~ /^\d+$/ && $self->freq > 0; + sprintf('%.2f', $self->recur_cost / $self->freq ); +} + =item format OPTION DATA Returns data formatted according to the function 'format' described