Geolocalizzazione automatica per anagrafiche e sedi

This commit is contained in:
Beppe 2024-09-02 17:10:22 +02:00
parent caf3de5ae3
commit 306a1897d5
6 changed files with 240 additions and 102 deletions

View File

@ -53,60 +53,8 @@ switch (post('op')) {
case 'ricerca-coordinate':
foreach ($id_records as $id) {
$anagrafica = Anagrafica::find($id);
if (!empty($anagrafica->sedeLegale->indirizzo) && !empty($anagrafica->sedeLegale->citta) && !empty($anagrafica->sedeLegale->provincia)) {
$indirizzo = urlencode($anagrafica->sedeLegale->indirizzo.', '.$anagrafica->sedeLegale->citta.', '.$anagrafica->sedeLegale->provincia);
// TODO: da riscrivere con Guzzle e spostare su hook
if (!function_exists('curl_init')) {
// cURL non è attivo
flash()->error(tr('cURL non attivo, impossibile continuare l\'operazione.'));
return false;
} else {
$ch = curl_init();
}
$url = 'https://nominatim.openstreetmap.org/search.php?q='.$indirizzo.'&format=jsonv2&accept-language='.$lang;
$user_agent = 'traccar';
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = json_decode(curl_exec($ch));
curl_close($ch);
// Salvataggio informazioni
$anagrafica->gaddress = $data[0]->display_name;
$anagrafica->lat = $data[0]->lat;
$anagrafica->lng = $data[0]->lon;
$anagrafica->save();
}
}
break;
case 'ricerca-coordinate-google':
$curl = new CurlHttpAdapter();
$geocoder = new GoogleMaps($curl, 'IT-it', null, true, $google);
foreach ($id_records as $id) {
$anagrafica = Anagrafica::find($id);
if (empty($anagrafica->lat) && empty($anagrafica->lng) && !empty($anagrafica->sedeLegale->indirizzo) && !empty($anagrafica->sedeLegale->citta) && !empty($anagrafica->sedeLegale->cap)) {
$indirizzo = urlencode($anagrafica->sedeLegale->indirizzo.' '.$anagrafica->sedeLegale->citta.' '.$anagrafica->sedeLegale->cap);
try {
// Ricerca indirizzo
$address = $geocoder->geocode($indirizzo)->first();
$coordinates = $address->getCoordinates();
// Salvataggio informazioni
$anagrafica->lat = $coordinates->getLatitude();
$anagrafica->lng = $coordinates->getLongitude();
$anagrafica->save();
} catch (Exception) {
flash()->error("Impossibile recuperare le coordinate dell'anagrafica ".$anagrafica->ragione_sociale." per l'indirizzo ".$anagrafica->sedeLegale->indirizzo.' '.$anagrafica->sedeLegale->citta.' '.$anagrafica->sedeLegale->cap);
}
}
}
break;

View File

@ -0,0 +1,89 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use Modules\Anagrafiche\Anagrafica;
if (!function_exists('geolocalizzazione')) {
function geolocalizzazione($id_record, $is_sede = false)
{
$dbo = database();
if( $is_sede ){
$sede = $dbo->table('an_sedi')->where('id',$id_record)->first();
if (!empty($sede->indirizzo) && !empty($sede->citta) && !empty($sede->provincia) && empty($sede->lat) && empty($sede->lng)) {
$indirizzo = urlencode($sede->indirizzo.', '.$sede->citta.', '.$sede->provincia);
// TODO: da riscrivere con Guzzle e spostare su hook
if (!function_exists('curl_init')) {
// cURL non è attivo
flash()->error(tr('cURL non attivo, impossibile continuare l\'operazione.'));
return false;
} else {
$ch = curl_init();
}
$url = 'https://nominatim.openstreetmap.org/search.php?q='.$indirizzo.'&format=jsonv2&accept-language='.$lang;
$user_agent = 'traccar';
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = json_decode(curl_exec($ch));
curl_close($ch);
// Salvataggio informazioni
$dbo->update('an_sedi', [
'gaddress' => $data[0]->display_name,
'lat' => $data[0]->lat,
'lng' => $data[0]->lon,
],['id' => $sede->id]);
}
}else{
$anagrafica = Anagrafica::find($id_record);
if (!empty($anagrafica->sedeLegale->indirizzo) && !empty($anagrafica->sedeLegale->citta) && !empty($anagrafica->sedeLegale->provincia) && empty($anagrafica->lat) && empty($anagrafica->lng)) {
$indirizzo = urlencode($anagrafica->sedeLegale->indirizzo.', '.$anagrafica->sedeLegale->citta.', '.$anagrafica->sedeLegale->provincia);
// TODO: da riscrivere con Guzzle e spostare su hook
if (!function_exists('curl_init')) {
// cURL non è attivo
flash()->error(tr('cURL non attivo, impossibile continuare l\'operazione.'));
return false;
} else {
$ch = curl_init();
}
$url = 'https://nominatim.openstreetmap.org/search.php?q='.$indirizzo.'&format=jsonv2&accept-language='.$lang;
$user_agent = 'traccar';
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = json_decode(curl_exec($ch));
curl_close($ch);
// Salvataggio informazioni
$anagrafica->gaddress = $data[0]->display_name;
$anagrafica->lat = $data[0]->lat;
$anagrafica->lng = $data[0]->lon;
$anagrafica->save();
}
}
return true;
}
}

View File

@ -222,6 +222,10 @@ class Anagrafica extends Model
{
$this->fixRagioneSociale();
if( setting('Geolocalizzazione automatica') ){
$this->geolocalizzazione();
}
return parent::save($options);
}
@ -442,4 +446,47 @@ class Anagrafica extends Model
}
$this->aggiornaConto();
}
protected function geolocalizzazione()
{
if (!empty($this->sedeLegale->indirizzo) && !empty($this->sedeLegale->citta) && !empty($this->sedeLegale->provincia)) {
$indirizzo = urlencode($this->sedeLegale->indirizzo.', '.$this->sedeLegale->citta.', '.$this->sedeLegale->provincia);
if( setting('Gestore mappa')=='OpenStreetMap' ){
// TODO: da riscrivere con Guzzle e spostare su hook
if (!function_exists('curl_init')) {
// cURL non è attivo
flash()->error(tr('cURL non attivo, impossibile continuare l\'operazione.'));
return false;
} else {
$ch = curl_init();
}
$url = 'https://nominatim.openstreetmap.org/search.php?q='.$indirizzo.'&format=jsonv2&accept-language='.$lang;
$user_agent = 'traccar';
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = json_decode(curl_exec($ch));
curl_close($ch);
// Salvataggio informazioni
$this->gaddress = $data[0]->display_name;
$this->lat = $data[0]->lat;
$this->lng = $data[0]->lon;
}elseif( setting('Gestore mappa')=='Google Maps' ){
$apiKey = setting('Google Maps API key per Tecnici');
$url = "https://maps.googleapis.com/maps/api/geocode/json?address=".$indirizzo."&key=".$apiKey;
$response = file_get_contents($url);
$data = json_decode($response, true);
if ($data['status'] == 'OK') {
$this->lat = $data['results'][0]['geometry']['location']['lat'];
$this->lng = $data['results'][0]['geometry']['location']['lng'];
$this->gaddress = $data['results'][0]['formatted_address'];
}
}
}
}
}

View File

@ -21,6 +21,8 @@ namespace Modules\Anagrafiche;
use Common\SimpleModelTrait;
use Illuminate\Database\Eloquent\Model;
use Geocoder\Provider\GoogleMaps;
use Ivory\HttpAdapter\CurlHttpAdapter;
class Sede extends Model
{
@ -67,6 +69,10 @@ class Sede extends Model
{
$this->fixRappresentanteFiscale();
if( setting('Geolocalizzazione automatica') ){
$this->geolocalizzazione();
}
return parent::save($options);
}
@ -84,4 +90,47 @@ class Sede extends Model
$this->attributes['is_rappresentante_fiscale'] = $rappresentante_fiscale;
}
}
protected function geolocalizzazione()
{
if (!empty($this->indirizzo) && !empty($this->citta) && !empty($this->provincia) && empty($this->gaddress)) {
$indirizzo = urlencode($this->indirizzo.', '.$this->citta.', '.$this->provincia);
if( setting('Gestore mappa')=='OpenStreetMap' ){
// TODO: da riscrivere con Guzzle e spostare su hook
if (!function_exists('curl_init')) {
// cURL non è attivo
flash()->error(tr('cURL non attivo, impossibile continuare l\'operazione.'));
return false;
} else {
$ch = curl_init();
}
$url = 'https://nominatim.openstreetmap.org/search.php?q='.$indirizzo.'&format=jsonv2&accept-language='.$lang;
$user_agent = 'traccar';
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = json_decode(curl_exec($ch));
curl_close($ch);
// Salvataggio informazioni
$this->gaddress = $data[0]->display_name;
$this->lat = $data[0]->lat;
$this->lng = $data[0]->lon;
}elseif( setting('Gestore mappa')=='Google Maps' ){
$curl = new CurlHttpAdapter();
$geocoder = new GoogleMaps($curl, 'IT-it', null, true, $google);
// Ricerca indirizzo
$address = $geocoder->geocode($indirizzo)->first();
$coordinates = $address->getCoordinates();
// Salvataggio informazioni
$this->gaddress = $data[0]->display_name;
$this->lat = $coordinates->getLatitude();
$this->lng = $coordinates->getLongitude();
}
}
}
}

View File

@ -27,29 +27,29 @@ switch ($operazione) {
case 'addsede':
if (!empty(post('nomesede'))) {
$opt_out_newsletter = post('disable_newsletter_add');
$dbo->insert('an_sedi', [
'idanagrafica' => $id_parent,
'nomesede' => post('nomesede'),
'indirizzo' => post('indirizzo'),
'citta' => post('citta'),
'cap' => post('cap'),
'provincia' => strtoupper(post('provincia')),
'km' => post('km'),
'id_nazione' => !empty(post('id_nazione')) ? post('id_nazione') : null,
'idzona' => !empty(post('idzona')) ? post('idzona') : 0,
'cellulare' => post('cellulare'),
'telefono' => post('telefono'),
'email' => post('email'),
'enable_newsletter' => empty($opt_out_newsletter),
'codice_destinatario' => post('codice_destinatario'),
'is_automezzo' => post('is_automezzo_add'),
'is_rappresentante_fiscale' => post('is_rappresentante_fiscale_add'),
'targa' => post('targa'),
'nome' => post('nome'),
'descrizione' => post('descrizione'),
]);
$sede = Sede::build(Anagrafica::find($id_parent));
$id_record = $dbo->lastInsertedID();
$sede->nomesede = post('nomesede');
$sede->indirizzo = post('indirizzo');
$sede->citta = post('citta');
$sede->cap = post('cap');
$sede->provincia = strtoupper(post('provincia'));
$sede->km = post('km');
$sede->id_nazione = !empty(post('id_nazione')) ? post('id_nazione') : null;
$sede->idzona = !empty(post('idzona')) ? post('idzona') : 0;
$sede->cellulare = post('cellulare');
$sede->telefono = post('telefono');
$sede->email = post('email');
$sede->enable_newsletter = empty($opt_out_newsletter);
$sede->codice_destinatario = post('codice_destinatario');
$sede->is_automezzo = post('is_automezzo');
$sede->is_rappresentante_fiscale = post('is_rappresentante_fiscale');
$sede->targa = post('targa');
$sede->nome = post('nome');
$sede->descrizione = post('descrizione');
$sede->save();
$id_record = $sede->id;
$id_referenti = (array) post('id_referenti');
foreach ($id_referenti as $id_referente) {
@ -78,32 +78,28 @@ switch ($operazione) {
$opt_out_newsletter = post('disable_newsletter');
$sede = Sede::find($id_record);
$dbo->update('an_sedi', [
'nomesede' => post('nomesede'),
'indirizzo' => post('indirizzo'),
'citta' => post('citta'),
'cap' => post('cap'),
'provincia' => strtoupper(post('provincia')),
'id_nazione' => !empty(post('id_nazione')) ? post('id_nazione') : null,
'telefono' => post('telefono'),
'cellulare' => post('cellulare'),
'email' => post('email'),
'enable_newsletter' => empty($opt_out_newsletter),
'codice_destinatario' => post('codice_destinatario'),
'is_rappresentante_fiscale' => post('is_rappresentante_fiscale'),
'piva' => post('piva'),
'codice_fiscale' => post('codice_fiscale'),
'is_automezzo' => post('is_automezzo'),
'idzona' => post('idzona'),
'km' => post('km'),
'note' => post('note'),
'gaddress' => post('gaddress'),
'lat' => post('lat'),
'lng' => post('lng'),
'targa' => post('targa'),
'nome' => post('nome'),
'descrizione' => post('descrizione'),
], ['id' => $id_record]);
$sede->nomesede = post('nomesede');
$sede->indirizzo = post('indirizzo');
$sede->citta = post('citta');
$sede->cap = post('cap');
$sede->provincia = strtoupper(post('provincia'));
$sede->km = post('km');
$sede->id_nazione = !empty(post('id_nazione')) ? post('id_nazione') : null;
$sede->idzona = !empty(post('idzona')) ? post('idzona') : 0;
$sede->cellulare = post('cellulare');
$sede->telefono = post('telefono');
$sede->email = post('email');
$sede->enable_newsletter = empty($opt_out_newsletter);
$sede->codice_destinatario = post('codice_destinatario');
$sede->is_automezzo = post('is_automezzo');
$sede->is_rappresentante_fiscale = post('is_rappresentante_fiscale');
$sede->targa = post('targa');
$sede->nome = post('nome');
$sede->descrizione = post('descrizione');
$sede->gaddress = post('gaddress');
$sede->lat = post('lat');
$sede->lng = post('lng');
$sede->save();
$referenti = $dbo->fetchArray('SELECT id FROM an_referenti WHERE idsede = '.$id_record);
$id_referenti = (array) post('id_referenti');

View File

@ -53,3 +53,12 @@ HAVING
ORDER BY
`data` DESC,
CAST(`numero_esterno` AS UNSIGNED) DESC" WHERE `zz_modules`.`name` = 'Ordini cliente';
-- Geolocalizzazione automatica
INSERT INTO `zz_settings` (`id`, `nome`, `valore`, `tipo`, `editable`, `sezione`, `order`) VALUES
(NULL, 'Geolocalizzazione automatica', '1', 'boolean', '1', 'Anagrafiche', NULL),
(NULL, 'Gestore mappa', 'Google Maps', 'list[Google Maps, OpenStreetMap]', '1', 'Generale', NULL);
INSERT INTO `zz_settings_lang` (`id`, `id_lang`, `id_record`, `title`, `help`) VALUES (NULL, '1', (SELECT `zz_settings`.`id` FROM `zz_settings` WHERE `zz_settings`.`nome` = 'Geolocalizzazione automatica'), 'Geolocalizzazione automatica', '');
INSERT INTO `zz_settings_lang` (`id`, `id_lang`, `id_record`, `title`, `help`) VALUES (NULL, '1', (SELECT `zz_settings`.`id` FROM `zz_settings` WHERE `zz_settings`.`nome` = 'Gestore mappa'), 'Gestore mappa', '');