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