openstamanager/plugins/importPA/src/FatturaElettronica.php

281 lines
8.5 KiB
PHP
Raw Normal View History

2018-09-24 18:10:16 +02:00
<?php
namespace Plugins\ImportPA;
use Modules\Fatture\Fattura;
2018-09-25 11:55:52 +02:00
use Modules\Fatture\Riga;
use Modules\Fatture\Articolo;
use Modules\Articoli\Articolo as ArticoloOriginale;
2018-09-24 18:10:16 +02:00
use Modules\Fatture\Stato as StatoFattura;
use Modules\Fatture\Tipo as TipoFattura;
use Modules\Anagrafiche\Anagrafica;
use Modules\Anagrafiche\Tipo as TipoAnagrafica;
use Modules\Anagrafiche\Nazione;
use Uploads;
use Modules;
/**
* Classe per la gestione della fatturazione elettronica in XML.
*
* @since 2.4.2
*/
class FatturaElettronica
{
/** @var array XML della fattura */
protected $xml = null;
/** @var Fattura Fattura collegata */
protected $fattura = null;
2018-09-25 11:55:52 +02:00
protected $id_sezionale = null;
2018-09-24 18:10:16 +02:00
2018-09-25 11:55:52 +02:00
public function __construct($content, $id_sezionale)
2018-09-24 18:10:16 +02:00
{
$xml = simplexml_load_string($content, "SimpleXMLElement", LIBXML_NOCDATA);
$json = json_encode($xml);
$array = json_decode($json, true);
$this->xml = $array;
2018-09-25 11:55:52 +02:00
$this->id_sezionale = $id_sezionale;
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'];
$fattura = Fattura::where([
'id_segment' => $id_sezionale,
'data' => $data,
'numero' => $numero,
])->first();
if (!empty($fattura)) {
throw new \UnexpectedValueException();
}
2018-09-24 18:10:16 +02:00
}
public function getHeader()
{
return $this->xml['FatturaElettronicaHeader'];
}
public function getBody()
{
return $this->xml['FatturaElettronicaBody'];
}
public static function createAnagrafica($xml, $type = 'Fornitore')
{
$database = database();
$where = [];
$partita_iva = $xml['DatiAnagrafici']['IdFiscaleIVA']['IdCodice'];
if (!empty($partita_iva)) {
$where[] = '`piva` = '.prepare($partita_iva);
}
$codice_fiscale = $xml['DatiAnagrafici']['CodiceFiscale'];
if (!empty($codice_fiscale)) {
$where[] = '`codice_fiscale` = '.prepare($codice_fiscale);
}
$id_anagrafica = $database->fetchOne('SELECT `an_anagrafiche`.`idanagrafica` FROM `an_anagrafiche`
INNER JOIN `an_tipianagrafiche_anagrafiche` ON `an_anagrafiche`.`idanagrafica` = `an_tipianagrafiche_anagrafiche`.`idanagrafica`
INNER JOIN `an_tipianagrafiche` ON `an_tipianagrafiche`.`idtipoanagrafica` = `an_tipianagrafiche_anagrafiche`.`idtipoanagrafica`
WHERE `an_tipianagrafiche`.`descrizione` = '.prepare($type).' AND ('.implode(' OR ', $where).')')['idanagrafica'];
if (!empty($id_anagrafica)) {
return $id_anagrafica;
}
$ragione_sociale = $xml['DatiAnagrafici']['Anagrafica']['Denominazione'] ?: $xml['DatiAnagrafici']['Anagrafica']['Nome'].' '.$xml['DatiAnagrafici']['Anagrafica']['Cognome'];
$anagrafica = Anagrafica::create([
'ragione_sociale' => $ragione_sociale,
'tipologie' => [
TipoAnagrafica::where('descrizione', 'Fornitore')->first()->id
],
]);
// Informazioni sull'anagrafica
$REA = $xml['IscrizioneREA'];
if (!empty($REA)) {
$anagrafica->codicerea = $REA['Ufficio'].'-'.$REA['NumeroREA'];
if (!empty($REA['CapitaleSociale'])) {
$anagrafica->capitale_sociale = $REA['CapitaleSociale'];
}
}
$anagrafica->save();
// Informazioni sulla sede
$info = $xml['Sede'];
$sede = $anagrafica->sedeLegale();
if (!empty($partita_iva)) {
$sede->partita_iva = $partita_iva;
}
if (!empty($codice_fiscale)) {
$sede->codice_fiscale = $codice_fiscale;
}
$sede->indirizzo = $info['Indirizzo'];
$sede->cap = $info['CAP'];
$sede->citta = $info['Comune'];
$sede->indirizzo = $info['Indirizzo'];
$sede->nazione()->associate(Nazione::where('iso2', $info['Nazione'])->first());
if (!empty($info['Provincia'])) {
$sede->provincia = $info['Provincia'];
}
$contatti = $xml['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->id;
}
2018-09-25 11:55:52 +02:00
public function getRighe()
2018-09-24 18:10:16 +02:00
{
2018-09-25 11:55:52 +02:00
$result = $this->getBody()['DatiBeniServizi']['DettaglioLinee'];
if (!isset($result[0])) {
$result = [$result];
}
return $result;
2018-09-24 18:10:16 +02:00
}
2018-09-25 11:55:52 +02:00
public function saveRighe($articoli, $iva)
2018-09-24 18:10:16 +02:00
{
2018-09-25 11:55:52 +02:00
$righe = $this->getRighe();
foreach ($righe as $key => $riga) {
$articolo = ArticoloOriginale::find($articoli[$key]);
if (!empty($articolo)) {
$obj = new Articolo($this->getFattura(), $articolo);
} else {
$obj = new Riga($this->getFattura());
}
$obj->descrizione = $riga['Descrizione'];
$obj->setSubtotale($riga['PrezzoUnitario'], $riga['Quantita']);
/*
$obj->qta = $riga['Quantita'];
$obj->prezzo = $riga['PrezzoUnitario'];
*/
$obj->um = $riga['UnitaMisura'];
$sconto =$riga['ScontoMaggiorazione'];
if (!empty($sconto)) {
$tipo = !empty($sconto['Percentuale']) ? 'PRC' : 'EUR';
$unitario = $sconto['Percentuale'] ?: $sconto['Importo'];
$unitario = ($sconto['Tipo'] == 'SC') ? $unitario : -$unitario;
$obj->sconto_unitario = $unitario;
$obj->tipo_sconto = $tipo;
$obj->sconto = $obj->sconto;
}
$obj->setIVA($iva[$key]);
$obj->save();
}
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'];
if (!isset($result[0])) {
$result = [$result];
}
return $result;
2018-09-24 18:10:16 +02:00
}
public function saveAllegati($directory)
{
2018-09-25 11:55:52 +02:00
$allegati = $this->getAllegati();
2018-09-24 18:10:16 +02:00
foreach ($allegati as $allegato) {
$content = base64_decode($allegato['Attachment']);
$filename = $directory.'/'.$allegato['NomeAttachment'].'.'.strtolower($allegato['FormatoAttachment']);
file_put_contents($filename, $content);
Uploads::register([
'original' => $allegato['NomeAttachment'],
'category' => tr('Fattura elettronica'),
'id_module' => Modules::get('Fatture di acquisto')['id'],
'id_record' => $this->fattura->id,
]);
}
}
2018-09-25 11:55:52 +02:00
public function getFattura()
{
return $this->fattura;
}
2018-09-24 18:10:16 +02:00
/**
* Registra la fattura elettronica come fattura del gestionale.
*
* @return int
*/
2018-09-25 11:55:52 +02:00
public function saveFattura()
2018-09-24 18:10:16 +02:00
{
$id_anagrafica = static::createAnagrafica($this->getHeader()['CedentePrestatore']);
$dati_generali = $this->getBody()['DatiGenerali']['DatiGeneraliDocumento'];
$data = $dati_generali['Data'];
$numero = $dati_generali['Numero'];
2018-09-25 11:55:52 +02:00
$tipo = empty($this->getBody()['DatiGenerali']['DatiTrasporto']) ? 'Fattura immediata di acquisto' : 'Fattura accompagnatoria di acquisto';
$id_tipo = TipoFattura::where('descrizione', $tipo)->first()->id;
2018-09-24 18:10:16 +02:00
$fattura = Fattura::create([
'idanagrafica' => $id_anagrafica,
'data' => $data,
2018-09-25 11:55:52 +02:00
'id_segment' => $this->id_sezionale,
2018-09-24 18:10:16 +02:00
'tipo' => $id_tipo,
]);
2018-09-25 11:55:52 +02:00
$this->fattura = $fattura;
2018-09-24 18:10:16 +02:00
$fattura->numero = $numero;
$stato_documento = StatoFattura::where('descrizione', 'Emessa')->first();
$fattura->stato()->associate($stato_documento);
2018-09-25 11:55:52 +02:00
// Sconto globale
$sconto = $dati_generali['ScontoMaggiorazione'];
if (!empty($sconto)) {
$tipo = !empty($sconto['Percentuale']) ? 'PRC' : 'EUR';
$unitario = $sconto['Percentuale'] ?: $sconto['Importo'];
$unitario = ($sconto['Tipo'] == 'SC') ? $unitario : -$unitario;
$fattura->sconto_globale = $unitario;
$fattura->tipo_sconto_globale = $tipo;
}
$fattura->save();
2018-09-24 18:10:16 +02:00
return $fattura->id;
}
}