first pass at netsapiens integration, RT#5226
[freeside.git] / FS / FS / part_export / netsapiens.pm
1 package FS::part_export::netsapiens;
2
3 use vars qw(@ISA %info);
4 use URI;
5 use MIME::Base64;
6 use Tie::IxHash;
7 use FS::part_export;
8
9 @ISA = qw(FS::part_export);
10
11 tie my %options, 'Tie::IxHash',
12   'login'         => { label=>'NetSapiens tac2 API username' },
13   'password'      => { label=>'NetSapiens tac2 API password' },
14   'url'           => { label=>'NetSapiens tac2 URL' },
15   'domain'        => { label=>'NetSapiens Domain' },
16 ;
17
18 %info = (
19   'svc'      => 'svc_phone',
20   'desc'     => 'Provision phone numbers to NetSapiens',
21   'options'  => \%options,
22   'notes'    => <<'END'
23 Requires installation of
24 <a href="http://search.cpan.org/dist/REST-Client">REST::Client</a>
25 from CPAN.
26 END
27 );
28
29 sub rebless { shift; }
30
31 sub ns_command {
32   my( $self, $method, $command, @args ) = @_;
33
34   eval 'use REST::Client';
35   die $@ if $@;
36
37   my $ns = new REST::Client 'host'=>$self->option('url');
38
39   my $content = $method eq 'PUT' ? $ns->buildQuery( { @args } ) : '';
40   $content =~ s/^\?//;
41
42   warn $content;
43
44   my $auth =
45     encode_base64( $self->option('login'). ':'. $self->option('password') );
46
47   $ns->$method( $command, $content, { 'Authorization' => "Basic $auth" } );
48
49   $ns;
50 }
51
52 sub ns_subscriber {
53   my($self, $svc_phone) = (shift, shift);
54
55   my $domain = $self->option('domain');
56   my $phonenum = $svc_phone->phonenum;
57
58   "/domains_config/$domain/subscriber_config/$phonenum";
59 }
60
61 sub ns_create_or_update {
62   my($self, $svc_phone, $dial_policy) = (shift, shift, shift);
63
64   my $domain = $self->option('domain');
65   my $phonenum = $svc_phone->phonenum;
66
67   my( $firstname, $lastname );
68   if ( $svc_phone->phone_name =~ /^\s*(\S+)\s+(\S.*\S)\s*$/ ) {
69     $firstname = $1;
70     $lastname  = $2;
71   } else {
72     #deal w/unaudited netsapiens services?
73     my $cust_main = $svc_phone->cust_svc->cust_pkg->cust_main;
74     $firstname = $cust_main->get('first');
75     $lastname  = $cust_main->get('last');
76   }
77
78   my $ns = $self->ns_command( 'PUT', $self->ns_subscriber($svc_phone), 
79                                 'subscriber_login' => $phonenum.'@'.$domain,
80                                 'firstname'        => $firstname, #4?
81                                 'lastname'         => $lastname,  #5?
82                                 'subscriber_pin'   => $svc_phone->pin, #6?
83                                 'dial_plan'        => 'Default',    #config? #7?
84                                 'dial_policy'      => $dial_policy, #8?
85 #no_answer_timeout30   
86 #  simultaneous_ringyes   
87 #  gmt_offset-8   
88 #  aor_schemesip:   
89 #  do_not_disturbyes   
90 #  email_vmail   
91 #  data_limit0   
92 #  screen   
93 #  last_update2008-10-01 12:19:01.0   
94 #  domain_diryes   
95 #  callid_name[*]   
96 #  admin_vmailyes   
97 #  subscriber_name   
98 #  rcv_broadcast   
99 #  directory_order1   
100 #  accept   
101 #  rating_required   
102 #  date_created2008-02-22 08:38:01   
103 #  message_waiting   
104 #  rate   
105 #  directory_listingno   
106 #  time_zoneUS/Pacific   
107 #  forward_no_answeryes   
108 #  vmail_sort_lifo   
109 #  modeover-capacity   
110 #  subscriber_groupn/a   
111 #  vmail_say_time   
112 #  presenceinactive   
113 #  directory_match826   
114 #  language   
115 #  forward_busyyes   
116 #  callid_nmbr[*]   
117 #  vmail   
118 #  subscriber_login1007@vbox.netsapiens.com   
119 #  rejectyes   
120 #  forwardyes   
121 #  vmail_say_cidno   
122 #  email_address   
123 #  greeting_index
124                             );
125
126   if ( $ns->responseCode !~ /^2/ ) {
127      return $ns->responseCode. ' '.
128             join(', ', $self->ns_parse_response( $ns->responseContent ) );
129   }
130
131   '';
132 }
133
134 sub ns_delete {
135   my($self, $svc_phone) = (shift, shift);
136
137   my $ns = $self->ns_command( 'DELETE', $self->ns_subscriber($svc_phone) );
138
139   if ( $ns->responseCode !~ /^2/ ) {
140      return $ns->responseCode. ' '.
141             join(', ', $self->ns_parse_response( $ns->responseContent ) );
142   }
143
144   '';
145
146 }
147
148 sub ns_parse_response {
149   my( $self, $content ) = ( shift, shift );
150
151   tie my %hash, Tie::IxHash;
152   #while ( $content =~ s/^.*?<p>\s*<b>(.+?)<\/b>\s*<(\w+)>(.+?)<\/\2><\/p>//i ) {
153   while ( $content =~ s/^.*?<p>\s*<b>(.+?)<\/b>\s*(.+?)\s*<\/p>//is ) {
154     ( $hash{$1} = $2 ) =~ s/^\s*<(\w+)>(.+?)<\/\1>/$2/is;
155   }
156
157   #warn $content; #probably useless
158
159   %hash;
160 }
161
162 sub _export_insert {
163   my($self, $svc_phone) = (shift, shift);
164   $self->ns_create_or_update($svc_phone, 'Permit All');
165 }
166
167 sub _export_replace {
168   my( $self, $new, $old ) = (shift, shift, shift);
169   return "can't change phonenum with NetSapiens (unprovision and reprovision?)"
170     if $old->phonenum ne $new->phonenum;
171   $self->_export_insert($new);
172 }
173
174 sub _export_delete {
175   my( $self, $svc_phone ) = (shift, shift);
176
177   $self->ns_delete($svc_phone);
178 }
179
180 sub _export_suspend {
181   my( $self, $svc_phone ) = (shift, shift);
182   $self->ns_create_or_udpate($svc_phone, 'Deny');
183 }
184
185 sub _export_unsuspend {
186   my( $self, $svc_phone ) = (shift, shift);
187   #$self->ns_create_or_update($svc_phone, 'Permit All');
188   $self->_export_insert($svc_phone);
189 }
190
191 sub export_links {
192   my($self, $svc_phone, $arrayref) = (shift, shift, shift);
193   #push @$arrayref, qq!<A HREF="http://example.com/~!. $svc_phone->username.
194   #                 qq!">!. $svc_phone->username. qq!</A>!;
195   '';
196 }
197
198 1;