domain names in netsapiens export (domain name association w/svc_phone), RT#5864
authorivan <ivan>
Mon, 8 Mar 2010 07:02:58 +0000 (07:02 +0000)
committerivan <ivan>
Mon, 8 Mar 2010 07:02:58 +0000 (07:02 +0000)
13 files changed:
FS/FS/Conf.pm
FS/FS/Schema.pm
FS/FS/part_export/netsapiens.pm
FS/FS/svc_Domain_Mixin.pm [new file with mode: 0644]
FS/FS/svc_acct.pm
FS/FS/svc_phone.pm
FS/MANIFEST
FS/t/svc_Domain_Mixin.t [new file with mode: 0644]
httemplate/edit/elements/svc_Common.html
httemplate/edit/svc_phone.cgi
httemplate/elements/select-svc-domain.html [new file with mode: 0644]
httemplate/elements/tr-select-svc-domain.html [new file with mode: 0644]
httemplate/view/svc_phone.cgi

index 54b173a..909502f 100644 (file)
@@ -3297,6 +3297,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',
index ab33667..3754f22 100644 (file)
@@ -2594,10 +2594,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' => {
index b806894..83f0f01 100644 (file)
@@ -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 (file)
index 0000000..202899c
--- /dev/null
@@ -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<FS::svc_domain>).
+
+=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<FS::svc_domain>).
+
+=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<pkgnum> and I<svcpart>.
+
+=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<FS::svc_Common>, L<FS::Record>
+
+=cut
+
+1;
index 7d3c9c5..fbf4707 100644 (file)
@@ -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<FS::svc_domain>).
-
-=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<FS::cust_svc>).
@@ -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<pkgnum> I<svcpart>
-
-=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;
-
index 071b807..0ed01ad 100644 (file)
@@ -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;
 
index 567f878..e0cd972 100644 (file)
@@ -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 (file)
index 0000000..261af75
--- /dev/null
@@ -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";
index 453d07f..2e98a1b 100644 (file)
                      $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,
index 55ee890..3c7b752 100644 (file)
@@ -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',
 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',
+;
+
 </%init>
diff --git a/httemplate/elements/select-svc-domain.html b/httemplate/elements/select-svc-domain.html
new file mode 100644 (file)
index 0000000..4c04466
--- /dev/null
@@ -0,0 +1,50 @@
+<SELECT NAME="domsvc" SIZE=1>
+% foreach my $svcnum (
+%                      sort { $svc_domain{$a} cmp $svc_domain{$b} }
+%                      keys %svc_domain
+%                    ) {
+
+    <OPTION VALUE="<% $svcnum %>"
+            <% ($svcnum == $domsvc) ? ' SELECTED' : '' %>
+    ><% $svc_domain{$svcnum} %>
+
+% } 
+
+</SELECT>
+<%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,
+                                          )
+);
+
+</%init>
diff --git a/httemplate/elements/tr-select-svc-domain.html b/httemplate/elements/tr-select-svc-domain.html
new file mode 100644 (file)
index 0000000..437bc58
--- /dev/null
@@ -0,0 +1,34 @@
+%if ( $columnflag eq 'F' ) {
+  <INPUT TYPE="hidden" NAME="domsvc" VALUE="<% $domsvc %>">
+% } else { 
+
+  <TR>
+    <TD ALIGN="right"><% $opt{'label'} || 'Domain' %></TD>
+    <TD>
+      <% include('/elements/select-svc-domain.html',
+                   'curr_value' => $domsvc,
+                   'part_svc'   => $part_svc,
+                   'cust_pkg'   => $cust_pkg,
+                )
+      %>
+    </TD>
+  </TR>
+% } 
+<%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'};
+
+</%init>
index 2733e25..76ee739 100644 (file)
@@ -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',
 %>
 <%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;