summaryrefslogtreecommitdiff
path: root/FS/FS
diff options
context:
space:
mode:
authorivan <ivan>2011-12-13 05:09:32 +0000
committerivan <ivan>2011-12-13 05:09:32 +0000
commit8cbe016ac2c28cd209c48f053f361573368e7988 (patch)
tree5a39513e71f4e9528f71fa298c2abf8b8dbd07db /FS/FS
parentea1b65c11b8781160b5a76a77e1ee8108e528048 (diff)
add latitude/longitude to prospects, customers and package locations, RT#15539
Diffstat (limited to 'FS/FS')
-rw-r--r--FS/FS/Conf.pm37
-rw-r--r--FS/FS/Mason.pm2
-rw-r--r--FS/FS/Record.pm23
-rw-r--r--FS/FS/Upgrade.pm3
-rw-r--r--FS/FS/cust_location.pm6
-rw-r--r--FS/FS/cust_main.pm41
-rw-r--r--FS/FS/geocode_Mixin.pm31
-rw-r--r--FS/FS/part_svc.pm15
-rwxr-xr-xFS/FS/svc_broadband.pm19
9 files changed, 160 insertions, 17 deletions
diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm
index fcdcd57..efdad43 100644
--- a/FS/FS/Conf.pm
+++ b/FS/FS/Conf.pm
@@ -2650,14 +2650,28 @@ and customer address. Include units.',
{
'key' => 'network_monitoring_system',
- 'section' => '',
+ 'section' => 'network_monitoring',
'description' => 'Networking monitoring system (NMS) integration. <b>Torrus_Internal</b> uses the built-in Torrus ticketing system (see the <a href="http://www.freeside.biz/mediawiki/index.php/Freeside:2.1:Documentation:Torrus_Installation">integrated networking monitoring system installation instructions</a>).',
'type' => 'select',
- #'select_enum' => [ '', qw(RT_Internal RT_Libs RT_External) ],
'select_enum' => [ '', qw(Torrus_Internal) ],
},
{
+ 'key' => 'nms-auto_add-svc_ips',
+ 'section' => 'network_monitoring',
+ 'description' => 'Automatically add (and remove) IP addresses from these service tables to the network monitoring system.',
+ 'type' => 'selectmultiple',
+ 'select_enum' => [ 'svc_acct', 'svc_broadband', 'svc_dsl' ],
+ },
+
+ {
+ 'key' => 'nms-auto_add-community',
+ 'section' => 'network_monitoring',
+ 'description' => 'SNMP community string to use when automatically adding IP addresses from these services to the network monitoring system.',
+ 'type' => 'text',
+ },
+
+ {
'key' => 'ticket_system-default_queueid',
'section' => 'ticketing',
'description' => 'Default queue used when creating new customer tickets.',
@@ -3738,6 +3752,21 @@ and customer address. Include units.',
},
{
+ 'key' => 'geocode_module',
+ 'section' => '',
+ 'description' => 'Module to geocode (retrieve a latitude and longitude for) addresses',
+ 'type' => 'select',
+ 'select_enum' => [ 'Geo::Coder::Googlev3' ],
+ },
+
+ {
+ 'key' => 'geocode-require_nw_coordinates',
+ 'section' => 'UI',
+ 'description' => 'Require latitude and longitude in the North Western quadrant, e.g. for North American co-ordinates, etc.',
+ 'type' => 'checkbox',
+ },
+
+ {
'key' => 'disable_acl_changes',
'section' => '',
'description' => 'Disable all ACL changes, for demos.',
@@ -4656,8 +4685,8 @@ and customer address. Include units.',
{
'key' => 'svc_broadband-require-nw-coordinates',
- 'section' => 'UI',
- 'description' => 'On svc_broadband add/edit, require latitude and longitude in the North Western quadrant, e.g. for North American co-ordinates, etc.',
+ 'section' => 'deprecated',
+ 'description' => 'Deprecated; see geocode-require_nw_coordinates instead',
'type' => 'checkbox',
},
diff --git a/FS/FS/Mason.pm b/FS/FS/Mason.pm
index 0cb2a0b..773261f 100644
--- a/FS/FS/Mason.pm
+++ b/FS/FS/Mason.pm
@@ -114,6 +114,8 @@ if ( -e $addl_handler_use_file ) {
#selectlayers.html
use Locale::Country;
use Business::US::USPS::WebTools::AddressStandardization;
+ use HTML::GoogleMaps;
+ use Geo::GoogleEarth::Pluggable;
use LWP::UserAgent;
use Storable qw( nfreeze thaw );
use FS;
diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm
index caddc6f..6773487 100644
--- a/FS/FS/Record.pm
+++ b/FS/FS/Record.pm
@@ -3,7 +3,7 @@ package FS::Record;
use strict;
use vars qw( $AUTOLOAD @ISA @EXPORT_OK $DEBUG
%virtual_fields_cache
- $conf $conf_encryption $money_char
+ $conf $conf_encryption $money_char $lat_lower $lon_upper
$me
$nowarn_identical $nowarn_classload
$no_update_diff $no_check_foreign
@@ -57,18 +57,25 @@ my $rsa_decrypt;
$conf = '';
$conf_encryption = '';
FS::UID->install_callback( sub {
+
eval "use FS::Conf;";
die $@ if $@;
$conf = FS::Conf->new;
$conf_encryption = $conf->exists('encryption');
$money_char = $conf->config('money_char') || '$';
+ my $nw_coords = $conf->exists('geocode-require_nw_coordinates');
+ $lat_lower = $nw_coords ? 1 : -90;
+ $lon_upper = $nw_coords ? -1 : 180;
+
$File::CounterFile::DEFAULT_DIR = $conf->base_dir . "/counters.". datasrc;
+
if ( driver_name eq 'Pg' ) {
eval "use DBD::Pg ':pg_types'";
die $@ if $@;
} else {
eval "sub PG_BYTEA { die 'guru meditation #9: calling PG_BYTEA when not running Pg?'; }";
}
+
} );
=head1 NAME
@@ -2343,11 +2350,17 @@ for lower and upper bounds, respectively.
=cut
sub ut_coord {
-
my ($self, $field) = (shift, shift);
- my $lower = shift if scalar(@_);
- my $upper = shift if scalar(@_);
+ my($lower, $upper);
+ if ( $field =~ /latitude/ ) {
+ $lower = $lat_lower;
+ $upper = 90;
+ } elsif ( $field =~ /longitude/ ) {
+ $lower = -180;
+ $upper = $lon_upper;
+ }
+
my $coord = $self->getfield($field);
my $neg = $coord =~ s/^(-)//;
@@ -2395,7 +2408,7 @@ sub ut_coordn {
my ($self, $field) = (shift, shift);
- if ($self->getfield($field) =~ /^$/) {
+ if ($self->getfield($field) =~ /^\s*$/) {
return '';
} else {
return $self->ut_coord($field, @_);
diff --git a/FS/FS/Upgrade.pm b/FS/FS/Upgrade.pm
index eac8333..3134b8c 100644
--- a/FS/FS/Upgrade.pm
+++ b/FS/FS/Upgrade.pm
@@ -47,6 +47,9 @@ sub upgrade_config {
if $conf->exists('payment_receipt_email')
|| $conf->config('payment_receipt_msgnum');
+ $conf->touch('geocode-require_nw_coordinates')
+ if $conf->exists('svc_broadband-require-nw-coordinates');
+
upgrade_overlimit_groups($conf);
map { upgrade_overlimit_groups($conf,$_->agentnum) } qsearch('agent', {});
diff --git a/FS/FS/cust_location.pm b/FS/FS/cust_location.pm
index 7ffa5ed..a3d5bcb 100644
--- a/FS/FS/cust_location.pm
+++ b/FS/FS/cust_location.pm
@@ -135,6 +135,9 @@ sub check {
|| $self->ut_textn('state')
|| $self->ut_country('country')
|| $self->ut_zip('zip', $self->country)
+ || $self->ut_coordn('latitude')
+ || $self->ut_coordn('longitude')
+ || $self->ut_enum('coord_auto', [ '', 'Y' ])
|| $self->ut_alphan('location_type')
|| $self->ut_textn('location_number')
|| $self->ut_enum('location_kind', [ '', 'R', 'B' ] )
@@ -142,6 +145,9 @@ sub check {
;
return $error if $error;
+ $self->set_coord
+ unless $self->latitude && $self->longitude;
+
return "No prospect or customer!" unless $self->prospectnum || $self->custnum;
return "Prospect and customer!" if $self->prospectnum && $self->custnum;
diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm
index a0a7e91..5c78d8a 100644
--- a/FS/FS/cust_main.pm
+++ b/FS/FS/cust_main.pm
@@ -1481,6 +1481,29 @@ sub replace {
&& length($self->get($pre.'zip')) >= 10;
}
+ for my $pre ( grep $old->get($_.'coord_auto'), ( '', 'ship_' ) ) {
+
+ $self->set($pre.'coord_auto', '') && next
+ if $self->get($pre.'latitude') && $self->get($pre.'longitude')
+ && ( $self->get($pre.'latitude') != $old->get($pre.'latitude')
+ || $self->get($pre.'longitude') != $old->get($pre.'longitude')
+ );
+
+ $self->set_coord($pre)
+ if $old->get($pre.'address1') ne $self->get($pre.'address1')
+ || $old->get($pre.'city') ne $self->get($pre.'city')
+ || $old->get($pre.'state') ne $self->get($pre.'state')
+ || $old->get($pre.'country') ne $self->get($pre.'country');
+
+ }
+
+ $self->set_coord
+ if ! $self->coord_auto && ! $self->latitude && ! $self->longitude;
+
+ $self->set_coord('ship_')
+ if $self->has_ship_address && ! $self->ship_coord_auto
+ && ! $self->ship_latitude && ! $self->ship_longitude;
+
local($ignore_expired_card) = 1
if $old->payby =~ /^(CARD|DCRD)$/
&& $self->payby =~ /^(CARD|DCRD)$/
@@ -1696,6 +1719,9 @@ sub check {
|| $self->ut_textn('county')
|| $self->ut_textn('state')
|| $self->ut_country('country')
+ || $self->ut_coordn('latitude')
+ || $self->ut_coordn('longitude')
+ || $self->ut_enum('coord_auto', [ '', 'Y' ])
|| $self->ut_anything('comments')
|| $self->ut_numbern('referral_custnum')
|| $self->ut_textn('stateid')
@@ -1710,6 +1736,9 @@ sub check {
|| $self->ut_enum('locale', [ '', FS::Locales->locales ])
;
+ $self->set_coord
+ unless $import || ($self->latitude && $self->longitude);
+
#barf. need message catalogs. i18n. etc.
$error .= "Please select an advertising source."
if $error =~ /^Illegal or empty \(numeric\) refnum: /;
@@ -1807,9 +1836,15 @@ sub check {
|| $self->ut_textn('ship_county')
|| $self->ut_textn('ship_state')
|| $self->ut_country('ship_country')
+ || $self->ut_coordn('ship_latitude')
+ || $self->ut_coordn('ship_longitude')
+ || $self->ut_enum('ship_coord_auto', [ '', 'Y' ] )
;
return $error if $error;
+ $self->set_coord('ship_')
+ unless $import || ($self->ship_latitude && $self->ship_longitude);
+
#false laziness with above
unless ( qsearchs('cust_main_county', {
'country' => $self->ship_country,
@@ -2079,6 +2114,7 @@ Returns a list of fields which have ship_ duplicates.
sub addr_fields {
qw( last first company
address1 address2 city county state zip country
+ latitude longitude
daytime night fax mobile
);
}
@@ -2500,8 +2536,9 @@ sub batch_card {
'custnum' => $self->custnum,
} );
- foreach (qw( address1 address2 city state zip country payby payinfo paydate
- payname )) {
+ foreach (qw( address1 address2 city state zip country latitude longitude
+ payby payinfo paydate payname ))
+ {
$options{$_} = '' unless exists($options{$_});
}
diff --git a/FS/FS/geocode_Mixin.pm b/FS/FS/geocode_Mixin.pm
index c1b9f86..9ac8e7a 100644
--- a/FS/FS/geocode_Mixin.pm
+++ b/FS/FS/geocode_Mixin.pm
@@ -4,6 +4,7 @@ use strict;
use vars qw( $DEBUG $me );
use Carp;
use Locale::Country;
+use Geo::Coder::Googlev3; #compile time for now, until others are supported
use FS::Record qw( qsearchs qsearch );
use FS::Conf;
use FS::cust_pkg;
@@ -131,6 +132,36 @@ sub location_label {
$line;
}
+=item set_coord
+
+=cut
+
+sub set_coord {
+ my $self = shift;
+ my $pre = scalar(@_) ? shift : '';
+
+ #my $module = FS::Conf->new->config('geocode_module') || 'Geo::Coder::Googlev3';
+
+ my $geocoder = Geo::Coder::Googlev3->new;
+ my $location = $geocoder->geocode( location =>
+ $self->get($pre.'address1'). ','.
+ ( $self->get($pre.'address2') ? $self->get($pre.'address2').',' : '' ).
+ $self->get($pre.'city'). ','.
+ $self->get($pre.'state'). ','.
+ code2country($self->get($pre.'country'))
+ );
+
+ #errors?
+
+ my $geo_loc = $location->{'geometry'}{'location'} or return;
+ if ( $geo_loc->{'lat'} && $geo_loc->{'lng'} ) {
+ $self->set($pre.'latitude', $geo_loc->{'lat'} );
+ $self->set($pre.'longitude', $geo_loc->{'lng'} );
+ $self->set($pre.'coord_auto', 'Y');
+ }
+
+}
+
=item geocode DATA_VENDOR
Returns a value for the customer location as encoded by DATA_VENDOR.
diff --git a/FS/FS/part_svc.pm b/FS/FS/part_svc.pm
index cc30dbb..dea115c 100644
--- a/FS/FS/part_svc.pm
+++ b/FS/FS/part_svc.pm
@@ -872,6 +872,21 @@ sub _upgrade_data { #class method
die $error if $error;
}
+ my @badlabels = qsearch({
+ 'table' => 'part_svc_column',
+ 'hashref' => {},
+ 'extra_sql' => 'WHERE columnlabel IN ('.
+ "'Descriptive label for this particular device.',".
+ "'IP address. Leave blank for automatic assignment.',".
+ "'Maximum upload speed for this service in Kbps. 0 denotes unlimited.',".
+ "'Maximum download speed for this service in Kbps. 0 denotes unlimited.')"
+ });
+ foreach my $col ( @badlabels ) {
+ $col->columnlabel('');
+ my $error = $col->replace;
+ die $error if $error;
+ }
+
}
=head1 BUGS
diff --git a/FS/FS/svc_broadband.pm b/FS/FS/svc_broadband.pm
index c5034b0..678a788 100755
--- a/FS/FS/svc_broadband.pm
+++ b/FS/FS/svc_broadband.pm
@@ -347,10 +347,6 @@ sub check {
return $x unless ref($x);
- my $nw_coords = $conf->exists('svc_broadband-require-nw-coordinates');
- my $lat_lower = $nw_coords ? 1 : -90;
- my $lon_upper = $nw_coords ? -1 : 180;
-
# remove delimiters
my $mac_addr = uc($self->get('mac_addr'));
$mac_addr =~ s/[-: ]//g;
@@ -366,8 +362,8 @@ sub check {
|| $self->ut_ipn('ip_addr')
|| $self->ut_hexn('mac_addr')
|| $self->ut_hexn('auth_key')
- || $self->ut_coordn('latitude', $lat_lower, 90)
- || $self->ut_coordn('longitude', -180, $lon_upper)
+ || $self->ut_coordn('latitude')
+ || $self->ut_coordn('longitude')
|| $self->ut_sfloatn('altitude')
|| $self->ut_textn('vlan_profile')
|| $self->ut_textn('plan_id')
@@ -400,6 +396,17 @@ sub check {
}
}
+ if ( $cust_pkg && ! $self->latitude && ! $self->longitude ) {
+ my $l = $cust_pkg->cust_location_or_main;
+ if ( $l->ship_latitude && $l->ship_longitude ) {
+ $self->latitude = $l->ship_latitude;
+ $self->longitude = $l->ship_longitude;
+ } elsif ( $l->latitude && $l->longitude ) {
+ $self->latitude = $l->latitude;
+ $self->longitude = $l->longitude;
+ }
+ }
+
$error = $self->_check_ip_addr;
return $error if $error;