queue suspend, unsuspend, and delete (fixes #1657)
[freeside.git] / FS / FS / part_export / prizm.pm
1 package FS::part_export::prizm;
2
3 use vars qw(@ISA %info %options $DEBUG);
4 use Tie::IxHash;
5 use FS::Record qw(fields);
6 use FS::part_export;
7
8 @ISA = qw(FS::part_export);
9 $DEBUG = 1;
10
11 tie %options, 'Tie::IxHash',
12   'url'      => { label => 'Northbound url', default=>'https://localhost:8443/prizm/nbi' },
13   'user'     => { label => 'Northbound username', default=>'nbi' },
14   'password' => { label => 'Password', default => '' },
15 ;
16
17 %info = (
18   'svc'      => 'svc_broadband',
19   'desc'     => 'Real-time export to Northbound Interface',
20   'options'  => \%options,
21   'nodomain' => 'Y',
22   'notes'    => 'These are notes.'
23 );
24
25 sub prizm_command {
26   my ($self,$namespace,$method) = (shift,shift,shift);
27
28   eval "use Net::Prizm qw(CustomerInfo PrizmElement);";
29   die $@ if $@;
30
31   my $prizm = new Net::Prizm (
32     namespace => $namespace,
33     url => $self->option('url'),
34     user => $self->option('user'),
35     password => $self->option('password'),
36   );
37   
38   $prizm->$method(@_);
39 }
40
41 sub _export_insert {
42   my( $self, $svc ) = ( shift, shift );
43
44   my $cust_main = $svc->cust_svc->cust_pkg->cust_main;
45
46   my $err_or_som = $self->prizm_command('CustomerIfService', 'getCustomers',
47                                         ['import_id'],
48                                         [$cust_main->custnum],
49                                         ['='],
50                                        );
51   return $err_or_som
52     unless ref($err_or_som);
53
54   my $pre = '';
55   if ( defined $cust_main->dbdef_table->column('ship_last') ) {
56     $pre = $cust_main->ship_last ? 'ship_' : '';
57   }
58   my $name = $pre ? $cust_main->ship_name : $cust_main->name;
59   my $location = join(" ", map { my $method = "$pre$_"; $cust_main->$method }
60                            qw (address1 address2 city state zip)
61                      );
62   my $contact = join(" ", map { my $method = "$pre$_"; $cust_main->$method }
63                           qw (daytime night)
64                      );
65
66   my $pcustomer;
67   if ($err_or_som->result->[0]) {
68     $pcustomer = $err_or_som->result->[0]->customerId;
69   }else{
70     my $chashref = $cust_main->hashref;
71     my $customerinfo = {
72       importId         => $cust_main->custnum,
73       customerName     => $name,
74       customerType     => 'freeside',
75       address1         => $chashref->{"${pre}address1"},
76       address2         => $chashref->{"${pre}address2"},
77       city             => $chashref->{"${pre}city"},
78       state            => $chashref->{"${pre}state"},
79       zipCode          => $chashref->{"${pre}zip"},
80       workPhone        => $chashref->{"${pre}daytime"},
81       homePhone        => $chashref->{"${pre}night"},
82       email            => @{[$cust_main->invoicing_list_emailonly]}[0],
83       extraFieldNames  => [ 'country', 'freesideId',
84                           ],
85       extraFieldValues => [ $chashref->{"${pre}country"}, $cust_main->custnum,
86                           ],
87     };
88
89     $err_or_som = $self->prizm_command('CustomerIfService', 'addCustomer',
90                                        $customerinfo);
91     return $err_or_som
92       unless ref($err_or_som);
93
94     $pcustomer = $err_or_som->result;
95   }
96   warn "multiple prizm customers found for $cust_main->custnum"
97     if scalar(@$pcustomer) > 1;
98
99   #kinda big question/expensive
100   $err_or_som = $self->prizm_command('NetworkIfService', 'getPrizmElements',
101                                      ['Network Default Gateway Address'],
102                                      [$svc->addr_block->ip_gateway],
103                                      ['='],
104                    );
105   return $err_or_som
106     unless ref($err_or_som);
107
108   return "No elements in network" unless exists $err_or_som->result->[0];
109
110   my $networkid = 0;
111   for (my $i = 0; $i < $err_or_som->result->[0]->attributeNames; $i++) {
112     if ($err_or_som->result->[0]->attributeNames->[$i] eq "Network.ID"){
113       $networkid = $err_or_som->result->[0]->attributeValues->[$i];
114       last;
115     }
116   }
117
118   $err_or_som = $self->prizm_command('NetworkIfService', 'addProvisionedElement',
119                                       $networkid,
120                                       $svc->mac_addr,
121                                       $name, # we fix this below (bug in prizm?)
122                                       $location,
123                                       $contact,
124                                       sprintf("%032X", $svc->authkey),
125                                       $svc->cust_svc->cust_pkg->part_pkg->pkg,
126                                       $svc->vlan_profile,
127                                       1,
128                                      );
129   return $err_or_som
130     unless ref($err_or_som);
131
132   my (@names) = ('Management IP',
133                  'GPS Latitude',
134                  'GPS Longitude',
135                  'GPS Altitude',
136                  'Site Name',
137                  'Site Location',
138                  'Site Contact',
139                  );
140   my (@values) = ($svc->ip_addr,
141                   $svc->latitude,
142                   $svc->longitude,
143                   $svc->altitude,
144                   $name . " " . $svc->description,
145                   $location,
146                   $contact,
147                   );
148   $element = $err_or_som->result->elementId;
149   $err_or_som = $self->prizm_command('NetworkIfService', 'setElementConfig',
150                                      [ $element ],
151                                      \@names,
152                                      \@values,
153                                      0,
154                                      1,
155                                     );
156   return $err_or_som
157     unless ref($err_or_som);
158
159   $err_or_som = $self->prizm_command('NetworkIfService', 'setElementConfigSet',
160                                      [ $element ],
161                                      $svc->vlan_profile,
162                                      0,
163                                      1,
164                                     );
165   return $err_or_som
166     unless ref($err_or_som);
167
168   $err_or_som = $self->prizm_command('NetworkIfService', 'setElementConfigSet',
169                                      [ $element ],
170                                      $svc->cust_svc->cust_pkg->part_pkg->pkg,
171                                      0,
172                                      1,
173                                     );
174   return $err_or_som
175     unless ref($err_or_som);
176
177   $err_or_som = $self->prizm_command('NetworkIfService',
178                                      'activateNetworkElements',
179                                      [ $element ],
180                                      1,
181                                      1,
182                                     );
183
184   return $err_or_som
185     unless ref($err_or_som);
186
187   $err_or_som = $self->prizm_command('CustomerIfService',
188                                      'addElementToCustomer',
189                                      0,
190                                      $cust_main->custnum,
191                                      0,
192                                      $svc->mac_addr,
193                                     );
194
195   return $err_or_som
196     unless ref($err_or_som);
197
198   '';
199 }
200
201 sub _export_delete {
202   my( $self, $svc ) = ( shift, shift );
203   $self->queue_statuschange('deleteElement', $svc);
204 }
205
206 sub _export_replace {
207   my( $self, $new, $old ) = ( shift, shift, shift );
208
209   my $err_or_som = $self->prizm_command('NetworkIfService', 'getPrizmElements',
210                                         [ 'MAC Address' ],
211                                         [ $old->mac_addr ],
212                                         [ '=' ],
213                                        );
214   return $err_or_som
215     unless ref($err_or_som);
216
217   return "Can't find prizm element for " . $old->mac_addr
218     unless $err_or_som->result->[0];
219
220   my %freeside2prizm = (  mac_addr     => 'MAC Address',
221                           ip_addr      => 'Management IP',
222                           latitude     => 'GPS Latitude',
223                           longitude    => 'GPS Longitude',
224                           altitude     => 'GPS Altitude',
225                           authkey      => 'Authentication Key',
226                        );
227   
228   my (@values);
229   my (@names) = map { push @values, $new->$_; $freeside2prizm{$_} }
230     grep { $old->$_ ne $new->$_ }
231       grep { exists($freeside2prizm{$_}) }
232         fields( 'svc_broadband' );
233
234   if ($old->description ne $new->description) {
235     my $cust_main = $old->cust_svc->cust_pkg->cust_main;
236     my $name = defined($cust_main->dbdef_table->column('ship_last'))
237              ? $cust_main->ship_name
238              : $cust_main->name;
239     push @values, $name . " " . $new->description;
240     push @names, "Site Name";
241   }
242
243   my $element = $err_or_som->result->[0]->elementId;
244
245   $err_or_som = $self->prizm_command('NetworkIfService', 'setElementConfig',
246                                         [ $element ],
247                                         \@names,
248                                         \@values,
249                                         0,
250                                         1,
251                                        );
252   return $err_or_som
253     unless ref($err_or_som);
254
255   $err_or_som = $self->prizm_command('NetworkIfService', 'setElementConfigSet',
256                                      [ $element ],
257                                      $new->vlan_profile,
258                                      0,
259                                      1,
260                                     )
261     if $old->vlan_profile ne $new->vlan_profile;
262
263   return $err_or_som
264     unless ref($err_or_som);
265
266   '';
267
268 }
269
270 sub _export_suspend {
271   my( $self, $svc ) = ( shift, shift );
272   $self->queue_statuschange('suspendNetworkElements', $svc);
273 }
274
275 sub _export_unsuspend {
276   my( $self, $svc ) = ( shift, shift );
277   $self->queue_statuschange('activateNetworkElements', $svc);
278 }
279
280 sub queue_statuschange {
281   my( $self, $method, $svc ) = @_;
282
283   my $queue = new FS::queue {
284     'svcnum' => $svc->svcnum,
285     'job'    => 'FS::part_export::prizm::statuschange',
286   };
287   $queue->insert(
288     ( map { $self->option($_) }
289           qw( url user password ) ),
290     $method,
291     $svc->mac_addr,
292   );
293 }
294
295 sub statuschange {  # subroutine
296   my( $url, $user, $password, $method, $mac_addr ) = @_;
297
298   eval "use Net::Prizm qw(CustomerInfo PrizmElement);";
299   die $@ if $@;
300
301   my $prizm = new Net::Prizm (
302     namespace => 'NetworkIfService',
303     url => $url,
304     user => $user,
305     password => $password,
306   );
307   
308   my $err_or_som = $prizm->getPrizmElements( [ 'MAC Address' ],
309                                              [ $mac_addr ],
310                                              [ '=' ],
311                                            );
312   die $err_or_som
313     unless ref($err_or_som);
314
315   die "Can't find prizm element for " . $mac_addr
316     unless $err_or_som->result->[0];
317
318   my @args;
319   # yuck! should pass args in when we know 'em
320   if ($method =~ /suspendNetworkElements/ || $method =~ /activateNetworkElements/) {
321     @args = ( [ $err_or_som->result->[0]->elementId ], 1, 1);
322   }else{
323     @args = ( $err_or_som->result->[0]->elementId, 1);
324   }
325   $err_or_som = $prizm->$method( @args );
326
327   die $err_or_som
328     unless ref($err_or_som);
329
330   '';
331
332 }
333
334 1;