diff options
author | Ivan Kohler <ivan@freeside.biz> | 2015-04-30 04:01:21 -0700 |
---|---|---|
committer | Ivan Kohler <ivan@freeside.biz> | 2015-04-30 04:01:21 -0700 |
commit | 67b56f17cc51d10394a986fb3d105213b097ee79 (patch) | |
tree | a4c41eb1fa5caca96430658b4b70319f776d657f /FS | |
parent | 7d34aacffa38c4cac09b54080487a66c264e4668 (diff) |
service dependencies: part_pkg_restrict / part_pkg_restrict_soft, RT#33685
Diffstat (limited to 'FS')
-rw-r--r-- | FS/FS/Schema.pm | 2 | ||||
-rw-r--r-- | FS/FS/part_pkg.pm | 92 | ||||
-rw-r--r-- | FS/FS/part_svc_link.pm | 14 |
3 files changed, 99 insertions, 9 deletions
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 114acb8..93220ad 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -3630,7 +3630,7 @@ sub tables_hashref { ], 'primary_key' => 'svclinknum', 'unique' => [ ['agentnum','src_svcpart','dst_svcpart','link_type'] ], - 'index' => [ [ 'src_svcpart' ] ], + 'index' => [ [ 'src_svcpart' ], [ 'src_svcpart', 'link_type' ], [ 'disabled' ] ], 'foreign_keys' => [ { columns => [ 'src_svcpart' ], table => 'part_svc', diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm index 540919e..2fba2f4 100644 --- a/FS/FS/part_pkg.pm +++ b/FS/FS/part_pkg.pm @@ -301,6 +301,12 @@ sub insert { } } + my $error = $self->check_pkg_svc(%options); + if ( $error ) { + $dbh->rollback if $oldAutoCommit; + return $error; + } + } if ( $options{'cust_pkg'} ) { @@ -514,6 +520,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 +571,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 +736,84 @@ 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 ) { + + warn 'checking '. $pkg_svc{$svcpart}->svcpart; + + foreach my $part_svc_link ( $self->part_svc_link( + 'src_svcpart' => $svcpart, + 'link_type' => 'part_pkg_restrict', + ) + ) { + + use Data::Dumper; + warn 'checking '. Dumper($part_svc_link); + + 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<FS::part_svc_link>) 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 { + my( $self, %opt ) = @_; + + my $agentnum = $self->agentnum; + + qsearch({ 'table' => 'part_svc_link', + 'hashref' => \%opt, + 'extra_sql' => + $agentnum + ? "AND ( agentnum IS NULL OR agentnum = $agentnum )" + : 'AND agentnum IS NULL', + }); +} + =item supersede OLD [, OPTION => VALUE ... ] Inserts this package as a successor to the package OLD. All options are as diff --git a/FS/FS/part_svc_link.pm b/FS/FS/part_svc_link.pm index cf82a90..af70d8f 100644 --- a/FS/FS/part_svc_link.pm +++ b/FS/FS/part_svc_link.pm @@ -64,15 +64,14 @@ Link type: # XXX false laziness w/edit/part_svc_link.html -=item part_svc_restrict +=item part_pkg_restrict In package defintions, require the destination service definition when the source service definition is included -=item part_svc_restrict_soft +=item part_pkg_restrict_soft -Soft order block: in package definitions, warn if the destination service -definition is included without the source service definition +Soft order block: in package definitions, suggest the destination service definition when the source service definition is included =item cust_svc_provision_restrict @@ -167,10 +166,10 @@ sub description { # (and hooks each place we have manual checks for the various rules) # but this will do for now - $self->link_type eq 'part_svc_restrict' + $self->link_type eq 'part_pkg_restrict' and return "In package definitions, $dst is required when $src is included"; - $self->link_type eq 'part_svc_restrict_soft' + $self->link_type eq 'part_pkg_restrict_soft' and return "In package definitions, $dst is suggested when $src is included"; $self->link_type eq 'cust_svc_provision_restrict' @@ -219,7 +218,6 @@ L<FS::part_svc>). =cut - sub dst_part_svc { my $self = shift; qsearchs('part_svc', { svcpart=>$self->dst_svcpart } ); @@ -232,7 +230,7 @@ Returns the destination service definition name (part_svc.svc). =cut sub dst_svc { - shift->src_part_svc->svc; + shift->dst_part_svc->svc; } =back |