From 3402ff329fde97d6ac96723b5c2a4ed46ed2ce25 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 8 Mar 2010 07:03:00 +0000 Subject: [PATCH] domain names in netsapiens export (domain name association w/svc_phone), RT#5864 --- FS/FS/Conf.pm | 7 ++ FS/FS/Schema.pm | 3 +- FS/FS/part_export/netsapiens.pm | 15 ++- FS/FS/svc_Domain_Mixin.pm | 134 ++++++++++++++++++++++++++ FS/FS/svc_acct.pm | 90 +---------------- FS/FS/svc_phone.pm | 19 +++- FS/MANIFEST | 2 + FS/t/svc_Domain_Mixin.t | 5 + httemplate/edit/elements/svc_Common.html | 5 +- httemplate/edit/svc_phone.cgi | 39 +++++--- httemplate/elements/select-svc-domain.html | 50 ++++++++++ httemplate/elements/tr-select-svc-domain.html | 34 +++++++ httemplate/view/svc_phone.cgi | 16 +-- 13 files changed, 298 insertions(+), 121 deletions(-) create mode 100644 FS/FS/svc_Domain_Mixin.pm create mode 100644 FS/t/svc_Domain_Mixin.t create mode 100644 httemplate/elements/select-svc-domain.html create mode 100644 httemplate/elements/tr-select-svc-domain.html diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index c00a085d0..6da81ee46 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -3289,6 +3289,13 @@ worry that config_items is freeside-specific and icky. }, { + 'key' => 'svc_phone-domain', + 'section' => '', + 'description' => 'Track an optional domain association with each phone service.', + 'type' => 'checkbox', + }, + + { 'key' => 'default_phone_countrycode', 'section' => '', 'description' => 'Default countrcode', diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm index 485570fb3..9016676c3 100644 --- a/FS/FS/Schema.pm +++ b/FS/FS/Schema.pm @@ -2438,10 +2438,11 @@ sub tables_hashref { 'sip_password', 'varchar', 'NULL', $char_d, '', '', 'phone_name', 'varchar', 'NULL', $char_d, '', '', 'pbxsvc', 'int', 'NULL', '', '', '', + 'domsvc', 'int', 'NULL', '', '', '', ], 'primary_key' => 'svcnum', 'unique' => [], - 'index' => [ [ 'countrycode', 'phonenum' ], ['pbxsvc'] ], + 'index' => [ [ 'countrycode', 'phonenum' ], ['pbxsvc'], ['domsvc'] ], }, 'phone_device' => { diff --git a/FS/FS/part_export/netsapiens.pm b/FS/FS/part_export/netsapiens.pm index b8068940b..83f0f0184 100644 --- a/FS/FS/part_export/netsapiens.pm +++ b/FS/FS/part_export/netsapiens.pm @@ -72,10 +72,15 @@ sub _ns_command { $ns; } +sub ns_domain { + my($self, $svc_phone) = (shift, shift); + $svc_phone->domain || $self->option('domain'); +} + sub ns_subscriber { my($self, $svc_phone) = (shift, shift); - my $domain = $self->option('domain'); + my $domain = $self->ns_domain($svc_phone); my $phonenum = $svc_phone->phonenum; "/domains_config/$domain/subscriber_config/$phonenum"; @@ -91,7 +96,7 @@ sub ns_registrar { sub ns_devicename { my( $self, $svc_phone ) = (shift, shift); - my $domain = $self->option('domain'); + my $domain = $self->ns_domain($svc_phone); #my $countrycode = $svc_phone->countrycode; my $phonenum = $svc_phone->phonenum; @@ -121,7 +126,7 @@ sub ns_device { sub ns_create_or_update { my($self, $svc_phone, $dial_policy) = (shift, shift, shift); - my $domain = $self->option('domain'); + my $domain = $self->ns_domain($svc_phone); #my $countrycode = $svc_phone->countrycode; my $phonenum = $svc_phone->phonenum; @@ -238,7 +243,7 @@ sub _export_unsuspend { sub export_device_insert { my( $self, $svc_phone, $phone_device ) = (shift, shift, shift); - #my $domain = $self->option('domain'); + my $domain = $self->ns_domain($svc_phone); my $countrycode = $svc_phone->countrycode; my $phonenum = $svc_phone->phonenum; @@ -256,7 +261,7 @@ sub export_device_insert { #'notes' => 'server' => 'SiPbx', - 'domain' => $self->option('domain'), + 'domain' => $domain, 'brand' => $phone_device->part_device->devicename, diff --git a/FS/FS/svc_Domain_Mixin.pm b/FS/FS/svc_Domain_Mixin.pm new file mode 100644 index 000000000..202899cab --- /dev/null +++ b/FS/FS/svc_Domain_Mixin.pm @@ -0,0 +1,134 @@ +package FS::svc_Domain_Mixin; + +use strict; +use FS::Conf; +use FS::Record qw(qsearch qsearchs); +use FS::part_svc; +use FS::cust_pkg; +use FS::cust_svc; +use FS::svc_domain; + +=head1 NAME + +FS::svc_Domain_Mixin - Mixin class for svc_classes with a domsvc field + +=head1 SYNOPSIS + +package FS::svc_table; +use base qw( FS::svc_Domain_Mixin FS::svc_Common ); + +=head1 DESCRIPTION + +This is a mixin class for svc_ classes that contain a domsvc field linking to +a domain (see L). + +=head1 METHODS + +=over 4 + +=item domain [ END_TIMESTAMP [ START_TIMESTAMP ] ] + +Returns the domain associated with this account. + +END_TIMESTAMP and START_TIMESTAMP can optionally be passed when dealing with +history records. + +=cut + +sub domain { + my $self = shift; + #die "svc_acct.domsvc is null for svcnum ". $self->svcnum unless $self->domsvc; + return '' unless $self->domsvc; + my $svc_domain = $self->svc_domain(@_) + or die "no svc_domain.svcnum for domsvc ". $self->domsvc; + $svc_domain->domain; +} + +=item svc_domain + +Returns the FS::svc_domain record for this account's domain (see +L). + +=cut + +# FS::h_svc_acct has a history-aware svc_domain override + +sub svc_domain { + my $self = shift; + $self->{'_domsvc'} + ? $self->{'_domsvc'} + : qsearchs( 'svc_domain', { 'svcnum' => $self->domsvc } ); +} + +=item domain_select_hash %OPTIONS + +Object or class method. + +Returns a hash SVCNUM => DOMAIN ... representing the domains this customer +may at present purchase. + +Currently available options are: I and I. + +=cut + +sub domain_select_hash { + my ($self, %options) = @_; + my %domains = (); + + my $conf = new FS::Conf; + + my $part_svc; + my $cust_pkg; + + if (ref($self)) { + $part_svc = $self->part_svc; + $cust_pkg = $self->cust_svc->cust_pkg + if $self->cust_svc; + } + + $part_svc = qsearchs('part_svc', { 'svcpart' => $options{svcpart} }) + if $options{'svcpart'}; + + $cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => $options{pkgnum} }) + if $options{'pkgnum'}; + + if ($part_svc && ( $part_svc->part_svc_column('domsvc')->columnflag eq 'S' + || $part_svc->part_svc_column('domsvc')->columnflag eq 'F')) { + %domains = map { $_->svcnum => $_->domain } + map { qsearchs('svc_domain', { 'svcnum' => $_ }) } + split(',', $part_svc->part_svc_column('domsvc')->columnvalue); + }elsif ($cust_pkg && !$conf->exists('svc_acct-alldomains') ) { + %domains = map { $_->svcnum => $_->domain } + map { qsearchs('svc_domain', { 'svcnum' => $_->svcnum }) } + map { qsearch('cust_svc', { 'pkgnum' => $_->pkgnum } ) } + qsearch('cust_pkg', { 'custnum' => $cust_pkg->custnum }); + }else{ + %domains = map { $_->svcnum => $_->domain } qsearch('svc_domain', {} ); + } + + if ($part_svc && $part_svc->part_svc_column('domsvc')->columnflag eq 'D') { + my $svc_domain = qsearchs('svc_domain', + { 'svcnum' => $part_svc->part_svc_column('domsvc')->columnvalue } ); + if ( $svc_domain ) { + $domains{$svc_domain->svcnum} = $svc_domain->domain; + }else{ + warn "unknown svc_domain.svcnum for part_svc_column domsvc: ". + $part_svc->part_svc_column('domsvc')->columnvalue; + + } + } + + (%domains); +} + +=back + +=head1 BUGS + +=head1 SEE ALSO + +L, L + +=cut + +1; diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm index 7d3c9c5fd..fbf47072d 100644 --- a/FS/FS/svc_acct.pm +++ b/FS/FS/svc_acct.pm @@ -1,7 +1,8 @@ package FS::svc_acct; use strict; -use vars qw( @ISA $DEBUG $me $conf $skip_fuzzyfiles +use base qw( FS::svc_Domain_Mixin FS::svc_Common ); +use vars qw( $DEBUG $me $conf $skip_fuzzyfiles $dir_prefix @shells $usernamemin $usernamemax $passwordmin $passwordmax $username_ampersand $username_letter $username_letterfirst @@ -32,8 +33,6 @@ use FS::Msgcat qw(gettext); use FS::UI::bytecount; use FS::UI::Web; use FS::part_pkg; -use FS::svc_Common; -use FS::cust_svc; use FS::part_svc; use FS::svc_acct_pop; use FS::cust_main_invoice; @@ -48,8 +47,6 @@ use FS::svc_forward; use FS::svc_www; use FS::cdr; -@ISA = qw( FS::svc_Common ); - $DEBUG = 0; $me = '[FS::svc_acct]'; @@ -356,16 +353,6 @@ sub table_info { select_key => 'svcnum', select_label => 'domain', disable_inventory => 1, - - }, - 'domsvc' => { - label => 'Domain', - type => 'select', - select_table => 'svc_domain', - select_key => 'svcnum', - select_label => 'domain', - disable_inventory => 1, - }, 'pbxsvc' => { label => 'PBX', type => 'select-svc_pbx.html', @@ -1810,22 +1797,6 @@ sub domain { $svc_domain->domain; } -=item svc_domain - -Returns the FS::svc_domain record for this account's domain (see -L). - -=cut - -# FS::h_svc_acct has a history-aware svc_domain override - -sub svc_domain { - my $self = shift; - $self->{'_domsvc'} - ? $self->{'_domsvc'} - : qsearchs( 'svc_domain', { 'svcnum' => $self->domsvc } ); -} - =item cust_svc Returns the FS::cust_svc record for this account (see L). @@ -3147,61 +3118,4 @@ schema.html from the base documentation. =cut -=item domain_select_hash %OPTIONS - -Returns a hash SVCNUM => DOMAIN ... representing the domains this customer -may at present purchase. - -Currently available options are: I I - -=cut - -sub domain_select_hash { - my ($self, %options) = @_; - my %domains = (); - my $part_svc; - my $cust_pkg; - - if (ref($self)) { - $part_svc = $self->part_svc; - $cust_pkg = $self->cust_svc->cust_pkg - if $self->cust_svc; - } - - $part_svc = qsearchs('part_svc', { 'svcpart' => $options{svcpart} }) - if $options{'svcpart'}; - - $cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => $options{pkgnum} }) - if $options{'pkgnum'}; - - if ($part_svc && ( $part_svc->part_svc_column('domsvc')->columnflag eq 'S' - || $part_svc->part_svc_column('domsvc')->columnflag eq 'F')) { - %domains = map { $_->svcnum => $_->domain } - map { qsearchs('svc_domain', { 'svcnum' => $_ }) } - split(',', $part_svc->part_svc_column('domsvc')->columnvalue); - }elsif ($cust_pkg && !$conf->exists('svc_acct-alldomains') ) { - %domains = map { $_->svcnum => $_->domain } - map { qsearchs('svc_domain', { 'svcnum' => $_->svcnum }) } - map { qsearch('cust_svc', { 'pkgnum' => $_->pkgnum } ) } - qsearch('cust_pkg', { 'custnum' => $cust_pkg->custnum }); - }else{ - %domains = map { $_->svcnum => $_->domain } qsearch('svc_domain', {} ); - } - - if ($part_svc && $part_svc->part_svc_column('domsvc')->columnflag eq 'D') { - my $svc_domain = qsearchs('svc_domain', - { 'svcnum' => $part_svc->part_svc_column('domsvc')->columnvalue } ); - if ( $svc_domain ) { - $domains{$svc_domain->svcnum} = $svc_domain->domain; - }else{ - warn "unknown svc_domain.svcnum for part_svc_column domsvc: ". - $part_svc->part_svc_column('domsvc')->columnvalue; - - } - } - - (%domains); -} - 1; - diff --git a/FS/FS/svc_phone.pm b/FS/FS/svc_phone.pm index 071b8073c..0ed01ad36 100644 --- a/FS/FS/svc_phone.pm +++ b/FS/FS/svc_phone.pm @@ -1,16 +1,15 @@ package FS::svc_phone; use strict; -use vars qw( @ISA @pw_set $conf ); +use base qw( FS::svc_Domain_Mixin FS::svc_Common ); +use vars qw( @pw_set $conf ); use FS::Conf; use FS::Record qw( qsearch qsearchs dbh ); use FS::Msgcat qw(gettext); -use FS::svc_Common; use FS::part_svc; use FS::phone_device; use FS::svc_pbx; - -@ISA = qw( FS::svc_Common ); +use FS::svc_domain; #avoid l 1 and o O 0 @pw_set = ( 'a'..'k', 'm','n', 'p-z', 'A'..'N', 'P'..'Z' , '2'..'9' ); @@ -114,6 +113,14 @@ sub table_info { disable_inventory => 1, disable_select => 1, #UI wonky, pry works otherwise }, + 'domsvc' => { + label => 'Domain', + type => 'select', + select_table => 'svc_domain', + select_key => 'svcnum', + select_label => 'domain', + disable_inventory => 1, + }, }, }; } @@ -159,6 +166,7 @@ sub label { my $self = shift; my $phonenum = $self->phonenum; #XXX format it better my $label = $phonenum; + $label .= '@'.$self->domain if $self->domsvc; $label .= ' ('.$self->phone_name.')' if $self->phone_name; $label; } @@ -268,7 +276,8 @@ sub check { || $self->ut_anything('sip_password') || $self->ut_numbern('pin') || $self->ut_textn('phone_name') - || $self->ut_foreign_keyn('pbxsvc', 'svc_pbx', 'svcnum' ) + || $self->ut_foreign_keyn('pbxsvc', 'svc_pbx', 'svcnum' ) + || $self->ut_foreign_keyn('domsvc', 'svc_domain', 'svcnum' ) ; return $error if $error; diff --git a/FS/MANIFEST b/FS/MANIFEST index bcf4cd3fa..0df1ddeaa 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -366,6 +366,8 @@ FS/cust_credit_bill_pkg.pm t/cust_credit_bill_pkg.t FS/registrar.pm t/registrar.t +FS/svc_Domain_Mixin.pm +t/svc_Domain_Mixin.t FS/svc_External_Common.pm t/svc_External_Common.t FS/svc_Parent_Mixin.pm diff --git a/FS/t/svc_Domain_Mixin.t b/FS/t/svc_Domain_Mixin.t new file mode 100644 index 000000000..261af7537 --- /dev/null +++ b/FS/t/svc_Domain_Mixin.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::svc_Domain_Mixin; +$loaded=1; +print "ok 1\n"; diff --git a/httemplate/edit/elements/svc_Common.html b/httemplate/edit/elements/svc_Common.html index 453d07f88..2e98a1b25 100644 --- a/httemplate/edit/elements/svc_Common.html +++ b/httemplate/edit/elements/svc_Common.html @@ -81,7 +81,10 @@ $f->{'disable_empty'} = $object->svcnum ? 1 : 0, } - if ( $f->{'type'} eq 'select-svc_pbx' ) { + if ( $f->{'type'} eq 'select-svc_pbx' + || $f->{'type'} eq 'select-svc-domain' + ) + { $f->{'include_opt_callback'} = sub { ( 'pkgnum' => $pkgnum, 'svcpart' => $svcpart, diff --git a/httemplate/edit/svc_phone.cgi b/httemplate/edit/svc_phone.cgi index 55ee890f4..3c7b75249 100644 --- a/httemplate/edit/svc_phone.cgi +++ b/httemplate/edit/svc_phone.cgi @@ -1,22 +1,11 @@ <% include( 'elements/svc_Common.html', 'name' => 'Phone number', 'table' => 'svc_phone', - 'fields' => [ 'countrycode', - { field => 'phonenum', - type => 'select-did', - label => 'Phone number', - }, - { field => 'pbxsvc', - type => 'select-svc_pbx', - label => 'PBX', - }, - 'sip_password', - 'pin', - 'phone_name', - ], + 'fields' => \@fields, 'labels' => { 'countrycode' => 'Country code', 'phonenum' => 'Phone number', + 'domsvc' => 'Domain', 'sip_password' => 'SIP password', 'pin' => 'Voicemail PIN', 'phone_name' => 'Name', @@ -29,4 +18,28 @@ die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('Provision customer service'); #something else more specific? +my $conf = new FS::Conf; + +my @fields = ( 'countrycode', + { field => 'phonenum', + type => 'select-did', + label => 'Phone number', + }, + ); + +push @fields, { field => 'domsvc', + type => 'select-svc-domain', + label => 'Domain', + } + if $conf->exists('svc_phone-domain'); + +push @fields, { field => 'pbxsvc', + type => 'select-svc_pbx', + label => 'PBX', + }, + 'sip_password', + 'pin', + 'phone_name', +; + diff --git a/httemplate/elements/select-svc-domain.html b/httemplate/elements/select-svc-domain.html new file mode 100644 index 000000000..4c04466db --- /dev/null +++ b/httemplate/elements/select-svc-domain.html @@ -0,0 +1,50 @@ + +<%init> + +my %opt = @_; + +my %svc_domain = (); +my $domsvc; + +my $domsvc = $opt{'curr_value'}; +my $part_svc = $opt{'part_svc'} + || qsearchs('part_svc', { 'svcpart' => $opt{'svcpart'} }); + +#optional +my $cust_pkg = $opt{'cust_pkg'}; +$cust_pkg ||= qsearchs('cust_pkg', { 'pkgnum' => $opt{'pkgnum'} }) + if $opt{'pkgnum'}; + +my $pkgnum = $cust_pkg ? $cust_pkg->pkgnum : ''; + +my %svc_domain = (); + +if ( $domsvc ) { + my $svc_domain = qsearchs('svc_domain', { 'svcnum' => $domsvc } ); + if ( $svc_domain ) { + $svc_domain{$svc_domain->svcnum} = $svc_domain; + } else { + warn "unknown svc_domain.svcnum for svc_acct.domsvc: $domsvc"; + } +} + +%svc_domain = ( + %svc_domain, + FS::svc_Domain_Mixin->domain_select_hash( 'svcpart' => $part_svc->svcpart, + 'pkgnum' => $pkgnum, + ) +); + + diff --git a/httemplate/elements/tr-select-svc-domain.html b/httemplate/elements/tr-select-svc-domain.html new file mode 100644 index 000000000..437bc5896 --- /dev/null +++ b/httemplate/elements/tr-select-svc-domain.html @@ -0,0 +1,34 @@ +%if ( $columnflag eq 'F' ) { + +% } else { + + + <% $opt{'label'} || 'Domain' %> + + <% include('/elements/select-svc-domain.html', + 'curr_value' => $domsvc, + 'part_svc' => $part_svc, + 'cust_pkg' => $cust_pkg, + ) + %> + + +% } +<%init> + +my %opt = @_; + +my $domsvc = $opt{'curr_value'}; + +#required +my $part_svc = $opt{'part_svc'} + || qsearchs('part_svc', { 'svcpart' => $opt{'svcpart'} }); + +my $columnflag = $part_svc->part_svc_column('domsvc')->columnflag; + +#optional +my $cust_pkg = $opt{'cust_pkg'}; +$cust_pkg ||= qsearchs('cust_pkg', { 'pkgnum' => $opt{'pkgnum'} }) + if $opt{'pkgnum'}; + + diff --git a/httemplate/view/svc_phone.cgi b/httemplate/view/svc_phone.cgi index 2733e258e..76ee7397d 100644 --- a/httemplate/view/svc_phone.cgi +++ b/httemplate/view/svc_phone.cgi @@ -1,16 +1,10 @@ <% include('elements/svc_Common.html', 'table' => 'svc_phone', - 'fields' => [qw( - countrycode - phonenum - pbx_title - sip_password - pin - phone_name - )], + 'fields' => \@fields, 'labels' => { 'countrycode' => 'Country code', 'phonenum' => 'Phone number', + 'domain' => 'Domain', 'pbx_title' => 'PBX', 'sip_password' => 'SIP password', 'pin' => 'PIN', @@ -21,6 +15,12 @@ %> <%init> +my $conf = new FS::Conf; + +my @fields = qw( countrycode phonenum ); +push @fields, 'domain' if $conf->exists('svc_phone-domain'); +push @fields, qw( pbx_title sip_password pin phone_name ); + my $html_foot = sub { my $svc_phone = shift; -- 2.11.0