get DIDs from globalpops
authorivan <ivan>
Sat, 28 Jun 2008 23:03:10 +0000 (23:03 +0000)
committerivan <ivan>
Sat, 28 Jun 2008 23:03:10 +0000 (23:03 +0000)
18 files changed:
FS/FS/Record.pm
FS/FS/part_export/globalpops_voip.pm
FS/FS/part_svc.pm
httemplate/edit/cust_main/select-state.html
httemplate/edit/elements/svc_Common.html
httemplate/edit/svc_phone.cgi
httemplate/elements/input-text.html [new file with mode: 0644]
httemplate/elements/select-areacode.html [new file with mode: 0644]
httemplate/elements/select-did.html [new file with mode: 0644]
httemplate/elements/select-exchange.html [new file with mode: 0644]
httemplate/elements/select-phonenum.html [new file with mode: 0644]
httemplate/elements/select-state.html [new file with mode: 0644]
httemplate/elements/tr-input-text.html
httemplate/elements/tr-select-did.html [new file with mode: 0644]
httemplate/images/wait-orange.gif [new file with mode: 0644]
httemplate/misc/areacodes.cgi [new file with mode: 0644]
httemplate/misc/exchanges.cgi [new file with mode: 0644]
httemplate/misc/phonenums.cgi [new file with mode: 0644]

index cc485a8..cd54b84 100644 (file)
@@ -6,6 +6,7 @@ use vars qw( $AUTOLOAD @ISA @EXPORT_OK $DEBUG
              %virtual_fields_cache $nowarn_identical $no_update_diff );
 use Exporter;
 use Carp qw(carp cluck croak confess);
+use Scalar::Util qw( blessed );
 use File::CounterFile;
 use Locale::Country;
 use DBI qw(:sql_types);
@@ -665,11 +666,11 @@ sub AUTOLOAD {
   $field =~ s/.*://;
   if ( defined($value) ) {
     confess "errant AUTOLOAD $field for $self (arg $value)"
-      unless ref($self) && $self->can('setfield');
+      unless blessed($self) && $self->can('setfield');
     $self->setfield($field,$value);
   } else {
     confess "errant AUTOLOAD $field for $self (no args)"
-      unless ref($self) && $self->can('getfield');
+      unless blessed($self) && $self->can('getfield');
     $self->getfield($field);
   }    
 }
index c641e04..13c263b 100644 (file)
@@ -24,6 +24,181 @@ END
 
 sub rebless { shift; }
 
+sub get_dids {
+  my $self = shift;
+  my %opt = ref($_[0]) ? %{$_[0]} : @_;
+
+  my %search = ();
+  #  'orderby' => 'npa', #but it doesn't seem to work :/
+
+  if ( $opt{'areacode'} && $opt{'exchange'} ) { #return numbers
+    %getdids = ( 'npa'   => $opt{'areacode'},
+                 'nxx'   => $opt{'exchange'},
+               );
+  } elsif ( $opt{'areacode'} ) { #return city (npa-nxx-XXXX)
+    %getdids = ( 'npa'   => $opt{'areacode'} );
+  } elsif ( $opt{'state'} ) {
+    %getdids = ( 'state' => $opt{'state'} );
+  }
+
+  my $dids = $self->gp_command('getDIDs', %getdids);
+
+  #use Data::Dumper;
+  #warn Dumper($dids);
+
+  my $search = $dids->{'search'};
+
+  #warn Dumper($search);
+
+  if ( $search->{'statuscode'} == 302200 ) {
+    return [];
+  } elsif ( $search->{'statuscode'} != 100 ) {
+    die "Error running globalpop getDIDs: ".
+        $search->{'statuscode'}. ': '. $search->{'status'}; #die??
+  }
+
+  my @return = ();
+
+  #my $latas = $search->{state}{lata};
+
+  my %latas;
+  if ( grep $search->{state}{lata}{$_}, qw(name rate_center) ) {
+    %latas = map $search->{state}{lata}{$_},
+                 qw(name rate_center);
+  } else {
+    %latas = %{ $search->{state}{lata} };
+  } 
+
+  foreach my $lata ( keys %latas ) {
+
+    #warn "LATA $lata";
+    
+    #my $l = $latas{$lata};
+    #$l = $l->{rate_center} if exists $l->{rate_center};
+    
+    my $lata_dids = $self->gp_command('getDIDs', %getdids, 'lata'=>$lata);
+    my $lata_search = $lata_dids->{'search'};
+    unless ( $lata_search->{'statuscode'} == 100 ) {
+      die "Error running globalpop getDIDs: ". $lata_search->{'status'}; #die??
+    }
+   
+    my $l = $lata_search->{state}{lata}{'rate_center'};
+
+    #use Data::Dumper;
+    #warn Dumper($l);
+
+    my %rate_center;
+    if ( grep $l->{$_}, qw(name friendlyname) ) {
+      %rate_center = map $l->{$_},
+                         qw(name friendlyname);
+    } else {
+      %rate_center = %$l;
+    } 
+
+    foreach my $rate_center ( keys %rate_center ) {
+      
+      #warn "rate center $rate_center";
+
+      my $rc = $rate_center{$rate_center}; 
+      $rc = $rc->{friendlyname} if exists $rc->{friendlyname};
+
+      my @r = ();
+      if ( exists($rc->{npa}) ) {
+        @r = ($rc);
+      } else {
+        @r = map { { 'name'=>$_, %{ $rc->{$_} } }; } keys %$rc
+      }
+
+      foreach my $r (@r) {
+
+        my @npa = ();
+        if ( exists($r->{npa}{name}) ) {
+          @npa = ($r->{npa})
+        } else {
+          @npa = map { { 'name'=>$_, %{ $r->{npa}{$_} } } } keys %{ $r->{npa} };
+        }
+
+        foreach my $npa (@npa) {
+
+          if ( $opt{'areacode'} && $opt{'exchange'} ) { #return numbers
+
+            #warn Dumper($npa);
+
+            my $tn = $npa->{nxx}{tn} || $npa->{nxx}{$opt{'exchange'}}{tn};
+
+            my @tn = ref($tn) ? @$tn : ($tn);
+            #push @return, @tn;
+            push @return, map {
+                                if ( /^\s*(\d{3})(\d{3})(\d{4})\s*$/ ) {
+                                  "$1-$2-$3";
+                                } else {
+                                  $_;
+                                }
+                              }
+                              @tn;
+
+          } elsif ( $opt{'areacode'} ) { #return city (npa-nxx-XXXX)
+
+            if ( $npa->{nxx}{name} ) {
+              @nxx = ( $npa->{nxx}{name} );
+            } else {
+              @nxx = keys %{ $npa->{nxx} };
+            }
+
+            push @return, map { $r->{name}. ' ('. $npa->{name}. "-$_-XXXX)"; }
+                              @nxx;
+
+          } elsif ( $opt{'state'} ) { #and not other things, then return areacode
+            #my $ac = $npa->{name};
+            #use Data::Dumper;
+            #warn Dumper($r) unless length($ac) == 3;
+
+            push @return, $npa->{name}
+              unless grep { $_ eq $npa->{name} } @return;
+
+          } else {
+            warn "WARNING: returning nothing for get_dids without known options"; #?
+          }
+
+        } #foreach my $npa
+
+      } #foreach my $r
+
+    } #foreach my $rate_center
+
+  } #foreach my $lata
+
+  if ( $opt{'areacode'} && $opt{'exchange'} ) { #return numbers
+    @return = sort { $a cmp $b } @return; #string comparison actually dwiw
+  } elsif ( $opt{'areacode'} ) { #return city (npa-nxx-XXXX)
+    @return = sort { lc($a) cmp lc($b) } @return;
+  } elsif ( $opt{'state'} ) { #and not other things, then return areacode
+    #@return = sort { (split(' ', $a))[0] <=> (split(' ', $b))[0] } @return;
+    @return = sort { $a <=> $b } @return;
+  } else {
+    warn "WARNING: returning nothing for get_dids without known options"; #?
+  }
+
+  \@return;
+
+}
+
+sub gp_command {
+  my( $self, $command, @args ) = @_;
+
+  eval "use Net::GlobalPOPs::MediaServicesAPI;";
+  die $@ if $@;
+
+  my $gp = Net::GlobalPOPs::MediaServicesAPI->new(
+    'login'    => $self->option('login'),
+    'password' => $self->option('password'),
+    #'debug'    => $debug,
+  );
+
+  $gp->$command(@args);
+}
+
+
 sub _export_insert {
   my( $self, $svc_phone ) = (shift, shift);
   #we want to provision and catch errors now, not queue
index 4fae457..580038b 100644 (file)
@@ -425,6 +425,19 @@ sub part_export_usage {
   grep $_->can('usage_sessions'), $self->part_export;
 }
 
+=item part_export_did
+
+Returns a list of any exports (see L<FS::part_export>) for this service that
+are capable of returing available DID (phone number) information.
+
+=cut
+
+sub part_export_did {
+  my $self = shift;
+  grep $_->can('get_dids'), $self->part_export;
+}
+
+
 =item cust_svc [ PKGPART ] 
 
 Returns a list of associated customer services (FS::cust_svc records).
index 4f1c056..ce08443 100644 (file)
@@ -1,24 +1,4 @@
-<SELECT NAME="<% $opt{'prefix'} %>state" onChange="<% $opt{'prefix'} %>state_changed(this); <% $opt{'onchange'} %>" <% $opt{'disabled'} %>>
-
-% if ($opt{empty}) {
-  <OPTION VALUE=""<% $opt{state} eq '' ? ' SELECTED' : '' %>><% $opt{empty} %>
-% }
-
-% foreach my $state ( keys %states ) { 
-
-  <OPTION VALUE="<% $state %>"<% $state eq $opt{'state'} ? ' SELECTED' : '' %>><% $states{$state} || '(n/a)' %>
-
-% } 
-
-
-</SELECT>
-
+<% include('/elements/select-state.html', @_) %>
 <%init>
-my %opt = @_;
-foreach my $opt (qw( county state country prefix onchange disabled empty )) {
-  $opt{$_} = '' unless exists($opt{$_}) && defined($opt{$_});
-}
-
-tie my %states, 'Tie::IxHash', states_hash( $opt{'country'} ); 
+warn "cust_main/select-state.html depreated; use /elements/select-state.html instead";
 </%init>
-
index b6737c1..4355cb4 100644 (file)
@@ -28,6 +28,8 @@
 
                    $part_svc = qsearchs( 'part_svc', { svcpart=>$svcpart });
                    die "No part_svc entry!" unless $part_svc;
+
+                   $svc_x->setfield('svcpart', $svcpart);
                  },
 
                  'edit_callback' => sub {
@@ -43,7 +45,7 @@
                    die "No part_svc entry!" unless $part_svc;
                  },
 
-                 'new_hash_callback' => sub {
+                 'new_hashref_callback' => sub {
                    #my( $cgi, $svc_x ) = @_;
 
                    { svcpart => $svcpart };
index 958558b..109fba2 100644 (file)
@@ -1,7 +1,13 @@
 <% include( 'elements/svc_Common.html',
                'name'     => 'Phone number',
                'table'    => 'svc_phone',
-               'fields'   => [qw( countrycode phonenum pin )],
+               'fields'   => [ 'countrycode',
+                               { field => 'phonenum',
+                                 type  => 'select-did',
+                                 label => 'Phone number',
+                               },
+                               'pin',
+                             ],
                'labels'   => {
                                'countrycode' => 'Country code',
                                'phonenum'    => 'Phone number',
diff --git a/httemplate/elements/input-text.html b/httemplate/elements/input-text.html
new file mode 100644 (file)
index 0000000..9db0643
--- /dev/null
@@ -0,0 +1,44 @@
+<% $opt{'prefix'} %><INPUT TYPE  = "<% $opt{type} || 'text' %>"
+                           NAME  = "<% $opt{field} %>"
+                           ID    = "<% $opt{id} %>"
+                           VALUE = "<% $value |h %>"
+                           <% $size %>
+                           <% $maxlength %>
+                           <% $style %>
+                           <% $opt{disabled} %>
+                           <% $onchange %>
+                    ><% $opt{'postfix'} %>
+<%init>
+
+my %opt = @_;
+
+my $value = length($opt{curr_value}) ? $opt{curr_value} : $opt{value};
+
+my $onchange = $opt{'onchange'}
+                 ? 'onChange="'. $opt{'onchange'}. '(this)"'
+                 : '';
+
+my $size = $opt{'size'}
+             ? 'SIZE="'. $opt{'size'}. '"'
+             : '';
+
+my $maxlength = $opt{'maxlength'}
+                ? 'MAXLENGTH="'. $opt{'maxlength'}. '"'
+                : '';
+
+$opt{'disabled'} = &{ $opt{'disabled'} }( \%opt )
+  if ref($opt{'disabled'}) eq 'CODE';
+$opt{'disabled'} = 'DISABLED'
+  if $opt{'disabled'} && $opt{'disabled'} !~ /disabled/i; # uuh... yeah?
+
+my @style = ();
+
+push @style, 'text-align: '. $opt{'text-align'}
+  if $opt{'text-align'};
+
+push @style, 'background-color: #dddddd'
+  if $opt{'disabled'};
+
+my $style = scalar(@style) ? 'STYLE="'. join(';', @style). '"' : '';
+
+</%init>
diff --git a/httemplate/elements/select-areacode.html b/httemplate/elements/select-areacode.html
new file mode 100644 (file)
index 0000000..aa2d73b
--- /dev/null
@@ -0,0 +1,91 @@
+<% include('/elements/xmlhttp.html',
+              'url'  => $p.'misc/areacodes.cgi',
+              'subs' => [ $opt{'prefix'}. 'get_areacodes' ],
+          )
+%>
+
+<SCRIPT TYPE="text/javascript">
+
+  function opt(what,value,text) {
+    var optionName = new Option(text, value, false, false);
+    var length = what.length;
+    what.options[length] = optionName;
+  }
+
+  function <% $opt{'prefix'} %>state_changed(what, callback) {
+
+    what.form.<% $opt{'prefix'} %>areacode.disabled = 'disabled';
+    what.form.<% $opt{'prefix'} %>areacode.style.display = 'none';
+    var areacodewait = document.getElementById('<% $opt{'prefix'} %>areacodewait');
+    areacodewait.style.display = '';
+    var areacodeerror = document.getElementById('<% $opt{'prefix'} %>areacodeerror');
+    areacodeerror.style.display = 'none';
+
+    what.form.<% $opt{'prefix'} %>exchange.disabled = 'disabled';
+    what.form.<% $opt{'prefix'} %>phonenum.disabled = 'disabled';
+
+    state = what.options[what.selectedIndex].value;
+
+    function <% $opt{'prefix'} %>update_areacodes(areacodes) {
+
+      // blank the current areacode
+      for ( var i = what.form.<% $opt{'prefix'} %>areacode.length; i >= 0; i-- )
+          what.form.<% $opt{'prefix'} %>areacode.options[i] = null;
+      // blank the current exchange too
+      for ( var i = what.form.<% $opt{'prefix'} %>exchange.length; i >= 0; i-- )
+          what.form.<% $opt{'prefix'} %>exchange.options[i] = null;
+      opt(what.form.<% $opt{'prefix'} %>exchange, '', 'Select city / exchange');
+      // blank the current phonenum too
+      for ( var i = what.form.<% $opt{'prefix'} %>phonenum.length; i >= 0; i-- )
+          what.form.<% $opt{'prefix'} %>phonenum.options[i] = null;
+      opt(what.form.<% $opt{'prefix'} %>phonenum, '', 'Select phone number');
+
+%     if ($opt{empty}) {
+        opt(what.form.<% $opt{'prefix'} %>areacode, '', '<% $opt{empty} %>');
+%     }
+
+      // add the new areacodes
+      var areacodeArray = eval('(' + areacodes + ')' );
+      for ( var s = 0; s < areacodeArray.length; s++ ) {
+          var areacodeLabel = areacodeArray[s];
+          if ( areacodeLabel == "" )
+              areacodeLabel = '(n/a)';
+          opt(what.form.<% $opt{'prefix'} %>areacode, areacodeArray[s], areacodeLabel);
+      }
+
+      areacodewait.style.display = 'none';
+      if ( areacodeArray.length >= 1 ) {
+        what.form.<% $opt{'prefix'} %>areacode.disabled = '';
+        what.form.<% $opt{'prefix'} %>areacode.style.display = '';
+      } else {
+        var areacodeerror = document.getElementById('<% $opt{'prefix'} %>areacodeerror');
+        areacodeerror.style.display = '';
+      }
+
+      //run the callback
+      if ( callback != null ) 
+        callback();
+    }
+
+    // go get the new areacodes
+    <% $opt{'prefix'} %>get_areacodes( state, <% $opt{'svcpart'} %>, <% $opt{'prefix'} %>update_areacodes );
+
+  }
+
+</SCRIPT>
+
+<DIV ID="areacodewait" STYLE="display:none"><IMG SRC="<%$fsurl%>images/wait-orange.gif"> <B>Finding area codes</B></DIV>
+
+<DIV ID="areacodeerror" STYLE="display:none"><IMG SRC="<%$fsurl%>images/cross.png"> <B>Select a different state</B></DIV>
+
+<SELECT NAME="<% $opt{'prefix'} %>areacode" onChange="<% $opt{'prefix'} %>areacode_changed(this); <% $opt{'onchange'} %>" <% $opt{'disabled'} %>>
+  <OPTION VALUE="">Select area code</OPTION>
+</SELECT>
+
+<%init>
+
+my %opt = @_;
+
+$opt{disabled} = 'disabled' unless exists $opt{disabled};
+
+</%init>
diff --git a/httemplate/elements/select-did.html b/httemplate/elements/select-did.html
new file mode 100644 (file)
index 0000000..999274f
--- /dev/null
@@ -0,0 +1,80 @@
+<%doc>
+
+Example:
+
+  include('/elements/select-did.html',
+            'field'   => 'phonenum',
+            'svcpart' => 5,
+         );
+
+</%doc>
+% if ( $use_selector ) {
+
+    <TABLE>
+
+      <TR>
+        <TD>
+          <% include('/elements/select-state.html',
+                       'country' => $country,
+                       'empty'   => 'Select state',
+                    )
+          %>
+        </TD>
+        <TD>
+          <% include('/elements/select-areacode.html',
+                       'svcpart' => $svcpart,
+                       'empty'   => 'Select area code',
+                    )
+          %>
+        </TD>
+        <TD>
+          <% include('/elements/select-exchange.html',
+                       'svcpart' => $svcpart,
+                       'empty'   => 'Select exchange',
+                    )
+          %>
+        </TD>
+        <TD>
+          <% include('/elements/select-phonenum.html',
+                       'svcpart' => $svcpart,
+                       'empty'   => 'Select phone number',
+                    )
+          %>
+        </TD>
+      </TR>
+
+      <TR>
+        <TD><FONT SIZE="-1">State</FONT></TD>
+        <TD><FONT SIZE="-1">Area code</FONT></TD>
+        <TD><FONT SIZE="-1">City / Exchange</FONT></TD>
+        <TD><FONT SIZE="-1">Phone number</FONT></TD>
+      </TR>
+
+    </TABLE>
+
+% } else {
+
+    <% include( '/elements/input-text.html', %opt, 'type'=>'text' ) %>
+
+% }
+<%init>
+
+my %opt = @_;
+
+my $conf = new FS::Conf;
+my $country = $conf->config('countrydefault') || 'US';
+
+#XXX make sure this comes through on errors too
+my $svcpart = $opt{'object'}->svcpart;
+
+my $part_svc = qsearchs('part_svc', { 'svcpart'=>$svcpart } );
+die "unknown svcpart $svcpart" unless $part_svc;
+
+my @exports = $part_svc->part_export_did;
+if ( scalar(@exports) > 1 ) {
+  die "more than one DID-providing export attached to svcpart $svcpart";
+}
+
+my $use_selector = scalar(@exports) ? 1 : 0;
+
+</%init>
diff --git a/httemplate/elements/select-exchange.html b/httemplate/elements/select-exchange.html
new file mode 100644 (file)
index 0000000..012e7c6
--- /dev/null
@@ -0,0 +1,86 @@
+<% include('/elements/xmlhttp.html',
+              'url'  => $p.'misc/exchanges.cgi',
+              'subs' => [ $opt{'prefix'}. 'get_exchanges' ],
+          )
+%>
+
+<SCRIPT TYPE="text/javascript">
+
+  function opt(what,value,text) {
+    var optionName = new Option(text, value, false, false);
+    var length = what.length;
+    what.options[length] = optionName;
+  }
+
+  function <% $opt{'prefix'} %>areacode_changed(what, callback) {
+
+    what.form.<% $opt{'prefix'} %>exchange.disabled = 'disabled';
+    what.form.<% $opt{'prefix'} %>exchange.style.display = 'none';
+    var exchangewait = document.getElementById('<% $opt{'prefix'} %>exchangewait');
+    exchangewait.style.display = '';
+    var exchangeerror = document.getElementById('<% $opt{'prefix'} %>exchangeerror');
+    exchangeerror.style.display = 'none';
+
+    what.form.<% $opt{'prefix'} %>phonenum.disabled = 'disabled';
+
+    areacode = what.options[what.selectedIndex].value;
+
+    function <% $opt{'prefix'} %>update_exchanges(exchanges) {
+
+      // blank the current exchange
+      for ( var i = what.form.<% $opt{'prefix'} %>exchange.length; i >= 0; i-- )
+          what.form.<% $opt{'prefix'} %>exchange.options[i] = null;
+      // blank the current phonenum too
+      for ( var i = what.form.<% $opt{'prefix'} %>phonenum.length; i >= 0; i-- )
+          what.form.<% $opt{'prefix'} %>phonenum.options[i] = null;
+      opt(what.form.<% $opt{'prefix'} %>phonenum, '', 'Select phone number');
+
+%     if ($opt{empty}) {
+        opt(what.form.<% $opt{'prefix'} %>exchange, '', '<% $opt{empty} %>');
+%     }
+
+      // add the new exchanges
+      var exchangeArray = eval('(' + exchanges + ')' );
+      for ( var s = 0; s < exchangeArray.length; s++ ) {
+          var exchangeLabel = exchangeArray[s];
+          if ( exchangeLabel == "" )
+              exchangeLabel = '(n/a)';
+          opt(what.form.<% $opt{'prefix'} %>exchange, exchangeArray[s], exchangeLabel);
+      }
+
+      exchangewait.style.display = 'none';
+      if ( exchangeArray.length >= 1 ) {
+        what.form.<% $opt{'prefix'} %>exchange.disabled = '';
+        what.form.<% $opt{'prefix'} %>exchange.style.display = '';
+      } else {
+        var exchangeerror = document.getElementById('<% $opt{'prefix'} %>exchangeerror');
+        exchangeerror.style.display = '';
+      }
+
+      //run the callback
+      if ( callback != null ) 
+        callback();
+    }
+
+    // go get the new exchanges
+    <% $opt{'prefix'} %>get_exchanges( areacode, <% $opt{'svcpart'} %>, <% $opt{'prefix'} %>update_exchanges );
+
+  }
+
+</SCRIPT>
+
+<DIV ID="exchangewait" STYLE="display:none"><IMG SRC="<%$fsurl%>images/wait-orange.gif"> <B>Finding cities / exchanges</B></DIV>
+
+<DIV ID="exchangeerror" STYLE="display:none"><IMG SRC="<%$fsurl%>images/cross.png"> <B>Select a different area code</B></DIV>
+
+<SELECT NAME="<% $opt{'prefix'} %>exchange" onChange="<% $opt{'prefix'} %>exchange_changed(this); <% $opt{'onchange'} %>" <% $opt{'disabled'} %>>
+  <OPTION VALUE="">Select city / exchange</OPTION>
+</SELECT>
+
+<%init>
+
+my %opt = @_;
+
+$opt{disabled} = 'disabled' unless exists $opt{disabled};
+
+</%init>
diff --git a/httemplate/elements/select-phonenum.html b/httemplate/elements/select-phonenum.html
new file mode 100644 (file)
index 0000000..99ddafc
--- /dev/null
@@ -0,0 +1,84 @@
+<% include('/elements/xmlhttp.html',
+              'url'  => $p.'misc/phonenums.cgi',
+              'subs' => [ $opt{'prefix'}. 'get_phonenums' ],
+          )
+%>
+
+<SCRIPT TYPE="text/javascript">
+
+  function opt(what,value,text) {
+    var optionName = new Option(text, value, false, false);
+    var length = what.length;
+    what.options[length] = optionName;
+  }
+
+  function <% $opt{'prefix'} %>exchange_changed(what, callback) {
+
+    what.form.<% $opt{'prefix'} %>phonenum.disabled = 'disabled';
+    what.form.<% $opt{'prefix'} %>phonenum.style.display = 'none';
+    var phonenumwait = document.getElementById('<% $opt{'prefix'} %>phonenumwait');
+    phonenumwait.style.display = '';
+    var phonenumerror = document.getElementById('<% $opt{'prefix'} %>phonenumerror');
+    phonenumerror.style.display = 'none';
+
+    exchange = what.options[what.selectedIndex].value;
+
+    function <% $opt{'prefix'} %>update_phonenums(phonenums) {
+
+      // blank the current phonenum
+      for ( var i = what.form.<% $opt{'prefix'} %>phonenum.length; i >= 0; i-- )
+          what.form.<% $opt{'prefix'} %>phonenum.options[i] = null;
+
+%     if ($opt{empty}) {
+        opt(what.form.<% $opt{'prefix'} %>phonenum, '', '<% $opt{empty} %>');
+%     }
+
+      // add the new phonenums
+      var phonenumArray = eval('(' + phonenums + ')' );
+      for ( var s = 0; s < phonenumArray.length; s++ ) {
+          var phonenumLabel = phonenumArray[s];
+          if ( phonenumLabel == "" )
+              phonenumLabel = '(n/a)';
+          opt(what.form.<% $opt{'prefix'} %>phonenum, phonenumArray[s], phonenumLabel);
+      }
+
+      //var phonenumFormLabel = document.getElementById('<% $opt{'prefix'} %>phonenumlabel');
+
+      what.form.<% $opt{'prefix'} %>phonenum.disabled = '';
+
+      phonenumwait.style.display = 'none';
+      if ( phonenumArray.length >= 1 ) {
+        what.form.<% $opt{'prefix'} %>phonenum.disabled = '';
+        what.form.<% $opt{'prefix'} %>phonenum.style.display = '';
+      } else {
+        var phonenumerror = document.getElementById('<% $opt{'prefix'} %>phonenumerror');
+        phonenumerror.style.display = '';
+      }
+
+      //run the callback
+      if ( callback != null ) 
+        callback();
+    }
+
+    // go get the new phonenums
+    <% $opt{'prefix'} %>get_phonenums( exchange, <% $opt{'svcpart'} %>, <% $opt{'prefix'} %>update_phonenums );
+
+  }
+
+</SCRIPT>
+
+<DIV ID="phonenumwait" STYLE="display:none"><IMG SRC="<%$fsurl%>images/wait-orange.gif"> <B>Finding phone numbers</B></DIV>
+
+<DIV ID="phonenumerror" STYLE="display:none"><IMG SRC="<%$fsurl%>images/cross.png"> <B>Select a different city/exchange</B></DIV>
+
+<SELECT NAME="<% $opt{'prefix'} %>phonenum" onChange="<% $opt{'prefix'} %>phonenum_changed(this); <% $opt{'onchange'} %>" <% $opt{'disabled'} %>>
+  <OPTION VALUE="">Select phone number</OPTION>
+</SELECT>
+
+<%init>
+
+my %opt = @_;
+
+$opt{disabled} = 'disabled' unless exists $opt{disabled};
+
+</%init>
diff --git a/httemplate/elements/select-state.html b/httemplate/elements/select-state.html
new file mode 100644 (file)
index 0000000..4f1c056
--- /dev/null
@@ -0,0 +1,24 @@
+<SELECT NAME="<% $opt{'prefix'} %>state" onChange="<% $opt{'prefix'} %>state_changed(this); <% $opt{'onchange'} %>" <% $opt{'disabled'} %>>
+
+% if ($opt{empty}) {
+  <OPTION VALUE=""<% $opt{state} eq '' ? ' SELECTED' : '' %>><% $opt{empty} %>
+% }
+
+% foreach my $state ( keys %states ) { 
+
+  <OPTION VALUE="<% $state %>"<% $state eq $opt{'state'} ? ' SELECTED' : '' %>><% $states{$state} || '(n/a)' %>
+
+% } 
+
+
+</SELECT>
+
+<%init>
+my %opt = @_;
+foreach my $opt (qw( county state country prefix onchange disabled empty )) {
+  $opt{$_} = '' unless exists($opt{$_}) && defined($opt{$_});
+}
+
+tie my %states, 'Tie::IxHash', states_hash( $opt{'country'} ); 
+</%init>
+
index f71f2f7..14f1425 100644 (file)
@@ -1,19 +1,6 @@
 <% include('tr-td-label.html', @_ ) %>
 
-  <TD <% $cell_style %>>
-
-    <% $opt{'prefix'} %><INPUT TYPE  = "<% $opt{type} || 'text' %>"
-                               NAME  = "<% $opt{field} %>"
-                               ID    = "<% $opt{id} %>"
-                               VALUE = "<% $value |h %>"
-                               <% $size %>
-                               <% $maxlength %>
-                               <% $style %>
-                               <% $opt{disabled} %>
-                               <% $onchange %>
-                        ><% $opt{'postfix'} %>
-
-  </TD>
+  <TD <% $cell_style %>><% include('input-text.html', @_ ) %></TD>
 
 </TR>
 
@@ -21,35 +8,6 @@
 
 my %opt = @_;
 
-my $value = length($opt{curr_value}) ? $opt{curr_value} : $opt{value};
-
-my $onchange = $opt{'onchange'}
-                 ? 'onChange="'. $opt{'onchange'}. '(this)"'
-                 : '';
-
-my $size = $opt{'size'}
-             ? 'SIZE="'. $opt{'size'}. '"'
-             : '';
-
-my $maxlength = $opt{'maxlength'}
-                ? 'MAXLENGTH="'. $opt{'maxlength'}. '"'
-                : '';
-
-$opt{'disabled'} = &{ $opt{'disabled'} }( \%opt )
-  if ref($opt{'disabled'}) eq 'CODE';
-$opt{'disabled'} = 'DISABLED'
-  if $opt{'disabled'} && $opt{'disabled'} !~ /disabled/i; # uuh... yeah?
-
-my @style = ();
-
-push @style, 'text-align: '. $opt{'text-align'}
-  if $opt{'text-align'};
-
-push @style, 'background-color: #dddddd'
-  if $opt{'disabled'};
-
-my $style = scalar(@style) ? 'STYLE="'. join(';', @style). '"' : '';
-
 my $cell_style = $opt{'cell_style'} ? 'STYLE="'. $opt{'cell_style'}. '"' : '';
 
 </%init>
diff --git a/httemplate/elements/tr-select-did.html b/httemplate/elements/tr-select-did.html
new file mode 100644 (file)
index 0000000..29c5bb7
--- /dev/null
@@ -0,0 +1,23 @@
+<% include('tr-td-label.html', @_ ) %>
+
+% if ( $opt{'curr_value'} ne '' ) {
+
+    <TD BGCOLOR="#dddddd" <% $cell_style %>><% $opt{'formatted_value'} || $opt{'curr_value'} || $opt{'value'} |h %></TD>
+
+% } else {
+  
+    <TD <% $cell_style %>>
+      <% include('/elements/select-did.html', %opt ) %>
+    </TD>
+
+% }
+
+</TR>
+
+<%init>
+
+my %opt = @_;
+
+my $cell_style = $opt{'cell_style'} ? 'STYLE="'. $opt{'cell_style'}. '"' : '';
+
+</%init>
diff --git a/httemplate/images/wait-orange.gif b/httemplate/images/wait-orange.gif
new file mode 100644 (file)
index 0000000..92c7f34
Binary files /dev/null and b/httemplate/images/wait-orange.gif differ
diff --git a/httemplate/misc/areacodes.cgi b/httemplate/misc/areacodes.cgi
new file mode 100644 (file)
index 0000000..69c9573
--- /dev/null
@@ -0,0 +1,24 @@
+%# [ <% join(', ', map { qq("$_") } @areacodes) %> ]
+<% objToJson(\@areacodes) %>
+<%init>
+
+my( $state, $svcpart ) = $cgi->param('arg');
+
+my $part_svc = qsearchs('part_svc', { 'svcpart'=>$svcpart } );
+die "unknown svcpart $svcpart" unless $part_svc;
+
+my @exports = $part_svc->part_export_did;
+if ( scalar(@exports) > 1 ) {
+  die "more than one DID-providing export attached to svcpart $svcpart";
+} elsif ( ! @exports ) {
+  die "no DID providing export attached to svcpart $svcpart";
+}
+my $export = $exports[0];
+
+my $something = $export->get_dids('state'=>$state);
+
+#warn Dumper($something);
+
+my @areacodes = @{ $something };
+
+</%init>
diff --git a/httemplate/misc/exchanges.cgi b/httemplate/misc/exchanges.cgi
new file mode 100644 (file)
index 0000000..f5860cf
--- /dev/null
@@ -0,0 +1,24 @@
+%# [ <% join(', ', map { qq("$_") } @exchanges) %> ]
+<% objToJson(\@exchanges) %>
+<%init>
+
+my( $areacode, $svcpart ) = $cgi->param('arg');
+
+my $part_svc = qsearchs('part_svc', { 'svcpart'=>$svcpart } );
+die "unknown svcpart $svcpart" unless $part_svc;
+
+my @exports = $part_svc->part_export_did;
+if ( scalar(@exports) > 1 ) {
+  die "more than one DID-providing export attached to svcpart $svcpart";
+} elsif ( ! @exports ) {
+  die "no DID providing export attached to svcpart $svcpart";
+}
+my $export = $exports[0];
+
+my $something = $export->get_dids('areacode'=>$areacode);
+
+#warn Dumper($something);
+
+my @exchanges = @{ $something };
+
+</%init>
diff --git a/httemplate/misc/phonenums.cgi b/httemplate/misc/phonenums.cgi
new file mode 100644 (file)
index 0000000..2ed0f61
--- /dev/null
@@ -0,0 +1,29 @@
+%# [ <% join(', ', map { qq("$_") } @exchanges) %> ]
+<% objToJson(\@exchanges) %>
+<%init>
+
+my( $exchangestring, $svcpart ) = $cgi->param('arg');
+
+$exchangestring =~ /\((\d{3})-(\d{3})-XXXX\)\s*$/i
+  or die "unparsable exchange: $exchangestring";
+my( $areacode, $exchange ) = ( $1, $2 );
+my $part_svc = qsearchs('part_svc', { 'svcpart'=>$svcpart } );
+die "unknown svcpart $svcpart" unless $part_svc;
+
+my @exports = $part_svc->part_export_did;
+if ( scalar(@exports) > 1 ) {
+  die "more than one DID-providing export attached to svcpart $svcpart";
+} elsif ( ! @exports ) {
+  die "no DID providing export attached to svcpart $svcpart";
+}
+my $export = $exports[0];
+
+my $something = $export->get_dids('areacode'=>$areacode,
+                                  'exchange'=>$exchange,
+                                 );
+
+#warn Dumper($something);
+
+my @exchanges = @{ $something };
+
+</%init>