Skip to content

Commit 6c95730

Browse files
committed
refactor: miglioria associazione ricevute
1 parent efdf8fe commit 6c95730

4 files changed

Lines changed: 555 additions & 13 deletions

File tree

plugins/receiptFE/actions.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
include_once __DIR__.'/../../core.php';
2222

23+
use Modules\Fatture\Fattura;
2324
use Plugins\ReceiptFE\Interaction;
2425
use Plugins\ReceiptFE\Ricevuta;
2526

@@ -93,4 +94,75 @@
9394
}
9495

9596
break;
97+
98+
case 'search_fatture_elaborazione':
99+
// Cerca fatture con stato "In elaborazione" (WAIT)
100+
$fatture = Fattura::vendita()
101+
->where('codice_stato_fe', 'WAIT')
102+
->where('data_stato_fe', '>=', $_SESSION['period_start'])
103+
->orderBy('data_stato_fe', 'desc')
104+
->get();
105+
106+
$results = [];
107+
foreach ($fatture as $fattura) {
108+
$results[] = [
109+
'id' => $fattura->id,
110+
'numero_esterno' => $fattura->numero_esterno,
111+
'data' => $fattura->data,
112+
'anagrafica' => $fattura->anagrafica->ragione_sociale,
113+
'totale' => $fattura->totale,
114+
'progressivo_invio' => $fattura->progressivo_invio,
115+
];
116+
}
117+
118+
echo json_encode($results);
119+
break;
120+
121+
case 'associa_ricevuta_fattura':
122+
$name = get('name');
123+
$id_fattura = get('id_fattura');
124+
125+
try {
126+
// Verifica che la fattura esista
127+
$fattura_check = Fattura::find($id_fattura);
128+
if (!$fattura_check) {
129+
echo json_encode([
130+
'success' => false,
131+
'message' => tr('Fattura non trovata con ID: ') . $id_fattura
132+
]);
133+
break;
134+
}
135+
136+
$fattura = Ricevuta::process($name, true, $id_fattura);
137+
138+
if ($fattura) {
139+
echo json_encode([
140+
'success' => true,
141+
'file' => $name,
142+
'fattura' => $fattura,
143+
'message' => tr('Ricevuta associata correttamente alla fattura')
144+
]);
145+
} else {
146+
echo json_encode([
147+
'success' => false,
148+
'message' => tr('Errore durante l\'elaborazione della ricevuta')
149+
]);
150+
}
151+
} catch (\Exception $e) {
152+
echo json_encode([
153+
'success' => false,
154+
'message' => tr('Errore durante l\'associazione: ') . $e->getMessage()
155+
]);
156+
}
157+
break;
158+
159+
case 'get_receipt_info':
160+
$name = get('name');
161+
$progressivo_invio = Ricevuta::getProgressivoInvio($name);
162+
163+
echo json_encode([
164+
'name' => $name,
165+
'progressivo_invio' => $progressivo_invio
166+
]);
167+
break;
96168
}

plugins/receiptFE/edit.php

Lines changed: 248 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,14 @@
130130
</div>
131131
132132
<div class="col-md-3 align-items-end">
133-
<button type="button" class="btn btn-primary btn-block" onclick="upload(this)">
134-
<i class="fa fa-upload mr-1"></i> '.tr('Carica ricevuta').'
135-
</button>
133+
<div class="btn-group btn-block">
134+
<button type="button" class="btn btn-primary" onclick="upload(this)">
135+
<i class="fa fa-upload mr-1"></i> '.tr('Carica ricevuta').'
136+
</button>
137+
<button type="button" class="btn btn-info" onclick="manual_upload(this)" title="'.tr('Carica e associa manualmente').'">
138+
<i class="fa fa-link"></i>
139+
</button>
140+
</div>
136141
</div>
137142
</div>
138143
</div>
@@ -258,6 +263,41 @@ function searchReceipts(button) {
258263
$(".tip").tooltip();
259264
});
260265
}
266+
267+
function manual_upload(btn) {
268+
if ($("#blob").val()) {
269+
var restore = buttonLoading(btn);
270+
271+
// Mostra un\'animazione di caricamento
272+
$("#main_loading").show();
273+
274+
$("#upload").ajaxSubmit({
275+
url: globals.rootdir + "/actions.php",
276+
data: {
277+
op: "save",
278+
id_module: "'.$id_module.'",
279+
id_plugin: "'.$id_plugin.'",
280+
},
281+
type: "post",
282+
success: function(data){
283+
$("#main_loading").fadeOut();
284+
var result = JSON.parse(data);
285+
286+
// Mostra sempre il selettore per l\'associazione manuale
287+
showInvoiceSelector(result.file, btn, restore, result);
288+
},
289+
error: function(xhr) {
290+
$("#main_loading").fadeOut();
291+
swal("'.tr('Errore').'", xhr.responseJSON.error.message, "error");
292+
293+
buttonRestore(btn, restore);
294+
}
295+
});
296+
} else {
297+
swal("'.tr('Attenzione').'", "'.tr('Seleziona un file da caricare').'", "warning");
298+
}
299+
}
300+
261301
function upload(btn) {
262302
if ($("#blob").val()) {
263303
var restore = buttonLoading(btn);
@@ -276,7 +316,6 @@ function upload(btn) {
276316
success: function(data){
277317
$("#main_loading").fadeOut();
278318
importMessage(data);
279-
280319
buttonRestore(btn, restore);
281320
},
282321
error: function(xhr) {
@@ -347,20 +386,30 @@ function importAllReceipt(btn) {
347386
var html = "'.tr('Non sono state trovate ricevute da importare').'.";
348387
} else {
349388
var html = "'.tr('Sono state elaborate le seguenti ricevute:').'";
389+
var ricevute_non_associate = [];
350390
351391
data.forEach(function(element) {
352392
var text = "";
353393
if(element.fattura) {
354394
text += element.fattura;
355395
} else {
356-
text += "<i>'.tr('Fattura relativa alla ricevuta non rilevata. Controlla che esista una fattura di vendita corrispondente caricata a gestionale.').'</i>";
396+
text += "<i>'.tr('Fattura relativa alla ricevuta non rilevata').'</i>";
397+
ricevute_non_associate.push(element.file);
357398
}
358399
359400
text += " (" + element.file + ")";
360401
361402
html += "<small><li>" + text + "</li></small>";
362403
});
363404
405+
if (ricevute_non_associate.length > 0) {
406+
html += "<br><div class=\"alert alert-warning\"><strong>'.tr('Attenzione').':</strong> '.tr('Le seguenti ricevute non sono state associate automaticamente').':<br>";
407+
ricevute_non_associate.forEach(function(file) {
408+
html += "<small>- " + file + "</small><br>";
409+
});
410+
html += "'.tr('Puoi associarle manualmente utilizzando il pulsante di importazione per ogni singola ricevuta').'</div>";
411+
}
412+
364413
html += "<br><small>'.tr("Se si sono verificati degli errori durante la procedura e il problema continua a verificarsi, contatta l'assistenza ufficiale").'</small>";
365414
}
366415
@@ -386,4 +435,198 @@ function importAllReceipt(btn) {
386435
}
387436
});
388437
}
438+
439+
function showInvoiceSelector(receiptFile, originalButton, originalRestore, receiptData) {
440+
// Se receiptData non è fornito, ottieni le informazioni sulla ricevuta
441+
if (!receiptData) {
442+
$.ajax({
443+
url: globals.rootdir + "/actions.php",
444+
type: "get",
445+
data: {
446+
id_module: "'.$id_module.'",
447+
id_plugin: "'.$id_plugin.'",
448+
op: "get_receipt_info",
449+
name: receiptFile,
450+
},
451+
success: function(data) {
452+
var receiptInfo = JSON.parse(data);
453+
showInvoiceSelectorInternal(receiptFile, originalButton, originalRestore, receiptInfo);
454+
},
455+
error: function(xhr) {
456+
swal("'.tr('Errore').'", "'.tr('Errore nel caricamento delle informazioni della ricevuta').'", "error");
457+
buttonRestore(originalButton, originalRestore);
458+
}
459+
});
460+
} else {
461+
showInvoiceSelectorInternal(receiptFile, originalButton, originalRestore, receiptData);
462+
}
463+
}
464+
465+
function showInvoiceSelectorInternal(receiptFile, originalButton, originalRestore, receiptInfo) {
466+
467+
// Poi cerca le fatture in elaborazione
468+
$.ajax({
469+
url: globals.rootdir + "/actions.php",
470+
type: "get",
471+
data: {
472+
id_module: "'.$id_module.'",
473+
id_plugin: "'.$id_plugin.'",
474+
op: "search_fatture_elaborazione",
475+
},
476+
success: function(data) {
477+
var fatture = JSON.parse(data);
478+
479+
if (fatture.length === 0) {
480+
swal({
481+
title: "'.tr('Nessuna fattura trovata').'",
482+
html: "'.tr('Non sono state trovate fatture con stato \"In elaborazione\" da associare alla ricevuta').' <strong>" + receiptFile + "</strong>",
483+
type: "warning",
484+
});
485+
buttonRestore(originalButton, originalRestore);
486+
return;
487+
}
488+
489+
// Crea le opzioni per il select
490+
var options = "";
491+
var hasMatchingProgressivo = false;
492+
493+
fatture.forEach(function(fattura) {
494+
var isMatching = (fattura.progressivo_invio === receiptInfo.progressivo_invio && receiptInfo.progressivo_invio);
495+
var selected = isMatching ? "selected" : "";
496+
if (isMatching) hasMatchingProgressivo = true;
497+
498+
var dataFormatted = new Date(fattura.data).toLocaleDateString("it-IT");
499+
var totaleFormatted = parseFloat(fattura.totale).toLocaleString("it-IT", {
500+
style: "currency",
501+
currency: "EUR"
502+
});
503+
504+
var anagraficaTruncated = fattura.anagrafica.length > 25 ?
505+
fattura.anagrafica.substring(0, 25) + "..." : fattura.anagrafica;
506+
507+
var optionText = fattura.numero_esterno + " - " + dataFormatted + " - " + anagraficaTruncated + " - " + totaleFormatted;
508+
509+
if (fattura.progressivo_invio && fattura.progressivo_invio !== null && fattura.progressivo_invio !== "") {
510+
var progressivoShort = fattura.progressivo_invio.toString().slice(-5);
511+
optionText += " (" + progressivoShort + ")";
512+
}
513+
514+
if (isMatching) {
515+
optionText = "★ " + optionText + " ★";
516+
options += "<option value=\"" + fattura.id + "\" " + selected + " class=\"matching\">" + optionText + "</option>";
517+
} else {
518+
options += "<option value=\"" + fattura.id + "\" " + selected + ">" + optionText + "</option>";
519+
}
520+
});
521+
522+
swal({
523+
title: "'.tr('Seleziona fattura da associare').'",
524+
html: "<style>" +
525+
"#swal-fattura-select { width: 95% !important; margin: 0 auto; display: block; max-height: 200px; overflow-y: auto; }" +
526+
"#swal-fattura-select option { white-space: normal !important; word-wrap: break-word !important; padding: 8px 4px !important; line-height: 1.3 !important; height: auto !important; }" +
527+
".swal2-popup { word-wrap: break-word !important; }" +
528+
"</style>" +
529+
"<div style=\"background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 6px; padding: 12px; margin-bottom: 20px;\">" +
530+
"<div style=\"display: flex; justify-content: space-between; margin-bottom: 8px;\"><span style=\"font-weight: 600; color: #495057; font-size: 13px;\">'.tr('Ricevuta').':</span><span style=\"color: #212529; font-size: 13px; font-weight: 500;\">" + receiptFile + "</span></div>" +
531+
"<div style=\"display: flex; justify-content: space-between; margin-bottom: 8px;\"><span style=\"font-weight: 600; color: #495057; font-size: 13px;\">'.tr('Progressivo invio').':</span><span style=\"color: #212529; font-size: 13px; font-weight: 500;\">" + (receiptInfo.progressivo_invio || "'.tr('Non disponibile').'") + "</span></div>" +
532+
"</div>" +
533+
"<div style=\"margin: 15px 0;\">" +
534+
"<label style=\"display: block; margin-bottom: 8px; font-weight: 600; color: #495057; font-size: 14px;\">'.tr('Seleziona la fattura da associare').':</label>" +
535+
"<select id=\"swal-fattura-select\" class=\"form-control\">" +
536+
"<option value=\"\">'.tr('Seleziona una fattura').'...</option>" +
537+
options +
538+
"</select>" +
539+
"<div style=\"font-size: 12px; color: #6c757d; margin-top: 8px; font-style: italic; text-align: center;\">" +
540+
(hasMatchingProgressivo ? "'.tr('★ Fattura con progressivo corrispondente trovata e preselezionata').' ★" : "'.tr('Nessuna fattura con progressivo corrispondente trovata. Seleziona manualmente.').'") +
541+
"</div>" +
542+
"</div>",
543+
showCancelButton: true,
544+
confirmButtonText: "'.tr('Associa').'",
545+
cancelButtonText: "'.tr('Annulla').'",
546+
width: 600
547+
}).then(function(result) {
548+
if (result) {
549+
var selectedFattura = $("#swal-fattura-select").val();
550+
if (selectedFattura && selectedFattura !== "") {
551+
associateReceiptToInvoice(receiptFile, selectedFattura, originalButton, originalRestore);
552+
} else {
553+
swal("'.tr('Errore').'", "'.tr('Seleziona una fattura').'", "error");
554+
buttonRestore(originalButton, originalRestore);
555+
}
556+
} else {
557+
buttonRestore(originalButton, originalRestore);
558+
}
559+
}).catch(function() {
560+
buttonRestore(originalButton, originalRestore);
561+
});
562+
},
563+
error: function(xhr) {
564+
swal("'.tr('Errore').'", "'.tr('Errore nel caricamento delle fatture').'", "error");
565+
buttonRestore(originalButton, originalRestore);
566+
}
567+
});
568+
}
569+
570+
function associateReceiptToInvoice(receiptFile, fatturaId, originalButton, originalRestore) {
571+
$("#main_loading").show();
572+
573+
$.ajax({
574+
url: globals.rootdir + "/actions.php",
575+
type: "get",
576+
data: {
577+
id_module: "'.$id_module.'",
578+
id_plugin: "'.$id_plugin.'",
579+
op: "associa_ricevuta_fattura",
580+
name: receiptFile,
581+
id_fattura: fatturaId,
582+
},
583+
success: function(data) {
584+
$("#main_loading").fadeOut();
585+
586+
try {
587+
var result = JSON.parse(data);
588+
589+
if (result.success) {
590+
// Mostra messaggio di successo
591+
if(result.fattura) {
592+
var data_fattura = new Date(result.fattura.data);
593+
data_fattura = data_fattura.toLocaleDateString("it-IT", {
594+
year: "numeric",
595+
month: "2-digit",
596+
day: "2-digit"
597+
});
598+
599+
swal({
600+
title: "'.tr('Associazione completata!').'",
601+
html: "'.tr('Ricevuta associata correttamente alla fattura').': <h4>" + result.fattura.numero_esterno + " '.tr('del').' " + data_fattura + "</h4><br><h5>'.tr('Ricevuta').': " + result.file + "</h5>",
602+
type: "success",
603+
});
604+
} else {
605+
swal({
606+
title: "'.tr('Associazione completata!').'",
607+
html: result.message + "<br><h5>'.tr('Ricevuta').': " + result.file + "</h5>",
608+
type: "success",
609+
});
610+
}
611+
612+
// Ricarica la lista
613+
$("#list-receiptfe").load("'.$structure->fileurl('list.php').'?id_module='.$id_module.'&id_plugin='.$id_plugin.'", function() {
614+
start_local_datatables();
615+
});
616+
} else {
617+
swal("'.tr('Errore').'", result.message || "'.tr('Errore sconosciuto').'", "error");
618+
}
619+
} catch (e) {
620+
swal("'.tr('Errore').'", "'.tr('Errore nel parsing della risposta del server').'", "error");
621+
}
622+
623+
buttonRestore(originalButton, originalRestore);
624+
},
625+
error: function(xhr) {
626+
$("#main_loading").fadeOut();
627+
swal("'.tr('Errore').'", "'.tr('Errore durante l\'associazione').'", "error");
628+
buttonRestore(originalButton, originalRestore);
629+
}
630+
});
631+
}
389632
</script>';

0 commit comments

Comments
 (0)