diff --git a/modules/interventi/ajax_automezzo.php b/modules/interventi/ajax_automezzo.php new file mode 100644 index 000000000..65fdced57 --- /dev/null +++ b/modules/interventi/ajax_automezzo.php @@ -0,0 +1,83 @@ +table('zz_user_sedi') + ->join('zz_users', 'zz_user_sedi.id_user', '=', 'zz_users.id') + ->join('an_sedi', 'zz_user_sedi.id_sede', '=', 'an_sedi.id') + ->where('zz_users.id_anagrafica', $id_tecnico) + ->where('an_sedi.is_automezzo', 1) + ->distinct() + ->limit(2) + ->pluck('an_sedi.id') + ->toArray(); + + echo json_encode([ + 'id_automezzo' => count($automezzi) === 1 ? reset($automezzi) : null, + ]); + exit; +} + +if ($op === 'set') { + $id_sessione = post('id_sessione'); + $id_record = post('id_record'); + $id_automezzo = post('id_automezzo') ?: null; + + if (!is_numeric($id_sessione) || !is_numeric($id_record) || (!empty($id_automezzo) && !is_numeric($id_automezzo))) { + http_response_code(422); + echo json_encode(['error' => tr('Parametri non validi')]); + exit; + } + + $sessione = database()->table('in_interventi_tecnici') + ->where('id', (int) $id_sessione) + ->where('id_intervento', (int) $id_record) + ->first(); + + if (empty($sessione)) { + http_response_code(404); + echo json_encode(['error' => tr('Sessione non trovata')]); + exit; + } + + if (!empty($id_automezzo)) { + $automezzo = database()->table('an_sedi') + ->where('id', (int) $id_automezzo) + ->where('is_automezzo', 1) + ->first(); + + if (empty($automezzo)) { + http_response_code(422); + echo json_encode(['error' => tr('Automezzo non valido')]); + exit; + } + } + + database()->table('in_interventi_tecnici') + ->where('id', (int) $id_sessione) + ->where('id_intervento', (int) $id_record) + ->update(['id_automezzo' => empty($id_automezzo) ? null : (int) $id_automezzo]); + + echo json_encode(['success' => true]); + exit; +} + +http_response_code(400); +echo json_encode(['error' => tr('Operazione non valida')]); diff --git a/modules/interventi/modals/manage_sessione.php b/modules/interventi/modals/manage_sessione.php index 43eb8dcd3..af2f639ac 100644 --- a/modules/interventi/modals/manage_sessione.php +++ b/modules/interventi/modals/manage_sessione.php @@ -41,7 +41,7 @@ '; -// Tecnico +// Tecnico, tipo attività e automezzo echo '
@@ -51,6 +51,10 @@
{[ "type": "select", "label": "'.tr('Tipo attività').'", "name": "id_tipo_interventot", "value": "'.$sessione['id_tipo_intervento'].'", "required": 1, "ajax-source": "tipiintervento-tecnico", "select-options": '.json_encode(['id_tecnico' => $sessione['id_tecnico'], 'id_intervento' => $id_record, 'id_anagrafica' => $intervento['id_anagrafica'], 'id_contratto' => $intervento['id_contratto']]).' ]}
+ +
+ {[ "type": "select", "label": "'.tr('Automezzo').'", "name": "id_automezzo", "value": "'.$sessione['id_automezzo'].'", "values": "query=SELECT `id`, `nome_sede` AS descrizione FROM `an_sedi` WHERE `is_automezzo` = 1 ORDER BY `nome_sede`" ]} +
'; $class = $show_prezzi ? '' : 'hide'; @@ -134,11 +138,12 @@ } }); - // Quando cambio il tecnico, aggiorno le select-options del tipo attività + // Quando cambio il tecnico, aggiorno tipo attività e propongo l\'automezzo assegnato. $("#id_tecnico").change(function() { var id_tecnico = $(this).val(); if (!id_tecnico) { + $("#id_automezzo").val(null).trigger("change"); return; } @@ -148,6 +153,19 @@ // Resetto e ricarico il select dei tipi di intervento $("#id_tipo_interventot").selectReset(); + + $.ajax({ + url: globals.rootdir + "/modules/interventi/ajax_automezzo.php", + type: "POST", + dataType: "json", + data: { + op: "default", + id_tecnico: id_tecnico, + }, + success: function(response) { + $("#id_automezzo").val(response.id_automezzo || null).trigger("change"); + } + }); }); // Quando cambio il tipo di intervento, aggiorno i prezzi @@ -162,6 +180,13 @@ }); }); +function chiudiSalvataggioSessione() { + renderMessages(); + $("#modals > div").modal("hide"); + caricaCosti(); + caricaTecnici(); +} + function salvaSessione() { // Validazione del form var valid = $("#add_form").parsley().validate(); @@ -169,7 +194,7 @@ function salvaSessione() { return false; } - // Invio dei dati via AJAX + // Invio dei dati standard della sessione via AJAX $("#add_form").ajaxSubmit({ url: globals.rootdir + "/actions.php", data: { @@ -179,17 +204,28 @@ function salvaSessione() { }, type: "post", success: function(response) { - renderMessages(); - - // Chiusura del modale - $("#modals > div").modal("hide"); - - // Ricaricamento dei costi - caricaCosti(); - caricaTecnici(); + // Salvataggio dell\'automezzo separato per mantenere la modifica poco invasiva sul core Interventi. + $.ajax({ + url: globals.rootdir + "/modules/interventi/ajax_automezzo.php", + type: "POST", + dataType: "json", + data: { + op: "set", + id_sessione: '.$sessione['id'].', + id_record: globals.id_record, + id_automezzo: $("#id_automezzo").val(), + }, + success: function() { + chiudiSalvataggioSessione(); + }, + error: function(xhr) { + var response = xhr.responseJSON || {}; + Swal.fire("'.tr('Errore').'", response.error || "'.tr('Errore durante il salvataggio dell’automezzo').'", "error"); + } + }); }, error: function() { - alert("'.tr('Errore durante il salvataggio').'"); + Swal.fire("'.tr('Errore').'", "'.tr('Errore durante il salvataggio della sessione').'", "error"); } }); } diff --git a/modules/interventi/src/Components/Sessione.php b/modules/interventi/src/Components/Sessione.php index ddf96630b..c402a57e9 100755 --- a/modules/interventi/src/Components/Sessione.php +++ b/modules/interventi/src/Components/Sessione.php @@ -60,6 +60,7 @@ public static function build(?Intervento $intervento = null, ?Anagrafica $anagra $model->document()->associate($intervento); $model->anagrafica()->associate($anagrafica); + $model->setAutomezzoPredefinito(); $id_tipo = $intervento['id_tipo_intervento']; $tipo_sessione = TipoSessione::find($id_tipo); @@ -148,12 +149,38 @@ public function setTecnico($id_tecnico) $anagrafica = Anagrafica::find($id_tecnico); $this->anagrafica()->associate($anagrafica); + if ($previous != $id_tecnico) { + $this->setAutomezzoPredefinito(true); + } + // Se il tecnico è cambiato, ricarico le tariffe per il tipo di intervento corrente if ($previous != $id_tecnico && !empty($this->id_tipo_intervento)) { $this->setTipo($this->id_tipo_intervento, false); } } + /** + * Propone automaticamente l'automezzo quando il tecnico ha un solo mezzo assegnato. + * In presenza di zero o più automezzi la scelta rimane manuale. + */ + public function setAutomezzoPredefinito($force = false) + { + if (!$force && !empty($this->id_automezzo)) { + return; + } + + $automezzi = database()->table('zz_user_sedi') + ->join('zz_users', 'zz_user_sedi.id_user', '=', 'zz_users.id') + ->join('an_sedi', 'zz_user_sedi.id_sede', '=', 'an_sedi.id') + ->where('zz_users.id_anagrafica', $this->id_tecnico) + ->where('an_sedi.is_automezzo', 1) + ->distinct() + ->pluck('an_sedi.id') + ->toArray(); + + $this->id_automezzo = count($automezzi) === 1 ? reset($automezzi) : null; + } + public function getOreCalcolateAttribute() { $inizio = new \DateTime($this->orario_inizio); @@ -198,6 +225,11 @@ public function anagrafica() return $this->belongsTo(Anagrafica::class, 'id_tecnico'); } + public function automezzo() + { + return $this->belongsTo(Sede::class, 'id_automezzo'); + } + public function tipo() { return $this->belongsTo(TipoSessione::class, 'id_tipo_intervento'); diff --git a/update/2_12.sql b/update/2_12.sql index 201536992..9fc80f1e2 100644 --- a/update/2_12.sql +++ b/update/2_12.sql @@ -102,3 +102,8 @@ INSERT INTO `zz_settings` (`nome`, `valore`, `tipo`, `editable`, `sezione`, `ord INSERT INTO `zz_settings_lang` (`id_lang`, `id_record`, `title`, `help`) VALUES (1, (SELECT `id` FROM `zz_settings` WHERE `nome` = 'Tipologia anagrafica predefinita'), 'Tipologia anagrafica predefinita', 'Tipologia (Azienda, Ente pubblico o Privato) preselezionata automaticamente nella finestra di aggiunta di una nuova anagrafica. Se non impostata, nessuna tipologia viene preselezionata.'), (2, (SELECT `id` FROM `zz_settings` WHERE `nome` = 'Tipologia anagrafica predefinita'), 'Default entity classification', 'Classification (Company, Public entity or Private) automatically preselected in the new entity creation window. If not set, no classification is preselected.'); + +-- Associazione automezzo alle singole sessioni delle attività (#1693) +ALTER TABLE `in_interventi_tecnici` + ADD `id_automezzo` INT NULL AFTER `id_tecnico`, + ADD INDEX `idx_in_interventi_tecnici_automezzo` (`id_automezzo`);