X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fpart_pkg.pm;h=0e9ee05fb858925becdc909549eee9699b65928d;hb=e1675f79af01255e7bfa0e1ce8d55b25369ee047;hp=540919ee5932996621135b7c10fb7a6b8e3e10d2;hpb=3a8fa4f27ef08792e3d653cee167979a411f89d1;p=freeside.git diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm index 540919ee5..0e9ee05fb 100644 --- a/FS/FS/part_pkg.pm +++ b/FS/FS/part_pkg.pm @@ -30,6 +30,7 @@ use FS::part_pkg_link; use FS::part_pkg_discount; use FS::part_pkg_vendor; use FS::part_pkg_currency; +use FS::part_svc_link; $DEBUG = 0; $setup_hack = 0; @@ -301,6 +302,12 @@ sub insert { } } + my $error = $self->check_pkg_svc(%options); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } if ( $options{'cust_pkg'} ) { @@ -514,6 +521,7 @@ sub replace { my $hidden_svc = $options->{'hidden_svc'} || {}; my $bulk_skip = $options->{'bulk_skip'} || {}; if ( $pkg_svc ) { # if it wasn't passed, don't change existing pkg_svcs + foreach my $part_svc ( qsearch('part_svc', {} ) ) { my $quantity = $pkg_svc->{$part_svc->svcpart} || 0; my $hidden = $hidden_svc->{$part_svc->svcpart} || ''; @@ -564,6 +572,13 @@ sub replace { return $error; } } #foreach $part_svc + + my $error = $new->check_pkg_svc(%$options); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } #if $options->{pkg_svc} my @part_pkg_vendor = $old->part_pkg_vendor; @@ -722,6 +737,69 @@ sub check { ''; } +=item check_pkg_svc + +Checks pkg_svc records as a whole (for part_svc_link dependencies). + +If there is an error, returns the error, otherwise returns false. + +=cut + +sub check_pkg_svc { + my( $self, %opt ) = @_; + + my $agentnum = $self->agentnum; + + my %pkg_svc = map { $_->svcpart => $_ } $self->pkg_svc; + + foreach my $svcpart ( keys %pkg_svc ) { + + foreach my $part_svc_link ( $self->part_svc_link( + 'src_svcpart' => $svcpart, + 'link_type' => 'part_pkg_restrict', + ) + ) { + + return $part_svc_link->dst_svc. ' must be included with '. + $part_svc_link->src_svc + unless $pkg_svc{ $part_svc_link->dst_svcpart }; + } + + } + + return '' if $opt{part_pkg_restrict_soft_override}; + + foreach my $svcpart ( keys %pkg_svc ) { + + foreach my $part_svc_link ( $self->part_svc_link( + 'src_svcpart' => $svcpart, + 'link_type' => 'part_pkg_restrict_soft', + ) + ) { + return $part_svc_link->dst_svc. ' is suggested with '. + $part_svc_link->src_svc + unless $pkg_svc{ $part_svc_link->dst_svcpart }; + } + + } + + ''; +} + +=item part_svc_link OPTION => VALUE ... + +Returns the service dependencies (see L) for the given +search options, taking into account this package definition's agent. + +Available options are any field in part_svc_link. Typically used options are +src_svcpart and link_type. + +=cut + +sub part_svc_link { + FS::part_svc_link->by_agentnum( shift->agentnum, @_ ); +} + =item supersede OLD [, OPTION => VALUE ... ] Inserts this package as a successor to the package OLD. All options are as @@ -1314,6 +1392,11 @@ sub option { my %plandata = map { /^(\w+)=(.*)$/; ( $1 => $2 ); } split("\n", $self->get('plandata') ); return $plandata{$opt} if exists $plandata{$opt}; + + # check whether the option is defined in plan info (if so, don't warn) + if (exists $plans{ $self->plan }->{fields}->{$opt}) { + return ''; + } cluck "WARNING: (pkgpart ". $self->pkgpart. ") Package def option $opt ". "not found in options or plandata!\n" unless $ornull;