[freeside-commits] branch FREESIDE_4_BRANCH updated. 4c20bb23330aff5df05a211762106ec50402f7c7

Mark Wells mark at 420.am
Sun Mar 20 16:42:56 PDT 2016


The branch, FREESIDE_4_BRANCH has been updated
       via  4c20bb23330aff5df05a211762106ec50402f7c7 (commit)
       via  14d83a8b09462027016c0ea3511b8d54b1f2519a (commit)
       via  9ed4d732a91d71a024d1c469730c737f64fa848a (commit)
      from  699758d489a44bddc6ce92809fd6176e2548d45f (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 4c20bb23330aff5df05a211762106ec50402f7c7
Author: Mark Wells <mark at freeside.biz>
Date:   Sun Mar 20 16:41:14 2016 -0700

    add pgloader config to migrate from mysql, #39756

diff --git a/bin/freeside-mysql.load b/bin/freeside-mysql.load
new file mode 100644
index 0000000..02f47da
--- /dev/null
+++ b/bin/freeside-mysql.load
@@ -0,0 +1,6 @@
+LOAD DATABASE
+  FROM mysql://freeside@/freeside
+  INTO postgresql://freeside@/freeside
+WITH include drop, create tables, reset sequences, create indexes
+CAST type varbinary to varchar
+;

commit 14d83a8b09462027016c0ea3511b8d54b1f2519a
Author: Mark Wells <mark at freeside.biz>
Date:   Sat Mar 12 18:59:05 2016 -0800

    show map of svc_broadband and tower locations, #37802

diff --git a/httemplate/images/antenna-square-21x51.png b/httemplate/images/antenna-square-21x51.png
new file mode 100644
index 0000000..0ba5e73
Binary files /dev/null and b/httemplate/images/antenna-square-21x51.png differ
diff --git a/httemplate/search/elements/gmap.html b/httemplate/search/elements/gmap.html
new file mode 100644
index 0000000..8b070eb
--- /dev/null
+++ b/httemplate/search/elements/gmap.html
@@ -0,0 +1,123 @@
+<%args>
+ at features
+</%args>
+<%doc>
+Generic Google Maps front end.
+
+<& /elements/gmap.html,
+  features => [
+    { id => 'svc_acct/12',
+      geometry => {
+        type        => 'Point',
+        coordinates => [ -86, 40 ], # optionally altitude as the third coord
+      },
+      properties => {
+        # see https://developers.google.com/maps/documentation/javascript/3.exp/reference#Data.StyleOptions
+        style => {
+          icon => {
+            scale => 4,
+            fillColor => 'orange',
+          }
+        },
+        # content of popup info box (might AJAX this later)
+        content => '<a href="view/svc_acct.cgi?12">username at example.com</a>',
+      }
+    }, # end of feature
+  ],
+&>
+
+</%doc>
+<%init>
+foreach (@features) {
+  $_->{type} = 'Feature';
+  # any other per-feature massaging can go here
+}
+my $tree = {
+  type => 'FeatureCollection',
+  features => \@features
+};
+
+</%init>
+<div id="map_canvas"></div>
+
+<style type="text/css">
+html { height: 100% }
+
+body { height: 100%; margin: 0px; padding: 0px }
+
+#map_canvas { height: 100%; }
+</style>
+
+<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3">
+</script>
+
+<script type="text/javascript">
+
+var data_geojson = <% encode_json($tree) %>;
+
+var baseStyle = {
+  clickable: true,
+  icon: {
+    path: google.maps.SymbolPath.CIRCLE,
+    scale: 4,
+    fillColor: 'green',
+    fillOpacity: 1,
+    strokeColor: 'black',
+    strokeWeight: 1,
+  },
+};
+
+var featureStyle = function(feature) {
+  // jQuery.extend(): merge properties of objects
+  // 'true' makes it a deep copy; start the merge with {} so that
+  // baseStyle doesn't get overwritten
+  return $.extend(true, {}, baseStyle, feature.getProperty('style'));
+};
+
+var map;
+function initMap() {
+  var canvas = $('#map_canvas');
+  map = new google.maps.Map(canvas[0], { zoom: 6 });
+  try {
+    map.data.addGeoJson(data_geojson);
+  } catch(ex) {
+    console.log(ex.toString);
+    debugger;
+  }
+
+  // construct bounds around all of the features
+  var bounds = new google.maps.LatLngBounds;
+  map.data.forEach(function(feature) {
+    var g = feature.getGeometry();
+    if (g.getType() == 'Point') {
+      bounds.extend(g.get());
+    } else if (g.getArray) {
+      g.getArray().forEach(function(point) { bounds.extend(point); });
+    }
+  });
+
+  map.fitBounds(bounds);
+  map.data.setStyle(featureStyle);
+
+  var info = new google.maps.InfoWindow;
+  map.data.addListener('click', function(ev) {
+    var feature = ev.feature;
+    if ( feature.getGeometry().getType() == 'Point' ) {
+      // then pop up an info box with the feature content
+      info.close();
+      info.setPosition(feature.getGeometry().get());
+      info.setContent(feature.getProperty('content'));
+      info.open(map);
+    }
+
+    // snap to feature ROI if it has one
+    if ( feature.getProperty('bounds') ) {
+      map.fitBounds( feature.getProperty('bounds') );
+    }
+
+  }); // addListener()
+}
+
+$().ready( initMap );
+</script>
+
diff --git a/httemplate/search/svc_broadband-map.html b/httemplate/search/svc_broadband-map.html
new file mode 100755
index 0000000..4c660b0
--- /dev/null
+++ b/httemplate/search/svc_broadband-map.html
@@ -0,0 +1,178 @@
+<& /elements/header.html, 'Broadband Search Results' &>
+  
+<& elements/gmap.html, features => \@features &>
+
+<& /elements/footer.html &>
+<%init>
+
+die "access denied" unless
+  $FS::CurrentUser::CurrentUser->access_right('List services');
+
+my $conf = new FS::Conf;
+
+my @features; # geoJSON structure
+
+# accept all the search logic from svc_broadband.cgi...
+my %search_hash;
+if ( $cgi->param('magic') eq 'unlinked' ) {
+  %search_hash = ( 'unlinked' => 1 );
+} else {
+  foreach (qw( custnum agentnum svcpart cust_fields )) {
+    $search_hash{$_} = $cgi->param($_) if $cgi->param($_);
+  }
+  foreach (qw(pkgpart routernum towernum sectornum)) {
+    $search_hash{$_} = [ $cgi->param($_) ] if $cgi->param($_);
+  }
+}
+
+if ( $cgi->param('sortby') =~ /^(\w+)$/ ) {
+  $search_hash{'order_by'} = "ORDER BY $1";
+}
+
+my $sql_query = FS::svc_broadband->search(\%search_hash);
+
+my %routerbyblock = ();
+
+my @rows = qsearch($sql_query);
+my %sectors;
+my %towers;
+my %tower_coord;
+my %tower_bounds;
+foreach my $svc_broadband (@rows) {
+  # don't try to show it if coords aren't set
+  next if !$svc_broadband->latitude || !$svc_broadband->longitude;
+  # coerce coordinates to numbers
+  my @coord = (
+    $svc_broadband->longitude + 0,
+    $svc_broadband->latitude + 0,
+  );
+  push @coord, $svc_broadband->altitude + 0
+    if length($svc_broadband->altitude); # it's optional
+
+  push @features,
+  {
+    id        => 'svc_broadband/'.$svc_broadband->svcnum,
+    geometry  => {
+      type        => 'Point',
+      coordinates => \@coord,
+    },
+    properties => {
+      content => include('.svc_broadband', $svc_broadband),
+    },
+  };
+  # look up tower location and draw connecting line
+  next if !$svc_broadband->sectornum;
+  my $sector = $sectors{$svc_broadband->sectornum} ||= $svc_broadband->tower_sector;
+  my $towernum = $sector->towernum;
+  my $tower = $towers{$towernum};
+
+  if (!$tower) {
+    $tower = $towers{$towernum} = $sector->tower;
+    $tower_coord{$towernum} =
+      [ $tower->longitude + 0,
+        $tower->latitude + 0,
+        ($tower->altitude || 0) + 0,
+      ];
+
+  }
+
+  my $tower = $towers{$towernum};
+  if ( $tower->latitude and $tower->longitude ) {
+    push @features,
+    {
+      geometry => {
+        type        => 'LineString',
+        coordinates => [ \@coord, $tower_coord{$towernum} ],
+      },
+      properties  => {
+        style       => {
+          strokeColor  => ($tower->color || 'green'),
+          strokeWeight => 2,
+        },
+      },
+    };
+
+    # also extend tower's ROI to include this point
+    # (this is experimental; might get better results using the centroid of
+    # all connected services or something)
+    my $bounds = $tower_bounds{$towernum} ||= {
+      east => $tower->longitude,
+      west => $tower->longitude,
+      north => $tower->latitude,
+      south => $tower->latitude,
+    };
+    if ($coord[0] > $bounds->{east}) {
+      $bounds->{east} = $coord[0];
+    } elsif ($coord[0] < $bounds->{west}) {
+      $bounds->{west} = $coord[0];
+    }
+    if ($coord[1] > $bounds->{north}) {
+      $bounds->{north} = $coord[1]
+    } elsif ($coord[1] < $bounds->{south}) {
+      $bounds->{south} = $coord[1]
+    }
+
+  } # if tower has coords
+} # foreach $svc_broadband
+
+foreach my $tower (values(%towers)) {
+  my $towernum = $tower->towernum;
+  my $bounds = $tower_bounds{$towernum};
+  # add some padding for easier reading
+  my $dx = 0.1 * ($bounds->{east} - $bounds->{west});
+  my $dy = 0.1 * ($bounds->{north} - $bounds->{south});
+  $bounds->{east} += $dx; 
+  $bounds->{west} -= $dx;
+  $bounds->{north} += $dy;
+  $bounds->{south} -= $dy;
+  push @features,
+  {
+    id        => 'tower/'.$towernum,
+    geometry  => {
+      type        => 'Point',
+      coordinates => $tower_coord{$towernum},
+    },
+    properties => {
+      style     => {
+        icon => {
+          path        => undef,
+          url         => $fsurl.'images/jcartier-antenna-square-21x51.png',
+          anchor      => { x => 10, y => 4 }
+        },
+      },
+      content   => include('.tower', $tower),
+      bounds    => $tower_bounds{$towernum},
+    },
+  };
+}
+
+</%init>
+<%def .svc_broadband>
+% my $svc = shift;
+% my @label = $svc->cust_svc->label;
+<H3>
+  <a target="_blank" href="<% $fsurl %>view/svc_broadband.cgi?<% $svc->svcnum %>">
+    <% $label[0] |h %> #<% $svc->svcnum %> | <% $label[1] %>
+  </a>
+</H3>
+% my $cust_main = $svc->cust_main;
+<a target="_blank" href="<% $fsurl %>view/cust_main.cgi?<% $cust_main->custnum %>">
+<& /elements/small_custview.html, {
+  cust_main => $svc->cust_main,
+  #url => $fsurl.'view/cust_main.cgi',
+} &>
+</a>
+</%def>
+<%def .tower>
+% my $tower = shift;
+% my $can_edit = $FS::CurrentUser::CurrentUser->access_right('Configuration');
+<H3>
+% if ( $can_edit ) {
+  <a target="_blank" href="<% $fsurl %>edit/tower.html?<% $tower->towernum %>">
+% }
+Tower #<% $tower->towernum %> | <% $tower->towername %>
+% if ( $can_edit ) {
+  </a>
+% }
+</H3>
+</%def>
diff --git a/httemplate/search/svc_broadband.cgi b/httemplate/search/svc_broadband.cgi
index 8561977..6bf4f08 100755
--- a/httemplate/search/svc_broadband.cgi
+++ b/httemplate/search/svc_broadband.cgi
@@ -105,5 +105,9 @@ my $html_init = include('/elements/email-link.html',
                   'search_hash' => \%search_hash,
                   'table' => 'svc_broadband' 
                 );
+$html_init .= ' | ' .
+  '<a href="' .
+  $fsurl . 'search/svc_broadband-map.html?' . $cgi->query_string .
+  '">' . emt('View a map of these services') . '</a>';
 
 </%init>

commit 9ed4d732a91d71a024d1c469730c737f64fa848a
Author: Mark Wells <mark at freeside.biz>
Date:   Sat Mar 12 18:59:26 2016 -0800

    fix squashing of capital letters in KML

diff --git a/httemplate/view/kml.cgi b/httemplate/view/kml.cgi
index 7eaaa2a..a156edc 100644
--- a/httemplate/view/kml.cgi
+++ b/httemplate/view/kml.cgi
@@ -6,6 +6,6 @@ $kml->Point( map { $_=>scalar($cgi->param($_)) } qw( name lat lon ) );
 
 #http_header('Content-Type' => 'application/vnd.google-earth.kml+xml' ); #kml
 http_header('Content-Type' => 'application/vnd.google-earth.kmz' ); #kmz
-( my $name = $cgi->param('name') ) =~ s/[^a-z0-9]/_/g; #perhaps too restrictive
+( my $name = $cgi->param('name') ) =~ s/[^a-z0-9]/_/gi; #perhaps too restrictive
 http_header('Content-Disposition' => "filename=$name.kmz" );
 </%init>

-----------------------------------------------------------------------

Summary of changes:
 bin/freeside-mysql.load                    |    6 +
 httemplate/images/antenna-square-21x51.png |  Bin 0 -> 1475 bytes
 httemplate/search/elements/gmap.html       |  123 +++++++++++++++++++
 httemplate/search/svc_broadband-map.html   |  178 ++++++++++++++++++++++++++++
 httemplate/search/svc_broadband.cgi        |    4 +
 httemplate/view/kml.cgi                    |    2 +-
 6 files changed, 312 insertions(+), 1 deletion(-)
 create mode 100644 bin/freeside-mysql.load
 create mode 100644 httemplate/images/antenna-square-21x51.png
 create mode 100644 httemplate/search/elements/gmap.html
 create mode 100755 httemplate/search/svc_broadband-map.html




More information about the freeside-commits mailing list