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-18 18:18:05 -07: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-03 15:37:49 -07: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-18 18:18:05 -07: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-18 18:18:05 -07:00
public static function manage ( $name )
2018-09-24 18:10:16 +02:00
{
2019-04-18 18:18:05 -07:00
try {
$fattura = new FatturaOrdinaria ( $name );
2018-09-24 18:10:16 +02:00
2019-04-18 18:18:05 -07:00
return $fattura ;
} catch ( UnexpectedValueException $e ) {
$fattura = new FatturaSemplificata ( $name );
2018-09-24 18:10:16 +02:00
2019-04-18 18:18:05 -07:00
return $fattura ;
2018-09-24 18:10:16 +02:00
}
}
2019-04-18 18:18:05 -07:00
public function getHeader ()
2018-09-24 18:10:16 +02:00
{
2019-04-18 18:18:05 -07:00
return $this -> xml [ 'FatturaElettronicaHeader' ];
2018-09-24 18:10:16 +02:00
}
2019-04-18 18:18:05 -07:00
public function getBody ()
2018-09-24 18:10:16 +02:00
{
2019-04-18 18:18:05 -07:00
return $this -> xml [ 'FatturaElettronicaBody' ];
}
2019-02-18 10:34:31 +01:00
2019-04-18 18:18:05 -07: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-18 18:18:05 -07: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-22 11:35:44 +02:00
/**
* Restituisce l ' anagrafica collegata alla fattura , eventualmente generandola con i dati forniti .
*
* @ param string $type
* @ return Anagrafica
*/
2019-04-18 18:18:05 -07:00
public function saveAnagrafica ( $type = 'Fornitore' )
2018-09-25 11:55:52 +02:00
{
2019-04-18 18:18:05 -07: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 );
});
if ( ! empty ( $info [ 'partita_iva' ])) {
$anagrafica -> where ( 'piva' , $info [ 'partita_iva' ]);
}
if ( ! empty ( $info [ 'codice_fiscale' ])) {
$anagrafica -> where ( 'codice_fiscale' , $info [ 'codice_fiscale' ]);
}
$anagrafica = $anagrafica -> first ();
if ( ! empty ( $anagrafica )) {
return $anagrafica ;
}
$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 11:35:44 +02:00
* @ param int $id_pagamento
* @ param int $id_sezionale
* @ param int $id_tipo
* @ param string $data_registrazione
* @ param int $ref_fattura
*
2019-04-18 18:18:05 -07:00
* @ return Fattura
2018-09-24 18:10:16 +02:00
*/
2019-07-22 11:35:44 +02:00
public function saveFattura ( $id_pagamento , $id_sezionale , $id_tipo , $data_registrazione , $ref_fattura = null )
2018-09-24 18:10:16 +02:00
{
2019-04-18 18:18:05 -07:00
$anagrafica = $this -> saveAnagrafica ();
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
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
2019-01-10 18:41:25 +01:00
$tipo = TipoFattura :: where ( 'id' , $id_tipo ) -> first ();
2019-01-10 18:06:15 +01:00
2019-01-02 14:15:16 +01:00
$fattura = Fattura :: build ( $anagrafica , $tipo , $data , $id_sezionale );
2018-09-25 11:55:52 +02:00
$this -> fattura = $fattura ;
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 08:30:58 -07:00
2019-07-22 11:35:44 +02:00
// Riferimento per nota di credito e debito
$fattura -> ref_documento = $ref_fattura ? : null ;
2019-04-18 18:18:05 -07:00
// Per il destinatario, la data di ricezione della fattura assume grande rilievo ai fini IVA, poiché determina la decorrenza dei termini per poter esercitare il diritto alla detrazione.
// La data di ricezione della fattura è contenuta all’ interno della “ricevuta di consegna” visibile al trasmittente della stessa.
2019-05-16 20:56:10 -07:00
if ( empty ( $data_registrazione )) {
$fattura -> data_registrazione = $dati_generali [ 'Data' ];
2019-05-15 19:52:16 -07:00
} else {
2019-05-16 20:56:10 -07:00
$fattura -> data_registrazione = $data_registrazione ;
2019-05-15 19:52:16 -07:00
}
2019-05-16 20:56:10 -07: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 );
2018-09-26 16:28:02 +02:00
// Ritenuta d'Acconto
$ritenuta = $dati_generali [ 'DatiRitenuta' ];
if ( ! empty ( $ritenuta )) {
$percentuale = $ritenuta [ 'AliquotaRitenuta' ];
$importo = $ritenuta [ 'ImportoRitenuta' ];
// TODO: salvare in fattura
}
2019-01-10 18:41:25 +01:00
$causali = $dati_generali [ 'Causale' ];
2019-04-18 18:18:05 -07:00
if ( ! empty ( $causali )) {
$note = '' ;
2019-01-10 18:41:25 +01:00
foreach ( $causali as $causale ) {
$note .= $causale ;
}
$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-18 18:18:05 -07:00
return $fattura ;
2018-09-24 18:10:16 +02:00
}
2018-11-30 15:33:25 +01:00
2019-04-18 18:18:05 -07:00
public function getFattura ()
2018-11-30 15:33:25 +01:00
{
2019-04-18 18:18:05 -07: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-18 18:18:05 -07:00
$this -> saveRighe ( $info [ 'articoli' ], $info [ 'iva' ], $info [ 'conto' ], $info [ 'movimentazione' ]);
$this -> saveAllegati ();
return $this -> getFattura () -> id ;
}
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
}