This commit was generated by cvs2svn to compensate for changes in r11022,
[freeside.git] / FS / FS / part_export / thirdlane.pm
1 package FS::part_export::thirdlane;
2
3 use base qw( FS::part_export );
4
5 use vars qw(%info $me);
6 use Tie::IxHash;
7 use URI::Escape;
8 use Frontier::Client;
9
10 $me = '['.__PACKAGE__.']';
11
12 tie my %options, 'Tie::IxHash',
13   #'server'           => { label => 'Thirdlane server name or IP address', },
14   'username'         => { label => 'Thirdlane username', },
15   'password'         => { label => 'Thirdlane password', },
16   'ssl'              => { label => 'Enable HTTPS (SSL) connection',
17                           type  => 'checkbox',
18                         },
19   'port'             => { label => 'Port number if not 80 or 443', },
20   'prototype_tenant' => { label => 'Prototype tenant name', },
21   'omit_countrycode' => { label => 'Omit country code', type => 'checkbox' },
22   'debug'            => { label => 'Checkbox label', type => 'checkbox' },
23 #  'select_option'   => { label   => 'Select option description',
24 #                         type    => 'select', options=>[qw(chocolate vanilla)],
25 #                         default => 'vanilla',
26 #                       },
27 #  'textarea_option' => { label   => 'Textarea option description',
28 #                         type    => 'textarea',
29 #                         default => 'Default text.',
30 #                      },
31 ;
32
33 %info = (
34   'svc'      => [qw( svc_pbx svc_phone svc_acct )],
35   'desc'     =>
36     'Export tenants, DIDs and admins to Thirdlane PBX manager',
37   'options'  => \%options,
38   'notes'    => <<'END'
39 Exports tenants, DIDs and admins to Thirdlane PBX manager using the XML-RPC API.
40 END
41 );
42
43 sub rebless { shift; }
44
45 sub _export_insert {
46   my($self, $svc_x) = (shift, shift);
47
48   if ( $svc_x->isa('FS::svc_pbx') ) {
49
50     return 'Name must be 19 characters or less (thirdlane restriction?)'
51       if length($svc_x->title) > 19;
52
53     return 'Name must consist of alphanumerics and spaces only (thirdlane restriction?)'
54       unless $svc_x->title =~ /^[\w\s]+$/;
55
56     my $tenant = {
57       'tenant'   => $svc_x->title,
58       'maxusers' => $svc_x->max_extensions,
59       #others?  will they not clone?
60     };
61
62     @what_to_clone = qw(routes schedules menus queues voiceprompts moh);
63
64     my $result = $self->_thirdlane_command( 'asterisk::rpc_tenant_create',
65                                             $tenant,
66                                             $self->option('prototype_tenant'),
67                                             \@what_to_clone,
68                                           );
69
70     #use Data::Dumper;
71     #warn Dumper(\$result);
72     $result eq '0' ? '' : 'Thirdlane API failure (rpc_tenant_create)';
73
74   } elsif ( $svc_x->isa('FS::svc_phone') ) {
75
76     my $result = $self->_thirdlane_command(
77       'asterisk::rpc_did_create',
78       $self->_thirdlane_did($svc_x)
79     );
80
81     #use Data::Dumper;
82     #warn Dumper(\$result);
83     $result eq '0' or return 'Thirdlane API failure (rpc_did_create)';
84
85     return '' unless $svc_x->pbxsvc;
86
87     $result = $self->_thirdlane_command(
88       'asterisk::rpc_did_assign',
89       $self->_thirdlane_did($svc_x),
90       $svc_x->pbx_title,
91     );
92
93     #use Data::Dumper;
94     #warn Dumper(\$result);
95     $result eq '0' ? '' : 'Thirdlane API failure (rpc_did_assign)';
96
97   } elsif ( $svc_x->isa('FS::svc_acct') ) {
98
99     return 'Must select a PBX' unless $svc_x->pbxsvc;
100
101     my $result = $self->_thirdlane_command(
102       'asterisk::rpc_admin_create',
103       $svc_x->username,
104       $svc_x->_password,
105       $svc_x->pbx_title,
106     );
107
108     #use Data::Dumper;
109     #warn Dumper(\$result);
110     $result eq '0' ? '' : 'Thirdlane API failure (rpc_admin_create)';
111
112   } else {
113     die "guru meditation #10: $svc_x is not FS::svc_pbx, FS::svc_phone or FS::svc_acct";
114   }
115
116 }
117
118 sub _export_replace {
119   my($self, $new, $old) = (shift, shift, shift);
120
121 #  #return "can't change username with thirdlane"
122 #  #  if $old->username ne $new->username;
123 #  #return '' unless $old->_password ne $new->_password;
124 #  $err_or_queue = $self->thirdlane_queue( $new->svcnum,
125 #    'replace', $new->username, $new->_password );
126 #  ref($err_or_queue) ? '' : $err_or_queue;
127
128   if ( $new->isa('FS::svc_pbx') ) {
129
130     #need more info on how the API works for changing names.. can it?
131     return "can't change PBX name with thirdlane (yet?)"
132       if $old->title ne $new->title;
133
134     my $tenant = {
135       'tenant'   => $old->title,
136       'maxusers' => $new->max_extensions,
137       #others?  will they not clone?
138     };
139
140     my $result = $self->_thirdlane_command( 'asterisk::rpc_tenant_update',
141                                             $tenant
142                                           );
143
144     #use Data::Dumper;
145     #warn Dumper(\$result);
146     $result eq '0' ? '' : 'Thirdlane API failure (rpc_tenant_update)';
147
148   } elsif ( $new->isa('FS::svc_phone') ) {
149
150     return "can't change DID countrycode with thirdlane"
151       if $old->countrycode ne $new->countrycode;
152     return "can't change DID number with thirdlane"
153       if $old->phonenum ne $new->phonenum;
154
155     if ( $old->pbxsvc != $new->pbxsvc ) {
156
157       if ( $old->pbxsvc ) {
158         my $result = $self->_thirdlane_command(
159           'asterisk::rpc_did_unassign',
160           $self->_thirdlane_did($old),
161         );
162         $result eq '0' or return 'Thirdlane API failure (rpc_did_unassign)';
163       }
164
165       if ( $new->pbxsvc ) {
166         my $result = $self->_thirdlane_command(
167           'asterisk::rpc_did_assign',
168           $self->_thirdlane_did($new),
169           $new->pbx_title,
170         );
171         $result eq '0' or return 'Thirdlane API failure (rpc_did_assign)';
172       }
173
174
175     }
176
177     '';
178
179   } elsif ( $new->isa('FS::svc_acct') ) {
180
181     return "can't change uesrname with thirdlane"
182       if $old->username ne $new->username;
183
184     return "can't change password with thirdlane"
185       if $old->_password ne $new->_password;
186
187     return "can't change PBX for user with thirdlane"
188       if $old->pbxsvc != $new->pbxsvc;
189
190     ''; #we don't care then
191
192   } else {
193     die "guru meditation #11: $new is not FS::svc_pbx, FS::svc_phone or FS::svc_acct";
194   }
195
196 }
197
198 sub _export_delete {
199   my($self, $svc_x) = (shift, shift);
200   #my( $self, $svc_something ) = (shift, shift);
201   #$err_or_queue = $self->thirdlane_queue( $svc_something->svcnum,
202   #  'delete', $svc_something->username );
203   #ref($err_or_queue) ? '' : $err_or_queue;
204
205   if ( $svc_x->isa('FS::svc_pbx') ) {
206
207     my $result = $self->_thirdlane_command( 'asterisk::rpc_tenant_delete',
208                                             $svc_x->title,
209                                           );
210
211     #use Data::Dumper;
212     #warn Dumper(\$result);
213     #$result eq '0' ? '' : 'Thirdlane API failure (rpc_tenant_delete)';
214     warn "Thirdlane API failure (rpc_tenant_delete); deleting anyway\n"
215       if $result ne '0';
216     '';
217
218   } elsif ( $svc_x->isa('FS::svc_phone') ) {
219
220     if ( $svc_x->pbxsvc ) {
221       my $result = $self->_thirdlane_command(
222         'asterisk::rpc_did_unassign',
223         $self->_thirdlane_did($svc_x),
224       );
225       $result eq '0' or return 'Thirdlane API failure (rpc_did_unassign)';
226     }
227
228     my $result = $self->_thirdlane_command(
229       'asterisk::rpc_did_delete',
230       $self->_thirdlane_did($svc_x),
231     );
232     $result eq '0' ? '' : 'Thirdlane API failure (rpc_did_delete)';
233
234   } elsif ( $svc_x->isa('FS::svc_acct') ) {
235
236     return '' unless $svc_x->pbxsvc; #error out?  nah
237
238     my $result = $self->_thirdlane_command(
239       'asterisk::rpc_admin_delete',
240       $svc_x->username,
241       $svc_x->pbx_title,
242     );
243
244     #use Data::Dumper;
245     #warn Dumper(\$result);
246     #$result eq '0' ? '' : 'Thirdlane API failure (rpc_admin_delete)';
247     warn "Thirdlane API failure (rpc_admin_delete); deleting anyway\n"
248       if $result ne '0';
249     '';
250
251   } else {
252     die "guru meditation #12: $svc_x is not FS::svc_pbx, FS::svc_phone or FS::svc_acct";
253   }
254
255 }
256
257 sub _thirdlane_command {
258   my($self, @param) = @_;
259
260   my $url = $self->option('ssl') ? 'https://' : 'http://';
261   $url .= uri_escape($self->option('username')). ':'.
262           uri_escape($self->option('password')). '@'.
263           $self->machine;
264   $url .= ':'. $self->option('port') if $self->option('port');
265   $url .= '/xmlrpc.cgi';
266
267   warn "$me connecting to $url\n"
268     if $self->option('debug');
269   my $conn = Frontier::Client->new( 'url'   => $url,
270                                     #no, spews output to browser
271                                     #'debug' => $self->option('debug'),
272                                   );
273
274   warn "$me sending command: ". join(' ', @param). "\n"
275     if $self->option('debug');
276   $conn->call(@param);
277   
278 }
279
280 sub _thirdlane_did {
281   my($self, $svc_phone) = @_;
282   if ( $self->option('omit_countrycode') ) {
283     $svc_phone->phonenum;
284   } else {
285     $svc_phone->countrycode. $svc_phone->phonenum;
286   }
287 }
288
289   #my( $self, $svc_something ) = (shift, shift);
290   #$err_or_queue = $self->thirdlane_queue( $svc_something->svcnum,
291   #  'delete', $svc_something->username );
292   #ref($err_or_queue) ? '' : $err_or_queue;
293
294 #these three are optional
295 ## fallback for svc_acct will change and restore password
296 #sub _export_suspend {
297 #  my( $self, $svc_something ) = (shift, shift);
298 #  $err_or_queue = $self->thirdlane_queue( $svc_something->svcnum,
299 #    'suspend', $svc_something->username );
300 #  ref($err_or_queue) ? '' : $err_or_queue;
301 #}
302 #
303 #sub _export_unsuspend {
304 #  my( $self, $svc_something ) = (shift, shift);
305 #  $err_or_queue = $self->thirdlane_queue( $svc_something->svcnum,
306 #    'unsuspend', $svc_something->username );
307 #  ref($err_or_queue) ? '' : $err_or_queue;
308 #}
309 #
310 #sub export_links {
311 #  my($self, $svc_something, $arrayref) = (shift, shift, shift);
312 #  #push @$arrayref, qq!<A HREF="http://example.com/~!. $svc_something->username.
313 #  #                 qq!">!. $svc_something->username. qq!</A>!;
314 #  '';
315 #}
316
317 ####
318 #
319 ##a good idea to queue anything that could fail or take any time
320 #sub thirdlane_queue {
321 #  my( $self, $svcnum, $method ) = (shift, shift, shift);
322 #  my $queue = new FS::queue {
323 #    'svcnum' => $svcnum,
324 #    'job'    => "FS::part_export::thirdlane::thirdlane_$method",
325 #  };
326 #  $queue->insert( @_ ) or $queue;
327 #}
328 #
329 #sub thirdlane_insert { #subroutine, not method
330 #  my( $username, $password ) = @_;
331 #  #do things with $username and $password
332 #}
333 #
334 #sub thirdlane_replace { #subroutine, not method
335 #}
336 #
337 #sub thirdlane_delete { #subroutine, not method
338 #  my( $username ) = @_;
339 #  #do things with $username
340 #}
341 #
342 #sub thirdlane_suspend { #subroutine, not method
343 #}
344 #
345 #sub thirdlane_unsuspend { #subroutine, not method
346 #}
347
348 1;