Miglioramento import FE

This commit is contained in:
Thomas Zilio 2018-11-30 15:33:25 +01:00
parent 37e99d0777
commit 4d923b81e0
15 changed files with 2872 additions and 2617 deletions

View File

@ -6,6 +6,6 @@ return [
'modules/articoli' => 'Modules\Articoli',
'modules/fatture' => 'Modules\Fatture',
'modules/interventi' => 'Modules\Interventi',
'plugins/exportPA' => 'Plugins\ExportPA',
'plugins/importPA' => 'Plugins\ImportPA',
'plugins/exportFE' => 'Plugins\ExportFE',
'plugins/importFE' => 'Plugins\ImportFE',
];

View File

@ -25,7 +25,7 @@ if (!empty($fattura_pa)) {
}
// Campi obbligatori per l'anagrafica Azienda
$azienda = Plugins\ExportPA\FatturaElettronica::getAzienda();
$azienda = Plugins\ExportFE\FatturaElettronica::getAzienda();
$fields = [
'piva' => 'Partita IVA',
// 'codice_fiscale' => 'Codice Fiscale',
@ -125,7 +125,7 @@ echo '
echo '
<a href="'.ROOTDIR.'/plugins/exportPA/view.php?id_record='.$id_record.'" class="btn btn-info btn-lg '.($generated ? '' : 'disabled').'" target="_blank" '.($generated ? '' : 'disabled').'>
<a href="'.ROOTDIR.'/plugins/exportFE/view.php?id_record='.$id_record.'" class="btn btn-info btn-lg '.($generated ? '' : 'disabled').'" target="_blank" '.($generated ? '' : 'disabled').'>
<i class="fa fa-eye"></i> '.tr('Visualizza').'
</a>

View File

@ -1,6 +1,6 @@
<?php
use Plugins\ExportPA\FatturaElettronica;
use Plugins\ExportFE\FatturaElettronica;
try {
$fattura_pa = new FatturaElettronica($id_record);

View File

@ -1,6 +1,6 @@
<?php
namespace Plugins\ExportPA;
namespace Plugins\ExportFE;
use FluidXml\FluidXml;
use Respect\Validation\Validator as v;

View File

@ -2,30 +2,39 @@
include_once __DIR__.'/../../core.php';
use Plugins\ImportFE\FatturaElettronica;
use Plugins\ImportFE\Interaction;
include_once Modules::filepath('Fatture di vendita', 'modutil.php');
$directory = Uploads::getDirectory($id_module);
switch (filter('op')) {
case 'save':
$id = Uploads::getFakeID();
$filename = $upload = Uploads::upload($_FILES['blob'], [
'name' => tr('Fattura Elettronica'),
'category' => tr('Fattura Elettronica'),
'id_module' => $id_module,
'id_record' => $id,
]);
try {
$xml = file_get_contents(DOCROOT.'/'.$directory.'/'.$filename);
$fattura_pa = new Plugins\ImportPA\FatturaElettronica($xml, post('id_segment'));
$content = file_get_contents($_FILES['blob']['tmp_name']);
$file = FatturaElettronica::store($_FILES['blob']['name'], $content);
if (FatturaElettronica::isValid($file)) {
echo json_encode([
'id' => $id,
'filename' => $filename,
'id_segment' => post('id_segment'),
'filename' => $file,
]);
} catch (UnexpectedValueException $e) {
} else {
echo json_encode([
'already' => 1,
]);
}
break;
case 'prepare':
$name = get('name');
$file = Interaction::getImportXML($name);
if (FatturaElettronica::isValid($file)) {
echo json_encode([
'filename' => $file,
]);
} else {
echo json_encode([
'already' => 1,
]);
@ -34,23 +43,17 @@ switch (filter('op')) {
break;
case 'generate':
$id = post('id');
$filename = post('filename');
$xml = file_get_contents(DOCROOT.'/'.$directory.'/'.$filename);
$fattura_pa = new Plugins\ImportPA\FatturaElettronica($xml, post('id_segment'));
$id_record = $fattura_pa->saveFattura(post('pagamento'));
$idrivalsainps = 0;
$idritenutaacconto = 0;
$bollo = 0;
$fattura_pa = new FatturaElettronica(post('filename'));
$id_record = $fattura_pa->saveFattura(post('pagamento'), post('id_segment'));
$fattura_pa->saveRighe(post('articoli'), post('iva'), post('conto'));
$fattura_pa->getFattura()->updateSconto();
$fattura_pa->saveAllegati($directory);
$fattura_pa->saveAllegati();
Uploads::updateFake($id, $id_record);
$idrivalsainps = 0;
$idritenutaacconto = 0;
$bollo = 0;
ricalcola_costiagg_fattura($id_record, $idrivalsainps, $idritenutaacconto, $bollo);
elimina_scadenza($id_record);
@ -58,6 +61,8 @@ switch (filter('op')) {
aggiungi_scadenza($id_record, post('pagamento'));
aggiungi_movimento($id_record, 'uscita');
$fattura_pa->delete();
redirect(ROOTDIR.'/editor.php?id_module='.$id_module.'&id_record='.$id_record);
break;

View File

@ -2,6 +2,8 @@
include_once __DIR__.'/../../core.php';
use Plugins\ImportFE\Interaction;
echo '
<script>
function upload() {
@ -24,7 +26,7 @@ echo '
data = JSON.parse(data);
if (!data.already) {
launch_modal("'.tr('Righe fattura').'", globals.rootdir + "/actions.php?id_module=" + globals.id_module + "&id_plugin=" + '.$id_plugin.' + "&op=list&id=" + data.id + "&filename=" + data.filename + "&id_segment=" + data.id_segment);
launch_modal("'.tr('Righe fattura').'", globals.rootdir + "/actions.php?id_module=" + globals.id_module + "&id_plugin=" + '.$id_plugin.' + "&op=list&filename=" + data.filename);
} else {
swal({
title: "'.tr('Fattura già importata!').'",
@ -54,23 +56,47 @@ echo '
</h3>
</div>
<div class="box-body" id="upload">
<div class="row">
<div class="col-md-9">
<label><input type="file" name="blob" id="blob"></label>
</div>
<div class="col-md-3">
{[ "type": "select", "label": "'.tr('Sezionale').'", "name": "id_segment", "required": 1, "values": "query=SELECT id, name AS descrizione FROM zz_segments WHERE id_module='.$id_module.' ORDER BY name", "value": "'.$_SESSION['module_'.$id_module]['id_segment'].'" ]}
</div>
</div>
<div class="row">
<div class="col-md-12 text-center">
<button type="button" class="btn btn-primary btn-lg" onclick="upload()">
<button type="button" class="btn btn-primary btn-lg pull-right" onclick="upload()">
<i class="fa fa-upload"></i> '.tr('Carica').'...
</button>
</div>
</div>
</div>
</div>';
if (Interaction::isEnabled()) {
echo '
<div class="box box-info">
<div class="box-header with-border">
<h3 class="box-title">
'.tr('Importazione automatica').'</span>
</h3>
<button type="button" class="btn btn-primary pull-right" onclick="search(this)">
<i class="fa fa-refresh"></i> '.tr('Ricerca').'...
</button>
</div>
<div class="box-body" id="list">';
include $structure->filepath('list.php');
echo '
</div>
</div>
<script>
function search(button) {
var restore = buttonLoading(button);
$("#list").load("'.$structure->fileurl('list.php').'?id_module='.$id_module.'&id_plugin='.$id_plugin.'", function() {
buttonRestore(button, restore);
});
}
</script>';
}

70
plugins/importFE/list.php Normal file
View File

@ -0,0 +1,70 @@
<?php
include_once __DIR__.'/../../core.php';
use Plugins\ImportFE\Interaction;
$list = Interaction::listToImport();
if (!empty($list)) {
echo '
<table class="table table-striped table-hover table-condensed table-bordered">
<thead>
<tr>
<th>'.tr('Nome').'</th>
<th width="60" class="text-center">#</th>
</tr>
</thead>
<tbody>';
foreach ($list as $element) {
echo '
<tr>
<td>'.$element.'</td>
<td>
<button type="button" class="btn btn-warning" onclick="download(this, \''.$element.'\')">
<i class="fa fa-download"></i> '.tr('Importa').'
</button>
</td>
</tr>';
}
echo '
</tbody>
</table>';
} else {
echo '
<p>'.tr('Nessuna fattura da importare').'.</p>';
}
echo '
<script>
function download(button, file) {
var restore = buttonLoading(button);
$.ajax({
url: globals.rootdir + "/actions.php",
type: "get",
data: {
id_module: globals.id_module,
id_plugin: '.$id_plugin.',
op: "prepare",
name: file,
},
success: function(data) {
data = JSON.parse(data);
if (!data.already) {
launch_modal("'.tr('Righe fattura').'", globals.rootdir + "/actions.php?id_module=" + globals.id_module + "&id_plugin=" + '.$id_plugin.' + "&op=list&filename=" + data.filename);
} else {
swal({
title: "'.tr('Fattura già importata!').'",
type: "info",
})
}
buttonRestore(button, restore);
}
});
}
</script>';

View File

@ -2,10 +2,7 @@
include_once __DIR__.'/../../core.php';
$directory = Uploads::getDirectory($id_module);
$xml = file_get_contents(DOCROOT.'/'.$directory.'/'.get('filename'));
$fattura_pa = new Plugins\ImportPA\FatturaElettronica($xml, post('id_segment'));
$fattura_pa = new Plugins\ImportFE\FatturaElettronica(get('filename'));
echo '
<form action="'.$rootdir.'/actions.php" method="post">
@ -63,6 +60,10 @@ echo '
echo '
{[ "type": "select", "label": "'.tr('Pagamento').'", "name": "pagamento", "required": 1, "values": "query='.$query.'" ]}';
// Sezionale
echo '
{[ "type": "select", "label": "'.tr('Sezionale').'", "name": "id_segment", "required": 1, "values": "query=SELECT id, name AS descrizione FROM zz_segments WHERE id_module='.$id_module.' ORDER BY name", "value": "'.$_SESSION['module_'.$id_module]['id_segment'].'" ]}';
// Righe
$righe = $fattura_pa->getRighe();
@ -77,7 +78,7 @@ if (!empty($righe)) {
<th width="10%">'.tr('Q.').'</th>
<th width="15%">'.tr('Prezzo unitario').'</th>
<th width="15%">'.tr('Iva associata').'*</th>
<th width="15%">'.tr('Conto').'</th>
<th width="15%">'.tr('Conto').'*</th>
<th width="15%">'.tr('Articolo associato').'</th>
</tr>';
@ -93,13 +94,13 @@ if (!empty($righe)) {
echo '
<tr>
<td>'.$riga['Descrizione'].'</td>
<td>'.Translator::numberToLocale( $riga['Quantita'] ).' '.$riga['UnitaMisura'].'</td>
<td>'.Translator::numberToLocale( $riga['PrezzoUnitario'] ).'&nbsp;&euro;</td>
<td>'.Translator::numberToLocale($riga['Quantita']).' '.$riga['UnitaMisura'].'</td>
<td>'.Translator::numberToLocale($riga['PrezzoUnitario']).'&nbsp;&euro;</td>
<td>
{[ "type": "select", "name": "iva['.$key.']", "values": "query='.str_replace('"', '\"', $query).'", "required": 1 ]}
</td>
<td>
{[ "type": "select", "name": "conto['.$key.']", "ajax-source": "conti-acquisti" ]}
{[ "type": "select", "name": "conto['.$key.']", "ajax-source": "conti-acquisti", "required": 1 ]}
</td>
<td>
{[ "type": "select", "name": "articoli['.$key.']", "ajax-source": "articoli" ]}

View File

@ -1,6 +1,6 @@
<?php
namespace Plugins\ImportPA;
namespace Plugins\ImportFE;
use Modules\Fatture\Fattura;
use Modules\Fatture\Riga;
@ -13,6 +13,7 @@ use Modules\Anagrafiche\Tipo as TipoAnagrafica;
use Modules\Anagrafiche\Nazione;
use Uploads;
use Modules;
use UnexpectedValueException;
/**
* Classe per la gestione della fatturazione elettronica in XML.
@ -21,35 +22,77 @@ use Modules;
*/
class FatturaElettronica
{
protected static $directory = null;
/** @var array Percorso del file XML */
protected $file = null;
/** @var array XML della fattura */
protected $xml = null;
/** @var Fattura Fattura collegata */
protected $fattura = null;
protected $id_sezionale = null;
public function __construct($content, $id_sezionale)
public function __construct($file)
{
$xml = simplexml_load_string($content, 'SimpleXMLElement', LIBXML_NOCDATA);
$json = json_encode($xml);
$array = json_decode($json, true);
$this->file = static::getImportDirectory().'/'.$file;
$this->xml = $array;
$this->id_sezionale = $id_sezionale;
$xml = simplexml_load_file($this->file, 'SimpleXMLElement', LIBXML_NOCDATA);
$json = json_decode(json_encode($xml), true);
$this->xml = $json;
// Individuazione fattura pre-esistente
$dati_generali = $this->getBody()['DatiGenerali']['DatiGeneraliDocumento'];
$data = $dati_generali['Data'];
$numero = $dati_generali['Numero'];
$progressivo_invio = $this->getHeader()['DatiTrasmissione']['ProgressivoInvio'];
$fattura = Fattura::where([
'id_segment' => $id_sezionale,
'progressivo_invio' => $progressivo_invio,
'data' => $data,
'numero' => $numero,
])->first();
if (!empty($fattura)) {
throw new \UnexpectedValueException();
$this->delete();
throw new UnexpectedValueException();
}
}
public static function getImportDirectory()
{
if (!isset(self::$directory)) {
$module = Modules::get('Fatture di acquisto');
$plugin = $module->plugins->first(function ($value, $key) {
return $value->name = 'Fatturazione Elettronica';
});
self::$directory = DOCROOT.'/'.$plugin->upload_directory;
}
return self::$directory;
}
public static function store($filename, $content)
{
$file = static::getImportDirectory().'/'.$filename;
file_put_contents($file, $content);
return $filename;
}
public static function isValid($file)
{
try {
new static($file);
return true;
} catch (UnexpectedValueException $e) {
return false;
}
}
@ -200,12 +243,18 @@ class FatturaElettronica
return $result;
}
public function saveAllegati($directory)
public function saveAllegati()
{
$allegati = $this->getAllegati();
$module = Modules::get('Fatture di acquisto');
$info = [
'category' => tr('Fattura Elettronica'),
'id_module' => $module->id,
'id_record' => $this->fattura->id,
];
foreach ($allegati as $allegato) {
$content = base64_decode($allegato['Attachment']);
$original = $allegato['NomeAttachment'].'.'.strtolower($allegato['FormatoAttachment']);
@ -213,16 +262,18 @@ class FatturaElettronica
'id_module' => $module['id'],
]);
file_put_contents($directory.'/'.$filename, $content);
file_put_contents($module->upload_directory.'/'.$filename, $content);
Uploads::register([
Uploads::register(array_merge($info, [
'filename' => $filename,
'original' => $original,
'category' => tr('Fattura elettronica'),
'id_module' => $module['id'],
'id_record' => $this->fattura->id,
]);
]));
}
// Registrazione XML come allegato
$filename = Uploads::upload($this->file, array_merge($info, [
'name' => tr('Fattura Elettronica'),
]));
}
public function getFattura()
@ -235,22 +286,22 @@ class FatturaElettronica
*
* @return int
*/
public function saveFattura($id_pagamento)
public function saveFattura($id_pagamento, $id_sezionale)
{
$anagrafica = static::createAnagrafica($this->getHeader()['CedentePrestatore']);
$dati_generali = $this->getBody()['DatiGenerali']['DatiGeneraliDocumento'];
$data = $dati_generali['Data'];
$numero = Fattura::getNumero($data, 'uscita', $this->id_sezionale);
$numero_esterno = $dati_generali['Numero'];
$progressivo_invio = $this->getHeader()['DatiTrasmissione']['ProgressivoInvio'];
$descrizione_tipo = empty($this->getBody()['DatiGenerali']['DatiTrasporto']) ? 'Fattura immediata di acquisto' : 'Fattura accompagnatoria di acquisto';
$tipo = TipoFattura::where('descrizione', $descrizione_tipo)->first();
$fattura = Fattura::make($anagrafica, $tipo, $data, $this->id_sezionale);
$fattura = Fattura::make($anagrafica, $tipo, $data, $id_sezionale);
$this->fattura = $fattura;
$fattura->numero = $numero;
$fattura->progressivo_invio = $progressivo_invio;
$fattura->numero_esterno = $numero_esterno;
$fattura->idpagamento = $id_pagamento;
@ -288,4 +339,9 @@ class FatturaElettronica
return $fattura->id;
}
public function delete()
{
delete($this->file);
}
}

View File

@ -0,0 +1,91 @@
<?php
namespace Plugins\ImportFE;
use GuzzleHttp\Client;
use Modules;
use Uploads;
/**
* Classe per l'interazione con API esterne.
*
* @since 2.4.3
*/
class Interaction
{
protected static $client = null;
/**
* Restituisce l'oggetto per la connessione all'API del progetto.
*
* @return Client
*/
protected static function getClient()
{
if (!isset(self::$client)) {
self::$client = new Client([
'base_uri' => 'https://services.osmcloud.it/v1/',
'verify' => false
]);
}
return self::$client;
}
public function isEnabled()
{
return false;
}
protected function request($type, $resource, $data = [], $options = [])
{
$client = static::getClient();
$json = array_merge($data, [
'token' => setting('OSMCloud Services API Token'),
'resource' => $resource,
]);
$options = array_merge($options, [
'json' => $json,
'http_errors' => false,
]);
return $client->request($type, '', $options);
}
public static function listToImport()
{
$directory = FatturaElettronica::getImportDirectory();
$response = static::request('GET', 'get_fatture_da_importare');
$body = $response->getBody();
$list = json_decode($body, true) ?: [];
$files = glob($directory.'/*.xml');
foreach ($files as $file) {
$list[] = basename($file);
}
return array_clean($list);
}
public static function getImportXML($name)
{
$directory = FatturaElettronica::getImportDirectory();
$file = $directory.'/'.$name;
if (!file_exists($file)) {
$response = static::request('GET', 'get_fattura_da_importare', [
'name' => $name,
]);
$body = $response->getBody();
FatturaElettronica::store($name, $body);
}
return $name;
}
}

View File

@ -86,15 +86,17 @@ class Uploads
*/
public static function upload($source, $data, $options = [])
{
$src = $source['tmp_name'];
$original = $source['name'];
$original = isset($source['name']) ? $source['name'] : $source;
$filename = self::getName($original, $data);
$directory = DOCROOT.'/'.self::getDirectory($data['id_module'], $data['id_plugin']);
// Creazione file fisico
if (!directory($directory) || !move_uploaded_file($src, $directory.'/'.$filename)) {
if (
!directory($directory) ||
(is_uploaded_file($source['tmp_name']) && !move_uploaded_file($source['tmp_name'], $directory.'/'.$filename)) ||
(is_string($source) && !copy($source, $directory.'/'.$filename))
) {
return null;
}

View File

@ -48,3 +48,7 @@ UPDATE `zz_views` SET `visible` = '0' WHERE `zz_views`.`name` = 'id' AND `id_mod
-- Colonna tipi di spedizione predefinita
INSERT INTO `zz_views` (`id`, `id_module`, `name`, `query`, `order`, `search`, `slow`, `format`, `search_inside`, `order_by`, `visible`, `summable`, `default` ) VALUES (NULL, (SELECT `id` FROM `zz_modules` WHERE `name` = 'Tipi di spedizione'), 'Predefinita', 'IF(predefined, '''', ''No'')', 2, 1, 0, 0, NULL, NULL, 0, 0, 0);
-- Fix plugin
UPDATE `zz_plugins` SET `directory` = 'exportFE' WHERE `idmodule_to` = (SELECT `id` FROM `zz_modules` WHERE `name`='Fatture di vendita') AND `name` = 'Fatturazione Elettronica';
UPDATE `zz_plugins` SET `directory` = 'importFE' WHERE `idmodule_to` = (SELECT `id` FROM `zz_modules` WHERE `name`='Fatture di acquisto') AND `name` = 'Fatturazione Elettronica';