Fix arrotondamenti in importFE

This commit is contained in:
valentina 2024-06-25 12:18:06 +02:00
parent 7be9848408
commit 3a3e023e2c
1 changed files with 82 additions and 56 deletions

View File

@ -84,14 +84,18 @@ class FatturaOrdinaria extends FatturaElettronica
public function getRighe() public function getRighe()
{ {
// Estraggo le linee
$linee = $this->getBody()['DatiBeniServizi']['DettaglioLinee']; $linee = $this->getBody()['DatiBeniServizi']['DettaglioLinee'];
$linee = $this->forceArray($linee); $linee = $this->forceArray($linee);
// Estraggo la cassa previdenziale
$cassa_previdenziale = $this->getBody()['DatiGenerali']['DatiGeneraliDocumento']['DatiCassaPrevidenziale']; $cassa_previdenziale = $this->getBody()['DatiGenerali']['DatiGeneraliDocumento']['DatiCassaPrevidenziale'];
$imponibile = []; $imponibile = [];
$totale_imposta = []; $totale_imposta = [];
$importo = 0; $importo = 0;
// Calcolo l'imponibile per aliquota al netto degli sconti
foreach ($linee as $linea) { foreach ($linee as $linea) {
$importo = $linea['PrezzoUnitario'] * $linea['Quantita']; $importo = $linea['PrezzoUnitario'] * $linea['Quantita'];
@ -122,22 +126,9 @@ class FatturaOrdinaria extends FatturaElettronica
$imponibile[$linea['AliquotaIVA']] += round($importo, 2); $imponibile[$linea['AliquotaIVA']] += round($importo, 2);
} }
// Aggiunta degli arrotondamenti IVA come righe indipendenti // Estraggo i riepiloghi
$riepiloghi = $this->getBody()['DatiBeniServizi']['DatiRiepilogo']; $riepiloghi = $this->getBody()['DatiBeniServizi']['DatiRiepilogo'];
$riepiloghi = $this->forceArray($riepiloghi); $riepiloghi = $this->forceArray($riepiloghi);
foreach ($riepiloghi as $riepilogo) {
$aliquota_iva = $riepilogo['AliquotaIVA'];
$imponibile[$aliquota_iva] += (float) $riepilogo['Arrotondamento'];
}
foreach ($imponibile as $aliquota_iva => $importo) {
$totale_imposta[$aliquota_iva] = $imponibile[$aliquota_iva] * $aliquota_iva / 100;
if ($cassa_previdenziale['AliquotaIVA'] == $aliquota_iva) {
$totale_imposta[$aliquota_iva] += $cassa_previdenziale['ImportoContributoCassa'] * $cassa_previdenziale['AliquotaIVA'] / 100;
}
}
$riepiloghi_raggruppati = []; $riepiloghi_raggruppati = [];
foreach ($riepiloghi as $riepilogo) { foreach ($riepiloghi as $riepilogo) {
@ -151,12 +142,20 @@ class FatturaOrdinaria extends FatturaElettronica
} }
} }
foreach ($imponibile as $aliquota_iva => $importo) {
$totale_imposta[$aliquota_iva] = $imponibile[$aliquota_iva] * $aliquota_iva / 100;
if ($cassa_previdenziale['AliquotaIVA'] == $aliquota_iva) {
$totale_imposta[$aliquota_iva] += $cassa_previdenziale['ImportoContributoCassa'] * $cassa_previdenziale['AliquotaIVA'] / 100;
}
}
// Calcolo la differenza IVA per aliquota, per creare una riga relativa all'arrotondamento IVA
foreach ($riepiloghi_raggruppati as $riepilogo) { foreach ($riepiloghi_raggruppati as $riepilogo) {
$valore = 0; $valore = 0;
$diff_iva = round((float) $riepilogo['Imposta'] - $totale_imposta[$riepilogo['AliquotaIVA']], 2); $differenza_iva = round((float) $riepilogo['Imposta'] - $totale_imposta[$riepilogo['AliquotaIVA']], 2);
if ($diff_iva) { if ($differenza_iva) {
$valore = $diff_iva * 100 / $riepilogo['AliquotaIVA']; $valore = $differenza_iva * 100 / $riepilogo['AliquotaIVA'];
} }
if ($valore != 0) { if ($valore != 0) {
@ -191,10 +190,11 @@ class FatturaOrdinaria extends FatturaElettronica
$ritenuta_contributi = !empty($fattura->id_ritenuta_contributi); $ritenuta_contributi = !empty($fattura->id_ritenuta_contributi);
$conto_arrotondamenti = null; $conto_arrotondamenti = null;
$tot_arr = 0; // Estraggo l'eventuale arrotondamento IVA applicato
$arrotondamento_iva = 0;
foreach ($righe as $riga) { foreach ($righe as $riga) {
if (str_contains((string) $riga['Descrizione'], 'Arrotondamento')) { if (str_contains((string) $riga['Descrizione'], 'Arrotondamento')) {
$tot_arr += $riga['PrezzoUnitario']; $arrotondamento_iva += round($riga['PrezzoUnitario'], 2);
} }
} }
@ -203,6 +203,54 @@ class FatturaOrdinaria extends FatturaElettronica
\Settings::setValue('Permetti il superamento della soglia quantità dei documenti di origine', 1); \Settings::setValue('Permetti il superamento della soglia quantità dei documenti di origine', 1);
// Estraggo i totali del documento
$totale_righe_riepilogo = 0;
$totale_arrotondamento_riepilogo = 0;
$totale_imponibile_riepilogo = 0;
$dati_riepilogo = $this->getBody()['DatiBeniServizi']['DatiRiepilogo'];
if (!empty($dati_riepilogo['ImponibileImporto'])) {
$totale_arrotondamento_riepilogo = $dati_riepilogo['Arrotondamento'];
$totale_imponibile_riepilogo = sum($dati_riepilogo['ImponibileImporto']);
} elseif (is_array($dati_riepilogo)) {
foreach ($dati_riepilogo as $dato) {
$totale_arrotondamento_riepilogo += $dato['Arrotondamento'];
$totale_imponibile_riepilogo += $dato['ImponibileImporto'];
}
}
// Estraggo il totale delle righe
foreach ($righe as $linea) {
$importo = $linea['PrezzoUnitario'] * $linea['Quantita'];
if ($linea['ScontoMaggiorazione']) {
$linea['ScontoMaggiorazione'] = $this->forceArray($linea['ScontoMaggiorazione']);
foreach ($linea['ScontoMaggiorazione'] as $sm) {
if (isset($sm['Percentuale'])) {
$sconto = ($importo * $sm['Percentuale'] / 100);
if ($sm['Tipo'] == 'SC') {
$importo -= $sconto;
} else {
$importo += $sconto;
}
} elseif (isset($sm['Importo'])) {
if ($sm['Tipo'] == 'SC') {
$importo -= $sm['Importo'] * $linea['Quantita'];
} else {
$importo += $sm['Importo'] * $linea['Quantita'];
}
}
}
}
if (!$linea['Quantita']) {
$importo = $linea['PrezzoUnitario'];
}
$totale_righe_riepilogo += round($importo, 2);
}
// Creazione righe
foreach ($righe as $key => $riga) { foreach ($righe as $key => $riga) {
$articolo = ArticoloOriginale::find($articoli[$key]); $articolo = ArticoloOriginale::find($articoli[$key]);
@ -302,32 +350,14 @@ class FatturaOrdinaria extends FatturaElettronica
$obj->id_rivalsa_inps = $id_rivalsa; $obj->id_rivalsa_inps = $id_rivalsa;
} }
// Totale documento
$totale_righe = 0;
$totale_arrotondamento = 0;
$totale_imp = 0;
$dati_riepilogo = $this->getBody()['DatiBeniServizi']['DatiRiepilogo'];
if (!empty($dati_riepilogo['ImponibileImporto'])) {
$totale_arrotondamento = $dati_riepilogo['Arrotondamento'];
$totale_imp = sum($dati_riepilogo['ImponibileImporto'], null, 2);
} elseif (is_array($dati_riepilogo)) {
foreach ($dati_riepilogo as $dato) {
$totale_arrotondamento += $dato['Arrotondamento'];
$totale_imp += $dato['ImponibileImporto'];
}
}
$totali_righe = array_column($righe, 'PrezzoTotale');
$tot_righe = sum($totali_righe, null, 2);
$totale_righe = round($tot_righe + $tot_arr + $totale_arrotondamento, 2);
// Nel caso il prezzo sia negativo viene gestito attraverso l'inversione della quantità (come per le note di credito) // Nel caso il prezzo sia negativo viene gestito attraverso l'inversione della quantità (come per le note di credito)
// TODO: per migliorare la visualizzazione, sarebbe da lasciare negativo il prezzo e invertire gli sconti. // TODO: per migliorare la visualizzazione, sarebbe da lasciare negativo il prezzo e invertire gli sconti.
if (!empty($articolo->um) && !empty($articolo->um_secondaria) && !empty((float) $articolo->fattore_um_secondaria) && $riga['UnitaMisura'] == $articolo->um_secondaria) { if (!empty($articolo->um) && !empty($articolo->um_secondaria) && !empty((float) $articolo->fattore_um_secondaria) && $riga['UnitaMisura'] == $articolo->um_secondaria) {
$qta = (($riga['Quantita'] ?: 1) / $articolo->fattore_um_secondaria); $qta = (($riga['Quantita'] ?: 1) / $articolo->fattore_um_secondaria);
$prezzo = $totale_righe > 0 ? $totale_righe / $qta : -($totale_righe / $qta); $prezzo = $totale_righe_riepilogo > 0 ? $totale_righe_riepilogo / $qta : -($totale_righe_riepilogo / $qta);
} else { } else {
$qta = ($riga['Quantita'] ?: 1); $qta = ($riga['Quantita'] ?: 1);
$prezzo = $totale_righe > 0 ? $riga['PrezzoUnitario'] : -$riga['PrezzoUnitario']; $prezzo = $totale_righe_riepilogo > 0 ? $riga['PrezzoUnitario'] : -$riga['PrezzoUnitario'];
} }
// Prezzo e quantità // Prezzo e quantità
@ -444,30 +474,26 @@ class FatturaOrdinaria extends FatturaElettronica
$fattura->refresh(); $fattura->refresh();
// Arrotondamenti differenti nella fattura XML // Arrotondamenti differenti nella fattura XML
$riepiloghi = $this->getBody()['DatiBeniServizi']['DatiRiepilogo']; $riepiloghi = $this->forceArray($dati_riepilogo);
$riepiloghi = $this->forceArray($riepiloghi); $imposta_riepilogo = 0;
$riep_imp = 0;
foreach ($riepiloghi as $riepilogo) { foreach ($riepiloghi as $riepilogo) {
$riep_imp += $riepilogo['Imposta']; $imposta_riepilogo += $riepilogo['Imposta'];
} }
$diff_iva = round(abs($riep_imp) - abs($fattura->iva), 2); $totale_documento = $this->getBody()['DatiGenerali']['DatiGeneraliDocumento']['ImportoTotaleDocumento'];
$diff = round(abs($fattura->totale_imponibile) - abs($totale_righe + $tot_arr), 2); $differenza_iva = round(abs($fattura->iva) - abs($imposta_riepilogo), 2);
$diff_tot = round($fattura->totale_imponibile + $fattura->rivalsa_inps - abs($totale_imp) + $tot_arr, 2); $diff = round(abs($fattura->totale_imponibile + abs($imposta_riepilogo) + $fattura->rivalsa_inps) - abs($totale_documento), 2);
$iva_arrotondamento = database()->fetchOne('SELECT * FROM `co_iva` WHERE `percentuale`= 0 AND `deleted_at` IS NULL LIMIT 1'); $iva_arrotondamento = database()->fetchOne('SELECT * FROM `co_iva` WHERE `percentuale`= 0 AND `deleted_at` IS NULL LIMIT 1');
if ($diff || $differenza_iva) {
if (($diff != 0 && $diff != $diff_tot) || (($diff_tot != $diff) && !$diff_iva) || $diff_iva) { if ($diff && $differenza_iva) {
if ($diff != 0 && $diff != $diff_tot) { $diff = abs($diff + $differenza_iva);
$diff *= 100 / (100 + $iva_arrotondamento['percentuale']); } elseif ($diff == 0 && $differenza_iva) {
} elseif (($diff == $diff_tot) && !$diff_iva) { $diff = $differenza_iva;
$diff = $totale_righe - $fattura->totale_imponibile;
} elseif (($diff == $diff_tot) && $diff_iva) {
$diff = $diff_iva;
} else { } else {
$diff = -($diff_tot * 100) / (100 + $iva_arrotondamento['percentuale']); $diff = -$diff;
} }
$obj = Riga::build($fattura); $obj = Riga::build($fattura);