openstamanager/plugins/receiptFE/src/Ricevuta.php

263 lines
7.7 KiB
PHP
Executable File

<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* 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/>.
*/
namespace Plugins\ReceiptFE;
use Models\Upload;
use Modules\Fatture\Fattura;
use Modules\Fatture\Stato;
use Plugins;
use UnexpectedValueException;
use Util\XML;
use Util\Zip;
/**
* Classe per la gestione delle ricevute collegate alle Fatture elettroniche in formato XML.
*
* @since 2.4.2
*/
class Ricevuta
{
protected static $directory = null;
/** @var array Percorso del file XML */
protected $file = null;
/** @var array XML della ricevuta */
protected $xml = null;
/** @var array XML della ricevuta */
protected $fattura = null;
public function __construct($name)
{
$file = static::getImportDirectory().'/'.$name;
// Estrazione implicita per il formato ZIP
if (string_ends_with($name, '.zip')) {
$original_file = $file;
$extraction_dir = static::getImportDirectory().'/tmp';
Zip::extract($file, $extraction_dir);
$name = basename($name, '.zip').'.xml';
$file = static::getImportDirectory().'/'.$name;
copy($extraction_dir.'/'.$name, $file);
delete($original_file);
delete($extraction_dir);
}
$this->file = $file;
$this->xml = XML::readFile($this->file);
$filename = explode('.', $name)[0];
$pieces = explode('_', $filename);
$progressivo_invio = $pieces[1];
$this->fattura = Fattura::where([
'progressivo_invio' => $progressivo_invio,
])->first();
if (empty($this->fattura)) {
throw new UnexpectedValueException();
}
}
/**
* Funzione per gestire in modo autonomo il download, l'importazione e il salvataggio di una specifica ricevuta identificata tramite nome.
*
* @param string $name
* @param bool $cambia_stato
*
* @return Fattura|null
*/
public static function process($name, $cambia_stato = true)
{
Interaction::getReceipt($name);
$fattura = null;
try {
$receipt = new Ricevuta($name);
$receipt->save($cambia_stato);
$fattura = $receipt->getFattura();
$receipt->cleanup();
Interaction::processReceipt($name);
} catch (UnexpectedValueException $e) {
}
return $fattura;
}
/**
* Salva il file indicato nella cartella temporanea per una futura elaborazione.
*
* @param string $filename
* @param string $content
*
* @return string
*/
public static function store($filename, $content)
{
$directory = static::getImportDirectory();
$file = $directory.'/'.$filename;
directory($directory);
file_put_contents($file, $content);
return $filename;
}
/**
* Restituisce la cartella temporanea utilizzabile per il salvataggio della ricevuta.
*
* @return string|null
*/
public static function getImportDirectory()
{
if (!isset(self::$directory)) {
$plugin = Plugins::get('Ricevute FE');
self::$directory = base_dir().'/'.$plugin->upload_directory;
}
return self::$directory;
}
/**
* @param string $codice
*
* @return Upload|null
*/
public function saveAllegato($codice)
{
$filename = basename($this->file);
$fattura = $this->getFattura();
// Controllo sulla presenza della stessa ricevuta
$module = $fattura->getModule();
$upload_esistente = $module
->uploads($fattura->id)
->where('original_name', $filename)
->first();
if (!empty($upload_esistente)) {
return $upload_esistente;
}
// Registrazione del file XML come allegato
$upload = Upload::build($this->file, [
'id_module' => $module->id,
'id_record' => $fattura->id,
'original' => $filename,
], tr('Ricevuta _TYPE_', [
'_TYPE_' => $codice,
]), tr('Fattura Elettronica'));
return $upload;
}
/**
* Aggiorna lo stato della fattura relativa alla ricevuta in modo tale da rispecchiare i dati richiesti.
*
* @param $codice
* @param $id_allegato
*/
public function saveStato($codice, $id_allegato)
{
$fattura = $this->getFattura();
// Modifica lo stato solo se la fattura non è già stata consegnata (per evitare problemi da doppi invii)
// In realtà per le PA potrebbe esserci lo stato NE (che può contenere un esito positivo EC01 o negativo EC02) successivo alla RC, quindi aggiungo eccezione nel caso il nuovo codice della ricevuta sia NE.
if ($fattura->codice_stato_fe == 'RC' && $codice != 'EC01' && $codice != 'EC02') {
return;
}
// Processo la ricevuta e salvo data ricezione, codice e messaggio
$descrizione = $this->xml['Destinatario']['Descrizione'];
$data = $this->xml['DataOraRicezione'];
$fattura->data_stato_fe = $data ? date('Y-m-d H:i:s', strtotime($data)) : '';
$fattura->codice_stato_fe = $codice;
$fattura->descrizione_ricevuta_fe = $descrizione;
$fattura->id_ricevuta_principale = $id_allegato;
$fattura->save();
}
/**
* Effettua le operazioni di salvataggio della ricevuta nella fattura relativa.
*/
public function save($cambia_stato = true)
{
$name = basename($this->file);
$filename = explode('.', $name)[0];
$pieces = explode('_', $filename);
$codice_stato = $pieces[2];
// Individuazione codice per il nome dell'allegato
$codice_nome = $codice_stato;
if ($codice_nome == 'NS') {
$lista_errori = $this->xml['ListaErrori'];
$errore = $lista_errori[0] ?: $lista_errori;
$codice_nome = $codice_nome.' - '.$errore['Errore']['Codice'];
}
$upload = $this->saveAllegato($codice_nome);
// Correzione eventuale per lo stato della fattura in Bozza
$fattura = $this->getFattura();
if ($fattura->stato->descrizione == 'Bozza') {
$stato_emessa = Stato::where('descrizione', 'Emessa')->first();
$fattura->stato()->associate($stato_emessa);
$fattura->save();
}
// Controllo per il cambio di stato FE
if ($cambia_stato) {
// In caso di Notifica Esito il codice è definito dal nodo <Esito> della ricevuta
if ($codice_stato == 'NE') {
$codice_stato = $this->xml['EsitoCommittente']['Esito'];
}
$this->saveStato($codice_stato, $upload->id);
}
}
/**
* Restituisce la fattura identificata per la ricevuta.
*
* @return Fattura|null
*/
public function getFattura()
{
return $this->fattura;
}
/**
* Rimuove i file temporanei relativi alla ricevuta.
*/
public function cleanup()
{
delete($this->file);
}
}