1
0
mirror of https://github.com/devcode-it/openstamanager.git synced 2025-02-01 16:36:45 +01:00

Introduzione sistema per le ricevute

This commit is contained in:
Thomas Zilio 2018-12-14 12:50:44 +01:00
parent 4f0091e7a2
commit 868dbb075a
13 changed files with 362 additions and 105 deletions

View File

@ -8,4 +8,5 @@ return [
'modules/interventi' => 'Modules\Interventi',
'plugins/exportFE' => 'Plugins\ExportFE',
'plugins/importFE' => 'Plugins\ImportFE',
'plugins/receiptFE' => 'Plugins\ReceiptFE',
];

View File

@ -39,9 +39,9 @@ if (!function_exists('array_clean')) {
*/
function array_clean($array)
{
return array_values(array_filter($array, function ($value) {
return array_unique(array_values(array_filter($array, function ($value) {
return !empty($value);
}));
})));
}
}

View File

@ -95,6 +95,7 @@ switch (post('op')) {
'rivalsainps' => 0,
'ritenutaacconto' => 0,
'iva_rivalsainps' => 0,
'codice_stato_fe' => post('codice_stato_fe'),
], $data), ['id' => $id_record]);
$query = 'SELECT descrizione FROM co_statidocumento WHERE id='.prepare($idstatodocumento);

View File

@ -99,6 +99,10 @@ if (empty($record['is_fiscale'])) {
<!-- TODO: Rimuovere possibilità di selezionare lo stato pagato obbligando l'utente ad aggiungere il movimento in prima nota -->
{[ "type": "select", "label": "<?php echo tr('Stato'); ?>", "name": "idstatodocumento", "required": 1, "values": "query=<?php echo $query; ?>", "value": "$idstatodocumento$", "class": "unblockable", "extra": " onchange = \"if ($('#idstatodocumento option:selected').text()=='Pagato' || $('#idstatodocumento option:selected').text()=='Parzialmente pagato' ){if( confirm('<?php echo tr('Sicuro di voler impostare manualmente la fattura come pagata senza aggiungere il movimento in prima nota?'); ?>') ){ return true; }else{ $('#idstatodocumento').selectSet(<?php echo $record['idstatodocumento']; ?>); }}\" " ]}
</div>
<div class="col-md-3">
{[ "type": "select", "label": "<?php echo tr('Stato FE'); ?>", "name": "codice_stato_fe", "required": 0, "values": "query=SELECT codice as id, descrizione as text FROM fe_stati_documento", "value": "$codice_stato_fe$", "disabled": <?php echo intval(Plugins\ExportFE\Connection::isEnabled()) ?> ]}
</div>
</div>
<div class="row">
@ -193,7 +197,7 @@ if (!empty($record['is_fiscale'])) {
if (($n2 <= 0 && $record['stato'] == 'Emessa') || $differenza != 0) {
?>
<a class="btn btn-sm btn-primary <?php echo ((!empty(Modules::get('Prima nota'))) ? '' : 'disabled'); ?>" href="javascript:;" onclick="launch_modal( 'Aggiungi prima nota', '<?php echo $rootdir; ?>/add.php?id_module=<?php echo Modules::get('Prima nota')['id']; ?>&iddocumento=<?php echo $id_record; ?>&dir=<?php echo $dir; ?>', 1 );"><i class="fa fa-euro"></i> <?php echo tr('Aggiungi prima nota'); ?>...</a><br><br>
<a class="btn btn-sm btn-primary <?php echo((!empty(Modules::get('Prima nota'))) ? '' : 'disabled'); ?>" href="javascript:;" onclick="launch_modal( 'Aggiungi prima nota', '<?php echo $rootdir; ?>/add.php?id_module=<?php echo Modules::get('Prima nota')['id']; ?>&iddocumento=<?php echo $id_record; ?>&dir=<?php echo $dir; ?>', 1 );"><i class="fa fa-euro"></i> <?php echo tr('Aggiungi prima nota'); ?>...</a><br><br>
<?php
}

View File

@ -28,9 +28,11 @@ switch (filter('op')) {
$result = Interaction::sendXML($id_record);
// Aggiornamento dello stato
database()->update('co_documenti', [
'codice_stato_fe' => 'WAIT',
], ['id' => $id_record]);
if ($result) {
database()->update('co_documenti', [
'codice_stato_fe' => 'WAIT',
], ['id' => $id_record]);
}
echo json_encode([
'sent' => $result,

View File

@ -0,0 +1,71 @@
<?php
namespace Plugins\ExportFE;
use GuzzleHttp\Client;
/**
* Classe per l'interazione con API esterne.
*
* @since 2.4.3
*/
class Connection
{
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 static function isEnabled()
{
return !empty(setting('OSMCloud Services API Token'));
}
protected function request($type, $resource, $data = [], $options = [])
{
$client = static::getClient();
$json = array_merge($data, [
'token' => setting('OSMCloud Services API Token'),
'resource' => $resource,
]);
if (!empty($options['multipart'])) {
foreach ($json as $key => $value) {
$options['multipart'][] = [
'name' => $key,
'contents' => $value,
];
}
} else {
$options['json'] = $json;
}
$options = array_merge($options, [
'http_errors' => false,
]);
return $client->request($type, '', $options);
}
protected function responseBody($response)
{
$body = $response->getBody();
return json_decode($body, true) ?: [];
}
}

View File

@ -9,75 +9,32 @@ use GuzzleHttp\Client;
*
* @since 2.4.3
*/
class Interaction
class Interaction extends Connection
{
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 static 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 sendXML($id_record)
{
try {
$fattura = new FatturaElettronica($id_record);
$file = DOCROOT.'/'.FatturaElettronica::getDirectory().'/'.$fattura->getFilename();
$response = static::request('POST', 'send', [
'name' => $fattura->getFilename(),
], [
$response = static::request('POST', 'send_xml', [], [
'multipart' => [
[
'name' => 'xml',
'contents' => fopen($file, 'r')
'filename' => $fattura->getFilename(),
'contents' => file_get_contents($file)
],
]
]);
$body = $response->getBody();
$body = static::responseBody($response);
if (!empty($body)) {
if (!empty($body['sent'])) {
return true;
}
} catch (UnexpectedValueException $e) {
return false;
}
return true;
return false;
}
}

View File

@ -3,63 +3,23 @@
namespace Plugins\ImportFE;
use GuzzleHttp\Client;
use Plugins\ExportFE\Connection;
/**
* Classe per l'interazione con API esterne.
*
* @since 2.4.3
*/
class Interaction
class Interaction extends Connection
{
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 static 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();
$response = static::request('POST', 'get_fatture_da_importare');
$body = static::responseBody($response);
$list = json_decode($body, true) ?: [];
$list = $body['results'];
$files = glob($directory.'/*.xml');
foreach ($files as $file) {
@ -75,13 +35,12 @@ class Interaction
$file = $directory.'/'.$name;
if (!file_exists($file)) {
$response = static::request('GET', 'get_fattura_da_importare', [
$response = static::request('POST', 'get_fattura_da_importare', [
'name' => $name,
]);
$body = static::responseBody($response);
$body = $response->getBody();
FatturaElettronica::store($name, $body);
FatturaElettronica::store($name, $body['content']);
}
return $name;

View File

@ -0,0 +1,59 @@
<?php
include_once __DIR__.'/../../core.php';
use Plugins\ReceiptFE\Ricevuta;
use Plugins\ReceiptFE\Interaction;
switch (filter('op')) {
case 'save':
$content = file_get_contents($_FILES['blob']['tmp_name']);
$file = FatturaElettronica::store($_FILES['blob']['name'], $content);
if (FatturaElettronica::isValid($file)) {
echo json_encode([
'filename' => $file,
]);
} else {
echo json_encode([
'already' => 1,
]);
}
break;
case 'import':
$list = Interaction::getReceiptList();
$results = [];
foreach ($list as $name) {
$file = Interaction::getReceipt($name);
$result = [];
if (!empty($file)) {
try {
$receipt = new Ricevuta($file['content']);
$result = [
'fattura' => $receipt->getFattura()->numero_esterno,
];
} catch (UnexpectedValueException $e) {
}
}
$results[] = array_merge([
'file' => $name,
], $result);
}
echo json_encode($results);
break;
case 'list':
$list = Interaction::getReceiptList();
echo json_encode($list);
break;
}

119
plugins/receiptFE/edit.php Normal file
View File

@ -0,0 +1,119 @@
<?php
include_once __DIR__.'/../../core.php';
use Plugins\ReceiptFE\Interaction;
if (!Interaction::isEnabled()) {
echo '
<p>'.tr('Il sistema di rilevazione automatico è attualmente disabilitato').'.</p>
<p>'.tr('Per maggiori informazioni contatta gli sviluppatori ufficiali').'.</p>';
return;
}
echo '
<p>'.tr("Le ricevute delle Fatture Elettroniche permettono di individuare se una determinata fattura rilasciata è $requesta accettata dal Sistema Di Interscambio e dal cliente relativo").'.</p>
<p>'.tr("Tramite il pulsante _BTN_ è possibile procedere all controllo automatico di queste ricevute, che aggiorneranno di conseguenza lo $requesto dei documenti relativi e verranno allegate ad essi", [
'_BTN_' => '<b>Ricerca</b>',
]).'.</p>
<br>';
echo '
<div class="text-center">
<button type="button" class="btn btn-primary btn-lg" onclick="search(this)">
<i class="fa fa-refresh"></i> '.tr('Ricerca').'...
</button>
</div>';
echo '
<script>
function search(btn) {
var restore = buttonLoading(btn);
$.ajax({
url: globals.rootdir + "/actions.php",
data: {
op: "list",
id_module: "'.$id_module.'",
id_plugin: "'.$id_plugin.'",
},
type: "post",
success: function(data){
data = JSON.parse(data);
count = data.length;
buttonRestore(btn, restore);
swal({
title: "'.tr('Ricevute da importare: _COUNT_', [
'_COUNT_' => '" + count + "'
]).'",
html: "'.tr('Sono state individuate _COUNT_ ricevute da importare', [
'_COUNT_' => '" + count + "'
]).'.",
showCancelButton: true,
confirmButtonText: "'.tr('Procedi').'",
type: "info",
}).then(function (result) {
importAll(btn);
});
},
error: function(data) {
alert("'.tr('Errore').': " + data);
buttonRestore(btn, restore);
}
});
}
function importAll(btn) {
var restore = buttonLoading(btn);
$.ajax({
url: globals.rootdir + "/actions.php",
data: {
op: "import",
id_module: "'.$id_module.'",
id_plugin: "'.$id_plugin.'",
},
type: "post",
success: function(data){
data = JSON.parse(data);
var html = "'.tr("Le seguenti ricevute sono state considerate:").'";
console.log(data);
data.forEach(function(element) {
var text = "";
if(element.fattura) {
text += element.fattura;
} else {
text += "<i>'.tr('Ricevuta non ottenuta correttamente').'</i>";
}
text += " (" + element.file + ")";
html += "<li>" + text + "</li>";
});
html += "<br><small>'.tr("Se si sono verificati degli errori durante la procedura e il problema continua a verificarsi, contatta l'assistenza ufficiale").'</small>";
swal({
title: "'.tr('Importazione completata!').'",
html: html,
type: "info",
})
buttonRestore(btn, restore);
},
error: function(data) {
alert("'.tr('Errore').': " + data);
buttonRestore(btn, restore);
}
});
}
</script>';

View File

@ -0,0 +1,36 @@
<?php
namespace Plugins\ReceiptFE;
use GuzzleHttp\Client;
use Plugins\ExportFE\Connection;
/**
* Classe per l'interazione con API esterne.
*
* @since 2.4.3
*/
class Interaction extends Connection
{
public static function getReceiptList()
{
$response = static::request('POST', 'get_receipt_list');
$body = static::responseBody($response)['results'];
return $body;
}
public static function getReceipt($name)
{
$response = static::request('POST', 'get_receipt', [
'name' => $name,
]);
$body = static::responseBody($response);
if($body['code'] != '200'){
return false;
}
return $body;
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace Plugins\ReceiptFE;
use Modules\Fatture\Fattura;
use Util\XML;
use Uploads;
use Modules;
use UnexpectedValueException;
/**
* Classe per la gestione della fatturazione elettronica in XML.
*
* @since 2.4.2
*/
class Ricevuta
{
/** @var array XML della fattura */
protected $xml = null;
/** @var array XML della fattura */
protected $fattura = null;
public function __construct($content)
{
$this->xml = XML::read($content);
$nome = $this->xml['NomeFile'];
$pieces = explode('_', $nome);
$progressivo_invio = explode('.', $pieces[1])[0];
$this->fattura = Fattura::where([
'progressivo_invio' => $progressivo_invio,
])->first();
if (empty($this->fattura)) {
throw new UnexpectedValueException();
}
}
public function getFattura()
{
return $this->fattura;
}
}

2
update/2_4_5.sql Normal file
View File

@ -0,0 +1,2 @@
INSERT INTO `zz_plugins` (`id`, `name`, `title`, `idmodule_from`, `idmodule_to`, `position`, `directory`, `options`) VALUES
(NULL, 'Ricevute FE', 'Ricevute FE', (SELECT `id` FROM `zz_modules` WHERE `name`='Fatture di vendita'), (SELECT `id` FROM `zz_modules` WHERE `name`='Fatture di vendita'), 'tab_main', 'receiptFE', 'custom'),