export tower/sector data to TowerCoverage API, #39776
[freeside.git] / FS / FS / tower_sector.pm
index 08e8cc0..2e92323 100644 (file)
@@ -1,6 +1,7 @@
 package FS::tower_sector;
 use base qw( FS::Record );
 
+use FS::Record qw(dbh qsearch);
 use Class::Load qw(load_class);
 use File::Path qw(make_path);
 use Data::Dumper;
@@ -8,6 +9,8 @@ use Cpanel::JSON::XS;
 
 use strict;
 
+our $noexport_hack = 0;
+
 =head1 NAME
 
 FS::tower_sector - Object methods for tower_sector records
@@ -118,9 +121,26 @@ otherwise returns false.
 
 sub insert {
   my $self = shift;
+
+  my $oldAutoCommit = $FS::UID::AutoCommit;
+  local $FS::UID::AutoCommit = 0;
+  my $dbh = dbh;
+
   my $error = $self->SUPER::insert;
   return $error if $error;
 
+  unless ($noexport_hack) {
+    foreach my $part_export ($self->part_export) {
+      my $error = $part_export->export_insert($self);
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        return "exporting to ".$part_export->exporttype.
+               " (transaction rolled back): $error";
+      }
+    }
+  }
+
+  # XXX exportify
   if (scalar($self->need_fields_for_coverage) == 0) {
     $self->queue_generate_coverage;
   }
@@ -128,7 +148,27 @@ sub insert {
 
 sub replace {
   my $self = shift;
+
+  my $oldAutoCommit = $FS::UID::AutoCommit;
+  local $FS::UID::AutoCommit = 0;
+  my $dbh = dbh;
+
   my $old = shift || $self->replace_old;
+  my $error = $self->SUPER::replace($old);
+  return $error if $error;
+
+  unless ( $noexport_hack ) {
+    foreach my $part_export ($self->part_export) {
+      my $error = $part_export->export_replace($self, $old);
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        return "exporting to ".$part_export->exporttype.
+               " (transaction rolled back): $error";
+      }
+    }
+  }
+
+  #XXX exportify
   my $regen_coverage = 0;
   if ( !$self->get('no_regen') ) {
     foreach (qw(height freq_mhz direction width downtilt
@@ -138,8 +178,6 @@ sub replace {
     }
   }
 
-  my $error = $self->SUPER::replace($old);
-  return $error if $error;
 
   if ($regen_coverage) {
     $self->queue_generate_coverage;
@@ -155,11 +193,31 @@ Delete this record from the database.
 sub delete {
   my $self = shift;
 
+  my $oldAutoCommit = $FS::UID::AutoCommit;
+  local $FS::UID::AutoCommit = 0;
+  my $dbh = dbh;
+
   #not the most efficient, not not awful, and its not like deleting a sector
   # with customers is a common operation
   return "Can't delete a sector with customers" if $self->svc_broadband;
 
-  $self->SUPER::delete;
+  unless ($noexport_hack) {
+    foreach my $part_export ($self->part_export) {
+      my $error = $part_export->export_delete($self);
+      if ( $error ) {
+        $dbh->rollback if $oldAutoCommit;
+        return "exporting to ".$part_export->exporttype.
+               " (transaction rolled back): $error";
+      }
+    }
+  }
+
+  my $error = $self->SUPER::delete;
+  if ( $error ) {
+    $dbh->rollback if $oldAutoCommit;
+    return $error;
+  }
+
 }
 
 =item check
@@ -185,13 +243,19 @@ sub check {
     || $self->ut_numbern('v_width')
     || $self->ut_numbern('downtilt')
     || $self->ut_floatn('sector_range')
-    || $self->ut_numbern('db_high')
-    || $self->ut_numbern('db_low')
+    || $self->ut_decimaln('power')
+    || $self->ut_decimaln('line_loss')
+    || $self->ut_decimaln('antenna_gain')
+    || $self->ut_numbern('hardware_typenum')
+    || $self->ut_textn('title')
+    # all of these might get relocated as part of coverage refactoring
     || $self->ut_anything('image')
     || $self->ut_sfloatn('west')
     || $self->ut_sfloatn('east')
     || $self->ut_sfloatn('south')
     || $self->ut_sfloatn('north')
+    || $self->ut_numbern('db_high')
+    || $self->ut_numbern('db_low')
   ;
   return $error if $error;
 
@@ -229,6 +293,7 @@ Returns a list of required fields for the coverage map that aren't yet filled.
 =cut
 
 sub need_fields_for_coverage {
+  # for now assume exports require all of this
   my $self = shift;
   my $tower = $self->tower;
   my %fields = (
@@ -238,7 +303,8 @@ sub need_fields_for_coverage {
     downtilt  => 'Downtilt',
     width     => 'Horiz. width',
     v_width   => 'Vert. width',
-    db_high   => 'High quality',
+    db_high   => 'High quality signal margin',
+    db_low    => 'Low quality signal margin',
     latitude  => 'Latitude',
     longitude => 'Longitude',
   );
@@ -257,10 +323,12 @@ Starts a job to recalculate the coverage map.
 
 =cut
 
+# XXX move to an export
+
 sub queue_generate_coverage {
   my $self = shift;
   my $need_fields = join(',', $self->need_fields_for_coverage);
-  return "Sector needs fields $need_fields" if $need_fields;
+  return "$need_fields required" if $need_fields;
   $self->set('no_regen', 1); # avoid recursion
   if ( length($self->image) > 0 ) {
     foreach (qw(image west south east north)) {
@@ -277,6 +345,28 @@ sub queue_generate_coverage {
 
 =back
 
+=head1 CLASS METHODS
+
+=over 4
+
+=item part_export
+
+Returns all sector exports. Eventually this may be refined to the level
+of enabling exports on specific sectors.
+
+=cut
+
+sub part_export {
+  my $info = $FS::part_export::exports{'tower_sector'} or return;
+  my @exporttypes = map { dbh->quote($_) } keys %$info or return;
+  qsearch({
+    'table'     => 'part_export',
+    'extra_sql' => 'WHERE exporttype IN(' . join(',', @exporttypes) . ')'
+  });
+}
+
+=back
+
 =head1 SUBROUTINES
 
 =over 4