. */ use Carbon\Carbon; use Models\Module; use Modules\Fatture\Fattura; use Modules\Pagamenti\Pagamento; use Plugins\ImportFE\FatturaElettronica; use Util\XML; include_once __DIR__.'/../../core.php'; echo ' '; $skip_link = $has_next ? base_path().'/editor.php?id_module='.$id_module.'&id_plugin='.$id_plugin.'&id_record='.($id_record + 1).'&sequence='.get('sequence') : base_path().'/editor.php?id_module='.$id_module; if (empty($fattura_pa)) { if (!empty($error)) { echo '

'.tr("Errore durante l'apertura della fattura elettronica _NAME_", [ '_NAME_' => $record['name'], ]).'.

'; } elseif (!empty($imported)) { echo '

'.tr('La fattura elettronica _NAME_ è già stata importata in passato', [ '_NAME_' => $record['name'], ]).'.

'; } echo '
'; if (!empty($imported)) { echo ' '; } echo '
'; return; } // Fornitore $fornitore = $fattura_pa->getAnagrafe(); $ragione_sociale = $fornitore['ragione_sociale'] ?: $fornitore['cognome'].' '.$fornitore['nome']; $codice_fiscale = $fornitore['codice_fiscale']; $partita_iva = $fornitore['partita_iva']; $sede = $fornitore['sede']; $cap = $sede['cap']; $citta = $sede['comune']; $provincia = $sede['provincia']; // Dati generali $fattura_body = $fattura_pa->getBody(); $dati_generali = $fattura_body['DatiGenerali']['DatiGeneraliDocumento']; $tipo_documento = $database->fetchOne('SELECT CONCAT("(", `codice`, ") ", `title`) AS descrizione FROM `fe_tipi_documento` LEFT JOIN `fe_tipi_documento_lang` ON (`fe_tipi_documento_lang`.`id_record` = `fe_tipi_documento`.`codice` AND `fe_tipi_documento_lang`.`id_lang` = '.prepare(Models\Locale::getDefault()->id).') WHERE codice = '.prepare($dati_generali['TipoDocumento']))['descrizione']; // Gestione per fattura elettroniche senza pagamento definito $pagamenti = []; if (isset($fattura_body['DatiPagamento'])) { $pagamenti = $fattura_body['DatiPagamento']; $pagamenti = isset($pagamenti[0]) ? $pagamenti : [$pagamenti]; } $is_autofattura = false; if (in_array($dati_generali['TipoDocumento'], ['TD16', 'TD17', 'TD18', 'TD19', 'TD20', 'TD21', 'TD28'])) { $is_autofattura = true; } // Individuazione metodo di pagamento di base $metodi = $pagamenti[0]['DettaglioPagamento'] ?? []; $metodi = isset($metodi[0]) ? $metodi : [$metodi]; $codice_modalita_pagamento = $metodi[0]['ModalitaPagamento']; echo '

'.$ragione_sociale.' '.(empty($anagrafica) ? ''.tr('Nuova anagrafica').'' : ''.Modules::link('Anagrafiche', $anagrafica->id, '', null, '').'').'
'.(!empty($codice_fiscale) ? (tr('Codice Fiscale').': '.$codice_fiscale.'
') : '').' '.(!empty($partita_iva) ? (tr('Partita IVA').': '.$partita_iva.'
') : '').' '.$cap.' '.$citta.' ('.$provincia.')

'.$dati_generali['Numero'].' '.tr('Visualizza').'
'.$tipo_documento.'
'.Translator::dateToLocale($dati_generali['Data']).'
'.$dati_generali['Divisa'].'

'; // Blocco DatiPagamento è valorizzato (opzionale) if (!empty($pagamenti)) { echo '

'.tr('Pagamento').'

'.tr('La fattura importata presenta _NUM_ rat_E_ di pagamento con le seguenti scadenze', [ '_NUM_' => count($metodi), '_E_' => ((count($metodi) > 1) ? 'e' : 'a'), ]).':

    '; foreach ($pagamenti as $pagamento) { $rate = $pagamento['DettaglioPagamento']; $rate = isset($rate[0]) ? $rate : [$rate]; // Scadenze di pagamento foreach ($rate as $rata) { $descrizione = !empty($rata['ModalitaPagamento']) ? $database->fetchOne('SELECT `title` FROM `fe_modalita_pagamento` LEFT JOIN `fe_modalita_pagamento_lang` ON (`fe_modalita_pagamento_lang`.`id_record`=`fe_modalita_pagamento`.`codice` AND `fe_modalita_pagamento_lang`.`id_lang`='.prepare(Models\Locale::getDefault()->id).') WHERE `codice` = '.prepare($rata['ModalitaPagamento']))['descrizione'] : ''; $data = !empty($rata['DataScadenzaPagamento']) ? FatturaElettronica::parseDate($rata['DataScadenzaPagamento']) : ''; echo '
  1. '.dateFormat($data).' '.moneyFormat($rata['ImportoPagamento']).' ('.$descrizione.')
  2. '; } } echo '
'; } echo '
'; // Tipo del documento $query = "SELECT `co_tipidocumento`.`id`, CONCAT('(', `codice_tipo_documento_fe`, ') ', `title`) AS descrizione FROM `co_tipidocumento` LEFT JOIN `co_tipidocumento_lang` ON (`co_tipidocumento_lang`.`id_record` = `co_tipidocumento`.`id` AND `co_tipidocumento_lang`.`id_lang` = ".prepare(Models\Locale::getDefault()->id).") WHERE `dir` = 'uscita'"; $query_tipo = $query.' AND `codice_tipo_documento_fe` = '.prepare($dati_generali['TipoDocumento']); $numero_tipo = $database->fetchNum($query_tipo); if (!empty($numero_tipo)) { $query = $query_tipo; } $id_tipodocumento = $database->fetchOne($query_tipo)['id']; echo '
{[ "type": "select", "label": "'.tr('Tipo fattura').'", "name": "id_tipo", "required": 1, "values": "query='.$query.'", "value": "'.($numero_tipo != 1 ? $id_tipodocumento : '').'" ]}
'; // Sezionale $id_segment = $database->table('co_tipidocumento')->where('id', '=', $id_tipodocumento)->value('id_segment'); echo '
{[ "type": "select", "label": "'.tr('Sezionale').'", "name": "id_segment", "required": 1, "ajax-source": "segmenti", "select-options": '.json_encode(['id_module' => $id_module, 'is_fiscale' => 1, 'is_sezionale' => 1, 'for_fe' => 1]).', "value": "'.$id_segment.'" ]}
'; // Data di registrazione $data_registrazione = get('data_registrazione'); $data_registrazione = new Carbon($data_registrazione); echo '
{[ "type": "date", "label": "'.tr('Data di registrazione').'", "name": "data_registrazione", "required": 1, "value": "'.($data_registrazione ?: $dati_generali['Data']).'", "max-date": "-now-", "min-date": "'.$dati_generali['Data'].'" ]}
'; if (!empty($anagrafica)) { $query = "SELECT `co_documenti`.`id`, CONCAT('Fattura num. ', `co_documenti`.`numero_esterno`, ' del ', DATE_FORMAT(`co_documenti`.`data`, '%d/%m/%Y')) AS descrizione FROM `co_documenti` INNER JOIN `co_tipidocumento` ON `co_tipidocumento`.`id` = `co_documenti`.`idtipodocumento` WHERE `co_tipidocumento`.`dir` = 'uscita' AND (`co_documenti`.`data` BETWEEN NOW() - INTERVAL 1 YEAR AND NOW()) AND `co_documenti`.`idstatodocumento` IN (SELECT `id_record` FROM `co_statidocumento_lang` WHERE `title` != 'Bozza') AND `co_documenti`.`idanagrafica` = ".prepare($anagrafica->id); // Riferimenti ad altre fatture if (in_array($dati_generali['TipoDocumento'], ['TD04', 'TD05'])) { echo '
{[ "type": "select", "label": "'.tr('Fattura collegata').'", "name": "ref_fattura", "required": 0, "values": "query='.$query.'" ]}
'; } elseif ($dati_generali['TipoDocumento'] == 'TD06') { $query .= 'AND `co_documenti`.`id_segment` = (SELECT `zz_segments`.`id` FROM `zz_segments` LEFT JOIN `zz_segments_lang` ON (`zz_segments_lang`.`id_record` = `zz_segments`.`id` AND `zz_segments_lang`.`id_lang` = '.prepare(Models\Locale::getDefault()->id).") WHERE `title` = 'Fatture pro-forma' AND `id_module` = ".prepare($id_module).')'; echo '
{[ "type": "select", "label": "'.tr('Collega a fattura pro-forma').'", "name": "ref_fattura", "values": "query='.$query.'" ]}
'; } elseif ($is_autofattura) { $query = "SELECT `co_documenti`.`id`, CONCAT('Fattura num. ', `co_documenti`.`numero_esterno`, ' del ', DATE_FORMAT(`co_documenti`.`data`, '%d/%m/%Y')) AS descrizione FROM `co_documenti` INNER JOIN `co_tipidocumento` ON `co_tipidocumento`.`id` = `co_documenti`.`idtipodocumento` WHERE `co_tipidocumento`.`dir` = 'entrata' AND `co_tipidocumento`.`codice_tipo_documento_fe` IN('TD16', 'TD17', 'TD18', 'TD19', 'TD20', 'TD21', 'TD28') AND (`co_documenti`.`data` BETWEEN NOW() - INTERVAL 1 YEAR AND NOW()) AND `co_documenti`.`idstatodocumento` IN (SELECT `id_record` FROM `co_statidocumento_lang` WHERE `title` != 'Bozza') AND `co_documenti`.`idanagrafica` = ".prepare($anagrafica->id); $autofattura_collegata = Fattura::where('progressivo_invio', '=', $fattura_pa->getHeader()['DatiTrasmissione']['ProgressivoInvio'])->first(); echo '
{[ "type": "select", "label": "'.tr('Autofattura collegata').'", "name": "autofattura", "values": "query='.$query.'", "value": "'.$autofattura_collegata->id.'" ]}
'; } } echo '
'; // Pagamento $pagamento = Pagamento::where('codice_modalita_pagamento_fe', $codice_modalita_pagamento)->where('predefined', '1')->first(); echo '
{[ "type": "select", "label": "'.tr('Pagamento').'", "name": "pagamento", "required": 1, "ajax-source": "pagamenti", "select-options": '.json_encode(['codice_modalita_pagamento_fe' => $codice_modalita_pagamento]).', "value": "'.$pagamento->id.'" ]}
'; // Movimentazioni echo '
{[ "type": "checkbox", "label": "'.tr('Movimenta gli articoli').'", "name": "movimentazione", "value": "'.setting('Movimenta magazzino da fatture di acquisto').'" ]}
{[ "type": "checkbox", "label": "'.tr('Creazione automatica articoli').'", "name": "flag_crea_articoli", "value": 0, "help": "'.tr('Nel caso di righe con almeno un nodo \'CodiceArticolo\', il gestionale procede alla creazione dell\'articolo se la riga non risulta assegnata manualmente').'." ]}
{[ "type": "checkbox", "label": "'.tr('Creazione seriali').'", "name": "flag_crea_seriali", "value": "'.setting('Creazione seriali in import FE').'", "help": "'.tr('Nel caso di righe contenenti serial number, il gestionale procede alla loro registrazione. Controllare che l\'XML della fattura di acquisto contenga il nodo \'CodiceTipo\' valorizzato con \'serial\' o \'Serial\' ').'." ]}
'; $ritenuta = $dati_generali['DatiRitenuta']; if (!empty($ritenuta)) { echo '
{[ "type": "checkbox", "label": "'.tr('Ritenuta pagata dal fornitore').'", "name": "is_ritenuta_pagata", "value": 0, "help": "'.tr('Attivare se la ritenuta è stata pagata dal fornitore').'" ]}
'; } echo '
'; // Righe if (setting('Aggiorna info di acquisto') == 'Non aggiornare') { $update_info = 'update_not'; } elseif (setting('Aggiorna info di acquisto') == 'Aggiorna prezzo di listino') { $update_info = 'update_price'; } else { $update_info = 'update_all'; } $righe = $fattura_pa->getRighe(); if (!empty($righe)) { echo '

'.tr('Righe').'

'; // Dati ordini $DatiOrdini = XML::forceArray($fattura_pa->getBody()['DatiGenerali']['DatiOrdineAcquisto']); $DatiDDT = XML::forceArray($fattura_pa->getBody()['DatiGenerali']['DatiDDT']); // Riorganizzazione dati ordini per numero di riga $dati_ordini = []; foreach ($DatiOrdini as $dato) { foreach ($dato['RiferimentoNumeroLinea'] as $dati => $linea) { $dati_ordini[(int) $linea] = [ 'numero' => $dato['IdDocumento'], 'data' => (new Carbon($dato['Data']))->format('d/m/Y'), ]; } } // Riorganizzazione dati ordini per numero di riga $dati_ddt = []; foreach ($DatiDDT as $dato) { foreach ($dato['RiferimentoNumeroLinea'] as $dati => $linea) { $dati_ddt[(int) $linea] = [ 'numero' => $dato['NumeroDDT'], 'data' => (new Carbon($dato['DataDDT']))->format('d/m/Y'), ]; } } foreach ($righe as $key => $riga) { $query = "SELECT `co_iva`.`id`, IF(`codice` IS NULL, `title`, CONCAT(`codice`, ' - ', `title`)) AS descrizione FROM `co_iva` LEFT JOIN `co_iva_lang` ON (`co_iva`.`id` = `co_iva_lang`.`id_record` AND `co_iva_lang`.`id_lang` = ".prepare(Models\Locale::getDefault()->id).') WHERE `deleted_at` IS NULL AND `percentuale` = '.prepare($riga['AliquotaIVA']); $start_query = $query; if (!empty($riga['Natura'])) { $query .= ' AND `codice_natura_fe` = '.prepare($riga['Natura']); // Fallback per natura iva mancante if (empty($dbo->fetchArray($query))) { $query = $start_query; } } $query .= ' ORDER BY `descrizione` ASC'; // Visualizzazione codici articoli $codici = $riga['CodiceArticolo'] ?: []; $codici = !empty($codici) && !isset($codici[0]) ? [$codici] : $codici; $codici_articoli = []; $serial = []; $i = 0; foreach ($codici as $codice) { $codici_articoli[] = (($i == 0) ? '' : '').$codice['CodiceValore'].' ('.$codice['CodiceTipo'].')'.(($i == 0) ? '' : ''); if (str_contains((string) $codice['CodiceTipo'], 'serial') || str_contains((string) $codice['CodiceTipo'], 'Serial')) { $serial[] = $codice['CodiceValore']; } ++$i; } // Individuazione articolo con codice relativo $id_articolo = null; // Prendo il codice articolo dal primo nodo CodiceValore che trovo $codice_principale = $codici[0]['CodiceValore']; if (!empty($codice_principale)) { if (!empty($anagrafica) && empty($id_articolo)) { $id_articolo = $database->fetchOne('SELECT `id_articolo` AS id FROM `mg_fornitore_articolo` WHERE `codice_fornitore` = '.prepare($codice_principale).' AND id_fornitore = '.prepare($anagrafica->id))['id']; if (empty($id_articolo)) { $id_articolo = $database->fetchOne('SELECT `id_articolo` AS id FROM `mg_fornitore_articolo` WHERE REPLACE(`codice_fornitore`, " ", "") = '.prepare($codice_principale).' AND `id_fornitore` = '.prepare($anagrafica->id))['id']; } } if (empty($id_articolo)) { $id_articolo = $database->fetchOne('SELECT `id` FROM `mg_articoli` WHERE `codice` = '.prepare($codice_principale))['id']; if (empty($id_articolo)) { $id_articolo = $database->fetchOne('SELECT `id` FROM `mg_articoli` WHERE REPLACE(`codice`, " ", "") = '.prepare($codice_principale))['id']; } } $idconto_acquisto = $database->fetchOne('SELECT `idconto_acquisto` FROM `mg_articoli` WHERE `id` = '.prepare($id_articolo))['idconto_acquisto']; } $idconto_acquisto = $is_autofattura ? setting('Conto per autofattura') : $idconto_acquisto; $qta = $riga['Quantita']; $um = $riga['UnitaMisura']; $prezzo_unitario = $riga['PrezzoUnitario'] ?: $riga['Importo']; $is_descrizione = empty((float) $riga['Quantita']) && empty((float) $prezzo_unitario); $sconto_unitario = 0; $sconti = $riga['ScontoMaggiorazione'] ?: 0; if (!empty($sconti)) { $tot_sconto_calcolato = 0; $sconto_unitario = 0; $sconti = $sconti[0] ? $sconti : [$sconti]; // Determina il tipo di sconto in caso di sconti misti UNT e PRC foreach ($sconti as $sconto) { $tipo_sconto = !empty($sconto['Importo']) ? '€' : '%'; if (!empty($tipo) && $tipo_sconto != $tipo) { $tipo = '€'; } else { $tipo = $tipo_sconto; } } foreach ($sconti as $sconto) { $unitario = $sconto['Importo'] ?: $sconto['Percentuale']; // Sconto o Maggiorazione $sconto_riga = ($sconto['Tipo'] == 'SC') ? $unitario : -$unitario; $tipo_sconto = !empty($sconto['Importo']) ? '€' : '%'; if ($tipo_sconto == '%') { $sconto_calcolato = calcola_sconto([ 'sconto' => $sconto_riga, 'prezzo' => $sconto_unitario ? $prezzo_unitario - ($tot_sconto_calcolato / ($qta?:1)) : $prezzo_unitario, 'tipo' => 'PRC', 'qta' => $qta, ]); if ($tipo == '%') { $tot_sconto = ($prezzo_unitario * $qta != 0 ? $sconto_calcolato * 100 / ($prezzo_unitario * $qta) : 0); } else { $tot_sconto = $sconto_calcolato; } } else { $tot_sconto = $sconto_riga; } $tot_sconto_calcolato += $sconto_calcolato; $sconto_unitario += $tot_sconto; } } $riferimento_fe = ''; if ($dati_ddt[(int) $riga['NumeroLinea']]) { $riferimento_fe = tr('DDT _NUMERO_ del _DATA_', [ '_NUMERO_' => $dati_ddt[(int) $riga['NumeroLinea']]['numero'], '_DATA_' => $dati_ddt[(int) $riga['NumeroLinea']]['data'], ]); } echo ' '; if (!$is_descrizione) { echo ' '; } else { echo ' '; } } echo '
'.tr('Descrizione').' '.tr('Quantità').' '.tr('Prezzo unitario').' '.tr('Aliquota').'
'.(empty($codice_principale) ? '' : '').'
'.$riferimento_fe.' '.$riga['Descrizione'].'
'.(!empty($codici_articoli) ? ''.implode(', ', $codici_articoli).'
' : '').'
'.numberFormat($qta, 'qta').' '.$um.' '.moneyFormat($prezzo_unitario); if (abs($sconto_unitario) > 0) { $text = ($prezzo_unitario >= 0 && $sconto_unitario > 0) || ($prezzo_unitario < 0 && $sconto_unitario < 0) ? tr('sconto _TOT_ _TYPE_', ['_TOT_' => Translator::numberToLocale(abs($sconto_unitario)), '_TYPE_' => $tipo]) : tr('maggiorazione _TOT__TYPE_', ['_TOT_' => Translator::numberToLocale(abs($sconto_unitario)), '_TYPE_' => $tipo]); echo '
'.$text.''; } echo '
'.replace('_VALUE_ _DESC_', [ '_VALUE_' => empty($riga['Natura']) ? numberFormat($riga['AliquotaIVA'], 0).'%' : $riga['Natura'], '_DESC_' => $riga['RiferimentoNormativo'] ? ' - '.$riga['RiferimentoNormativo'] : '', ]).'
'.$riga['AliquotaIVA'].'
{["type": "select", "name": "articoli['.$key.']", "ajax-source": "articoli", "select-options": '.json_encode(['permetti_movimento_a_zero' => 1, 'dir' => 'entrata', 'idanagrafica' => $anagrafica ? $anagrafica->id : '']).', "icon-after": "add|'.Module::where('name', 'Articoli')->first()->id.'|codice='.($codice_principale ? urlencode((string) $codice_principale) : '').'&descrizione='.($riga['Descrizione'] ? urlencode((string) $riga['Descrizione']) : '').'&prezzo_acquisto='.($riga['PrezzoUnitario'] ? urlencode((string) $riga['PrezzoUnitario']) : '').'", "value": "'.$id_articolo.'", "label": "'.tr('Articolo').'","extra": "data-id=\''.$key.'\'" ]}
{[ "type": "select", "name": "conto['.$key.']", "id": "conto-'.$key.'", "ajax-source": "conti-acquisti", "required": 1, "label": "'.tr('Conto acquisti').'", "value": "'.$idconto_acquisto.'" ]}
{[ "type": "select", "name": "iva['.$key.']", "values": '.json_encode('query='.$query).', "required": 1, "label": "'.tr('Aliquota IVA').'" ]}

{[ "type": "select", "name": "selezione_riferimento['.$key.']", "ajax-source": "riferimenti-fe", "select-options": '.json_encode(['id_anagrafica' => $anagrafica ? $anagrafica->id : '']).', "label": "'.tr('Riferimento acquisto').'", "icon-after": '.json_encode('').', "help": "'.tr('Articoli contenuti in Ordini o DDT del Fornitore').'" ]}
{[ "type": "select", "name": "selezione_riferimento_vendita['.$key.']", "ajax-source": "riferimenti-vendita-fe", "select-options": '.json_encode(['id_articolo' => $id_articolo]).', "label": "'.tr('Riferimento vendita').'", "icon-after": '.json_encode('').', "help": "'.tr('Articoli contenuti in Ordini Cliente').'" ]}
{[ "type": "select", "name": "update_info['.$key.']", "values": "list=\"update_not\":\"Nessuna operazione\", \"update_price\":\"Crea listino del fornitore (se non presente) e aggiorna il prezzo di acquisto\", \"update_all\":\"Crea listino del fornitore (se non presente) aggiorna prezzo di acquisto e imposta fornitore come predefinito\"", "label": "'.tr('Aggiorna informazioni di acquisto').'", "value": "'.$update_info.'", "help": "'.tr('Creazione automatica articolo deve essere attiva o l\'articolo deve essere selezionato affinché questa impostazione abbia effetto').'.", "readonly": "'.(empty($codice_principale) ? 1 : 0).'" ]}
'; if (setting('Creazione seriali in import FE') && $serial) { for ($i = 0; $i < $qta; ++$i) { echo '
{[ "type": "text", "label": "'.tr('Serial').'", "name": "serial['.$key.'][]", "value": "'.$serial[$i].'" ]}
'; } } echo '
'; echo ' '; } else { echo '

'.tr('Non ci sono righe nella fattura').'.

'; } echo '
'.tr('Salta fattura').'
';