From 696b790c88984203912b46c9e4b103c2925833c1 Mon Sep 17 00:00:00 2001 From: mark Date: Thu, 28 Oct 2010 07:47:13 +0000 Subject: [PATCH] global duplicate checking on svc_pbx.id, RT#9967 --- FS/FS/Conf.pm | 10 +++++++++- FS/FS/svc_Common.pm | 36 ++++++++++++++++++++++++++++++++++++ FS/FS/svc_pbx.pm | 23 ++++++++++++++--------- 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 72e38d3d2..73d39ada9 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -2305,7 +2305,15 @@ and customer address. Include units.', { 'key' => 'global_unique-pbx_title', 'section' => '', - 'description' => 'Global phone number uniqueness control: enabled (usual setting - svc_pbx.title must be unique), or disabled turns off duplicate checking for this field.', + 'description' => 'Global phone number uniqueness control: none (check uniqueness per exports), enabled (check across all services), or disabled (no duplicate checking).', + 'type' => 'select', + 'select_enum' => [ 'enabled', 'disabled' ], + }, + + { + 'key' => 'global_unique-pbx_id', + 'section' => '', + 'description' => 'Global PBX id uniqueness control: none (check uniqueness per exports), enabled (check across all services), or disabled (no duplicate checking).', 'type' => 'select', 'select_enum' => [ 'enabled', 'disabled' ], }, diff --git a/FS/FS/svc_Common.pm b/FS/FS/svc_Common.pm index 71290f441..e0f1e3338 100644 --- a/FS/FS/svc_Common.pm +++ b/FS/FS/svc_Common.pm @@ -1013,6 +1013,42 @@ sub clone_kludge_unsuspend { shift; } +=item find_duplicates MODE FIELDS... + +Method used by _check_duplicate routines to find services with duplicate +values in specified fields. Set MODE to 'global' to search across all +services, or 'export' to limit to those that share one or more exports +with this service. FIELDS is a list of field names; only services +matching in all fields will be returned. Empty fields will be skipped. + +=cut + +sub find_duplicates { + my $self = shift; + my $mode = shift; + my @fields = @_; + + my %search = map { $_ => $self->getfield($_) } + grep { length($self->getfield($_)) } @fields; + return () if !%search; + my @dup = grep { ! $self->svcnum or $_->svcnum != $self->svcnum } + qsearch( $self->table, \%search ); + return () if !@dup; + return @dup if $mode eq 'global'; + die "incorrect find_duplicates mode '$mode'" if $mode ne 'export'; + + my $exports = FS::part_export::export_info($self->table); + my %conflict_svcparts; + my $part_svc = $self->part_svc; + foreach my $part_export ( $part_svc->part_export ) { + %conflict_svcparts = map { $_->svcpart => 1 } $part_export->export_svc; + } + return grep { $conflict_svcparts{$_->cust_svc->svcpart} } @dup; +} + + + + =back =head1 BUGS diff --git a/FS/FS/svc_pbx.pm b/FS/FS/svc_pbx.pm index adc45a78f..0eb544318 100644 --- a/FS/FS/svc_pbx.pm +++ b/FS/FS/svc_pbx.pm @@ -253,22 +253,27 @@ sub check { $self->SUPER::check; } -#XXX this is a way-too simplistic implementation -# at the very least, title should be unique across exports that need that or -# controlled by a conf setting or something sub _check_duplicate { my $self = shift; my $conf = new FS::Conf; - return '' if $conf->config('global_unique-pbx_title') eq 'disabled'; - + $self->lock_table; - if ( qsearchs( 'svc_pbx', { 'title' => $self->title } ) ) { - return "Name in use"; - } else { - return ''; + foreach my $field ('title', 'id') { + my $global_unique = $conf->config("global_unique-pbx_$field"); + # can be 'disabled', 'enabled', or empty. + # if empty, check per exports; if not empty or disabled, check + # globally. + next if $global_unique eq 'disabled'; + my @dup = $self->find_duplicates( + ($global_unique ? 'global' : 'export') , $field + ); + next if !@dup; + return "duplicate $field '".$self->getfield($field). + "': conflicts with svcnum ".$dup[0]->svcnum; } + return ''; } =item get_cdrs -- 2.11.0