+=item country_full
+
+Returns the full country name.
+
+=cut
+
+sub country_full {
+ my $self = shift;
+ $self->code2country($self->get('country'));
+}
+
+sub code2country {
+ my( $self, $country ) = @_;
+
+ #a hash? not expecting an explosion of business from unrecognized countries..
+ return 'KKTC' if $country eq 'XC';
+
+ Locale::Country::code2country($country);
+}
+
+=item set_coord
+
+Look up the coordinates of the location using (currently) the Google Maps
+API and set the 'latitude' and 'longitude' fields accordingly.
+
+=cut
+
+sub set_coord {
+ my $self = shift;
+
+ # Google documetnation:
+ # https://developers.google.com/maps/documentation/geocoding/start
+
+
+ my $api_key = FS::Conf->new->config('google_maps_api_key');
+
+ unless ( $api_key ) {
+ # Google API now requires a valid key with a payment method attached
+ warn 'Geocoding unavailable, install a google_maps_api_key';
+ return;
+ }
+
+ my $google_api_url = 'https://maps.googleapis.com/maps/api/geocode/json';
+
+ my $address =
+ join ',',
+ map { $self->get( $_ ) ? uri_escape( $self->get( $_ ) ) : () }
+ qw( address1 address2 city state zip country_full );
+
+ my $query_url = sprintf
+ '%s?address=%s&key=%s',
+ $google_api_url, $address, $api_key;
+
+ my $ua = LWP::UserAgent->new;
+ $ua->timeout(10);
+ my $res = $ua->get( $query_url );
+ my $json_res = decode_json( $res->decoded_content );
+ my $json_error = $json_res->{error_message}
+ if ref $json_res && $json_res->{error_message};
+
+ if ( $DEBUG ) {
+ warn "\$query_url: $query_url\n";
+ warn "\$json_error: $json_error\n";
+ warn Dumper( $json_res || $res->decoded_content )."\n";
+ }
+
+ if ( !$res->is_success || $json_error ) {
+ warn "Error using google GeoCoding API";
+ warn Dumper( $json_res || $res->decoded_content );
+ return;
+ }
+
+ if (
+ ref $json_res
+ && ref $json_res->{results}
+ && ref $json_res->{results}->[0]
+ && ref $json_res->{results}->[0]->{geometry}
+ && ref $json_res->{results}->[0]->{geometry}->{location}
+ ) {
+ my $location = $json_res->{results}->[0]->{geometry}->{location};
+ if ( $location->{lat} && $location->{lng} ) {
+ $self->set( latitude => $location->{lat} );
+ $self->set( longitude => $location->{lng} );
+ $self->set( coord_auto => 'Y' );
+ }
+ } else {
+ # If google changes the API response structure, warnings abound
+ warn "No location match found using google GeoCoding API for $address";
+ warn Dumper( $json_res || $res->decoded_content );
+ }
+}
+