Skip to content

Commit 07a54a3

Browse files
committed
fix: esportazione Ri.Ba. per note di credito
1 parent e5475fd commit 07a54a3

2 files changed

Lines changed: 252 additions & 2 deletions

File tree

plugins/presentazioni_bancarie/actions.php

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,101 @@
2424
$azienda = Gestore::getAzienda();
2525

2626
// Individuazione delle scadenze indicate
27-
$scadenze = Scadenza::with('documento')->whereIn('id', $id_scadenze)->get();
28-
if ($scadenze->isEmpty()) {
27+
$scadenze_originali = Scadenza::with('documento')->whereIn('id', $id_scadenze)->get();
28+
if ($scadenze_originali->isEmpty()) {
2929
echo json_encode([
3030
'files' => [],
3131
'scadenze' => [],
3232
]);
3333
}
3434

35+
// Filtro per note di credito e gestione storno
36+
$scadenze = collect();
37+
$scadenze_da_escludere = collect();
38+
$scadenze_modificate = collect(); // Mappa id_scadenza => scadenza_modificata
39+
$note_credito_escluse = collect();
40+
$fatture_stornate = collect();
41+
$storni_parziali = collect(); // Per tracciare gli storni parziali
42+
43+
foreach ($scadenze_originali as $scadenza) {
44+
$documento = $scadenza->documento;
45+
46+
// Se la scadenza non ha un documento associato, la includiamo
47+
if (empty($documento)) {
48+
$scadenze->push($scadenza);
49+
continue;
50+
}
51+
52+
// Se è una nota di credito, non la consideriamo per l'esportazione
53+
if ($documento->isNota()) {
54+
$note_credito_escluse->push($documento);
55+
56+
// Verifica se corrisponde all'importo della fattura originale
57+
$fattura_originale = $documento->getFatturaOriginale();
58+
if (!empty($fattura_originale)) {
59+
$importo_nota = abs($documento->netto);
60+
$importo_fattura_originale = abs($fattura_originale->netto);
61+
62+
// Se gli importi corrispondono (tolleranza di 1 centesimo), escludiamo anche la fattura originale
63+
if (abs($importo_nota - $importo_fattura_originale) < 0.01) {
64+
// Trova tutte le scadenze della fattura originale e le esclude
65+
$scadenze_fattura_originale = $scadenze_originali->where('iddocumento', $fattura_originale->id);
66+
foreach ($scadenze_fattura_originale as $scad_orig) {
67+
$scadenze_da_escludere->push($scad_orig->id);
68+
}
69+
$fatture_stornate->push($fattura_originale);
70+
} else {
71+
// Importi diversi: storniamo il valore della nota di credito dalla fattura originale
72+
$scadenze_fattura_originale = $scadenze_originali->where('iddocumento', $fattura_originale->id);
73+
$importo_da_stornare = $importo_nota;
74+
75+
// Distribuiamo lo storno proporzionalmente tra le scadenze della fattura originale
76+
$totale_scadenze_originale = $scadenze_fattura_originale->sum(function($s) {
77+
return abs($s->da_pagare - $s->pagato);
78+
});
79+
80+
if ($totale_scadenze_originale > 0) {
81+
foreach ($scadenze_fattura_originale as $scad_orig) {
82+
$importo_scadenza = abs($scad_orig->da_pagare - $scad_orig->pagato);
83+
$percentuale = $importo_scadenza / $totale_scadenze_originale;
84+
$storno_scadenza = $importo_da_stornare * $percentuale;
85+
86+
// Creiamo una copia della scadenza con l'importo modificato
87+
$scadenza_modificata = clone $scad_orig;
88+
$nuovo_da_pagare = $scad_orig->da_pagare - ($scad_orig->da_pagare > 0 ? $storno_scadenza : -$storno_scadenza);
89+
$scadenza_modificata->da_pagare = $nuovo_da_pagare;
90+
91+
// Se dopo lo storno l'importo diventa zero o negativo, escludiamo la scadenza
92+
if (abs($nuovo_da_pagare - $scad_orig->pagato) < 0.01) {
93+
$scadenze_da_escludere->push($scad_orig->id);
94+
} else {
95+
// Salviamo la scadenza modificata
96+
$scadenze_modificate->put($scad_orig->id, $scadenza_modificata);
97+
}
98+
}
99+
100+
// Tracciamo lo storno parziale
101+
$storni_parziali->push([
102+
'nota_credito' => $documento,
103+
'fattura_originale' => $fattura_originale,
104+
'importo_stornato' => $importo_da_stornare
105+
]);
106+
}
107+
}
108+
}
109+
continue; // Non includiamo mai le note di credito nell'esportazione
110+
}
111+
112+
// Se non è una nota di credito e non è da escludere, la includiamo (eventualmente modificata)
113+
if (!$scadenze_da_escludere->contains($scadenza->id)) {
114+
if ($scadenze_modificate->has($scadenza->id)) {
115+
$scadenze->push($scadenze_modificate->get($scadenza->id));
116+
} else {
117+
$scadenze->push($scadenza);
118+
}
119+
}
120+
}
121+
35122
// Iterazione tra le scadenze selezionate
36123
$scadenze_completate = [];
37124
$gestori_esportazione = [];

plugins/presentazioni_bancarie/generate.php

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,171 @@
5757

5858
// Lettura delle informazioni
5959
$scadenze = $scadenze->get();
60+
61+
// Filtro per note di credito e gestione storno
62+
$scadenze_filtrate = collect();
63+
$scadenze_da_escludere = collect();
64+
$scadenze_modificate = collect(); // Mappa id_scadenza => scadenza_modificata
65+
$note_credito_escluse = collect();
66+
$fatture_stornate = collect();
67+
$storni_parziali = collect(); // Per tracciare gli storni parziali
68+
69+
// Prima passata: identifichiamo note di credito e calcoliamo storni
70+
foreach ($scadenze as $scadenza) {
71+
$documento = $scadenza->documento;
72+
73+
// Se è una nota di credito, gestiamo lo storno
74+
if (!empty($documento) && $documento->isNota()) {
75+
$note_credito_escluse->push($documento);
76+
77+
// Verifica se corrisponde all'importo della fattura originale
78+
$fattura_originale = $documento->getFatturaOriginale();
79+
if (!empty($fattura_originale)) {
80+
$importo_nota = abs($documento->netto);
81+
$importo_fattura_originale = abs($fattura_originale->netto);
82+
83+
// Se gli importi corrispondono (tolleranza di 1 centesimo), escludiamo anche la fattura originale
84+
if (abs($importo_nota - $importo_fattura_originale) < 0.01) {
85+
// Trova tutte le scadenze della fattura originale e le esclude
86+
$scadenze_fattura_originale = $scadenze->where('iddocumento', $fattura_originale->id);
87+
foreach ($scadenze_fattura_originale as $scad_orig) {
88+
$scadenze_da_escludere->push($scad_orig->id);
89+
}
90+
$fatture_stornate->push($fattura_originale);
91+
} else {
92+
// Importi diversi: storniamo il valore della nota di credito dalla fattura originale
93+
$scadenze_fattura_originale = $scadenze->where('iddocumento', $fattura_originale->id);
94+
$importo_da_stornare = $importo_nota;
95+
96+
// Distribuiamo lo storno proporzionalmente tra le scadenze della fattura originale
97+
$totale_scadenze_originale = $scadenze_fattura_originale->sum(function($s) {
98+
return abs($s->da_pagare - $s->pagato);
99+
});
100+
101+
if ($totale_scadenze_originale > 0) {
102+
foreach ($scadenze_fattura_originale as $scad_orig) {
103+
$importo_scadenza = abs($scad_orig->da_pagare - $scad_orig->pagato);
104+
$percentuale = $importo_scadenza / $totale_scadenze_originale;
105+
$storno_scadenza = $importo_da_stornare * $percentuale;
106+
107+
// Creiamo una copia della scadenza con l'importo modificato
108+
$scadenza_modificata = clone $scad_orig;
109+
$nuovo_da_pagare = $scad_orig->da_pagare - ($scad_orig->da_pagare > 0 ? $storno_scadenza : -$storno_scadenza);
110+
$scadenza_modificata->da_pagare = $nuovo_da_pagare;
111+
112+
// Se dopo lo storno l'importo diventa zero o negativo, escludiamo la scadenza
113+
if (abs($nuovo_da_pagare - $scad_orig->pagato) < 0.01) {
114+
$scadenze_da_escludere->push($scad_orig->id);
115+
} else {
116+
// Salviamo la scadenza modificata
117+
$scadenze_modificate->put($scad_orig->id, $scadenza_modificata);
118+
}
119+
}
120+
121+
// Tracciamo lo storno parziale
122+
$storni_parziali->push([
123+
'nota_credito' => $documento,
124+
'fattura_originale' => $fattura_originale,
125+
'importo_stornato' => $importo_da_stornare
126+
]);
127+
}
128+
}
129+
}
130+
continue; // Non includiamo mai le note di credito nell'esportazione
131+
}
132+
}
133+
134+
// Seconda passata: costruiamo la collezione finale
135+
foreach ($scadenze as $scadenza) {
136+
$documento = $scadenza->documento;
137+
138+
// Se la scadenza non ha un documento associato, la includiamo
139+
if (empty($documento)) {
140+
$scadenze_filtrate->push($scadenza);
141+
continue;
142+
}
143+
144+
// Saltiamo le note di credito
145+
if ($documento->isNota()) {
146+
continue;
147+
}
148+
149+
// Se non è da escludere, la includiamo (eventualmente modificata)
150+
if (!$scadenze_da_escludere->contains($scadenza->id)) {
151+
if ($scadenze_modificate->has($scadenza->id)) {
152+
$scadenze_filtrate->push($scadenze_modificate->get($scadenza->id));
153+
} else {
154+
$scadenze_filtrate->push($scadenza);
155+
}
156+
}
157+
}
158+
159+
// Rimuoviamo le scadenze da escludere dalla collezione filtrata
160+
$scadenze = $scadenze_filtrate->filter(function ($scadenza) use ($scadenze_da_escludere) {
161+
return !$scadenze_da_escludere->contains($scadenza->id);
162+
});
163+
60164
$id_scadenze = $scadenze->pluck('id');
61165

166+
// Messaggi informativi per l'utente
167+
if ($note_credito_escluse->isNotEmpty()) {
168+
echo '
169+
<div class="alert alert-info">
170+
<i class="fa fa-info-circle"></i> <strong>'.tr('Gestione Note di Credito').'</strong><br>';
171+
172+
echo tr('Sono state escluse _NUM_ note di credito dall\'esportazione', [
173+
'_NUM_' => $note_credito_escluse->count(),
174+
]).':';
175+
176+
echo '<ul>';
177+
foreach ($note_credito_escluse as $nota) {
178+
$numero_nota = $nota->numero_esterno ?: $nota->numero;
179+
echo '<li>'.tr('Nota di credito n. _NUM_ del _DATE_ - Importo: _AMOUNT_', [
180+
'_NUM_' => $numero_nota,
181+
'_DATE_' => dateFormat($nota->data),
182+
'_AMOUNT_' => moneyFormat(abs($nota->netto))
183+
]).'</li>';
184+
}
185+
echo '</ul>';
186+
187+
if ($fatture_stornate->isNotEmpty()) {
188+
echo '<strong>'.tr('Fatture completamente stornate (escluse dall\'esportazione)').':</strong>';
189+
echo '<ul>';
190+
foreach ($fatture_stornate as $fattura) {
191+
$numero_fattura = $fattura->numero_esterno ?: $fattura->numero;
192+
echo '<li>'.tr('Fattura n. _NUM_ del _DATE_ - Importo: _AMOUNT_', [
193+
'_NUM_' => $numero_fattura,
194+
'_DATE_' => dateFormat($fattura->data),
195+
'_AMOUNT_' => moneyFormat(abs($fattura->netto))
196+
]).'</li>';
197+
}
198+
echo '</ul>';
199+
}
200+
201+
if ($storni_parziali->isNotEmpty()) {
202+
echo '<strong>'.tr('Storni parziali applicati').':</strong>';
203+
echo '<ul>';
204+
foreach ($storni_parziali as $storno) {
205+
$numero_nota = $storno['nota_credito']->numero_esterno ?: $storno['nota_credito']->numero;
206+
$numero_fattura = $storno['fattura_originale']->numero_esterno ?: $storno['fattura_originale']->numero;
207+
$importo_fattura_originale = abs($storno['fattura_originale']->netto);
208+
$importo_residuo = $importo_fattura_originale - $storno['importo_stornato'];
209+
210+
echo '<li>'.tr('Fattura n. _FATTURA_ (€ _IMPORTO_FATTURA_): stornato € _IMPORTO_STORNO_ dalla nota di credito n. _NOTA_ - Residuo da esportare: € _RESIDUO_', [
211+
'_FATTURA_' => $numero_fattura,
212+
'_IMPORTO_FATTURA_' => moneyFormat($importo_fattura_originale),
213+
'_IMPORTO_STORNO_' => moneyFormat($storno['importo_stornato']),
214+
'_NOTA_' => $numero_nota,
215+
'_RESIDUO_' => moneyFormat($importo_residuo)
216+
]).'</li>';
217+
}
218+
echo '</ul>';
219+
}
220+
221+
echo '
222+
</div>';
223+
}
224+
62225
$raggruppamento = $scadenze->groupBy('idanagrafica');
63226
if ($raggruppamento->isEmpty()) {
64227
echo '

0 commit comments

Comments
 (0)