Skip to content

Commit 0b22f38

Browse files
committed
refactor: migliorata la gestione di modifica iva massiva righe documenti
1 parent 9234b41 commit 0b22f38

13 files changed

Lines changed: 304 additions & 1697 deletions

File tree

include/modifica_iva.php

Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
<?php
2+
/*
3+
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
4+
* Copyright (C) DevCode s.r.l.
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
include_once __DIR__.'/../core.php';
21+
22+
// Mapping dei tipi di documento con i relativi namespace
23+
$tipo_documento = get('tipo_documento');
24+
$namespace_map = [
25+
'fatture' => 'Modules\\Fatture\\Components',
26+
'ordini' => 'Modules\\Ordini\\Components',
27+
'preventivi' => 'Modules\\Preventivi\\Components',
28+
'interventi' => 'Modules\\Interventi\\Components',
29+
'ddt' => 'Modules\\DDT\\Components',
30+
'contratti' => 'Modules\\Contratti\\Components',
31+
];
32+
33+
// Se il tipo di documento non è specificato, prova a dedurlo dal modulo corrente
34+
if (empty($tipo_documento)) {
35+
$module = Modules::get($id_module);
36+
if ($module) {
37+
$module_name = strtolower($module['name']);
38+
// Mappatura dei nomi dei moduli ai tipi di documento
39+
$module_map = [
40+
'fatture di vendita' => 'fatture',
41+
'fatture di acquisto' => 'fatture',
42+
'ordini cliente' => 'ordini',
43+
'ordini fornitore' => 'ordini',
44+
'preventivi' => 'preventivi',
45+
'interventi' => 'interventi',
46+
'ddt in entrata' => 'ddt',
47+
'ddt in uscita' => 'ddt',
48+
'contratti' => 'contratti',
49+
];
50+
$tipo_documento = $module_map[$module_name] ?? null;
51+
}
52+
}
53+
54+
// Se non è stato possibile determinare il tipo di documento, usa il default (fatture)
55+
if (empty($tipo_documento) || !isset($namespace_map[$tipo_documento])) {
56+
$tipo_documento = 'fatture';
57+
}
58+
59+
// Carica le classi appropriate
60+
$namespace = $namespace_map[$tipo_documento];
61+
$articolo_class = $namespace . '\\Articolo';
62+
$riga_class = $namespace . '\\Riga';
63+
$sconto_class = $namespace . '\\Sconto';
64+
65+
/**
66+
* Funzione helper per recuperare una riga indipendentemente dal tipo
67+
*/
68+
function getRiga($id, $riga_class, $articolo_class, $sconto_class)
69+
{
70+
$riga = $riga_class::find($id) ?: $articolo_class::find($id);
71+
return $riga ?: $sconto_class::find($id);
72+
}
73+
74+
/**
75+
* Funzione helper per costruire l'array delle informazioni sull'aliquota IVA
76+
*/
77+
function buildAliquotaArray($riga)
78+
{
79+
return [
80+
'id' => $riga->idiva,
81+
'codice' => $riga->aliquota->codice,
82+
'descrizione' => $riga->aliquota->getTranslation('title'),
83+
'percentuale' => $riga->aliquota->percentuale,
84+
'count' => 0,
85+
];
86+
}
87+
88+
// Recupero le righe selezionate
89+
$riga_id = get('riga_id');
90+
$righe_ids = sanitizeRighe($_GET['righe'] ?? '');
91+
92+
// Array per memorizzare le aliquote IVA distinte
93+
$aliquote_iva = [];
94+
// Array per memorizzare le righe senza aliquota IVA o con aliquota non valida
95+
$righe_senza_iva = [];
96+
// Contatore per le righe totali
97+
$righe_totali = 0;
98+
// Array degli ID delle righe processate
99+
$righe_ids_array = [];
100+
101+
if (!empty($riga_id)) {
102+
// Caso singola riga
103+
$riga = getRiga($riga_id, $riga_class, $articolo_class, $sconto_class);
104+
$righe_totali = 1;
105+
$righe_ids_array = [$riga_id];
106+
107+
if (!empty($riga) && !empty($riga->idiva) && !empty($riga->aliquota)) {
108+
$aliquota = buildAliquotaArray($riga);
109+
$aliquota['count'] = 1;
110+
$aliquote_iva[$riga->idiva] = $aliquota;
111+
} elseif (!empty($riga)) {
112+
$righe_senza_iva[] = [
113+
'id' => $riga->id,
114+
'descrizione' => $riga->descrizione,
115+
'idiva' => $riga->idiva ?: 'N/D',
116+
];
117+
}
118+
} elseif (!empty($righe_ids)) {
119+
// Caso multiple righe
120+
$righe_ids_array = explode(',', (string) $righe_ids);
121+
$righe_totali = count($righe_ids_array);
122+
123+
foreach ($righe_ids_array as $id_riga) {
124+
$riga = getRiga($id_riga, $riga_class, $articolo_class, $sconto_class);
125+
126+
if (!empty($riga) && !empty($riga->idiva) && !empty($riga->aliquota)) {
127+
if (!isset($aliquote_iva[$riga->idiva])) {
128+
$aliquote_iva[$riga->idiva] = buildAliquotaArray($riga);
129+
}
130+
++$aliquote_iva[$riga->idiva]['count'];
131+
} elseif (!empty($riga)) {
132+
$righe_senza_iva[] = [
133+
'id' => $riga->id,
134+
'descrizione' => $riga->descrizione,
135+
'idiva' => $riga->idiva ?: 'N/D',
136+
];
137+
}
138+
}
139+
}
140+
141+
// Determina se mostrare il form
142+
$show_form = count($aliquote_iva) > 0 || count($righe_senza_iva) > 0 || !empty($righe_ids_array);
143+
$multiple_aliquote = count($aliquote_iva) > 1;
144+
?>
145+
146+
<form id="modifica-iva-form">
147+
<?php if ($show_form) { ?>
148+
<div class="row">
149+
<div class="col-md-5">
150+
<div class="alert alert-info">
151+
<p><strong><?php echo tr('Aliquote IVA attuali'); ?></strong></p>
152+
153+
<?php if (count($aliquote_iva) > 0) { ?>
154+
<ul class="list-unstyled">
155+
<?php foreach ($aliquote_iva as $aliquota) { ?>
156+
<li>
157+
<strong><?php echo $aliquota['codice']; ?></strong> - <?php echo $aliquota['descrizione']; ?> (<?php echo $aliquota['percentuale']; ?>%)
158+
<?php if ($multiple_aliquote) { ?>
159+
<span class="badge"><?php echo $aliquota['count']; ?> <?php echo tr('righe'); ?></span>
160+
<?php } ?>
161+
</li>
162+
<?php } ?>
163+
</ul>
164+
<?php } ?>
165+
166+
<?php if (count($righe_senza_iva) > 0) { ?>
167+
<p><strong><?php echo tr('Righe senza aliquota IVA valida'); ?>:</strong> <span class="badge"><?php echo count($righe_senza_iva); ?></span></p>
168+
<?php } ?>
169+
170+
<?php if ($righe_totali > 0) { ?>
171+
<p class="text-muted"><?php echo tr('Totale righe selezionate'); ?>: <?php echo $righe_totali; ?></p>
172+
<?php } ?>
173+
</div>
174+
</div>
175+
176+
<div class="col-md-2 text-center" style="padding-top: 30px;">
177+
<i class="fa fa-arrow-right fa-3x text-muted"></i>
178+
</div>
179+
180+
<div class="col-md-5">
181+
<div class="panel panel-success">
182+
<div class="panel-heading">
183+
<h4 class="panel-title"><?php echo tr('Aliquota da applicare'); ?></h4>
184+
</div>
185+
<div class="panel-body">
186+
{[ "type": "select", "label": "", "name": "iva_id", "required": 1, "ajax-source": "iva" ]}
187+
<input type="hidden" name="riga_id" value="<?php echo get('riga_id'); ?>">
188+
<input type="hidden" name="righe" value="<?php echo htmlspecialchars($righe_ids, ENT_QUOTES, 'UTF-8'); ?>">
189+
</div>
190+
</div>
191+
</div>
192+
</div>
193+
<?php } else { ?>
194+
<div class="row">
195+
<div class="col-md-12">
196+
<div class="alert alert-warning">
197+
<p><?php echo tr('Nessuna riga selezionata'); ?></p>
198+
</div>
199+
</div>
200+
</div>
201+
<?php } ?>
202+
203+
<!-- PULSANTI -->
204+
<div class="row">
205+
<div class="col-md-12 text-right">
206+
<button type="button" class="btn btn-primary" onclick="salvaIva()">
207+
<i class="fa fa-save"></i> <?php echo tr('Salva'); ?>
208+
</button>
209+
</div>
210+
</div>
211+
</form>
212+
213+
<script>
214+
// Inizializzazione dei select AJAX quando il modal viene caricato
215+
$(document).ready(function() {
216+
initializeAjaxSelects();
217+
});
218+
219+
// Inizializzazione quando il modal viene mostrato
220+
$('#modals').on('shown.bs.modal', function() {
221+
initializeAjaxSelects();
222+
});
223+
224+
// Funzione per inizializzare i select AJAX
225+
function initializeAjaxSelects() {
226+
$('#modifica-iva-form select[data-source], #modifica-iva-form .superselectajax').each(function() {
227+
if (!$(this).hasClass('select2-hidden-accessible')) {
228+
$(this).addClass('superselectajax');
229+
input(this);
230+
}
231+
});
232+
}
233+
234+
function salvaIva() {
235+
var riga_id = $('#modifica-iva-form input[name=riga_id]').val();
236+
var righe = $('#modifica-iva-form input[name=righe]').val();
237+
var iva_id = input('iva_id').get();
238+
239+
var requestData = {
240+
id_module: globals.id_module,
241+
id_record: globals.id_record,
242+
iva_id: iva_id
243+
};
244+
245+
// Determina l'operazione in base al tipo di selezione
246+
if (righe) {
247+
requestData.op = "update_iva_multiple";
248+
requestData.righe = righe.split(',');
249+
} else {
250+
requestData.op = "update_iva";
251+
requestData.riga_id = riga_id;
252+
}
253+
254+
$.ajax({
255+
url: globals.rootdir + "/actions.php",
256+
type: "POST",
257+
data: requestData,
258+
success: function(response) {
259+
$('#modals > div').modal('hide');
260+
caricaRighe(riga_id || null);
261+
renderMessages();
262+
},
263+
error: function() {
264+
alert(<?php echo json_encode(tr('Errore durante il salvataggio')); ?>);
265+
}
266+
});
267+
}
268+
</script>

lib/functions.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,37 @@ function sanitizeFilename($filename)
6565
return $filename;
6666
}
6767

68+
/**
69+
* Sanitizza un parametro contenente numeri interi separati da virgola.
70+
* Rimuove eventuali caratteri non validi, accettando solo numeri interi positivi.
71+
*
72+
* @param string $righe Stringa con numeri interi separati da virgola
73+
*
74+
* @since 2.5
75+
*
76+
* @return string Stringa sanitizzata con solo numeri interi separati da virgola
77+
*/
78+
function sanitizeRighe($righe)
79+
{
80+
if (empty($righe)) {
81+
return '';
82+
}
83+
84+
// Dividi la stringa per virgole e filtra solo i numeri interi validi
85+
$righe_array = explode(',', (string) $righe);
86+
$righe_sanitizzate = [];
87+
88+
foreach ($righe_array as $riga) {
89+
$riga = trim($riga);
90+
// Verifica che sia un numero intero positivo
91+
if (ctype_digit($riga) && $riga !== '') {
92+
$righe_sanitizzate[] = $riga;
93+
}
94+
}
95+
96+
return implode(',', $righe_sanitizzate);
97+
}
98+
6899
/**
69100
* Elimina i file indicati.
70101
*

0 commit comments

Comments
 (0)