BulkVS E911 provisioning, #23894
authorMark Wells <mark@freeside.biz>
Sat, 20 Jul 2013 00:25:25 +0000 (17:25 -0700)
committerMark Wells <mark@freeside.biz>
Sat, 20 Jul 2013 00:25:25 +0000 (17:25 -0700)
FS/FS/part_export/bulkvs_e911.pm [new file with mode: 0644]

diff --git a/FS/FS/part_export/bulkvs_e911.pm b/FS/FS/part_export/bulkvs_e911.pm
new file mode 100644 (file)
index 0000000..c66305b
--- /dev/null
@@ -0,0 +1,124 @@
+package FS::part_export::bulkvs_e911;
+
+use strict;
+use vars qw(%info $me $DEBUG);
+use base 'FS::part_export';
+use FS::svc_phone;
+use Tie::IxHash;
+
+use SOAP::Lite;
+use Digest::MD5 'md5_hex';
+use Data::Dumper;
+
+$DEBUG = 2;
+$me = '['.__PACKAGE__.']';
+
+tie my %options, 'Tie::IxHash', (
+  'apikey'    => { label=>'Bulkvs.com API key' },
+  'password'  => { label=>'Bulkvs.com website password' },
+);
+
+%info = (
+  'svc'     => 'svc_phone',
+  'desc'    => 'Provision e911 services via BulkVS',
+  'notes'   => <<END
+<p>Provision e911 services via BulkVS.  Currently does not support provisioning
+phone numbers, only e911 service itself.</p>
+<p><i>apikey</i> is available through the web interface (look under the E911 
+Portal submenu). <i>password</i> is your password for the website, which will
+be used to calculate your API password.</p>
+END
+  ,
+  'no_machine' => 1,
+  'options' => \%options,
+);
+
+my $client;
+
+sub client {
+  my $self = shift;
+  my $endpoint = 'https://portal.bulkvs.com/api';
+  my $wsdl = $endpoint . '?wsdl';
+  # it's expensive to create but completely stateless, so cache it freely
+  $client ||= SOAP::Lite->service( $wsdl )->proxy( $endpoint );
+}
+
+sub login {
+  my $self = shift;
+  my $apikey = $self->option('apikey')
+      or die "no Bulkvs.com API key configured";
+  my $pass = $self->option('password')
+      or die "no Bulkvs.com password configured";
+
+  ( $apikey, md5_hex($pass) );
+}
+
+sub _export_insert {
+  my ($self, $svc_phone) = @_;
+  my @login = $self->login;
+
+  my $location = $svc_phone->cust_location
+    or return 'no e911 location defined for this phone service';
+
+  warn "$me validating address for svcnum ".$svc_phone->svcnum."\n"
+    if $DEBUG;
+  my $result = $self->client->e911validateAddress( @login,
+    $location->address1,
+    $location->address2,
+    $location->city,
+    $location->state,
+    $location->zip,
+  );
+  warn Dumper $result if $DEBUG > 1;
+  if ( $result->{'faultstring'} ) {
+    return "E911 provisioning error: ".$result->{'faultstring'};
+  } elsif ( !exists($result->{entry0}->{addressid}) ) {
+    return "E911 provisioning error: server returned no address ID";
+  }
+
+  my $caller_name = $svc_phone->cust_linked ?
+                    $svc_phone->cust_main->name_short :
+                    'unknown';
+
+  warn "$me provisioning address for svcnum ".$svc_phone->svcnum."\n"
+    if $DEBUG;
+  $result = $self->client->e911provisionAddress( @login,
+    '1'.$svc_phone->phonenum,
+    $caller_name,
+    $result->{entry0}->{addressid},
+  );
+  warn Dumper $result if $DEBUG > 1;
+  if ( $result->{'faultstring'} ) {
+    return "E911 provisioning error: ".$result->{'faultstring'};
+  }
+  '';
+}
+
+sub _export_delete {
+  my ($self, $svc_phone) = @_;
+  my @login = $self->login;
+  warn "$me removing address for svcnum ".$svc_phone->svcnum."\n"
+    if $DEBUG;
+  my $result = $self->client->e911removeRecord( @login,
+    '1'.$svc_phone->phonenum
+  );
+  warn Dumper $result if $DEBUG > 1;
+  if ( $result->{'faultstring'} ) {
+    return "E911 unprovisioning error: ".$result->{'faultstring'};
+  }
+  '';
+}
+
+sub _export_replace {
+  my ($self, $new, $old) = @_;
+  # BulkVS says that to change an address for an existing number,
+  # we should reprovision it without removing the old record.
+  if ( $new->phonenum ne $old->phonenum ) {
+    my $error = $self->_export_delete($old);
+    return $error if $error;
+  }
+  $self->_export_insert($new);
+}
+
+1;
+