openstamanager/plugins/importFE/src/FatturaElettronica.php

381 lines
11 KiB
PHP
Raw Normal View History

2018-09-24 18:10:16 +02:00
<?php
2018-11-30 15:33:25 +01:00
namespace Plugins\ImportFE;
2018-09-24 18:10:16 +02:00
2018-12-29 12:03:22 +01:00
use Modules;
use Modules\Anagrafiche\Anagrafica;
use Modules\Anagrafiche\Nazione;
use Modules\Anagrafiche\Tipo as TipoAnagrafica;
use Modules\Fatture\Fattura;
2018-09-24 18:10:16 +02:00
use Modules\Fatture\Stato as StatoFattura;
use Modules\Fatture\Tipo as TipoFattura;
2018-11-30 15:33:25 +01:00
use UnexpectedValueException;
2018-12-29 12:03:22 +01:00
use Uploads;
use Util\XML;
2018-09-24 18:10:16 +02:00
/**
* Classe per la gestione della fatturazione elettronica in XML.
*
2019-04-19 03:18:05 +02:00
* @since 2.4.9
2018-09-24 18:10:16 +02:00
*/
class FatturaElettronica
{
2018-11-30 15:33:25 +01:00
protected static $directory = null;
/** @var array Percorso del file XML */
protected $file = null;
2018-09-24 18:10:16 +02:00
/** @var array XML della fattura */
protected $xml = null;
2019-05-04 00:37:49 +02:00
/** @var Fattura Fattura collegata */
2018-09-24 18:10:16 +02:00
protected $fattura = null;
2019-02-20 16:07:42 +01:00
public function __construct($name)
2018-09-24 18:10:16 +02:00
{
2019-02-20 16:07:42 +01:00
$this->file = static::getImportDirectory().'/'.$name;
2019-02-13 11:26:56 +01:00
2019-03-23 17:43:42 +01:00
if (ends_with($name, '.p7m')) {
2019-02-13 11:26:56 +01:00
$file = XML::decodeP7M($this->file);
2019-02-13 12:04:36 +01:00
if (!empty($file)) {
2019-02-13 11:26:56 +01:00
delete($this->file);
$this->file = $file;
}
}
2018-12-07 10:56:49 +01:00
$this->xml = XML::readFile($this->file);
2018-09-24 18:10:16 +02:00
2018-09-25 11:55:52 +02:00
// Individuazione fattura pre-esistente
$dati_generali = $this->getBody()['DatiGenerali']['DatiGeneraliDocumento'];
$data = $dati_generali['Data'];
$numero = $dati_generali['Numero'];
2018-11-30 15:33:25 +01:00
$progressivo_invio = $this->getHeader()['DatiTrasmissione']['ProgressivoInvio'];
2018-09-25 11:55:52 +02:00
$fattura = Fattura::where([
2018-11-30 15:33:25 +01:00
'progressivo_invio' => $progressivo_invio,
2018-12-07 10:56:49 +01:00
'numero_esterno' => $numero,
2018-09-25 11:55:52 +02:00
'data' => $data,
])->first();
if (!empty($fattura)) {
2018-11-30 15:33:25 +01:00
throw new UnexpectedValueException();
}
}
public static function getImportDirectory()
{
if (!isset(self::$directory)) {
$module = Modules::get('Fatture di acquisto');
2019-07-05 09:53:53 +02:00
$plugins = $module->plugins;
if (!empty($plugins)) {
$plugin = $plugins->first(function ($value, $key) {
return $value->name == 'Fatturazione Elettronica';
});
2018-11-30 15:33:25 +01:00
2019-07-05 09:53:53 +02:00
self::$directory = DOCROOT.'/'.$plugin->upload_directory;
}
2018-11-30 15:33:25 +01:00
}
return self::$directory;
}
public static function store($filename, $content)
{
2018-12-12 17:26:25 +01:00
$directory = static::getImportDirectory();
$file = $directory.'/'.$filename;
2018-11-30 15:33:25 +01:00
2018-12-12 17:26:25 +01:00
directory($directory);
2018-11-30 15:33:25 +01:00
file_put_contents($file, $content);
return $filename;
}
2019-02-20 16:07:42 +01:00
public static function isValid($name)
2018-11-30 15:33:25 +01:00
{
try {
2019-02-20 16:07:42 +01:00
new static($name);
2018-11-30 15:33:25 +01:00
return true;
} catch (UnexpectedValueException $e) {
2019-04-19 03:18:05 +02:00
$file = static::getImportDirectory().'/'.$name;
delete($file);
2018-11-30 15:33:25 +01:00
return false;
2018-09-25 11:55:52 +02:00
}
2018-09-24 18:10:16 +02:00
}
2019-04-19 03:18:05 +02:00
public static function manage($name)
2018-09-24 18:10:16 +02:00
{
2019-04-19 03:18:05 +02:00
try {
2019-07-22 12:52:48 +02:00
$manager = new FatturaOrdinaria($name);
2018-09-24 18:10:16 +02:00
2019-07-22 12:52:48 +02:00
$tipo = $manager->getBody()['DatiGenerali']['DatiGeneraliDocumento']['TipoDocumento'];
if ($tipo == 'TD06') {
$manager = new Parcella($name);
}
2019-04-19 03:18:05 +02:00
} catch (UnexpectedValueException $e) {
2019-07-22 12:52:48 +02:00
$manager = new FatturaSemplificata($name);
2018-09-24 18:10:16 +02:00
}
2019-07-22 12:52:48 +02:00
return $manager;
2018-09-24 18:10:16 +02:00
}
2019-04-19 03:18:05 +02:00
public function getHeader()
2018-09-24 18:10:16 +02:00
{
2019-04-19 03:18:05 +02:00
return $this->xml['FatturaElettronicaHeader'];
2018-09-24 18:10:16 +02:00
}
2019-04-19 03:18:05 +02:00
public function getBody()
2018-09-24 18:10:16 +02:00
{
2019-04-19 03:18:05 +02:00
return $this->xml['FatturaElettronicaBody'];
}
2019-02-18 10:34:31 +01:00
2019-04-19 03:18:05 +02:00
public function delete()
{
delete($this->file);
2018-09-24 18:10:16 +02:00
}
2018-09-25 11:55:52 +02:00
public function getAllegati()
2018-09-24 18:10:16 +02:00
{
2018-09-25 11:55:52 +02:00
$result = $this->getBody()['Allegati'];
2019-04-19 03:18:05 +02:00
$result = $this->forceArray($result);
2018-09-25 11:55:52 +02:00
2018-12-07 10:56:49 +01:00
return array_clean($result);
2018-09-24 18:10:16 +02:00
}
2018-11-30 15:33:25 +01:00
public function saveAllegati()
2018-09-24 18:10:16 +02:00
{
2018-09-25 11:55:52 +02:00
$allegati = $this->getAllegati();
2018-09-24 18:10:16 +02:00
2018-09-25 16:47:44 +02:00
$module = Modules::get('Fatture di acquisto');
2018-11-30 15:33:25 +01:00
$info = [
'category' => tr('Fattura Elettronica'),
'id_module' => $module->id,
'id_record' => $this->fattura->id,
];
2018-09-24 18:10:16 +02:00
foreach ($allegati as $allegato) {
$content = base64_decode($allegato['Attachment']);
$extension = '';
if (!empty($allegato['FormatoAttachment'])) {
$extension = '.'.strtolower($allegato['FormatoAttachment']);
}
$original = $allegato['NomeAttachment'].$extension;
2018-09-25 16:47:44 +02:00
$filename = Uploads::getName($original, [
'id_module' => $module['id'],
]);
2018-09-24 18:10:16 +02:00
2018-11-30 15:33:25 +01:00
file_put_contents($module->upload_directory.'/'.$filename, $content);
2018-09-24 18:10:16 +02:00
2018-11-30 15:33:25 +01:00
Uploads::register(array_merge($info, [
2018-09-25 16:47:44 +02:00
'filename' => $filename,
'original' => $original,
2018-11-30 15:33:25 +01:00
]));
2018-09-24 18:10:16 +02:00
}
2018-11-30 15:33:25 +01:00
// Registrazione XML come allegato
2019-07-22 11:35:44 +02:00
Uploads::upload($this->file, array_merge($info, [
2018-11-30 15:33:25 +01:00
'name' => tr('Fattura Elettronica'),
2018-12-07 10:56:49 +01:00
'original' => basename($this->file),
2018-11-30 15:33:25 +01:00
]));
2018-09-24 18:10:16 +02:00
}
public function findAnagrafica($type = 'Fornitore')
2018-09-25 11:55:52 +02:00
{
2019-04-19 03:18:05 +02:00
$info = $this->getAnagrafe();
$tipologia = TipoAnagrafica::where('descrizione', $type)->first();
$anagrafica = Anagrafica::whereHas('tipi', function ($query) use ($tipologia) {
$query->where('an_tipianagrafiche.idtipoanagrafica', '=', $tipologia->id);
});
2019-07-24 15:41:04 +02:00
if (!empty($info['partita_iva']) && !empty($info['codice_fiscale'])) {
$anagrafica->where('piva', $info['partita_iva'])
->orWhere('codice_fiscale', $info['codice_fiscale']);
} elseif (!empty($info['codice_fiscale'])) {
2019-04-19 03:18:05 +02:00
$anagrafica->where('codice_fiscale', $info['codice_fiscale']);
2019-07-24 15:41:04 +02:00
} elseif (!empty($info['partita_iva'])) {
$anagrafica->where('piva', $info['partita_iva']);
2019-04-19 03:18:05 +02:00
}
return $anagrafica->first();
}
/**
* Restituisce l'anagrafica collegata alla fattura, eventualmente generandola con i dati forniti.
*
* @param string $type
*
* @return Anagrafica
*/
public function saveAnagrafica($type = 'Fornitore')
{
$anagrafica = $this->findAnagrafica($type);
2019-04-19 03:18:05 +02:00
if (!empty($anagrafica)) {
return $anagrafica;
}
$info = $this->getAnagrafe();
2019-04-19 03:18:05 +02:00
$anagrafica = Anagrafica::build($info['ragione_sociale'], $info['nome'], $info['cognome'], [
TipoAnagrafica::where('descrizione', $type)->first()->id,
]);
if (!empty($info['partita_iva'])) {
$anagrafica->partita_iva = $info['partita_iva'];
}
if (!empty($info['codice_fiscale'])) {
$anagrafica->codice_fiscale = $info['codice_fiscale'];
}
// Informazioni sull'anagrafica
if (!empty($info['rea'])) {
if (!empty($info['rea']['codice'])) {
$anagrafica->codicerea = $info['rea']['codice'];
}
if (!empty($info['rea']['capitale_sociale'])) {
$anagrafica->capitale_sociale = $info['rea']['capitale_sociale'];
}
}
$anagrafica->save();
// Informazioni sulla sede
$sede = $anagrafica->sedeLegale;
$sede->indirizzo = $info['sede']['indirizzo'];
$sede->cap = $info['sede']['cap'];
$sede->citta = $info['sede']['comune'];
if (!empty($info['sede']['provincia'])) {
$sede->provincia = $info['sede']['provincia'];
}
$sede->nazione()->associate(Nazione::where('iso2', $info['sede']['nazione'])->first());
$contatti = $info['contatti'];
if (!empty($contatti)) {
if (!empty($contatti['telefono'])) {
$sede->telefono = $contatti['telefono'];
}
if (!empty($contatti['fax'])) {
$sede->fax = $contatti['fax'];
}
if (!empty($contatti['email'])) {
$sede->email = $contatti['email'];
}
}
$sede->save();
return $anagrafica;
2018-09-25 11:55:52 +02:00
}
2018-09-24 18:10:16 +02:00
/**
* Registra la fattura elettronica come fattura del gestionale.
*
2019-07-22 12:52:48 +02:00
* @param int $id_pagamento
* @param int $id_sezionale
* @param int $id_tipo
2019-07-22 11:35:44 +02:00
* @param string $data_registrazione
2019-07-22 12:52:48 +02:00
* @param int $ref_fattura
2019-07-22 11:35:44 +02:00
*
2019-04-19 03:18:05 +02:00
* @return Fattura
2018-09-24 18:10:16 +02:00
*/
2019-07-22 12:52:48 +02:00
public function saveFattura($id_pagamento, $id_sezionale, $id_tipo, $data_registrazione, $ref_fattura)
2018-09-24 18:10:16 +02:00
{
$dati_generali = $this->getBody()['DatiGenerali']['DatiGeneraliDocumento'];
$data = $dati_generali['Data'];
2019-01-10 18:41:25 +01:00
2019-07-22 12:52:48 +02:00
$fattura = $this->prepareFattura($id_tipo, $data, $id_sezionale, $ref_fattura);
$this->fattura = $fattura;
$numero_esterno = $dati_generali['Numero'];
2018-11-30 15:33:25 +01:00
$progressivo_invio = $this->getHeader()['DatiTrasmissione']['ProgressivoInvio'];
2018-09-24 18:10:16 +02:00
2018-11-30 15:33:25 +01:00
$fattura->progressivo_invio = $progressivo_invio;
$fattura->numero_esterno = $numero_esterno;
2018-09-25 16:47:44 +02:00
$fattura->idpagamento = $id_pagamento;
2019-04-04 17:30:58 +02:00
2019-07-22 11:35:44 +02:00
// Riferimento per nota di credito e debito
$fattura->ref_documento = $ref_fattura ?: null;
2019-07-22 15:45:36 +02:00
// Per il destinatario, la data di registrazione della fattura assume grande rilievo ai fini IVA, poiché determina la decorrenza dei termini per poter esercitare il diritto alla detrazione.
2019-04-19 03:18:05 +02:00
// La data di ricezione della fattura è contenuta allinterno della “ricevuta di consegna” visibile al trasmittente della stessa.
2019-07-22 15:45:36 +02:00
$fattura->data_registrazione = $data_registrazione;
2019-05-17 05:56:10 +02:00
$fattura->data_competenza = $fattura->data_registrazione;
2018-09-24 18:10:16 +02:00
$stato_documento = StatoFattura::where('descrizione', 'Emessa')->first();
$fattura->stato()->associate($stato_documento);
2019-01-10 18:41:25 +01:00
$causali = $dati_generali['Causale'];
2019-04-19 03:18:05 +02:00
if (!empty($causali)) {
$note = '';
2019-01-10 18:41:25 +01:00
foreach ($causali as $causale) {
$note .= $causale;
}
2019-07-23 18:04:01 +02:00
2019-01-10 18:41:25 +01:00
$fattura->note = $note;
}
2018-09-26 16:28:02 +02:00
// Bollo
$bollo = $dati_generali['DatiBollo'];
if (!empty($bollo)) {
$fattura->bollo = $bollo['ImportoBollo'];
}
2018-09-25 11:55:52 +02:00
$fattura->save();
2018-09-24 18:10:16 +02:00
2019-04-19 03:18:05 +02:00
return $fattura;
2018-09-24 18:10:16 +02:00
}
2018-11-30 15:33:25 +01:00
2019-04-19 03:18:05 +02:00
public function getFattura()
2018-11-30 15:33:25 +01:00
{
2019-04-19 03:18:05 +02:00
return $this->fattura;
}
public function save($info = [])
{
2019-07-22 11:35:44 +02:00
$this->saveFattura($info['id_pagamento'], $info['id_segment'], $info['id_tipo'], $info['data_registrazione'], $info['ref_fattura']);
2019-04-19 03:18:05 +02:00
2019-10-18 16:40:15 +02:00
$this->saveRighe($info['articoli'], $info['iva'], $info['conto'], $info['movimentazione'], $info['crea_articoli']);
2019-04-19 03:18:05 +02:00
$this->saveAllegati();
return $this->getFattura()->id;
}
2019-07-22 12:52:48 +02:00
protected function prepareFattura($id_tipo, $data, $id_sezionale, $ref_fattura)
{
$anagrafica = $this->saveAnagrafica();
$tipo = TipoFattura::where('id', $id_tipo)->first();
$fattura = Fattura::build($anagrafica, $tipo, $data, $id_sezionale);
$this->fattura = $fattura;
// Riferimento per nota di credito e debito
$fattura->ref_documento = $ref_fattura ?: null;
return $fattura;
}
2019-04-19 03:18:05 +02:00
protected function forceArray($result)
{
$result = isset($result[0]) ? $result : [$result];
return $result;
2018-11-30 15:33:25 +01:00
}
2018-09-24 18:10:16 +02:00
}