[freeside-commits] freeside/FS/FS svc_phone.pm, 1.15, 1.16 svc_acct.pm, 1.247, 1.248 Record.pm, 1.172, 1.173 msgcat.pm, 1.6, 1.7 Setup.pm, 1.14, 1.15 Conf.pm, 1.255, 1.256 svc_Common.pm, 1.47, 1.48
Ivan,,,
ivan at wavetail.420.am
Sun Dec 21 13:33:30 PST 2008
Update of /home/cvs/cvsroot/freeside/FS/FS
In directory wavetail.420.am:/tmp/cvs-serv7874/FS/FS
Modified Files:
svc_phone.pm svc_acct.pm Record.pm msgcat.pm Setup.pm Conf.pm
svc_Common.pm
Log Message:
unique checking for svc_phone like svc_acct, closes: RT#4204 (also a few lines of the new per-agent config snuck in Conf.pm from RT#3989)
Index: Conf.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/Conf.pm,v
retrieving revision 1.255
retrieving revision 1.256
diff -u -d -r1.255 -r1.256
--- Conf.pm 1 Dec 2008 07:52:24 -0000 1.255
+++ Conf.pm 21 Dec 2008 21:33:28 -0000 1.256
@@ -97,7 +97,7 @@
$hashref->{agentnum} = $agentnum;
local $FS::Record::conf = undef; # XXX evil hack prevents recursion
my $cv = FS::Record::qsearchs('conf', $hashref);
- if (!$cv && defined($agentnum)) {
+ if (!$cv && defined($agentnum) && $agentnum) {
$hashref->{agentnum} = '';
$cv = FS::Record::qsearchs('conf', $hashref);
}
@@ -763,6 +763,7 @@
'section' => 'required',
'description' => 'Return address on email invoices',
'type' => 'text',
+ 'per_agent' => 1,
},
{
@@ -1701,6 +1702,14 @@
},
{
+ 'key' => 'global_unique-phonenum',
+ 'section' => '',
+ 'description' => 'Global phone number uniqueness control: none (usual setting - check countrycode+phonenumun uniqueness per exports), or countrycode+phonenum (all countrycode+phonenum pairs are globally unique, regardless of exports). disabled turns off duplicate checking completely and is STRONGLY NOT RECOMMENDED unless you REALLY need to turn this off.',
+ 'type' => 'select',
+ 'select_enum' => [ 'none', 'countrycode+phonenum', 'disabled' ],
+ },
+
+ {
'key' => 'svc_external-skip_manual',
'section' => 'UI',
'description' => 'When provisioning svc_external services, skip manual entry of id and title fields in the UI. Usually used in conjunction with an export that populates these fields (i.e. artera_turbo).',
@@ -1799,6 +1808,7 @@
'section' => 'required',
'description' => 'Your company name',
'type' => 'text',
+ 'per_agent' => 1,
},
{
@@ -1806,6 +1816,7 @@
'section' => 'required',
'description' => 'Your company address',
'type' => 'textarea',
+ 'per_agent' => 1,
},
{
Index: svc_phone.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/svc_phone.pm,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- svc_phone.pm 29 Nov 2008 21:54:35 -0000 1.15
+++ svc_phone.pm 21 Dec 2008 21:33:27 -0000 1.16
@@ -1,16 +1,22 @@
package FS::svc_phone;
use strict;
-use vars qw( @ISA @pw_set );
+use vars qw( @ISA @pw_set $conf );
use FS::Conf;
-#use FS::Record qw( qsearch qsearchs );
+use FS::Record qw( qsearch qsearchs );
use FS::svc_Common;
+use FS::part_svc;
@ISA = qw( FS::svc_Common );
#avoid l 1 and o O 0
@pw_set = ( 'a'..'k', 'm','n', 'p-z', 'A'..'N', 'P'..'Z' , '2'..'9' );
+#ask FS::UID to run this stuff for us later
+$FS::UID::callback{'FS::svc_acct'} = sub {
+ $conf = new FS::Conf;
+};
+
=head1 NAME
FS::svc_phone - Object methods for svc_phone records
@@ -102,6 +108,8 @@
sub table { 'svc_phone'; }
+sub table_dupcheck_fields { ( 'countrycode', 'phonenum' ); }
+
=item search_sql STRING
Class method which returns an SQL fragment to search for the given string.
@@ -215,6 +223,67 @@
$self->SUPER::check;
}
+=item _check duplicate
+
+Internal method to check for duplicate phone numers.
+
+=cut
+
+#false laziness w/svc_acct.pm's _check_duplicate.
+sub _check_duplicate {
+ my $self = shift;
+
+ my $global_unique = $conf->config('global_unique-phonenum') || 'none';
+ return '' if $global_unique eq 'disabled';
+
+ $self->lock_table;
+
+ my @dup_ccphonenum =
+ grep { !$self->svcnum || $_->svcnum != $self->svcnum }
+ qsearch( 'svc_phone', {
+ 'countrycode' => $self->countrycode,
+ 'phonenum' => $self->phonenum,
+ });
+
+ return gettext('phonenum_in_use')
+ if $global_unique eq 'countrycode+phonenum' && @dup_ccphonenum;
+
+ my $part_svc = qsearchs('part_svc', { 'svcpart' => $self->svcpart } );
+ unless ( $part_svc ) {
+ return 'unknown svcpart '. $self->svcpart;
+ }
+
+ if ( @dup_ccphonenum ) {
+
+ my $exports = FS::part_export::export_info('svc_phone');
+ my %conflict_ccphonenum_svcpart = ( $self->svcpart => 'SELF', );
+
+ foreach my $part_export ( $part_svc->part_export ) {
+
+ #this will catch to the same exact export
+ my @svcparts = map { $_->svcpart } $part_export->export_svc;
+
+ $conflict_ccphonenum_svcpart{$_} = $part_export->exportnum
+ foreach @svcparts;
+
+ }
+
+ foreach my $dup_ccphonenum ( @dup_ccphonenum ) {
+ my $dup_svcpart = $dup_ccphonenum->cust_svc->svcpart;
+ if ( exists($conflict_ccphonenum_svcpart{$dup_svcpart}) ) {
+ return "duplicate phone number ".
+ $self->countrycode. ' '. $self->phonenum.
+ ": conflicts with svcnum ". $dup_ccphonenum->svcnum.
+ " via exportnum ". $conflict_ccphonenum_svcpart{$dup_svcpart};
+ }
+ }
+
+ }
+
+ return '';
+
+}
+
=item check_pin
Checks the supplied PIN against the PIN in the database. Returns true for a
Index: svc_acct.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/svc_acct.pm,v
retrieving revision 1.247
retrieving revision 1.248
diff -u -d -r1.247 -r1.248
--- svc_acct.pm 6 Nov 2008 04:22:59 -0000 1.247
+++ svc_acct.pm 21 Dec 2008 21:33:28 -0000 1.248
@@ -337,6 +337,8 @@
sub table { 'svc_acct'; }
+sub table_dupcheck_fields { ( 'username', 'domsvc' ); }
+
sub _fieldhandlers {
{
#false laziness with edit/svc_acct.cgi
@@ -499,12 +501,6 @@
$self->svcpart($cust_svc->svcpart);
}
- $error = $self->_check_duplicate;
- if ( $error ) {
- $dbh->rollback if $oldAutoCommit;
- return $error;
- }
-
my @jobnums;
$error = $self->SUPER::insert(
'jobnums' => \@jobnums,
@@ -817,15 +813,6 @@
}
- if ( $old->username ne $new->username || $old->domsvc != $new->domsvc ) {
- $new->svcpart( $new->cust_svc->svcpart ) unless $new->svcpart;
- $error = $new->_check_duplicate;
- if ( $error ) {
- $dbh->rollback if $oldAutoCommit;
- return $error;
- }
- }
-
$error = $new->SUPER::replace($old, @_);
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
@@ -1227,7 +1214,7 @@
=item _check_duplicate
-Internal function to check for duplicates usernames, username at domain pairs and
+Internal method to check for duplicates usernames, username at domain pairs and
uids.
If the I<global_unique-username> configuration value is set to B<username> or
@@ -1244,20 +1231,7 @@
my $global_unique = $conf->config('global_unique-username') || 'none';
return '' if $global_unique eq 'disabled';
- warn "$me locking svc_acct table for duplicate search" if $DEBUG;
- if ( driver_name =~ /^Pg/i ) {
- dbh->do("LOCK TABLE svc_acct IN SHARE ROW EXCLUSIVE MODE")
- or die dbh->errstr;
- } elsif ( driver_name =~ /^mysql/i ) {
- dbh->do("SELECT * FROM duplicate_lock
- WHERE lockname = 'svc_acct'
- FOR UPDATE"
- ) or die dbh->errstr;
- } else {
- die "unknown database ". driver_name.
- "; don't know how to lock for duplicate search";
- }
- warn "$me acquired svc_acct table lock for duplicate search" if $DEBUG;
+ $self->lock_table;
my $part_svc = qsearchs('part_svc', { 'svcpart' => $self->svcpart } );
unless ( $part_svc ) {
Index: Setup.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/Setup.pm,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- Setup.pm 23 Aug 2008 21:59:43 -0000 1.14
+++ Setup.pm 21 Dec 2008 21:33:28 -0000 1.15
@@ -461,6 +461,10 @@
'en_US' => 'Username in use',
},
+ 'phonenum_in_use' => {
+ 'en_US' => 'Phone number in use',
+ },
+
'illegal_email_invoice_address' => {
'en_US' => 'Illegal email invoice address',
},
Index: msgcat.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/msgcat.pm,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- msgcat.pm 18 Jun 2008 00:36:51 -0000 1.6
+++ msgcat.pm 21 Dec 2008 21:33:28 -0000 1.7
@@ -4,7 +4,7 @@
use vars qw( @ISA );
use Exporter;
use FS::UID;
-use FS::Record;
+use FS::Record qw( qsearchs );
@ISA = qw(FS::Record);
@@ -117,6 +117,38 @@
$self->SUPER::check
}
+
+sub _upgrade_data { #class method
+ my( $class, %opts) = @_;
+
+ eval "use FS::Setup;";
+ die $@ if $@;
+
+ #"repopulate_msgcat", false laziness w/FS::Setup::populate_msgcat
+
+ my %messages = FS::Setup::msgcat_messages();
+
+ foreach my $msgcode ( keys %messages ) {
+ foreach my $locale ( keys %{$messages{$msgcode}} ) {
+ my %msgcat = (
+ 'msgcode' => $msgcode,
+ 'locale' => $locale,
+ #'msg' => $messages{$msgcode}{$locale},
+ );
+ my $msgcat = qsearchs('msgcat', \%msgcat);
+ next if $msgcat;
+
+ $msgcat = new FS::msgcat( {
+ %msgcat,
+ 'msg' => $messages{$msgcode}{$locale},
+ } );
+ my $error = $msgcat->insert;
+ die $error if $error;
+ }
+ }
+
+}
+
=back
=head1 BUGS
Index: Record.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/Record.pm,v
retrieving revision 1.172
retrieving revision 1.173
diff -u -d -r1.172 -r1.173
--- Record.pm 9 Dec 2008 01:49:55 -0000 1.172
+++ Record.pm 21 Dec 2008 21:33:28 -0000 1.173
@@ -766,6 +766,50 @@
} );
}
+=item lock_table
+
+Locks this table with a database-driver specific lock method. This is used
+as a mutex in order to do a duplicate search.
+
+For PostgreSQL, does "LOCK TABLE tablename IN SHARE ROW EXCLUSIVE MODE".
+
+For MySQL, does a SELECT FOR UPDATE on the duplicate_lock table.
+
+Errors are fatal; no useful return value.
+
+Note: To use this method for new tables other than svc_acct and svc_phone,
+edit freeside-upgrade and add those tables to the duplicate_lock list.
+
+=cut
+
+sub lock_table {
+ my $self = shift;
+ my $table = $self->table;
+
+ warn "$me locking $table table\n" if $DEBUG;
+
+ if ( driver_name =~ /^Pg/i ) {
+
+ dbh->do("LOCK TABLE $table IN SHARE ROW EXCLUSIVE MODE")
+ or die dbh->errstr;
+
+ } elsif ( driver_name =~ /^mysql/i ) {
+
+ dbh->do("SELECT * FROM duplicate_lock
+ WHERE lockname = '$table'
+ FOR UPDATE"
+ ) or die dbh->errstr;
+
+ } else {
+
+ die "unknown database ". driver_name. "; don't know how to lock table";
+
+ }
+
+ warn "$me acquired $table table lock\n" if $DEBUG;
+
+}
+
=item insert
Inserts this record to the database. If there is an error, returns the error,
Index: svc_Common.pm
===================================================================
RCS file: /home/cvs/cvsroot/freeside/FS/FS/svc_Common.pm,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -d -r1.47 -r1.48
--- svc_Common.pm 14 Aug 2008 01:52:28 -0000 1.47
+++ svc_Common.pm 21 Dec 2008 21:33:28 -0000 1.48
@@ -249,6 +249,7 @@
my $error = $self->set_auto_inventory
|| $self->check
+ || $self->_check_duplicate
|| $self->SUPER::insert;
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
@@ -314,6 +315,10 @@
'';
}
+#fallbacks
+sub _check_duplcate { ''; }
+sub table_dupcheck_fields { (); }
+
=item delete [ , OPTION => VALUE ... ]
Deletes this account from the database. If there is an error, returns the
@@ -390,6 +395,25 @@
return $error;
}
+ #redundant, but so any duplicate fields are maniuplated as appropriate
+ # (svc_phone.phonenum)
+ my $error = $new->check;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+
+ #if ( $old->username ne $new->username || $old->domsvc != $new->domsvc ) {
+ if ( grep { $old->$_ ne $new->$_ } $new->table_dupcheck_fields ) {
+
+ $new->svcpart( $new->cust_svc->svcpart ) unless $new->svcpart;
+ $error = $new->_check_duplicate;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ }
+
$error = $new->SUPER::replace($old);
if ($error) {
$dbh->rollback if $oldAutoCommit;
More information about the freeside-commits
mailing list