|
57 | 57 |
|
58 | 58 | // Lettura delle informazioni |
59 | 59 | $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 | + |
60 | 164 | $id_scadenze = $scadenze->pluck('id'); |
61 | 165 |
|
| 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 | + |
62 | 225 | $raggruppamento = $scadenze->groupBy('idanagrafica'); |
63 | 226 | if ($raggruppamento->isEmpty()) { |
64 | 227 | echo ' |
|
0 commit comments