Skip to content

Commit 9604161

Browse files
committed
refactor: miglioria risoluzione conti collegati alle anagrafiche non corrispondenti alle ragioni sociali
1 parent e98d4b3 commit 9604161

4 files changed

Lines changed: 448 additions & 41 deletions

File tree

modules/aggiornamenti/actions.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,5 +185,24 @@
185185

186186
echo json_encode($result);
187187

188+
break;
189+
190+
case 'controlli-action-global':
191+
$class = post('controllo');
192+
$params = post('params');
193+
194+
// Controllo sulla classe
195+
if (!is_subclass_of($class, Controllo::class)) {
196+
echo json_encode([]);
197+
198+
return;
199+
}
200+
201+
$manager = new $class();
202+
$manager->check(); // Ricarica i risultati
203+
$result = $manager->solveGlobal($params);
204+
205+
echo json_encode($result);
206+
188207
break;
189208
}

modules/aggiornamenti/controlli.php

Lines changed: 209 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ function avviaControllo(controllo) {
138138
}
139139
140140
// Creazione pannello informativo e aggiunta righe
141-
let card = initcard(controllo, success);
141+
let card = initcard(controllo, success, records);
142142
for(const record of records) {
143143
addRiga(controllo, card, record);
144144
}
@@ -192,9 +192,10 @@ function setPercentage(percent) {
192192
*
193193
* @param controllo
194194
* @param success
195+
* @param records
195196
* @returns {*|jQuery|HTMLElement}
196197
*/
197-
function initcard(controllo, success) {
198+
function initcard(controllo, success, records) {
198199
let cssClass = "";
199200
let icon = "minus";
200201
if (success) {
@@ -205,23 +206,41 @@ function initcard(controllo, success) {
205206
let card = `<div class="card ` + cssClass + `" id="controllo-` + controllo["id"] + `">
206207
<div class="card-header with-border">
207208
<h3 class="card-title">` + controllo["name"] + `</h3>
208-
<div class="card-tools pull-right">
209+
<div class="card-tools pull-right">`;
210+
211+
// Aggiungi pulsante azione globale se il controllo lo supporta e ci sono record
212+
if (!success && records.length > 0 && hasGlobalActions(controllo)) {
213+
card += `
214+
<button type="button" class="btn btn-success btn-sm" data-controllo-id="` + controllo["id"] + `" data-controllo-class="` + controllo["class"] + `" onclick="eseguiAzioneGlobale(this)">
215+
<i class="fa fa-check-circle"></i> '.tr('Risolvi tutti i conflitti').'
216+
</button>`;
217+
}
218+
219+
card += `
209220
<button type="button" class="btn btn-tool" data-widget="collapse">
210221
<i class="fa fa-` + icon + `"></i>
211222
</button>
212223
</div>
213224
</div>`
214225
215226
if (!success) {
227+
// Verifica se ci sono opzioni per le singole righe
228+
let hasRowOptions = records.length > 0 && records[0].options && records[0].options.length > 0;
229+
216230
card += `
217231
<div class="card-body">
218232
<div class="table-responsive">
219233
<table class="table table-striped table-hover table-sm table-bordered">
220234
<thead>
221235
<tr>
222236
<th width="15%">'.tr('Record').'</th>
223-
<th>'.tr('Descrizione').'</th>
224-
<th class="text-center" width="15%">'.tr('Opzioni').'</th>
237+
<th>'.tr('Descrizione').'</th>`;
238+
239+
if (hasRowOptions) {
240+
card += `<th class="text-center" width="15%">'.tr('Opzioni').'</th>`;
241+
}
242+
243+
card += `
225244
</tr>
226245
</thead>
227246
<tbody></tbody>
@@ -244,32 +263,201 @@ function initcard(controllo, success) {
244263
*/
245264
function addRiga(controllo, card, record) {
246265
let body = card.find("tbody");
266+
let hasOptions = record.options && record.options.length > 0;
247267
248268
// Generazione riga
249269
let riga = `<tr class="` + record.type + `" id="controllo-` + controllo["id"] + `-` + record.id + `">
250270
<td>` + record.nome + `</td>
251-
<td>` + record.descrizione + `</td>
252-
<td></td>
253-
</tr>`;
271+
<td>` + record.descrizione + `</td>`;
272+
273+
if (hasOptions) {
274+
riga += `<td></td>`;
275+
}
276+
277+
riga += `</tr>`;
254278
riga = $(riga);
255279
256-
// Generazione opzioni
257-
const options_columns = riga.find("td").last();
258-
record.options.forEach(function (option, id){
259-
let button = `<button type="button" class="btn btn-` + option.color + `">
260-
<i class="` + option.icon + `"></i> ` + option.name + `
261-
</buttton>`;
262-
button = $(button);
263-
264-
button.on("click", function () {
265-
option.params.id = id;
266-
eseguiAzione(controllo, record, option.params);
280+
// Generazione opzioni solo se presenti
281+
if (hasOptions) {
282+
const options_columns = riga.find("td").last();
283+
record.options.forEach(function (option, id){
284+
let button = `<button type="button" class="btn btn-` + option.color + `">
285+
<i class="` + option.icon + `"></i> ` + option.name + `
286+
</buttton>`;
287+
button = $(button);
288+
289+
button.on("click", function () {
290+
option.params.id = id;
291+
eseguiAzione(controllo, record, option.params);
292+
});
293+
294+
options_columns.append(button);
267295
});
296+
}
297+
298+
body.append(riga);
299+
}
268300
269-
options_columns.append(button);
301+
/**
302+
* Verifica se un controllo supporta azioni globali
303+
* @param controllo
304+
* @returns {boolean}
305+
*/
306+
function hasGlobalActions(controllo) {
307+
// Lista dei controlli che supportano azioni globali
308+
const controlliConAzioniGlobali = [
309+
"Modules\\\\Aggiornamenti\\\\Controlli\\\\PianoContiRagioneSociale"
310+
];
311+
312+
return controlliConAzioniGlobali.includes(controllo["class"]);
313+
}
314+
315+
/**
316+
* Esegue un\'azione globale su tutti i record di un controllo
317+
* @param buttonElement
318+
*/
319+
function eseguiAzioneGlobale(buttonElement) {
320+
let button = $(buttonElement);
321+
let controlloId = button.data("controllo-id");
322+
let controlloClass = button.data("controllo-class");
323+
324+
// Crea modal di conferma con lo stile del gestionale
325+
let modalHtml = `
326+
<div class="modal fade" id="modal-conferma-risoluzione" tabindex="-1" role="dialog">
327+
<div class="modal-dialog modal-lg" role="document">
328+
<div class="modal-content">
329+
<div class="modal-header">
330+
<h4 class="modal-title">
331+
<i class="fa fa-exclamation-triangle text-warning"></i>
332+
'.tr('Conferma risoluzione conflitti').'
333+
</h4>
334+
<button type="button" class="close" data-dismiss="modal">
335+
<span>&times;</span>
336+
</button>
337+
</div>
338+
<div class="modal-body">
339+
<p>'.tr('Sei sicuro di voler risolvere tutti i conflitti?').'</p>
340+
<div class="alert alert-warning">
341+
<i class="fa fa-info-circle"></i>
342+
'.tr('Questa operazione:').'
343+
<ul class="mb-0 mt-2">
344+
<li>'.tr('Creerà nuovi conti per le anagrafiche con conflitti multipli').'</li>
345+
<li>'.tr('Aggiornerà i movimenti contabili collegati').'</li>
346+
<li>'.tr('Eliminerà i conti vuoti non più utilizzati').'</li>
347+
<li>'.tr('Non può essere annullata').'</li>
348+
</ul>
349+
</div>
350+
</div>
351+
<div class="modal-footer">
352+
<button type="button" class="btn btn-default" data-dismiss="modal" style="float: left;">
353+
<i class="fa fa-times"></i> '.tr('Annulla').'
354+
</button>
355+
<button type="button" class="btn btn-warning" id="conferma-risoluzione" style="float: right;">
356+
<i class="fa fa-check"></i> '.tr('Procedi').'
357+
</button>
358+
<div style="clear: both;"></div>
359+
</div>
360+
</div>
361+
</div>
362+
</div>
363+
`;
364+
365+
// Rimuovi modal esistente se presente
366+
$("#modal-conferma-risoluzione").remove();
367+
368+
// Aggiungi modal al DOM
369+
$("body").append(modalHtml);
370+
371+
// Mostra modal con configurazione per evitare chiusura accidentale
372+
$("#modal-conferma-risoluzione").modal({
373+
backdrop: "static",
374+
keyboard: false,
375+
show: true
270376
});
271377
272-
body.append(riga);
378+
// Gestisci click su conferma
379+
$("#conferma-risoluzione").on("click", function(e) {
380+
e.preventDefault();
381+
e.stopPropagation();
382+
383+
let confirmButton = $(this);
384+
let restoreConfirm = buttonLoading(confirmButton);
385+
386+
// Disabilita il pulsante di annulla durante l\'operazione
387+
$("#modal-conferma-risoluzione .btn-default").prop("disabled", true);
388+
389+
eseguiRisoluzioneGlobale(button, controlloId, controlloClass, function() {
390+
// Callback di successo: chiudi modal
391+
$("#modal-conferma-risoluzione").modal("hide");
392+
}, function() {
393+
// Callback di errore: ripristina pulsanti
394+
buttonRestore(confirmButton, restoreConfirm);
395+
$("#modal-conferma-risoluzione .btn-default").prop("disabled", false);
396+
});
397+
398+
return false;
399+
});
400+
}
401+
402+
/**
403+
* Esegue effettivamente la risoluzione globale
404+
*/
405+
function eseguiRisoluzioneGlobale(button, controlloId, controlloClass, successCallback, errorCallback) {
406+
let restore = buttonLoading(button);
407+
408+
$.ajax({
409+
url: globals.rootdir + "/actions.php",
410+
type: "POST",
411+
dataType: "JSON",
412+
data: {
413+
id_module: globals.id_module,
414+
op: "controlli-action-global",
415+
controllo: controlloClass,
416+
params: {},
417+
},
418+
success: function(results) {
419+
// Rimuovi tutte le righe del controllo
420+
$("#controllo-" + controlloId + " tbody tr").remove();
421+
422+
// Nascondi il pulsante di azione globale
423+
button.hide();
424+
425+
// Mostra messaggio di successo dettagliato
426+
let successMessage = `
427+
<div class="alert alert-success">
428+
<h4><i class="fa fa-check-circle"></i> '.tr('Risoluzione completata con successo!').'</h4>
429+
<p>'.tr('Tutti i conflitti sono stati risolti. I conti sono stati aggiornati e i movimenti contabili sono stati rigenerati.').'</p>
430+
</div>
431+
`;
432+
433+
$("#controllo-" + controlloId + " .card-body").html(successMessage);
434+
435+
buttonRestore(button, restore);
436+
437+
// Chiama il callback di successo
438+
if (typeof successCallback === "function") {
439+
successCallback();
440+
}
441+
},
442+
error: function(xhr, r, error) {
443+
let errorMessage = xhr.responseJSON && xhr.responseJSON.error ? xhr.responseJSON.error.message : error;
444+
445+
let errorHtml = `
446+
<div class="alert alert-danger">
447+
<h4><i class="fa fa-exclamation-triangle"></i> '.tr('Errore durante la risoluzione').'</h4>
448+
<p>'.tr('Si è verificato un errore').': ${errorMessage}</p>
449+
</div>
450+
`;
451+
452+
$("#controllo-" + controlloId + " .card-body").prepend(errorHtml);
453+
buttonRestore(button, restore);
454+
455+
// Chiama il callback di errore
456+
if (typeof errorCallback === "function") {
457+
errorCallback();
458+
}
459+
}
460+
});
273461
}
274462
</script>
275463

modules/aggiornamenti/src/Controlli/Controllo.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,22 @@ public function getOptions($record)
4242
return [];
4343
}
4444

45+
/**
46+
* Indica se questo controllo supporta azioni globali
47+
*/
48+
public function hasGlobalActions()
49+
{
50+
return false;
51+
}
52+
53+
/**
54+
* Restituisce le azioni globali disponibili per questo controllo
55+
*/
56+
public function getGlobalActions()
57+
{
58+
return [];
59+
}
60+
4561
abstract public function getName();
4662

4763
abstract public function getType($record);
@@ -62,5 +78,18 @@ public function solve($records, $params = [])
6278
return $results;
6379
}
6480

81+
/**
82+
* Esegue un'azione globale su tutti i record del controllo
83+
*/
84+
public function solveGlobal($params = [])
85+
{
86+
$results = [];
87+
foreach ($this->results as $record) {
88+
$results[$record['id']] = $this->execute($record, $params);
89+
}
90+
91+
return $results;
92+
}
93+
6594
abstract public function execute($records, $params = []);
6695
}

0 commit comments

Comments
 (0)