openstamanager/plugins/exportFE/src/FatturaElettronica.php

1854 lines
66 KiB
PHP
Raw Normal View History

2018-07-05 17:56:38 +02:00
<?php
2020-09-07 15:04:06 +02:00
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
2021-01-20 15:08:51 +01:00
* Copyright (C) DevCode s.r.l.
2020-09-07 15:04:06 +02:00
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
2018-07-05 17:56:38 +02:00
2018-11-30 15:33:25 +01:00
namespace Plugins\ExportFE;
2018-07-05 17:56:38 +02:00
2018-12-29 12:03:22 +01:00
use FluidXml\FluidXml;
use GuzzleHttp\Client;
2019-01-10 19:31:26 +01:00
use Modules\Anagrafiche\Anagrafica;
use Modules\Anagrafiche\Sede;
2023-11-27 11:18:54 +01:00
use Modules\Banche\Banca;
2019-01-10 19:31:26 +01:00
use Modules\Fatture\Fattura;
use Modules\Fatture\Gestori\Bollo;
use Modules\Iva\Aliquota;
2018-12-29 12:03:22 +01:00
use Uploads;
2018-07-05 17:56:38 +02:00
/**
* Classe per la gestione della fatturazione elettronica in XML.
*
* @since 2.4.2
*/
class FatturaElettronica
{
2019-01-10 19:31:26 +01:00
/** @var Anagrafica Informazioni sull'anagrafica Azienda */
2018-07-06 18:06:23 +02:00
protected static $azienda = [];
2018-07-05 17:56:38 +02:00
2019-01-10 19:31:26 +01:00
/** @var Anagrafica Informazioni sull'anagrafica Cliente del documento */
2018-07-06 18:06:23 +02:00
protected $cliente = [];
2019-01-10 19:31:26 +01:00
2024-01-31 14:23:46 +01:00
/** @var Fattura Informazioni sul documento */
2024-01-15 15:30:45 +01:00
protected $documento;
2019-01-10 19:31:26 +01:00
/** @var Validator Oggetto dedicato alla validazione dell'XML */
2024-01-15 15:30:45 +01:00
protected $validator;
2018-07-06 18:06:23 +02:00
2018-11-09 12:45:22 +01:00
/** @var array Contratti collegati al documento */
protected $contratti = [];
2018-11-23 12:43:45 +01:00
/** @var array Ordini di acquisto collegati al documento */
protected $ordini = [];
2018-11-09 12:45:22 +01:00
/** @var array Righe del documento */
protected $righe = [];
2018-07-06 18:06:23 +02:00
/** @var array XML della fattura */
2024-01-15 15:30:45 +01:00
protected $xml;
2018-07-05 17:56:38 +02:00
2018-12-29 12:03:22 +01:00
public function __construct($id_documento)
{
// Documento
2019-01-10 19:31:26 +01:00
$this->documento = Fattura::find($id_documento);
2018-12-29 12:03:22 +01:00
// Controllo sulla possibilità di creare la fattura elettronica
// Posso fatturare ai privati utilizzando il codice fiscale
if ($this->documento->stato->descrizione == 'Bozza') {
2024-01-15 15:30:45 +01:00
throw new \UnexpectedValueException();
2018-12-29 12:03:22 +01:00
}
}
public function __toString()
{
return $this->toXML();
2018-12-29 12:03:22 +01:00
}
/**
2019-01-10 19:31:26 +01:00
* @return bool
2018-12-29 12:03:22 +01:00
*/
public function isGenerated()
{
$documento = $this->getDocumento();
$file = $documento->getFatturaElettronica();
2018-12-29 12:03:22 +01:00
return !empty($documento['progressivo_invio']) && file_exists(base_dir().'/'.$file->filepath);
2018-12-29 12:03:22 +01:00
}
/**
* Restituisce le informazioni sull'anagrafica azienda.
*
2019-01-10 19:31:26 +01:00
* @return Anagrafica
2018-12-29 12:03:22 +01:00
*/
public static function getAzienda()
{
if (empty(static::$azienda)) {
2019-01-10 19:31:26 +01:00
static::$azienda = Anagrafica::find(setting('Azienda predefinita'));
2018-12-29 12:03:22 +01:00
}
return static::$azienda;
}
/**
* Restituisce le informazioni sull'anagrafica cliente legata al documento.
*
2019-01-10 19:31:26 +01:00
* @return Anagrafica
2018-12-29 12:03:22 +01:00
*/
public function getCliente()
{
2019-01-10 19:31:26 +01:00
return $this->getDocumento()->anagrafica;
2018-12-29 12:03:22 +01:00
}
2018-12-29 12:03:22 +01:00
/**
* Restituisce le righe del documento.
*
* @return array
*/
public function getRighe()
{
if (empty($this->righe)) {
2019-02-15 13:00:05 +01:00
$this->righe = $this->getDocumento()->getRighe();
2018-12-29 12:03:22 +01:00
}
return $this->righe;
}
/**
2019-01-22 17:16:17 +01:00
* Restituisce i contratti collegati al documento (contratti e interventi e ordini).
2018-12-29 12:03:22 +01:00
*
* @return array
*/
public function getContratti()
{
if (empty($this->contratti)) {
$documento = $this->getDocumento();
$database = database();
2019-07-22 16:13:38 +02:00
$contratti = $database->fetchArray('SELECT `id_documento_fe` AS id_documento, `num_item`, `codice_cig`, `codice_cup` FROM `co_contratti` INNER JOIN `co_righe_documenti` ON `co_righe_documenti`.`idcontratto` = `co_contratti`.`id` WHERE `co_righe_documenti`.`iddocumento` = '.prepare($documento['id']).' AND `id_documento_fe` IS NOT NULL AND `co_righe_documenti`.`idordine` = 0');
2019-01-25 11:02:36 +01:00
2019-07-22 16:13:38 +02:00
$preventivi = $database->fetchArray('SELECT `id_documento_fe` AS id_documento, `num_item`, `codice_cig`, `codice_cup` FROM `co_preventivi` INNER JOIN `co_righe_documenti` ON `co_righe_documenti`.`idpreventivo` = `co_preventivi`.`id` WHERE `co_righe_documenti`.`iddocumento` = '.prepare($documento['id']).' AND `id_documento_fe` IS NOT NULL AND `co_righe_documenti`.`idordine` = 0');
2018-12-29 12:03:22 +01:00
2019-07-22 16:13:38 +02:00
$interventi = $database->fetchArray('SELECT `id_documento_fe` AS id_documento, `num_item`, `codice_cig`, `codice_cup` FROM `in_interventi` INNER JOIN `co_righe_documenti` ON `co_righe_documenti`.`idintervento` = `in_interventi`.`id` WHERE `co_righe_documenti`.`iddocumento` = '.prepare($documento['id']).' AND `id_documento_fe` IS NOT NULL AND `co_righe_documenti`.`idcontratto` = 0 AND `co_righe_documenti`.`idpreventivo` = 0');
2019-01-25 11:02:36 +01:00
2019-07-16 09:50:43 +02:00
$dati_aggiuntivi = $documento->dati_aggiuntivi_fe;
$dati = $dati_aggiuntivi['dati_contratto'] ?: [];
2020-01-28 17:09:43 +01:00
$this->contratti = array_merge($contratti, $preventivi, $interventi, $dati);
2018-12-29 12:03:22 +01:00
}
return $this->contratti;
}
/**
* Restituisce gli ordini di acquisto collegati al documento.
*
* @return array
*/
public function getOrdiniAcquisto()
{
if (empty($this->ordini)) {
$documento = $this->getDocumento();
$database = database();
$ordini = $database->fetchArray('SELECT `or_ordini`.`numero_cliente` AS id_documento, `or_ordini`.`num_item`, `or_ordini`.`codice_cig`, `or_ordini`.`codice_cup`, `or_ordini`.`codice_commessa`, `or_ordini`.`data_cliente` AS `data`, `co_righe_documenti`.`order` AS riferimento_linea FROM `or_ordini` INNER JOIN `co_righe_documenti` ON `co_righe_documenti`.`idordine` = `or_ordini`.`id` WHERE `co_righe_documenti`.`iddocumento` = '.prepare($documento['id']));
2018-12-29 12:03:22 +01:00
2019-07-16 09:50:43 +02:00
$dati_aggiuntivi = $documento->dati_aggiuntivi_fe;
$dati = $dati_aggiuntivi['dati_ordine'] ?: [];
$this->ordini = array_merge($ordini, $dati);
2018-12-29 12:03:22 +01:00
}
return $this->ordini;
}
/**
* Restituisce i ddt collegati al documento.
*
* @return array
*/
public function getDDT()
{
if (empty($this->ddt)) {
$documento = $this->getDocumento();
$database = database();
$ddt = $database->fetchArray('SELECT `dt_ddt`.`numero_esterno` AS id_documento, `co_righe_documenti`.`order` AS riferimento_linea, `dt_ddt`.`data` FROM `dt_ddt` INNER JOIN `co_righe_documenti` ON `co_righe_documenti`.`idddt` = `dt_ddt`.`id` WHERE `co_righe_documenti`.`iddocumento` = '.prepare($documento['id']));
$dati_aggiuntivi = $documento->dati_aggiuntivi_fe;
$dati = $dati_aggiuntivi['dati_ddt'] ?: [];
$this->ddt = array_merge($ddt, $dati);
}
return $this->ddt;
}
2018-12-29 12:03:22 +01:00
/**
* Restituisce le fatture collegate al documento.
*
* @return array
*/
public function getFattureCollegate()
{
if (empty($this->fatture_collegate)) {
$documento = $this->getDocumento();
$database = database();
2019-07-16 09:50:43 +02:00
$note_accredito = $database->fetchArray('SELECT numero_esterno AS id_documento, data FROM co_documenti WHERE id='.prepare($documento['ref_documento']));
$dati_aggiuntivi = $documento->dati_aggiuntivi_fe;
$dati = $dati_aggiuntivi['dati_fatture'] ?: [];
2018-12-29 12:03:22 +01:00
2019-07-16 09:50:43 +02:00
$this->fatture_collegate = array_merge($note_accredito, $dati);
2018-12-29 12:03:22 +01:00
}
return $this->fatture_collegate;
}
/**
* Restituisce le informazioni relative al documento.
*
2019-02-15 13:00:05 +01:00
* @return Fattura
2018-12-29 12:03:22 +01:00
*/
public function getDocumento()
{
return $this->documento;
}
/**
* Restituisce lo stato di validazione interna dell'XML della fattura.
*
* @return bool
*/
public function isValid()
{
return empty($this->getErrors());
}
/**
* Restituisce l'elenco delle irregolarità interne all'XML della fattura.
*
* @return bool
*/
public function getErrors()
{
2019-01-10 19:31:26 +01:00
if (!isset($this->validator)) {
2018-12-29 12:03:22 +01:00
$this->toXML();
}
2019-01-10 19:31:26 +01:00
return $this->validator->getErrors();
2018-12-29 12:03:22 +01:00
}
/**
* Ottiene il codice destinatario a partire dal database ufficiale indicepa www.indicepa.gov.it.
*
* @throws \GuzzleHttp\Exception\GuzzleException
*
* @return string|null
*/
2018-12-29 12:03:22 +01:00
public static function PA($codice_fiscale)
{
$id = setting('Authorization ID Indice PA');
if (empty($id)) {
return null;
}
// Configurazione per localhost: CURLOPT_SSL_VERIFYPEER
2018-12-29 12:03:22 +01:00
$client = new Client(['curl' => [CURLOPT_SSL_VERIFYPEER => false]]);
$response = $client->request('POST', 'https://www.indicepa.gov.it/public-ws/WS01_SFE_CF.php', [
'form_params' => [
'AUTH_ID' => $id,
'CF' => $codice_fiscale,
],
]);
$json = json_decode($response->getBody(), true);
return isset($json['data'][0]['OU'][0]['cod_uni_ou']) ? $json['data'][0]['OU'][0]['cod_uni_ou'] : null;
}
public static function getDirectory()
{
2024-01-15 15:30:45 +01:00
return \Uploads::getDirectory(\Modules::get('Fatture di vendita')['id']);
2018-12-29 12:03:22 +01:00
}
/**
* Salva il file XML.
*
* @return string Nome del file
*/
public function save()
2018-12-29 12:03:22 +01:00
{
$this->delete();
$name = 'Fattura Elettronica';
$data = $this->getUploadData();
2018-12-29 12:03:22 +01:00
// Generazione nome XML
$filename = $this->getFilename(true);
// Rimozione allegato precedente
$precedente = $this->getDocumento()->getFatturaElettronica();
if (!empty($precedente)) {
$precedente->delete();
}
2018-12-29 12:03:22 +01:00
// Registrazione come allegato
2024-01-15 15:30:45 +01:00
\Uploads::upload($this->toXML(), array_merge($data, [
2018-12-29 12:03:22 +01:00
'name' => $name,
'original_name' => $filename,
]));
2018-12-29 12:03:22 +01:00
// Aggiornamento effettivo
2024-01-31 14:23:46 +01:00
$result=database()->update('co_documenti', [
2018-12-29 12:03:22 +01:00
'progressivo_invio' => $this->getDocumento()['progressivo_invio'],
'codice_stato_fe' => 'GEN',
'id_ricevuta_principale' => null,
'data_stato_fe' => date('Y-m-d H:i:s'),
2018-12-29 12:03:22 +01:00
], ['id' => $this->getDocumento()['id']]);
return ($result === false) ? null : $filename;
}
/**
* Rimuove la fattura generata.
*/
public function delete()
{
$previous = $this->getFilename();
$data = $this->getUploadData();
2024-01-15 15:30:45 +01:00
\Uploads::delete($previous, $data);
}
2018-12-29 12:03:22 +01:00
/**
* Restituisce il nome del file XML per la fattura elettronica.
*
* @param bool $new
2020-10-16 17:06:06 +02:00
*
2018-12-29 12:03:22 +01:00
* @return string
*/
public function getFilename($new = false)
{
if (!empty(setting('Terzo intermediario'))) {
$anagrafica = Anagrafica::find(setting('Terzo intermediario'));
} else {
$anagrafica = static::getAzienda();
}
2019-03-29 12:46:17 +01:00
$prefix = 'IT'.(!empty($anagrafica['codice_fiscale'] and ($anagrafica['codice_fiscale'] != $anagrafica['piva'])) ? $anagrafica['codice_fiscale'] : str_replace($anagrafica->nazione->iso2, '', $anagrafica['piva']));
2018-12-29 12:03:22 +01:00
if (empty($this->documento['progressivo_invio']) || !empty($new)) {
$database = database();
do {
$code = date('y').secure_random_string(3);
} while ($database->fetchNum('SELECT `id` FROM `co_documenti` WHERE `progressivo_invio` = '.prepare($code)) != 0);
// Registrazione
$this->documento['progressivo_invio'] = $code;
}
return $prefix.'_'.$this->documento['progressivo_invio'].'.xml';
}
/**
* Restituisce il codice XML della fattura elettronica.
*
* @return string
*/
public function toXML()
{
if (empty($this->xml)) {
$this->errors = [];
$cliente = $this->getCliente();
// Inizializzazione libreria per la generazione della fattura in XML
$fattura = new FluidXml(null, ['stylesheet' => 'http://www.fatturapa.gov.it/export/fatturazione/sdi/fatturapa/v1.2.1/fatturaPA_v1.2.1.xsl']);
// Generazione dell'elemento root
2020-05-20 14:07:59 +02:00
$fattura->namespace('p', 'http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2');
2018-12-29 12:03:22 +01:00
$root = $fattura->addChild('p:FatturaElettronica', true);
$rootNode = $root[0];
// Completamento dei tag
$attributes = [
'versione' => ($cliente['tipo'] == 'Ente pubblico') ? 'FPA12' : 'FPR12',
'xmlns:ds' => 'http://www.w3.org/2000/09/xmldsig#',
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
'xsi:schemaLocation' => 'http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2.1 http://www.fatturapa.gov.it/export/fatturazione/sdi/fatturapa/v1.2.1/Schema_del_file_xml_FatturaPA_versione_1.2.1.xsd',
2018-12-29 12:03:22 +01:00
];
// Attributo SistemaEmittente (max 10 caratteri)
if (empty(setting('Terzo intermediario'))) {
$attributes['SistemaEmittente'] = 'OSM';
}
2018-12-29 12:03:22 +01:00
foreach ($attributes as $key => $value) {
$rootNode->setAttribute($key, $value);
}
// Generazione della fattura elettronica
2019-01-10 19:31:26 +01:00
$this->validator = new Validator([
2018-12-29 12:03:22 +01:00
'FatturaElettronicaHeader' => static::getHeader($this),
'FatturaElettronicaBody' => static::getBody($this),
]);
2019-01-10 19:31:26 +01:00
$xml = $this->validator->validate();
2018-12-29 12:03:22 +01:00
$fattura->add($xml);
$this->xml = $fattura->__toString();
}
return $this->xml;
}
public static function controllaFattura(Fattura $fattura)
{
$database = database();
$errors = [];
// Controlli sulla fattura stessa
2019-09-23 10:48:38 +02:00
if ($fattura->stato->descrizione == 'Bozza') {
$missing = [
'state' => tr('Stato ("Emessa")'),
];
}
if (!empty($missing)) {
2024-01-15 15:30:45 +01:00
$link = \Modules::link('Fatture di vendita', $fattura->id);
$errors[] = [
'link' => $link,
'name' => tr('Fattura'),
'errors' => $missing,
];
}
// Natura obbligatoria per iva con esenzione
$iva = $database->fetchArray('SELECT * FROM `co_iva` WHERE `id` IN (SELECT idiva FROM co_righe_documenti WHERE iddocumento = '.prepare($fattura->id).') AND esente = 1');
$fields = [
'codice_natura_fe' => 'Natura IVA',
];
foreach ($iva as $data) {
$missing = [];
if (!empty($data)) {
foreach ($fields as $key => $name) {
if (empty($data[$key])) {
$missing[] = $name;
}
}
}
if (!empty($missing)) {
2024-01-15 15:30:45 +01:00
$link = \Modules::link('IVA', $data['id']);
$errors[] = [
'link' => $link,
'name' => tr('IVA _DESC_', [
'_DESC_' => $data['descrizione'],
]),
'errors' => $missing,
];
}
}
// Campi obbligatori per il pagamento
$data = $fattura->pagamento;
$fields = [
'codice_modalita_pagamento_fe' => 'Codice modalità pagamento FE',
];
$missing = [];
if (!empty($data)) {
foreach ($fields as $key => $name) {
if (empty($data[$key])) {
$missing[] = $name;
}
}
}
if (!empty($missing)) {
2024-01-15 15:30:45 +01:00
$link = \Modules::link('Pagamenti', $data['id']);
$errors[] = [
'link' => $link,
'name' => tr('Pagamento'),
'errors' => $missing,
];
}
// Campi obbligatori per l'anagrafica Azienda
$data = FatturaElettronica::getAzienda();
$fields = [
'piva' => 'Partita IVA',
// 'codice_fiscale' => 'Codice Fiscale',
'citta' => 'Città',
'indirizzo' => 'Indirizzo',
'cap' => 'C.A.P.',
'nazione' => 'Nazione',
];
$missing = [];
if (!empty($data)) {
foreach ($fields as $key => $name) {
2019-09-23 10:48:38 +02:00
if (empty($data[$key]) && !empty($name)) {
$missing[] = $name;
}
}
}
if (!empty($missing)) {
2024-01-15 15:30:45 +01:00
$link = \Modules::link('Anagrafiche', $data['id']);
$errors[] = [
'link' => $link,
'name' => tr('Anagrafica Azienda'),
'errors' => $missing,
];
}
// Campi obbligatori per l'anagrafica Cliente
$data = $fattura->anagrafica;
$fields = [
// 'piva' => 'Partita IVA',
// 'codice_fiscale' => 'Codice Fiscale',
'citta' => 'Città',
'indirizzo' => 'Indirizzo',
'cap' => 'C.A.P.',
'nazione' => 'Nazione',
];
// se privato/pa o azienda
if ($data['tipo'] == 'Privato' or $data['tipo'] == 'Ente pubblico') {
// se privato/pa chiedo obbligatoriamente codice fiscale
2021-07-20 14:55:20 +02:00
$fields['codice_fiscale'] = ($data['nazione']->iso2 == 'IT' ? 'Codice Fiscale' : '');
// se pa chiedo codice unico ufficio
$fields['codice_destinatario'] = ($data['tipo'] == 'Ente pubblico' && empty($data['codice_destinatario'])) ? 'Codice unico ufficio' : '';
} else {
// se azienda chiedo partita iva
$fields['piva'] = 'Partita IVA';
}
$missing = [];
if (!empty($data)) {
foreach ($fields as $key => $name) {
2019-09-23 10:48:38 +02:00
if (empty($data[$key]) && !empty($name)) {
$missing[] = $name;
}
}
}
if (!empty($missing)) {
2024-01-15 15:30:45 +01:00
$link = \Modules::link('Anagrafiche', $data['id']);
$errors[] = [
'link' => $link,
'name' => tr('Anagrafica Cliente'),
'errors' => $missing,
];
}
// Campi obbligatori per l'anagrafica di tipo Vettore
$id_vettore = $fattura['idvettore'];
if (!empty($id_vettore)) {
$data = Anagrafica::find($id_vettore);
$fields = [
'piva' => 'Partita IVA',
'nazione' => 'Nazione',
];
$missing = [];
if (!empty($data)) {
foreach ($fields as $key => $name) {
if (empty($data[$key]) && !empty($name)) {
$missing[] = $name;
}
}
}
if (!empty($missing)) {
2024-01-15 15:30:45 +01:00
$link = \Modules::link('Anagrafiche', $data['id']);
$errors[] = [
'link' => $link,
'name' => tr('Anagrafica Vettore'),
'errors' => $missing,
];
}
}
return $errors;
}
2018-12-29 12:03:22 +01:00
/**
* Restituisce l'array responsabile per la generazione del tag DatiTrasmission.
*
* @return array
*/
protected static function getDatiTrasmissione($fattura)
{
// Se in impostazioni ho definito un terzo intermediario (es. Aruba, Teamsystem)
if (!empty(setting('Terzo intermediario'))) {
$anagrafica = Anagrafica::find(setting('Terzo intermediario'));
} else {
$anagrafica = static::getAzienda();
}
$documento = $fattura->getDocumento();
2024-01-15 15:30:45 +01:00
// Fattura per conto terzi, la mia Azienda (fornitore) diventa il cessionario al posto del cliente
2022-07-04 10:34:49 +02:00
if ($documento['is_fattura_conto_terzi']) {
$cliente = static::getAzienda();
} else {
$cliente = $fattura->getCliente();
}
2018-12-29 12:03:22 +01:00
$sede = database()->fetchOne('SELECT `codice_destinatario` FROM `an_sedi` WHERE `id` = '.prepare($documento['idsede_destinazione']));
2022-07-04 10:34:49 +02:00
if (!empty($sede['codice_destinatario']) && empty($documento['is_fattura_conto_terzi'])) {
2019-01-10 19:31:26 +01:00
$codice_destinatario = $sede['codice_destinatario'];
} else {
$codice_destinatario = $cliente->codice_destinatario;
}
2018-12-29 12:03:22 +01:00
// Se sto fatturando ad un ente pubblico il codice destinatario di default è 99999 (sei nove), in alternativa uso 0000000 (sette zeri)
$default_code = ($cliente['tipo'] == 'Ente pubblico') ? '999999' : '0000000';
// Se il mio cliente non ha sede in Italia, il codice destinatario di default diventa (XXXXXXX) (sette X)
$default_code = ($cliente->nazione->iso2 != 'IT') ? 'XXXXXXX' : $default_code;
// Se il cliente ha sede a San Marino non ha nessun codice destinatario imposto quello dell'Ufficio tributario di San Marino
$default_code = (($cliente->nazione->iso2 == 'SM') && ($default_code == 'XXXXXXX')) ? '2R4GTO8' : $default_code;
2018-12-29 12:03:22 +01:00
// Generazione dell'header
2019-02-13 17:49:01 +01:00
// Se all'Anagrafe Tributaria il trasmittente è censito con il codice fiscale, es. ditte individuali
$result = [
'IdTrasmittente' => [
'IdPaese' => $anagrafica->nazione->iso2,
2019-03-29 12:46:17 +01:00
'IdCodice' => (!empty($anagrafica['codice_fiscale']) and ($anagrafica['codice_fiscale'] != $anagrafica['piva'])) ? $anagrafica['codice_fiscale'] : str_replace($anagrafica->nazione->iso2, '', $anagrafica['piva']),
2019-02-13 17:49:01 +01:00
],
];
$result[] = [
2018-12-29 12:03:22 +01:00
'ProgressivoInvio' => $documento['progressivo_invio'],
'FormatoTrasmissione' => ($cliente['tipo'] == 'Ente pubblico') ? 'FPA12' : 'FPR12',
2019-05-04 00:32:28 +02:00
'CodiceDestinatario' => !empty($codice_destinatario) ? $codice_destinatario : $default_code,
2018-12-29 12:03:22 +01:00
];
// Telefono di contatto
if (!empty($anagrafica['telefono'])) {
$result['ContattiTrasmittente']['Telefono'] = $anagrafica['telefono'];
2018-12-29 12:03:22 +01:00
}
// Email di contatto
if (!empty($anagrafica['email'])) {
$result['ContattiTrasmittente']['Email'] = $anagrafica['email'];
2018-12-29 12:03:22 +01:00
}
// Inizializzazione PEC solo se anagrafica azienda e codice destinatario non compilato, per privato e PA la PEC non serve
if (empty($cliente['codice_destinatario']) && $cliente['tipo'] == 'Azienda' && !empty($cliente['pec'])) {
2018-12-29 12:03:22 +01:00
$result['PECDestinatario'] = $cliente['pec'];
}
return $result;
}
/**
* Restituisce l'array responsabile per la generazione dei tag DatiAnagrafici per Azienda e Cliente.
*
* @return array
*/
protected static function getDatiAnagrafici($anagrafica, $azienda = false)
{
$result = [];
$is_privato_estero = ($anagrafica->nazione->iso2 != 'IT' && $anagrafica->tipo == 'Privato');
2018-12-29 12:03:22 +01:00
// Partita IVA (obbligatoria se presente)
if (!empty($anagrafica['piva'])) {
2019-02-13 17:49:01 +01:00
if (!empty($anagrafica->nazione->iso2)) {
2019-01-10 19:31:26 +01:00
$result['IdFiscaleIVA']['IdPaese'] = $anagrafica->nazione->iso2;
}
2024-01-15 15:30:45 +01:00
// Rimuovo eventuali idicazioni relative alla nazione
2019-08-27 16:00:49 +02:00
$result['IdFiscaleIVA']['IdCodice'] = str_replace($anagrafica->nazione->iso2, '', $anagrafica['piva']);
2018-12-29 12:03:22 +01:00
}
// Codice fiscale
2024-01-15 15:30:45 +01:00
// TODO: Nella fattura elettronica, emessa nei confronti di soggetti titolari di partita IVA (nodo CessionarioCommittente), non va indicato il codice fiscale se è già presente la partita iva.
2018-12-29 12:03:22 +01:00
if (!empty($anagrafica['codice_fiscale'])) {
2019-02-07 18:27:15 +01:00
$result['CodiceFiscale'] = preg_replace('/\s+/', '', $anagrafica['codice_fiscale']);
2019-08-27 15:42:13 +02:00
2024-01-15 15:30:45 +01:00
// $result['CodiceFiscale'] = str_replace($anagrafica->nazione->iso2, '', $result['CodiceFiscale']);
2024-01-15 15:30:45 +01:00
// Rimuovo eventuali idicazioni relative all'iso2 della nazione, solo se la stringa inizia con quest'ultima.
$result['CodiceFiscale'] = preg_replace('/^'.preg_quote($anagrafica->nazione->iso2, '/').'/', '', $anagrafica['codice_fiscale']);
2018-12-29 12:03:22 +01:00
}
// Partita IVA: se privato estero non va considerato il codice fiscale ma la partita iva con 9 zeri
if ($is_privato_estero) {
2022-03-14 10:31:53 +01:00
$result['IdFiscaleIVA']['IdPaese'] = $anagrafica->nazione->iso2;
2022-01-31 10:00:05 +01:00
$result['IdFiscaleIVA']['IdCodice'] = '99999999999';
2021-11-05 17:48:31 +01:00
unset($result['CodiceFiscale']);
}
2019-01-10 18:41:25 +01:00
if (!empty($anagrafica['nome']) or !empty($anagrafica['cognome'])) {
$result['Anagrafica'] = [
2024-01-15 15:30:45 +01:00
// 'Denominazione' => $anagrafica['ragione_sociale'],
2019-01-10 18:41:25 +01:00
'Nome' => $anagrafica['nome'],
'Cognome' => $anagrafica['cognome'],
// TODO: 'Titolo' => $anagrafica['ragione_sociale'],
// TODO: CodEORI
];
} else {
$result['Anagrafica'] = [
'Denominazione' => $anagrafica['ragione_sociale'],
2024-01-15 15:30:45 +01:00
// 'Nome' => $anagrafica['nome'],
// 'Cognome' => $anagrafica['cognome'],
2019-01-10 18:41:25 +01:00
// TODO: 'Titolo' => $anagrafica['ragione_sociale'],
// TODO: CodEORI
];
}
2018-12-29 12:03:22 +01:00
// Informazioni specifiche azienda
if ($azienda) {
if ($anagrafica == static::getAzienda()) {
$result['RegimeFiscale'] = setting('Regime Fiscale');
} else {
$result['RegimeFiscale'] = 'RF18';
}
2018-12-29 12:03:22 +01:00
}
return $result;
}
/**
* Restituisce l'array responsabile per la generazione dei tag Sede per Azienda e Cliente.
*
2019-01-10 19:31:26 +01:00
* @param array $anagrafica
*
2018-12-29 12:03:22 +01:00
* @return array
*/
protected static function getSede($anagrafica)
{
$result = [
'Indirizzo' => $anagrafica['indirizzo'],
'CAP' => ($anagrafica->nazione->iso2 == 'IT') ? $anagrafica['cap'] : '00000',
2018-12-29 12:03:22 +01:00
'Comune' => $anagrafica['citta'],
];
2019-01-03 15:24:21 +01:00
// Provincia impostata e SOLO SE nazione ITALIA
2019-01-10 19:31:26 +01:00
if (!empty($anagrafica['provincia']) && $anagrafica->nazione->iso2 == 'IT') {
2019-01-03 15:24:21 +01:00
$result['Provincia'] = strtoupper($anagrafica['provincia']);
2018-12-29 12:03:22 +01:00
}
2019-01-17 16:11:10 +01:00
if (!empty($anagrafica->nazione->iso2)) {
$result['Nazione'] = $anagrafica->nazione->iso2;
}
2018-12-29 12:03:22 +01:00
return $result;
}
/**
2019-01-30 13:04:59 +01:00
* Restituisce l'array responsabile per la generazione del tag CedentePrestatore (mia Azienda ovvero il fornitore) (1.2).
2018-12-29 12:03:22 +01:00
*
* @return array
*/
protected static function getCedentePrestatore($fattura)
{
$documento = $fattura->getDocumento();
2024-01-15 15:30:45 +01:00
// Fattura per conto terzi, il cliente diventa il cedente al posto della mia Azienda (fornitore)
if ($documento['is_fattura_conto_terzi']) {
$azienda = $fattura->getCliente();
} else {
$azienda = static::getAzienda();
}
2018-12-29 12:03:22 +01:00
$result = [
'DatiAnagrafici' => static::getDatiAnagrafici($azienda, true),
'Sede' => static::getSede($azienda),
];
// IscrizioneREA
// Controllo che i codice non sia vuoto e che i primi due caratteri siano lettere
if (!empty($azienda['codicerea']) && (ctype_alpha($azienda['codicerea'][0]) && ctype_alpha($azienda['codicerea'][1]))) {
$codice = explode('-', clean($azienda['codicerea'], '\-'));
2018-12-29 12:03:22 +01:00
if (!empty($codice[0]) && !empty($codice[1])) {
$result['IscrizioneREA'] = [
'Ufficio' => strtoupper($codice[0]),
'NumeroREA' => $codice[1],
];
}
if (!empty($azienda['capitale_sociale'])) {
$result['IscrizioneREA']['CapitaleSociale'] = $azienda['capitale_sociale'];
}
$result['IscrizioneREA']['StatoLiquidazione'] = 'LN'; // Non in liquidazione
}
// Contatti
// Telefono
if (!empty($azienda['telefono'])) {
$result['Contatti']['Telefono'] = $azienda['telefono'];
}
// Fax
if (!empty($azienda['fax'])) {
$result['Contatti']['Fax'] = $azienda['fax'];
}
// Email
if (!empty($azienda['email'])) {
$result['Contatti']['Email'] = $azienda['email'];
}
// Riferimento Amministrazione
2023-09-27 17:08:33 +02:00
if ($fattura->getCliente()->tipo == 'Ente pubblico') {
if (!empty($fattura->getCliente()->riferimento_amministrazione)) {
$result['RiferimentoAmministrazione'] = $fattura->getCliente()->riferimento_amministrazione;
}
} else {
if (!empty($azienda['riferimento_amministrazione'])) {
$result['RiferimentoAmministrazione'] = $azienda['riferimento_amministrazione'];
}
}
2018-12-29 12:03:22 +01:00
return $result;
}
/**
* Restituisce l'array responsabile per la generazione del tag RappresentanteFiscale (1.3).
*
* @return array
*/
protected static function getRappresentanteFiscale($fattura)
{
2024-01-15 15:30:45 +01:00
// Fattura per conto terzi, il cliente diventa il cedente al posto della mia Azienda (fornitore)
$cliente = $fattura->getCliente();
$azienda = Sede::where('idanagrafica', $cliente->id)->where('is_rappresentante_fiscale', 1)->selectRaw('*, nomesede AS ragione_sociale')->first();
$result = [
'DatiAnagrafici' => static::getDatiAnagrafici($azienda, true),
];
return $result;
}
2018-12-29 12:03:22 +01:00
/**
2019-01-30 13:04:59 +01:00
* Restituisce l'array responsabile per la generazione del tag CessionarioCommittente (Cliente) (1.4).
2018-12-29 12:03:22 +01:00
*
* @return array
*/
protected static function getCessionarioCommittente($fattura)
{
$documento = $fattura->getDocumento();
2024-01-15 15:30:45 +01:00
// Fattura per conto terzi, la mia Azienda (fornitore) diventa il cessionario al posto del cliente
if ($documento['is_fattura_conto_terzi']) {
$cliente = static::getAzienda();
} else {
$cliente = $fattura->getCliente();
}
2018-12-29 12:03:22 +01:00
$result = [
'DatiAnagrafici' => static::getDatiAnagrafici($cliente),
'Sede' => static::getSede($cliente),
];
return $result;
}
/**
* Restituisce l'array responsabile per la generazione del tag TerzoIntermediarioOSoggettoEmittente (1.5).
*
* @return array
*/
protected static function getTerzoIntermediarioOSoggettoEmittente($fattura)
{
$intermediario = Anagrafica::find(setting('Terzo intermediario'));
$result = [
'DatiAnagrafici' => static::getDatiAnagrafici($intermediario),
];
return $result;
}
2019-02-24 10:24:39 +01:00
protected static function chunkSplit($str, $chunklen)
2019-02-21 16:16:43 +01:00
{
$res = [];
$k = ceil(strlen($str) / $chunklen);
for ($i = 0; $i < $k; ++$i) {
$res[] = substr($str, $i * $chunklen, $chunklen);
}
return $res;
}
2018-12-29 12:03:22 +01:00
/**
* Restituisce l'array responsabile per la generazione del tag DatiGeneraliDocumento.
*
* @return array
*/
protected static function getDatiGeneraliDocumento($fattura)
{
$documento = $fattura->getDocumento();
$azienda = static::getAzienda();
$result = [
2019-01-10 19:31:26 +01:00
'TipoDocumento' => $documento->tipo->codice_tipo_documento_fe,
2018-12-29 12:03:22 +01:00
'Divisa' => 'EUR',
'Data' => $documento['data'],
'Numero' => $documento['numero_esterno'],
];
$righe = $fattura->getRighe();
// Ritenuta d'Acconto
$id_ritenuta_acconto = null;
$totale_ritenuta_acconto = 0;
// Ritenuta Contributi
$id_ritenuta_contributi = $documento->id_ritenuta_contributi;
$totale_ritenuta_contributi = $documento->totale_ritenuta_contributi;
// Rivalsa
$id_rivalsainps = null;
$totale_rivalsainps = 0;
2018-12-29 12:03:22 +01:00
foreach ($righe as $riga) {
if (!empty($riga['idritenutaacconto']) and empty($riga['is_descrizione'])) {
$id_ritenuta_acconto = $riga['idritenutaacconto'];
$totale_ritenuta_acconto += $riga['ritenutaacconto'];
}
if (!empty($riga['idrivalsainps']) and empty($riga['is_descrizione'])) {
$id_rivalsainps = $riga['idrivalsainps'];
$totale_rivalsainps += $riga['rivalsainps'];
$aliquota_iva_rivalsainps = $riga['idiva'];
2018-12-29 12:03:22 +01:00
}
}
if (!empty($id_ritenuta_acconto)) {
$percentuale = database()->fetchOne('SELECT percentuale FROM co_ritenutaacconto WHERE id = '.prepare($id_ritenuta_acconto))['percentuale'];
// Con la nuova versione in vigore dal 01/01/2021, questo nodo diventa ripetibile.
$result[]['DatiRitenuta'] = [
'TipoRitenuta' => ($azienda['piva'] != $azienda['codice_fiscale'] & $azienda['tipo'] != 'Ente pubblico') ? 'RT01' : 'RT02',
'ImportoRitenuta' => $totale_ritenuta_acconto,
2018-12-29 12:03:22 +01:00
'AliquotaRitenuta' => $percentuale,
'CausalePagamento' => setting("Causale ritenuta d'acconto"),
];
}
if (!empty($id_ritenuta_contributi)) {
$ritenuta_contributi = database()->fetchOne('SELECT * FROM co_ritenuta_contributi WHERE id = '.prepare($id_ritenuta_contributi));
// Con la nuova versione in vigore dal 01/01/2021, questo nodo diventa ripetibile.
$result[]['DatiRitenuta'] = [
'TipoRitenuta' => $ritenuta_contributi['tipologia'],
'ImportoRitenuta' => $totale_ritenuta_contributi,
'AliquotaRitenuta' => $ritenuta_contributi['percentuale'],
'CausalePagamento' => $ritenuta_contributi['causale'],
];
}
// Bollo (2.1.1.6)
// ImportoBollo --> con la nuova versione in vigore dal 01/01/2021, la compilazione di questo nodo è diventata facoltativa.
// considerato che l'importo è noto e può essere solo di 2,00 Euro.
$bollo = new Bollo($documento);
if (!empty($bollo->getBollo())) {
2018-12-29 12:03:22 +01:00
$result['DatiBollo'] = [
'BolloVirtuale' => 'SI',
];
}
// Cassa Previdenziale (Rivalsa) (2.1.1.7)
if (!empty($id_rivalsainps)) {
$iva = database()->fetchOne('SELECT `percentuale`, `codice_natura_fe` FROM `co_iva` WHERE `id` = '.prepare($aliquota_iva_rivalsainps));
$percentuale = database()->fetchOne('SELECT percentuale FROM co_rivalse WHERE id = '.prepare($id_rivalsainps))['percentuale'];
2018-12-29 12:03:22 +01:00
$dati_cassa = [
'TipoCassa' => setting('Tipo Cassa Previdenziale'),
'AlCassa' => $percentuale,
2021-05-18 11:18:48 +02:00
'ImportoContributoCassa' => $totale_rivalsainps,
'ImponibileCassa' => $documento->imponibile,
2018-12-29 12:03:22 +01:00
'AliquotaIVA' => $iva['percentuale'],
];
if ($riga->calcolo_ritenuta_acconto == 'IMP+RIV') {
2018-12-29 12:03:22 +01:00
$dati_cassa['Ritenuta'] = 'SI';
2019-01-25 11:02:36 +01:00
}
if (!empty($iva['codice_natura_fe'])) {
$dati_cassa['Natura'] = $iva['codice_natura_fe'];
}
2024-01-15 15:30:45 +01:00
// $dati_cassa['RiferimentoAmministrazione'] = '';
2018-12-29 12:03:22 +01:00
$result['DatiCassaPrevidenziale'] = $dati_cassa;
}
2018-12-29 12:03:22 +01:00
// Sconto / Maggiorazione (2.1.1.8)
$sconti_maggiorazioni = [];
$sconto_finale = $documento->getScontoFinale();
if (!empty($sconto_finale)) {
$sconto = [
'Tipo' => 'SC',
];
if (!empty($documento->sconto_finale_percentuale)) {
$sconto['Percentuale'] = $documento->sconto_finale_percentuale;
} else {
$sconto['Importo'] = $documento->sconto_finale;
}
2021-02-26 18:52:35 +01:00
$sconti_maggiorazioni[] = $sconto;
}
if (!empty($documento->dati_aggiuntivi_fe['sconto_maggiorazione_tipo'])) {
$sconto = [
'Tipo' => $documento->dati_aggiuntivi_fe['sconto_maggiorazione_tipo'],
];
if (!empty($documento->dati_aggiuntivi_fe['sconto_maggiorazione_percentuale'])) {
$sconto['Percentuale'] = $documento->dati_aggiuntivi_fe['sconto_maggiorazione_percentuale'];
2023-08-04 14:54:28 +02:00
} elseif (!empty($documento->dati_aggiuntivi_fe['sconto_maggiorazione_importo'])) {
$sconto['Importo'] = $documento->dati_aggiuntivi_fe['sconto_maggiorazione_importo'];
}
2021-02-26 18:52:35 +01:00
$sconti_maggiorazioni[] = $sconto;
}
if (!empty($sconti_maggiorazioni)) {
2023-08-04 14:54:28 +02:00
foreach ($sconti_maggiorazioni as $sconto_maggiorazione) {
2022-08-03 13:08:03 +02:00
$result[]['ScontoMaggiorazione'] = $sconto_maggiorazione;
}
}
// Importo Totale Documento (2.1.1.9)
2019-02-12 11:41:32 +01:00
// Valorizzare limporto complessivo lordo della fattura (onnicomprensivo di Iva, bollo, contributi previdenziali, ecc…)
$result['ImportoTotaleDocumento'] = $documento->totale;
2018-12-29 12:03:22 +01:00
2019-02-26 21:38:26 +01:00
// Arrotondamento - Eventuale arrotondamento sul totale documento (ammette anche il segno negativo) (2.1.1.10)
// Causale - Descrizione della causale del documento (2.1.1.11)
$causali = self::chunkSplit($documento['note'], 200);
foreach ($causali as $causale) {
$result[] = ['Causale' => $causale];
}
2019-02-26 21:38:26 +01:00
// Art73 - Ciò consente al cedente/prestatore l'emissione nello stesso anno di più documenti aventi stesso numero (2.1.1.12)
2019-07-15 18:34:59 +02:00
$dati_aggiuntivi = $documento->dati_aggiuntivi_fe;
if (!empty($dati_aggiuntivi['art73'])) {
$result['Art73'] = 'SI';
}
2018-12-29 12:03:22 +01:00
return $result;
}
/**
* Restituisce l'array responsabile per la generazione del tag DatiTrasporto.
*
* @return array
*/
protected static function getDatiTrasporto($fattura)
{
$documento = $fattura->getDocumento();
$database = database();
$causale = $database->fetchOne('SELECT descrizione FROM dt_causalet WHERE id = '.prepare($documento['idcausalet']))['descrizione'];
$aspetto = $database->fetchOne('SELECT descrizione FROM dt_aspettobeni WHERE id = '.prepare($documento['idaspettobeni']))['descrizione'];
$result = [];
// Se imposto il vettore deve essere indicata anche la p.iva nella sua anagrafica
if ($documento->tipo->descrizione == 'Fattura accompagnatoria di vendita') {
if ($documento['idvettore']) {
$vettore = Anagrafica::find($documento['idvettore']);
$result['DatiAnagraficiVettore'] = static::getDatiAnagrafici($vettore);
}
2019-02-13 17:49:01 +01:00
if (!empty($causale)) {
2023-08-04 14:54:28 +02:00
/*
* Id SdI: 2.1.9.3
* Caratteri min-max: 1 - 100 caretteri
* Ripetibile: No
*/
$result['CausaleTrasporto'] = safe_truncate(html_entity_decode($causale), 100, null);
}
2019-02-13 17:49:01 +01:00
if (!empty($documento['n_colli'])) {
$result['NumeroColli'] = $documento['n_colli'];
}
if (!empty($aspetto)) {
$result['Descrizione'] = $aspetto;
}
if ($documento['tipo_resa']) {
$result['TipoResa'] = $documento['tipo_resa'];
}
2019-02-13 17:49:01 +01:00
}
2021-07-07 07:57:10 +02:00
if (!empty($documento['idsede_destinazione'])) {
$sede = $database->fetchOne('SELECT * FROM an_sedi WHERE id='.prepare($documento['idsede_destinazione']));
2021-07-07 07:57:10 +02:00
if (!empty($sede['indirizzo'])) {
$result['IndirizzoResa']['Indirizzo'] = $sede['indirizzo'];
}
2021-07-07 07:57:10 +02:00
if (!empty($sede['cap'])) {
$result['IndirizzoResa']['CAP'] = $sede['cap'];
}
2021-07-07 07:57:10 +02:00
if (!empty($sede['citta'])) {
$result['IndirizzoResa']['Comune'] = $sede['citta'];
}
2021-07-07 07:57:10 +02:00
if (!empty($sede['provincia'])) {
$result['IndirizzoResa']['Provincia'] = $sede['provincia'];
}
2021-07-07 07:57:10 +02:00
if (!empty($sede['id_nazione'])) {
$rs_nazione = $database->fetchOne('SELECT * FROM an_nazioni WHERE id='.prepare($sede['id_nazione']));
$result['IndirizzoResa']['Nazione'] = $rs_nazione['iso2'];
}
2019-02-13 17:49:01 +01:00
}
2018-12-29 12:03:22 +01:00
return $result;
}
/**
* Restituisce l'array responsabile per la generazione del tag DatiOrdineAcquisto.
*
* @return array
*/
2019-07-16 09:50:43 +02:00
protected static function getDatiOrdineAcquisto($fattura, $lista = null)
2018-12-29 12:03:22 +01:00
{
2019-07-16 09:50:43 +02:00
$lista = isset($lista) ? $lista : $fattura->getOrdiniAcquisto();
2018-12-29 12:03:22 +01:00
$result = [];
2019-07-16 09:50:43 +02:00
foreach ($lista as $element) {
if (empty($element['id_documento'])) {
2019-09-02 09:57:58 +02:00
continue;
}
2019-07-16 09:50:43 +02:00
$dati = [];
2023-11-06 12:34:32 +01:00
if (!empty($element['riferimento_linea']['id'])) {
2023-10-04 11:19:08 +02:00
$dati['RiferimentoNumeroLinea'] = $element['riferimento_linea']['id'];
2023-11-08 11:08:47 +01:00
} elseif (!empty($element['riferimento_linea'])) {
2023-11-06 12:34:32 +01:00
$dati['RiferimentoNumeroLinea'] = $element['riferimento_linea'];
}
2018-12-29 12:03:22 +01:00
2019-07-16 09:50:43 +02:00
$dati['IdDocumento'] = $element['id_documento'];
if (!empty($element['data'])) {
$dati['Data'] = $element['data'];
}
if (!empty($element['num_item'])) {
$dati['NumItem'] = $element['num_item'];
}
2019-07-16 09:50:43 +02:00
if (!empty($element['codice_commessa'])) {
$dati['CodiceCommessaConvenzione'] = $element['codice_commessa'];
}
2018-12-29 12:03:22 +01:00
if (!empty($element['codice_cup'])) {
$dati['CodiceCUP'] = $element['codice_cup'];
}
2019-07-16 11:55:14 +02:00
if (!empty($element['codice_cig'])) {
$dati['CodiceCIG'] = $element['codice_cig'];
}
2018-12-29 12:03:22 +01:00
$result[] = $dati;
}
return $result;
}
/**
* Restituisce l'array responsabile per la generazione del tag DatiDdt.
*
* @return array
*/
protected static function getDatiDDT($fattura)
{
$ddt = $fattura->getDDT();
$result = [];
foreach ($ddt as $element) {
if (empty($element['id_documento'])) {
continue;
}
$dati = [];
$dati['NumeroDDT'] = $element['id_documento'];
if (!empty($element['data'])) {
$dati['DataDDT'] = $element['data'];
}
if (!empty($element['riferimento_linea'])) {
$dati['RiferimentoNumeroLinea'] = $element['riferimento_linea'];
}
$result[] = $dati;
}
2021-02-23 11:40:27 +01:00
return $result;
}
2018-12-29 12:03:22 +01:00
/**
* Restituisce l'array responsabile per la generazione del tag DatiContratto.
*
* @return array
*/
protected static function getDatiContratto($fattura)
{
$contratti = $fattura->getContratti();
2019-07-16 09:50:43 +02:00
return self::getDatiOrdineAcquisto($fattura, $contratti);
}
2018-12-29 12:03:22 +01:00
2019-07-16 09:50:43 +02:00
/**
* Restituisce l'array responsabile per la generazione del tag DatiConvenzione.
*
* @return array
*/
protected static function getDatiConvenzione($fattura)
{
$documento = $fattura->getDocumento();
2019-05-10 06:32:06 +02:00
2019-07-16 09:50:43 +02:00
$dati_aggiuntivi = $documento->dati_aggiuntivi_fe;
$dati = $dati_aggiuntivi['dati_convenzione'] ?: [];
2019-05-10 06:32:06 +02:00
2019-07-16 09:50:43 +02:00
return self::getDatiOrdineAcquisto($fattura, $dati);
}
2018-12-29 12:03:22 +01:00
2019-07-16 09:50:43 +02:00
/**
* Restituisce l'array responsabile per la generazione del tag DatiRicezione.
*
* @return array
*/
protected static function getDatiRicezione($fattura)
{
$documento = $fattura->getDocumento();
2018-12-29 12:03:22 +01:00
2019-07-16 09:50:43 +02:00
$dati_aggiuntivi = $documento->dati_aggiuntivi_fe;
$dati = $dati_aggiuntivi['dati_ricezione'] ?: [];
return self::getDatiOrdineAcquisto($fattura, $dati);
2018-12-29 12:03:22 +01:00
}
/**
* Restituisce l'array responsabile per la generazione del tag DatiFattureCollegate.
*
* @return array
*/
protected static function getDatiFattureCollegate($fattura)
{
$fatture = $fattura->getFattureCollegate();
2019-07-16 09:50:43 +02:00
return self::getDatiOrdineAcquisto($fattura, $fatture);
2018-12-29 12:03:22 +01:00
}
/**
* Restituisce l'array responsabile per la generazione del tag DatiDocumento.
*
* @return array
*/
protected static function getDatiGenerali($fattura)
{
$documento = $fattura->getDocumento();
$cliente = $fattura->getCliente();
$result = [
'DatiGeneraliDocumento' => static::getDatiGeneraliDocumento($fattura),
];
// Controllo le le righe per la fatturazione di ordini
$dati_ordini = static::getDatiOrdineAcquisto($fattura);
if (!empty($dati_ordini)) {
foreach ($dati_ordini as $dato) {
if (!empty($dato)) {
$result[] = [
'DatiOrdineAcquisto' => $dato,
];
}
}
}
// Controllo le le righe per la fatturazione di contratti
$dati_contratti = static::getDatiContratto($fattura);
if (!empty($dati_contratti)) {
foreach ($dati_contratti as $dato) {
if (!empty($dato)) {
$result[] = [
'DatiContratto' => $dato,
];
}
}
}
2019-07-16 09:50:43 +02:00
// Controllo le le righe per la fatturazione di contratti
$dati_convenzioni = static::getDatiConvenzione($fattura);
if (!empty($dati_convenzioni)) {
foreach ($dati_convenzioni as $dato) {
if (!empty($dato)) {
$result[] = [
'DatiConvenzione' => $dato,
];
}
}
}
// Controllo le le righe per la fatturazione di contratti
$dati_ricezioni = static::getDatiRicezione($fattura);
if (!empty($dati_ricezioni)) {
foreach ($dati_ricezioni as $dato) {
if (!empty($dato)) {
$result[] = [
'DatiRicezione' => $dato,
];
}
}
}
2018-12-29 12:03:22 +01:00
// Controllo le le righe per la fatturazione di contratti
$dati_fatture_collegate = static::getDatiFattureCollegate($fattura);
if (!empty($dati_fatture_collegate)) {
foreach ($dati_fatture_collegate as $dato) {
if (!empty($dato)) {
$result[] = [
'DatiFattureCollegate' => $dato,
];
}
}
}
// Controllo le le righe per la fatturazione di contratti
$dati_ddt = static::getDatiDDT($fattura);
if (!empty($dati_ddt)) {
foreach ($dati_ddt as $dato) {
if (!empty($dato)) {
$result[] = [
'DatiDDT' => $dato,
];
}
}
}
if ($documento->tipo->descrizione == 'Fattura accompagnatoria di vendita' || !empty($documento['idsede_destinazione'])) {
2018-12-29 12:03:22 +01:00
$result['DatiTrasporto'] = static::getDatiTrasporto($fattura);
}
return $result;
}
/**
* Restituisce l'array responsabile per la generazione del tag DatiBeniServizi.
*
2019-02-15 13:00:05 +01:00
* @throws \Exception
*
2018-12-29 12:03:22 +01:00
* @return array
*/
protected static function getDatiBeniServizi($fattura)
{
$documento = $fattura->getDocumento();
2019-02-15 13:00:05 +01:00
$ritenuta_contributi = $documento->ritenutaContributi;
$righe = $documento->getRighe();
2018-12-29 12:03:22 +01:00
$database = database();
$result = [];
// Righe del documento
2019-02-21 11:51:03 +01:00
$iva_descrizioni = $righe->first(function ($item, $key) {
return $item->aliquota != null;
})->aliquota;
2022-08-11 17:50:20 +02:00
$order = 1;
foreach ($righe as $idx => $riga) {
// Righe - Descrizione della causale del documento (2.2.1.4)
$descrizioni = self::chunkSplit($riga['descrizione'], 1000);
2023-08-04 14:54:28 +02:00
foreach ($descrizioni as $i => $descrizione) {
2022-08-11 17:50:20 +02:00
$first_riga = ($i == 0 ? true : false);
$dati_aggiuntivi = $riga->dati_aggiuntivi_fe;
$dettaglio = [
2022-08-11 17:50:20 +02:00
'NumeroLinea' => $order++,
];
// 2.2.1.2
if (!empty($dati_aggiuntivi['tipo_cessione_prestazione'])) {
$dettaglio['TipoCessionePrestazione'] = $dati_aggiuntivi['tipo_cessione_prestazione'];
2022-03-17 23:16:48 +01:00
}
2019-01-25 11:02:36 +01:00
// 2.2.1.3
if (empty($riga->isDescrizione())) {
if (!empty($riga->codice) || (!empty($dati_aggiuntivi['codice_tipo']) && !empty($dati_aggiuntivi['codice_valore']))) {
$codice_articolo = [
'CodiceTipo' => $dati_aggiuntivi['codice_tipo'] ?: 'COD',
'CodiceValore' => $dati_aggiuntivi['codice_valore'] ?: $riga->codice,
];
2019-01-25 11:02:36 +01:00
$dettaglio['CodiceArticolo'] = $codice_articolo;
}
}
2024-01-15 15:30:45 +01:00
// $descrizione = $riga['descrizione'];
2019-02-15 13:00:05 +01:00
// Aggiunta dei riferimenti ai documenti
if (setting('Riferimento dei documenti in Fattura Elettronica') && $riga->hasOriginalComponent()) {
$descrizione .= "\n".$riga->getOriginalComponent()->getDocument()->getReference();
}
2018-12-29 12:03:22 +01:00
$dettaglio['Descrizione'] = $descrizione;
2018-12-29 12:03:22 +01:00
2022-08-11 17:50:20 +02:00
$qta = $riga->qta && $first_riga ? abs($riga->qta) : 1;
$dettaglio['Quantita'] = $qta;
2018-12-29 12:03:22 +01:00
if (!empty($riga['um'])) {
$dettaglio['UnitaMisura'] = $riga['um'];
}
2018-12-29 12:03:22 +01:00
if (!empty($dati_aggiuntivi['data_inizio_periodo'])) {
$dettaglio['DataInizioPeriodo'] = $dati_aggiuntivi['data_inizio_periodo'];
}
if (!empty($dati_aggiuntivi['data_fine_periodo'])) {
$dettaglio['DataFinePeriodo'] = $dati_aggiuntivi['data_fine_periodo'];
}
2022-08-11 17:50:20 +02:00
$dettaglio['PrezzoUnitario'] = $riga->prezzo_unitario && $first_riga ? $riga->prezzo_unitario : 0;
// Sconto (2.2.1.10)
$sconto_unitario = (float) $riga->sconto_unitario;
2018-12-29 12:03:22 +01:00
2022-08-11 17:50:20 +02:00
if (!empty($sconto_unitario) && $first_riga) {
$sconto = [
'Tipo' => $sconto_unitario > 0 ? 'SC' : 'MG',
];
if ($riga['tipo_sconto'] == 'PRC') {
$sconto['Percentuale'] = abs($riga->sconto_percentuale);
} else {
$sconto['Importo'] = abs($sconto_unitario);
}
$dettaglio['ScontoMaggiorazione'] = $sconto;
2018-12-29 12:03:22 +01:00
}
$aliquota = $riga->aliquota ?: $iva_descrizioni;
2023-08-04 14:54:28 +02:00
// Se sono presenti solo righe descrittive uso l'iva da impostazioni
if (empty($aliquota)) {
2023-08-04 14:54:28 +02:00
$aliquota_predefinita = Aliquota::find(setting('Iva predefinita'));
$aliquota = $aliquota_predefinita;
}
$percentuale = floatval($aliquota->percentuale);
2018-12-29 12:03:22 +01:00
$prezzo_totale = $riga->totale_imponibile;
2022-08-11 17:50:20 +02:00
$prezzo_totale = $prezzo_totale && $first_riga ? $prezzo_totale : 0;
$dettaglio['PrezzoTotale'] = $prezzo_totale;
2019-02-15 13:00:05 +01:00
$dettaglio['AliquotaIVA'] = $percentuale;
2019-07-16 11:33:19 +02:00
if (!empty($riga['idritenutaacconto']) && empty($riga['is_descrizione'])) {
$dettaglio['Ritenuta'] = 'SI';
}
2018-12-29 12:03:22 +01:00
// Controllo aggiuntivo codice_natura_fe per evitare che venga riportato il tag vuoto
if (empty($percentuale) && !empty($aliquota['codice_natura_fe'])) {
$dettaglio['Natura'] = $aliquota['codice_natura_fe'];
}
2018-12-29 12:03:22 +01:00
if (!empty($dati_aggiuntivi['riferimento_amministrazione'])) {
$dettaglio['RiferimentoAmministrazione'] = $dati_aggiuntivi['riferimento_amministrazione'];
}
2018-12-29 12:03:22 +01:00
// AltriDatiGestionali (2.2.1.16) - Ritenuta ENASARCO
// https://forum.italia.it/uploads/default/original/2X/d/d35d721c3a3a601d2300378724a270154e23af52.jpeg
if (!empty($riga['ritenuta_contributi'])) {
$dettaglio[]['AltriDatiGestionali'] = [
'TipoDato' => 'CASSA-PREV',
2024-01-15 15:30:45 +01:00
'RiferimentoTesto' => setting('Tipo Cassa Previdenziale').' - '.$ritenuta_contributi->descrizione.' ('.\Translator::numberToLocale($ritenuta_contributi->percentuale).'%)',
'RiferimentoNumero' => $riga->ritenuta_contributi,
];
}
2018-12-29 12:03:22 +01:00
$rs_ritenuta = $database->fetchOne('SELECT percentuale_imponibile FROM co_ritenutaacconto WHERE id='.prepare($riga['idritenutaacconto']));
if (!empty($rs_ritenuta['percentuale_imponibile'])) {
$dettaglio[]['AltriDatiGestionali'] = [
'TipoDato' => 'IMPON-RACC',
'RiferimentoTesto' => 'Imponibile % ritenuta d\'acconto',
'RiferimentoNumero' => $rs_ritenuta['percentuale_imponibile'],
];
}
2019-01-10 18:41:25 +01:00
// Dichiarazione d'intento
2024-01-15 15:30:45 +01:00
// Il numero di protocollo della dichiarazione dintento, rilevabile dalla ricevuta telematica rilasciata dallAgenzia delle entrate, è composto da 2 parti 17+6 (protocollo di ricezione della dichiarazione dintento e il suo progressivo)
// $id_iva_dichiarazione = setting("Iva per lettere d'intento");
$dichiarazione = $documento->dichiarazione;
$ive_accettate = [];
2023-08-04 14:54:28 +02:00
$rs = $database->table('co_iva')->where('codice_natura_fe', 'N3.5')->get();
foreach ($rs as $r) {
$ive_accettate[] = $r->id;
}
2023-08-04 14:54:28 +02:00
if (!empty($dichiarazione) && in_array($riga->aliquota->id, $ive_accettate)) {
$dettaglio[]['AltriDatiGestionali'] = [
'TipoDato' => 'INTENTO',
'RiferimentoTesto' => $dichiarazione->numero_protocollo,
'RiferimentoData' => $dichiarazione->data_protocollo,
];
}
// Dati aggiuntivi dinamici
if (!empty($dati_aggiuntivi['altri_dati'])) {
foreach ($dati_aggiuntivi['altri_dati'] as $dato) {
$altri_dati = [];
2019-09-13 12:27:29 +02:00
if (!empty($dato['tipo_dato'])) {
$altri_dati['TipoDato'] = $dato['tipo_dato'];
}
if (!empty($dato['riferimento_testo'])) {
$altri_dati['RiferimentoTesto'] = $dato['riferimento_testo'];
}
if (!empty($dato['riferimento_numero'])) {
$altri_dati['RiferimentoNumero'] = $dato['riferimento_numero'];
}
if (!empty($dato['riferimento_data'])) {
$altri_dati['RiferimentoData'] = $dato['riferimento_data'];
}
$dettaglio[]['AltriDatiGestionali'] = $altri_dati;
}
}
$result[] = [
'DettaglioLinee' => $dettaglio,
];
}
2018-12-29 12:03:22 +01:00
}
// Riepiloghi per IVA per percentuale
2019-02-14 18:33:25 +01:00
$riepiloghi_percentuale = $righe->filter(function ($item, $key) {
2019-02-21 11:51:03 +01:00
return $item->aliquota != null && $item->aliquota->codice_natura_fe == null;
2019-02-14 18:33:25 +01:00
})->groupBy(function ($item, $key) {
return $item->aliquota->percentuale;
});
2018-12-29 12:03:22 +01:00
foreach ($riepiloghi_percentuale as $riepilogo) {
2019-07-16 11:34:40 +02:00
$totale = round($riepilogo->sum('totale_imponibile') + $riepilogo->sum('rivalsa_inps'), 2);
2019-02-14 18:33:25 +01:00
$imposta = round($riepilogo->sum('iva') + $riepilogo->sum('iva_rivalsa_inps'), 2);
$dati = $riepilogo->first()->aliquota;
2018-12-29 12:03:22 +01:00
$iva = [
2019-02-14 18:33:25 +01:00
'AliquotaIVA' => $dati['percentuale'],
2019-07-16 11:33:19 +02:00
'ImponibileImporto' => $totale,
'Imposta' => $imposta,
2019-02-14 18:33:25 +01:00
'EsigibilitaIVA' => $dati['esigibilita'],
2018-12-29 12:03:22 +01:00
];
2019-02-14 18:33:25 +01:00
// Con split payment EsigibilitaIVA sempre a S
2018-12-29 12:03:22 +01:00
if ($documento['split_payment']) {
$iva['EsigibilitaIVA'] = 'S';
}
// TODO: la dicitura può essere diversa tra diverse IVA con stessa percentuale/natura
// nei riepiloghi viene fatto un accorpamento percentuale/natura
if (!empty($riepilogo['dicitura'])) {
// $iva['RiferimentoNormativo'] = $riepilogo['dicitura'];
}
2019-01-25 11:02:36 +01:00
2019-02-14 18:33:25 +01:00
// 2.2.2
2018-12-29 12:03:22 +01:00
$result[] = [
'DatiRiepilogo' => $iva,
];
}
// Riepiloghi per IVA per natura
2019-02-14 18:33:25 +01:00
$riepiloghi_natura = $righe->filter(function ($item, $key) {
2019-02-21 11:51:03 +01:00
return $item->aliquota != null && $item->aliquota->codice_natura_fe != null;
2019-02-14 18:33:25 +01:00
})->groupBy(function ($item, $key) {
return $item->aliquota->codice_natura_fe;
});
2018-12-29 12:03:22 +01:00
foreach ($riepiloghi_natura as $riepilogo) {
2019-07-16 11:34:40 +02:00
$totale = round($riepilogo->sum('totale_imponibile') + $riepilogo->sum('rivalsa_inps'), 2);
2019-02-14 18:33:25 +01:00
$imposta = round($riepilogo->sum('iva') + $riepilogo->sum('iva_rivalsa_inps'), 2);
$dati = $riepilogo->first()->aliquota;
2018-12-29 12:03:22 +01:00
$iva = [
'AliquotaIVA' => 0,
2019-02-15 13:00:05 +01:00
'Natura' => $dati->codice_natura_fe,
2019-07-16 11:33:19 +02:00
'ImponibileImporto' => $totale,
'Imposta' => $imposta,
2019-02-15 13:00:05 +01:00
'EsigibilitaIVA' => $dati->esigibilita,
'RiferimentoNormativo' => $dati->descrizione,
2018-12-29 12:03:22 +01:00
];
2019-02-14 18:33:25 +01:00
// Con split payment EsigibilitaIVA sempre a S
2018-12-29 12:03:22 +01:00
if ($documento['split_payment']) {
$iva['EsigibilitaIVA'] = 'S';
}
2019-01-25 11:02:36 +01:00
2019-02-14 18:33:25 +01:00
// 2.2.2
2018-12-29 12:03:22 +01:00
$result[] = [
'DatiRiepilogo' => $iva,
];
}
// Se sono presenti solo righe descrittive uso l'iva da impostazioni e creo un riepilogo con gli importi a 0
if (empty($iva)) {
$iva = [
'AliquotaIVA' => $aliquota_predefinita->percentuale,
'ImponibileImporto' => 0,
'Imposta' => 0,
'EsigibilitaIVA' => $aliquota_predefinita->esigibilita,
'RiferimentoNormativo' => $aliquota_predefinita->descrizione,
];
// 2.2.2
$result[] = [
'DatiRiepilogo' => $iva,
];
}
2018-12-29 12:03:22 +01:00
return $result;
}
/**
* Restituisce l'array responsabile per la generazione del tag DatiPagamento (2.4).
2018-12-29 12:03:22 +01:00
*
* @return array
*/
protected static function getDatiPagamento($fattura)
{
$documento = $fattura->getDocumento();
$fattura = Fattura::find($documento['id']);
2018-12-29 12:03:22 +01:00
$database = database();
$co_pagamenti = $database->fetchOne('SELECT * FROM `co_pagamenti` WHERE `id` = '.prepare($documento['idpagamento']));
2022-07-07 09:53:43 +02:00
/**
* TP01 - A Rate
* TP02 - Unica Soluzione
2023-08-04 14:54:28 +02:00
* TP03 - Anticipato.
*/
2018-12-29 12:03:22 +01:00
$result = [
2022-07-07 09:53:43 +02:00
'CondizioniPagamento' => ($co_pagamenti['prc'] < 100) ? 'TP01' : 'TP02',
2018-12-29 12:03:22 +01:00
];
$co_scadenziario = $database->fetchArray('SELECT * FROM `co_scadenziario` WHERE `iddocumento` = '.prepare($documento['id']));
foreach ($co_scadenziario as $scadenza) {
2023-11-27 11:18:54 +01:00
$co_pagamenti = $database->fetchOne('SELECT * FROM `co_pagamenti` WHERE `id` = '.prepare($scadenza['id_pagamento']));
$banca = Banca::find($scadenza['id_banca_azienda']);
2018-12-29 12:03:22 +01:00
$pagamento = [
'ModalitaPagamento' => $co_pagamenti['codice_modalita_pagamento_fe'],
'DataScadenzaPagamento' => $scadenza['scadenza'],
2019-01-10 18:41:25 +01:00
'ImportoPagamento' => abs($scadenza['da_pagare']),
2018-12-29 12:03:22 +01:00
];
if (!empty($banca->nome)) {
$pagamento['IstitutoFinanziario'] = $banca->nome;
}
2020-10-30 16:38:37 +01:00
if (!empty($banca->iban)) {
$pagamento['IBAN'] = clean($banca->iban);
2018-12-29 12:03:22 +01:00
}
2020-10-30 16:38:37 +01:00
// BIC senza parte per filiale (causa errori di validazione)
if (!empty($banca->bic)) {
2020-10-30 16:38:37 +01:00
$pagamento['BIC'] = substr($banca->bic, 0, 8);
}
2019-01-10 18:41:25 +01:00
$result[]['DettaglioPagamento'] = $pagamento;
}
2018-12-29 12:03:22 +01:00
return $result;
}
/**
* Restituisce l'array responsabile per la generazione del tag Allegati.
*
* @return array
*/
protected static function getAllegati($fattura)
{
$documento = $fattura->getDocumento();
$cliente = $fattura->getCliente();
$attachments = [];
// Informazioni sul modulo
2024-01-15 15:30:45 +01:00
$id_module = \Modules::get('Fatture di vendita')['id'];
$directory = \Uploads::getDirectory($id_module);
2018-12-29 12:03:22 +01:00
// Allegati
2024-01-15 15:30:45 +01:00
$allegati = \Uploads::get([
2018-12-29 12:03:22 +01:00
'id_module' => $id_module,
'id_record' => $documento['id'],
]);
// Inclusione
foreach ($allegati as $allegato) {
2019-07-12 16:08:15 +02:00
if ($allegato['category'] == 'Allegati Fattura Elettronica') {
$file = base_dir().'/'.$directory.'/'.$allegato['filename'];
2018-12-29 12:03:22 +01:00
$attachments[] = [
'NomeAttachment' => $allegato['name'],
2024-01-15 15:30:45 +01:00
'FormatoAttachment' => \Uploads::fileInfo($file)['extension'],
2018-12-29 12:03:22 +01:00
'Attachment' => base64_encode(file_get_contents($file)),
];
}
}
// Aggiunta della stampa
$print = false;
if ($cliente['tipo'] == 'Privato') {
$print = setting('Allega stampa per fattura verso Privati');
} elseif ($cliente['tipo'] == 'Azienda') {
$print = setting('Allega stampa per fattura verso Aziende');
} else {
$print = setting('Allega stampa per fattura verso PA');
}
if (!$print) {
return $attachments;
}
$data = $fattura->getUploadData();
// Generazione stampa
2024-01-15 15:30:45 +01:00
$print = \Prints::getModulePredefinedPrint($id_module);
$info = \Prints::render($print['id'], $documento['id'], null, true);
// Salvataggio stampa come allegato
$name = 'Stampa allegata';
$is_presente = database()->fetchNum('SELECT id FROM zz_files WHERE id_module = '.prepare($id_module).' AND id_record = '.prepare($documento['id']).' AND name = '.prepare($name));
2019-07-10 15:02:09 +02:00
if (empty($is_presente)) {
2024-01-15 15:30:45 +01:00
\Uploads::upload($info['pdf'], array_merge($data, [
'name' => $name,
'original_name' => $info['path'],
]));
}
2018-12-29 12:03:22 +01:00
// Introduzione allegato in Fattura Elettronica
2018-12-29 12:03:22 +01:00
$attachments[] = [
'NomeAttachment' => 'Fattura',
'FormatoAttachment' => 'PDF',
'Attachment' => base64_encode($info['pdf']),
2018-12-29 12:03:22 +01:00
];
return $attachments;
}
/**
* Restituisce l'array responsabile per la generazione del tag FatturaElettronicaHeader.
*
* @return array
*/
protected static function getHeader($fattura)
{
$documento = $fattura->getDocumento();
$rappresentante_fiscale = null;
2023-12-06 15:06:49 +01:00
2024-01-15 15:30:45 +01:00
// Fattura per conto terzi, il cliente diventa il cedente al posto della mia Azienda (fornitore)
if ($documento['is_fattura_conto_terzi']) {
$azienda = $fattura->getCliente();
$rappresentante_fiscale = Sede::where('idanagrafica', $azienda->id)->where('is_rappresentante_fiscale', 1)->first();
} else {
$azienda = static::getAzienda();
}
if ($rappresentante_fiscale) {
$result = [
'DatiTrasmissione' => static::getDatiTrasmissione($fattura),
'CedentePrestatore' => static::getCedentePrestatore($fattura),
'RappresentanteFiscale' => static::getRappresentanteFiscale($fattura),
'CessionarioCommittente' => static::getCessionarioCommittente($fattura),
];
} else {
$result = [
'DatiTrasmissione' => static::getDatiTrasmissione($fattura),
'CedentePrestatore' => static::getCedentePrestatore($fattura),
'CessionarioCommittente' => static::getCessionarioCommittente($fattura),
];
}
// 1.5 Terzo Intermediario
if (!empty(setting('Terzo intermediario'))) {
$result['TerzoIntermediarioOSoggettoEmittente'] = static::getTerzoIntermediarioOSoggettoEmittente($fattura);
// 1.6 Soggetto terzo
$result['SoggettoEmittente'] = 'TZ';
}
// 1.5 o Soggetto Emittente (Autofattura) - da parte del fornitore (mia Azienda) per conto del cliente esonerato
// In caso di acquisto di prodotti da un agricolo in regime agevolato (art. 34, comma 6, del d.P.R. n. 633/72) da parte di un operatore IVA obbligato alla FE, quest'ultimo emetterà una FE usando la tipologia "TD01" per conto dell'agricoltore venditore
2019-08-27 16:00:49 +02:00
if ($fattura->getDocumento()['is_fattura_conto_terzi']) {
$result['TerzoIntermediarioOSoggettoEmittente'] = [
2019-08-28 16:58:47 +02:00
'DatiAnagrafici' => static::getDatiAnagrafici(static::getAzienda()),
2019-08-27 16:00:49 +02:00
];
// 1.6 Cessionario/Committente
$result['SoggettoEmittente'] = 'CC';
}
2018-12-29 12:03:22 +01:00
return $result;
}
/**
* Restituisce l'array responsabile per la generazione del tag FatturaElettronicaBody.
*
* @return array
*/
protected static function getBody($fattura)
{
$result = [
'DatiGenerali' => static::getDatiGenerali($fattura),
'DatiBeniServizi' => static::getDatiBeniServizi($fattura),
'DatiPagamento' => static::getDatiPagamento($fattura),
];
// Allegati
$allegati = static::getAllegati($fattura);
if (!empty($allegati)) {
foreach ($allegati as $allegato) {
$result[] = [
'Allegati' => $allegato,
];
}
}
return $result;
}
protected function getUploadData()
{
return [
'category' => tr('Fattura Elettronica'),
2024-01-15 15:30:45 +01:00
'id_module' => \Modules::get('Fatture di vendita')['id'],
2018-12-29 12:03:22 +01:00
'id_record' => $this->getDocumento()['id'],
];
}
2023-08-04 14:54:28 +02:00
}