146146 <input type="hidden" name="backto" value="record-edit">
147147
148148 <!-- Fix creazione da Anagrafica -->
149- <input type="hidden" name="id_record" value="0"> ' ;
149+ <input type="hidden" name="id_record" value="0">
150+ <input type="hidden" name="idzona" id="idzona_hidden" value=" ' .$ id_zona .'"> ' ;
150151
151152if (!empty ($ id_promemoria_contratto )) {
152153 echo '<input type="hidden" name="idcontratto_riga" value=" ' .$ id_promemoria_contratto .'"> ' ;
339340
340341 <h5 class="text-primary border-bottom pb-2 mb-4"><i class="fa fa-clock-o"></i> ' .tr ('Sessioni di lavoro ' ).'</h5>
341342 <div class="row">
343+ <div class="col-md-4">
344+ {[ "type": "select", "label": " ' .tr ('Tipo attività ' ).'", "name": "idtipointervento", "value": " ' .$ id_tipo .'", "ajax-source": "tipiintervento", "help": " ' .tr ('Seleziona il tipo di attività per calcolare automaticamente la durata prevista ' ).'." ]}
345+ </div>
346+
342347 <div class="col-md-2">
343348 {[ "type": "timestamp", "label": " ' .tr ('Inizio attività ' ).'", "name": "orario_inizio", "required": ' .($ origine_dashboard ? 1 : 0 ).', "value": " ' .$ inizio_sessione .'" ]}
344349 </div>
348353 </div>
349354
350355 <div class="col-md-4">
351- {[ "type": "select", "label": " ' .tr ('Zona ' ).'", "name": "idzona ", "values ": "query=SELECT id, CONCAT_WS( \' - \ ', nome, descrizione) AS descrizione FROM an_zone ORDER BY nome" , "placeholder ": " ' .tr ( ' Nessuna zona ' ) .'", "help ": " ' . tr ( ' La zona viene definita automaticamente in base al cliente selezionato ' ). ' .", "readonly": "1", "value": " ' . $ id_zona .'" ]}
356+ {[ "type": "select", "label": " ' .tr ('Tecnico ' ).'", "name": "idtecnico ", "required ": ' .( $ origine_dashboard ? 1 : 0 ). ', "ajax-source": "tecnici" , "value ": " ' .$ id_tecnico .'", "icon-after ": "add| ' . $ id_modulo_anagrafiche . ' |tipoanagrafica=Tecnico&readonly_tipo=1|| ' .( empty ( $ id_tecnico ) ? '' : ' disabled ' ) .'" ]}
352357 </div>
358+ </div>
353359
360+ <div id="sessioni-aggiuntive"></div>
361+
362+ <div class="row mt-3">
363+ <div class="col-md-8">
364+ <div class="alert alert-info">
365+ <i class="fa fa-info-circle"></i> ' .tr ('Al clic su "Aggiungi sessione", verrà creata una nuova sessione che inizierà automaticamente alla fine della sessione precedente, utilizzando la durata prevista dal tipo di attività selezionato. ' ).'
366+ </div>
367+ </div>
354368 <div class="col-md-4">
355- {[ "type": "select", "label": " ' .tr ('Tecnici ' ).'", "multiple": "1", "name": "idtecnico[]", "required": ' .($ origine_dashboard ? 1 : 0 ).', "ajax-source": "tecnici", "value": " ' .$ id_tecnico .'", "icon-after": "add| ' .$ id_modulo_anagrafiche .'|tipoanagrafica=Tecnico&readonly_tipo=1|| ' .(empty ($ id_tecnico ) ? '' : 'disabled ' ).'" ]}
369+ <button type="button" class="btn btn-success btn-block" onclick="aggiungiNuovaSessione()">
370+ <i class="fa fa-plus"></i> ' .tr ('Aggiungi sessione ' ).'
371+ </button>
356372 </div>
357373 </div>
358374
424440 input("componenti").disable();
425441 input("idanagrafica").disable();
426442 input("idclientefinale").disable();
427- input("idzona").disable();
428443 input("idtipointervento").disable();
429444 input("idstatointervento").disable();
430445 input("data_richiesta").disable();
439454 $(document).ready(function() {
440455 input("idanagrafica").disable();
441456 input("idclientefinale").disable();
442- input("idzona").disable();
443457 input("idtipointervento").disable();
444458 });
445459</script> ' ;
@@ -563,7 +577,7 @@ function() {
563577
564578 let data = anagrafica.getData();
565579 if (data) {
566- input("idzona ").set (data.idzona ? data.idzona : "");
580+ $("#idzona_hidden ").val (data.idzona ? data.idzona : "");
567581 // session_set("superselect,idzona", $(this).selectData().idzona, 0);
568582
569583 // Impostazione del tipo intervento da anagrafica
@@ -632,7 +646,7 @@ function() {
632646
633647 let data = sede.getData();
634648 if (data) {
635- input("idzona ").set (data.idzona ? data.idzona : "");
649+ $("#idzona_hidden ").val (data.idzona ? data.idzona : "");
636650 // session_set("superselect,idzona", $(this).selectData().idzona, 0);
637651
638652 caricaMappa(data.lat, data.lng);
@@ -707,9 +721,24 @@ function() {
707721 let data = $("#idtipointervento").selectData();
708722 if (data && data.tempo_standard > 0) {
709723 let orario_inizio = input("orario_inizio").get();
710- let tempo_standard = data.tempo_standard * 60;
711- let nuovo_orario_fine = moment(orario_inizio, "DD/MM/YYYY HH:mm").add(tempo_standard, "m").format("DD/MM/YYYY HH:mm");
712- input("orario_fine").set(nuovo_orario_fine);
724+ if (orario_inizio) {
725+ let tempo_standard = data.tempo_standard * 60;
726+ let nuovo_orario_fine = moment(orario_inizio, "DD/MM/YYYY HH:mm").add(tempo_standard, "m").format("DD/MM/YYYY HH:mm");
727+ input("orario_fine").set(nuovo_orario_fine);
728+ }
729+ }
730+ });
731+
732+ // Automatismo per calcolare orario di fine quando cambia l \'orario di inizio
733+ input("orario_inizio").change(function() {
734+ let data = $("#idtipointervento").selectData();
735+ if (data && data.tempo_standard > 0) {
736+ let orario_inizio = input("orario_inizio").get();
737+ if (orario_inizio) {
738+ let tempo_standard = data.tempo_standard * 60;
739+ let nuovo_orario_fine = moment(orario_inizio, "DD/MM/YYYY HH:mm").add(tempo_standard, "m").format("DD/MM/YYYY HH:mm");
740+ input("orario_fine").set(nuovo_orario_fine);
741+ }
713742 }
714743 }); ' ;
715744
@@ -793,14 +822,18 @@ function() {
793822 }
794823
795824 function calcolaConflittiTecnici() {
796- let tecnici = input("idtecnico").get();
797-
798- return $("#info-conflitti-add").load(" ' .$ module ->fileurl ('occupazione_tecnici.php ' ).'", {
799- "id_module": globals.id_module,
800- "tecnici[]": tecnici,
801- "inizio": input("orario_inizio").get(),
802- "fine": input("orario_fine").get(),
803- });
825+ let tecnico = input("idtecnico").get();
826+
827+ if (tecnico) {
828+ return $("#info-conflitti-add").load(" ' .$ module ->fileurl ('occupazione_tecnici.php ' ).'", {
829+ "id_module": globals.id_module,
830+ "tecnici[]": [tecnico],
831+ "inizio": input("orario_inizio").get(),
832+ "fine": input("orario_fine").get(),
833+ });
834+ } else {
835+ $("#info-conflitti-add").html("");
836+ }
804837 }
805838
806839 function assegnaTuttiTecnici() {
@@ -823,6 +856,142 @@ function deassegnaTuttiTecnici() {
823856 input("tecnici_assegnati").getElement().selectReset();
824857 }
825858
859+ var sessioneCounter = 1;
860+ function aggiungiNuovaSessione() {
861+ sessioneCounter++;
862+
863+ // Calcola l \'orario di inizio della nuova sessione (fine dell \'ultima sessione)
864+ let ultimoOrarioFine = calcolaUltimoOrarioFine();
865+
866+ let nuovoOrarioFine = ""; // Sarà calcolato quando si seleziona il tipo attività
867+
868+ // Crea il HTML per la nuova sessione con le classi corrette
869+ let sessioneHtml = `
870+ <div class="row mt-3" id="sessione-${sessioneCounter}">
871+ <div class="col-md-4">
872+ {[ "type": "select", "label": " ' .tr ('Tipo attività ' ).'", "name": "sessioni[${sessioneCounter}][idtipointervento]", "ajax-source": "tipiintervento", "extra": "onchange= \\"calcolaOrarioFineSessione(${sessioneCounter}) \\"" ]}
873+ </div>
874+ <div class="col-md-2">
875+ {[ "type": "timestamp", "label": " ' .tr ('Inizio attività ' ).'", "name": "sessioni[${sessioneCounter}][orario_inizio]", "value": "", "class": "text-center", "extra": "onchange= \\"calcolaOrarioFineSessione(${sessioneCounter}) \\"" ]}
876+ </div>
877+ <div class="col-md-2">
878+ {[ "type": "timestamp", "label": " ' .tr ('Fine attività ' ).'", "name": "sessioni[${sessioneCounter}][orario_fine]", "value": "${nuovoOrarioFine}", "class": "text-center" ]}
879+ </div>
880+ <div class="col-md-3">
881+ {[ "type": "select", "label": " ' .tr ('Tecnico ' ).'", "name": "sessioni[${sessioneCounter}][idtecnico]", "ajax-source": "tecnici", "icon-after": "add| ' .$ id_modulo_anagrafiche .'|tipoanagrafica=Tecnico&readonly_tipo=1" ]}
882+ </div>
883+ <div class="col-md-1">
884+ <button type="button" class="btn btn-danger btn-block" onclick="rimuoviSessione(${sessioneCounter})" style="margin-top: 27px;">
885+ <i class="fa fa-trash"></i> ' .tr ('Elimina ' ).'
886+ </button>
887+ </div>
888+ </div>
889+ `;
890+
891+ $("#sessioni-aggiuntive").append(sessioneHtml);
892+
893+ // Reinizializza i componenti della nuova sessione
894+ init();
895+
896+ // Aggiungi gli eventi specifici per il calcolo automatico e sistema lo styling
897+ setTimeout(function() {
898+ let sessioneSelector = `#sessione-${sessioneCounter}`;
899+ let tipoSelect = $(`${sessioneSelector} select[name="sessioni[${sessioneCounter}][idtipointervento]"]`);
900+ let inizioInput = $(`${sessioneSelector} input[name="sessioni[${sessioneCounter}][orario_inizio]"]`);
901+
902+ // Imposta il valore dell \'orario di inizio dopo l \'inizializzazione
903+ if (inizioInput.length > 0) {
904+ inizioInput.val(ultimoOrarioFine);
905+ inizioInput.trigger("change");
906+ }
907+
908+ // Collega gli eventi con selettori più specifici
909+ if (tipoSelect.length > 0) {
910+ tipoSelect.on("change", function() {
911+ calcolaOrarioFineSessione(sessioneCounter);
912+ });
913+ }
914+
915+ if (inizioInput.length > 0) {
916+ inizioInput.on("dp.change change", function() {
917+ calcolaOrarioFineSessione(sessioneCounter);
918+ });
919+ }
920+
921+ // Sistema lo styling dei componenti
922+ $(`${sessioneSelector} .select2-container`).css("width", "100%");
923+ $(`${sessioneSelector} .timestamp-picker`).css("text-align", "center");
924+ }, 1000);
925+ }
926+
927+ function rimuoviSessione(id) {
928+ $("#sessione-" + id).remove();
929+
930+ // Aggiorna gli orari delle sessioni rimanenti se necessario
931+ aggiornaOrariSessioni();
932+ }
933+
934+ function calcolaOrarioFineSessione(sessioneId) {
935+ let tipoSelect = $(`select[name="sessioni[${sessioneId}][idtipointervento]"]`);
936+ let inizioInput = $(`input[name="sessioni[${sessioneId}][orario_inizio]"]`);
937+ let fineInput = $(`input[name="sessioni[${sessioneId}][orario_fine]"]`);
938+
939+ let tipoId = tipoSelect.val();
940+ let orarioInizio = inizioInput.val();
941+
942+ if (tipoId && orarioInizio) {
943+ // Ottieni i dati del tipo attività selezionato
944+ $.ajax({
945+ url: " ' .base_path ().'/ajax_select.php",
946+ type: "GET",
947+ dataType: "json",
948+ data: {
949+ op: "tipiintervento",
950+ search: "",
951+ id: tipoId
952+ },
953+ success: function(response) {
954+ if (response && response.results && response.results.length > 0) {
955+ // Trova l \'elemento con l \'ID corrispondente
956+ let tipoData = response.results.find(item => item.id == tipoId);
957+
958+ if (tipoData && tipoData.tempo_standard && tipoData.tempo_standard > 0) {
959+ let tempoStandard = parseFloat(tipoData.tempo_standard) * 60; // Converti ore in minuti
960+ let nuovoOrarioFine = moment(orarioInizio, "DD/MM/YYYY HH:mm").add(tempoStandard, "m").format("DD/MM/YYYY HH:mm");
961+
962+ fineInput.val(nuovoOrarioFine);
963+ fineInput.trigger("change");
964+ fineInput.trigger("dp.change");
965+ }
966+ }
967+ },
968+ error: function(xhr, status, error) {
969+ // Gestione errori silenziosa
970+ }
971+ });
972+ }
973+ }
974+
975+ function calcolaUltimoOrarioFine() {
976+ // Inizia con l \'orario di fine della prima sessione
977+ let ultimoOrario = input("orario_fine").get();
978+
979+ // Se non c \'è un orario di fine nella prima sessione, usa l \'orario corrente
980+ if (!ultimoOrario) {
981+ ultimoOrario = moment().format("DD/MM/YYYY HH:mm");
982+ }
983+
984+ // Controlla tutte le sessioni aggiuntive
985+ $("#sessioni-aggiuntive input[name*= \'orario_fine \']").each(function() {
986+ let orario = $(this).val();
987+ if (orario && moment(orario, "DD/MM/YYYY HH:mm").isAfter(moment(ultimoOrario, "DD/MM/YYYY HH:mm"))) {
988+ ultimoOrario = orario;
989+ }
990+ });
991+
992+ return ultimoOrario;
993+ }
994+
826995 // Gestione ricorrenza
827996 $("#ricorsiva_add").on("change", function(){
828997 if ($(this).is(":checked")) {
0 commit comments