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' ]);
2018-12-12 17:54:31 +01:00
$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
}
2019-07-24 15:29:03 +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
}
2019-07-22 18:35:13 +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' )
{
2019-07-24 15:29:03 +02:00
$anagrafica = $this -> findAnagrafica ( $type );
2019-04-19 03:18:05 +02:00
if ( ! empty ( $anagrafica )) {
return $anagrafica ;
}
2019-07-22 18:35:13 +02:00
$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 ;
2018-10-29 22:23:29 +01:00
$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 ;
2018-10-29 22:23:29 +01:00
$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 all’ interno 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
}