Fix generali

This commit is contained in:
Thomas Zilio 2019-02-12 11:42:48 +01:00
parent 4db0150cbf
commit f5a91d5d6d
14 changed files with 246 additions and 126 deletions

View File

@ -37,18 +37,17 @@ if ($dir == 'entrata') {
if ($dir == 'entrata') {
$rs2 = $dbo->fetchArray('SELECT piva, codice_fiscale, citta, indirizzo, cap, provincia, id_nazione, tipo FROM an_anagrafiche WHERE idanagrafica='.prepare($record['idanagrafica']));
$campi_mancanti = [];
//di default è un azienda e chiedo la partita iva
if (empty($rs2[0]['piva']) and (empty($rs2[0]['tipo']) or $rs2[0]['tipo'] == 'Azienda')) {
//di default è un azienda e chiedo la partita iva
if (empty($rs2[0]['piva']) and (empty($rs2[0]['tipo']) or $rs2[0]['tipo'] == 'Azienda')) {
array_push($campi_mancanti, 'Partita IVA');
}
//se è un privato o un ente pubblico controllo il codice fiscale
//se è un privato o un ente pubblico controllo il codice fiscale
if (($rs2[0]['tipo'] == 'Privato' or $rs2[0]['tipo'] == 'Ente pubblico') and empty($rs2[0]['codice_fiscale'])) {
array_push($campi_mancanti, 'Codice fiscale');
}
if ($rs2[0]['citta'] == '') {
array_push($campi_mancanti, 'Città');
}
@ -263,7 +262,7 @@ if ($dir == 'uscita') {
<div class="row">
<div class="col-md-12">
{[ "type": "textarea", "label": "<?php echo tr('Note aggiuntive'); ?>", "name": "note_aggiuntive", "help": "<?php echo tr('Note interne.'); ?>", "value": "$note_aggiuntive$" ]}
{[ "type": "textarea", "label": "<?php echo tr('Note aggiuntive'); ?>", "name": "note_aggiuntive", "help": "<?php echo tr('Note interne.'); ?>", "value": "$note_aggiuntive$", "class": "unblockable" ]}
</div>
</div>
</div>

View File

@ -109,11 +109,12 @@ function aggiungi_scadenza($iddocumento, $pagamento = '', $pagato = 0)
{
$dbo = database();
$totale_da_pagare = 0.00;
$totale_fattura = get_totale_fattura($iddocumento);
$netto_fattura = get_netto_fattura($iddocumento);
$imponibile_fattura = get_imponibile_fattura($iddocumento);
$totale_iva = sum(abs($totale_fattura), -abs($imponibile_fattura));
$fattura = Fattura::find($iddocumento);
$ricalcola = true;
if ($fattura->isFE()) {
$ricalcola = $fattura->registraScadenzeFE($pagato);
}
// Lettura data di emissione fattura
$query3 = 'SELECT ritenutaacconto, data FROM co_documenti WHERE id='.prepare($iddocumento);
@ -121,77 +122,86 @@ function aggiungi_scadenza($iddocumento, $pagamento = '', $pagato = 0)
$data = $rs[0]['data'];
$ritenutaacconto = $rs[0]['ritenutaacconto'];
// Verifico se la fattura è di acquisto o di vendita per scegliere che segno mettere nel totale
$query2 = 'SELECT dir FROM co_documenti INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id WHERE co_documenti.id='.prepare($iddocumento);
$rs2 = $dbo->fetchArray($query2);
$dir = $rs2[0]['dir'];
if ($ricalcola) {
$totale_da_pagare = 0.00;
/*
Inserisco la nuova scadenza (anche più di una riga per pagamenti multipli
*/
// Se il pagamento non è specificato lo leggo dal documento
if ($pagamento == '') {
$query = 'SELECT descrizione FROM co_pagamenti WHERE id=(SELECT idpagamento FROM co_documenti WHERE id='.prepare($iddocumento).')';
$rs = $dbo->fetchArray($query);
$pagamento = $rs[0]['descrizione'];
}
$totale_fattura = get_totale_fattura($iddocumento);
$netto_fattura = get_netto_fattura($iddocumento);
$imponibile_fattura = get_imponibile_fattura($iddocumento);
$totale_iva = sum(abs($totale_fattura), -abs($imponibile_fattura));
$query4 = 'SELECT * FROM co_pagamenti WHERE descrizione='.prepare($pagamento);
$rs = $dbo->fetchArray($query4);
for ($i = 0; $i < sizeof($rs); ++$i) {
// X giorni esatti
if ($rs[$i]['giorno'] == 0) {
$scadenza = date('Y-m-d', strtotime($data.' +'.$rs[$i]['num_giorni'].' day'));
// Verifico se la fattura è di acquisto o di vendita per scegliere che segno mettere nel totale
$query2 = 'SELECT dir FROM co_documenti INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id WHERE co_documenti.id='.prepare($iddocumento);
$rs2 = $dbo->fetchArray($query2);
$dir = $rs2[0]['dir'];
/*
Inserisco la nuova scadenza (anche più di una riga per pagamenti multipli
*/
// Se il pagamento non è specificato lo leggo dal documento
if ($pagamento == '') {
$query = 'SELECT descrizione FROM co_pagamenti WHERE id=(SELECT idpagamento FROM co_documenti WHERE id='.prepare($iddocumento).')';
$rs = $dbo->fetchArray($query);
$pagamento = $rs[0]['descrizione'];
}
// Ultimo del mese
elseif ($rs[$i]['giorno'] < 0) {
$date = new DateTime($data);
$add = floor($rs[$i]['num_giorni'] / 30);
for ($c = 0; $c < $add; ++$c) {
$date->modify('last day of next month');
$query4 = 'SELECT * FROM co_pagamenti WHERE descrizione='.prepare($pagamento);
$rs = $dbo->fetchArray($query4);
for ($i = 0; $i < sizeof($rs); ++$i) {
// X giorni esatti
if ($rs[$i]['giorno'] == 0) {
$scadenza = date('Y-m-d', strtotime($data.' +'.$rs[$i]['num_giorni'].' day'));
}
// Ultimo del mese più X giorni
$giorni = -$rs[$i]['giorno'] - 1;
if ($giorni > 0) {
$date->modify('+'.($giorni).' day');
} else {
$date->modify('last day of this month');
// Ultimo del mese
elseif ($rs[$i]['giorno'] < 0) {
$date = new DateTime($data);
$add = floor($rs[$i]['num_giorni'] / 30);
for ($c = 0; $c < $add; ++$c) {
$date->modify('last day of next month');
}
// Ultimo del mese più X giorni
$giorni = -$rs[$i]['giorno'] - 1;
if ($giorni > 0) {
$date->modify('+'.($giorni).' day');
} else {
$date->modify('last day of this month');
}
$scadenza = $date->format('Y-m-d');
}
$scadenza = $date->format('Y-m-d');
}
// Giorno preciso del mese
else {
$scadenza = date('Y-m-'.$rs[$i]['giorno'], strtotime($data.' +'.$rs[$i]['num_giorni'].' day'));
}
// Giorno preciso del mese
else {
$scadenza = date('Y-m-'.$rs[$i]['giorno'], strtotime($data.' +'.$rs[$i]['num_giorni'].' day'));
}
// All'ultimo ciclo imposto come cifra da pagare il totale della fattura meno gli importi già inseriti in scadenziario per evitare di inserire cifre arrotondate "male"
if ($i == (sizeof($rs) - 1)) {
$da_pagare = sum($netto_fattura, -$totale_da_pagare, 2);
}
// All'ultimo ciclo imposto come cifra da pagare il totale della fattura meno gli importi già inseriti in scadenziario per evitare di inserire cifre arrotondate "male"
if ($i == (sizeof($rs) - 1)) {
$da_pagare = sum($netto_fattura, -$totale_da_pagare, 2);
}
// Totale da pagare (totale x percentuale di pagamento nei casi pagamenti multipli)
else {
$da_pagare = sum($netto_fattura / 100 * $rs[$i]['prc'], 0, 2);
}
$totale_da_pagare = sum($da_pagare, $totale_da_pagare, 2);
// Totale da pagare (totale x percentuale di pagamento nei casi pagamenti multipli)
else {
$da_pagare = sum($netto_fattura / 100 * $rs[$i]['prc'], 0, 2);
}
$totale_da_pagare = sum($da_pagare, $totale_da_pagare, 2);
if ($dir == 'uscita') {
$da_pagare = -$da_pagare;
}
if ($dir == 'uscita') {
$da_pagare = -$da_pagare;
}
$dbo->query('INSERT INTO co_scadenziario(iddocumento, data_emissione, scadenza, da_pagare, pagato, tipo) VALUES('.prepare($iddocumento).', '.prepare($data).', '.prepare($scadenza).', '.prepare($da_pagare).", 0, 'fattura')");
$dbo->query('INSERT INTO co_scadenziario(iddocumento, data_emissione, scadenza, da_pagare, pagato, tipo) VALUES('.prepare($iddocumento).', '.prepare($data).', '.prepare($scadenza).', '.prepare($da_pagare).", 0, 'fattura')");
if ($pagato) {
$id_scadenza = $dbo->lastInsertedID();
$dbo->update('co_scadenziario', [
if ($pagato) {
$id_scadenza = $dbo->lastInsertedID();
$dbo->update('co_scadenziario', [
'pagato' => $da_pagare,
'data_pagamento' => $data,
], ['id' => $id_scadenza]);
}
}
}

View File

@ -4,6 +4,7 @@ namespace Modules\Fatture;
use Common\Document;
use Modules\Anagrafiche\Anagrafica;
use Plugins\ExportFE\FatturaElettronica;
use Traits\RecordTrait;
use Util\Generator;
@ -226,6 +227,51 @@ class Fattura extends Document
return $this->hasOne(Components\Sconto::class, 'iddocumento');
}
public function getXML()
{
if (empty($this->progressivo_invio)) {
$fe = new FatturaElettronica($this->id);
return $fe->toXML();
}
$file = $this->uploads()->where('name', 'Fattura Elettronica')->first();
return file_get_contents($file->filepath);
}
public function isFE()
{
return !empty($this->progressivo_invio) && $this->module == 'Fatture di acquisto';
}
public function registraScadenzeFE($is_pagato = false)
{
$database = $dbo = database();
$xml = \Util\XML::read($this->getXML());
$scadenze = $xml['FatturaElettronicaBody']['DatiPagamento']['DettaglioPagamento'];
$scadenze = isset($scadenze[0]) ? $scadenze : [$scadenze];
foreach ($scadenze as $scadenza) {
$data = $scadenza['DataScadenzaPagamento'];
$importo = $scadenza['ImportoPagamento'];
$dbo->insert('co_scadenziario', [
'iddocumento' => $this->id,
'data_emissione' => $this->data,
'scadenza' => $data,
'da_pagare' => $importo,
'tipo' => 'fattura',
'pagato' => $is_pagato ? $importo : 0,
'data_pagamento' => $is_pagato ? $data : '',
], ['id' => $id_scadenza]);
}
return !empty($scadenze);
}
// Metodi statici
/**

View File

@ -20,9 +20,8 @@ if (!empty($fattura_pa)) {
$generated = false;
}
// Natura obbligatoria per iva con esenzione
$iva = $database->fetchOne('SELECT * FROM `co_iva` WHERE `id` IN (SELECT idiva FROM co_righe_documenti WHERE iddocumento = '.prepare($id_record).') AND esente = 1' );
$iva = $database->fetchOne('SELECT * FROM `co_iva` WHERE `id` IN (SELECT idiva FROM co_righe_documenti WHERE iddocumento = '.prepare($id_record).') AND esente = 1');
$fields = [
'codice_natura_fe' => 'Natura IVA',
];
@ -45,8 +44,6 @@ if (!empty($missing) && !$generated) {
//$disabled = true;
}
// Campi obbligatori per il pagamento
$pagamento = $database->fetchOne('SELECT * FROM `co_pagamenti` WHERE `id` = '.prepare($record['idpagamento']));
$fields = [
@ -164,7 +161,7 @@ echo '
echo '
<i class="fa fa-arrow-right fa-fw text-muted"></i>
<a href="'.ROOTDIR.'/plugins/exportFE/download.php?id_record='.$id_record.'" class="btn btn-success btn-lg '.($generated ? '' : 'disabled').'" target="_blank" '.($generated ? '' : 'disabled').'>
<a href="'.$structure->fileurl('download.php').'?id_record='.$id_record.'" class="btn btn-success btn-lg '.($generated ? '' : 'disabled').'" target="_blank" '.($generated ? '' : 'disabled').'>
<i class="fa fa-download"></i> '.tr('Scarica').'
</a>';
@ -209,7 +206,7 @@ if (!empty($record['codice_stato_fe'])) {
echo '
<div class="alert text-left alert-'.$class.'">
<big><i class="'.$stato_fe['icon'].'" style="color:#fff;"></i>
<b>'.$stato_fe['codice'].'</b> - '.$stato_fe['descrizione'].'</big> '.( !empty($record['descrizione_ricevuta_fe']) ? '<br><b>NOTE:</b><br>'.$record['descrizione_ricevuta_fe'] : '' ).'
<b>'.$stato_fe['codice'].'</b> - '.$stato_fe['descrizione'].'</big> '.(!empty($record['descrizione_ricevuta_fe']) ? '<br><b>NOTE:</b><br>'.$record['descrizione_ricevuta_fe'] : '').'
<div class="pull-right">
<i class="fa fa-clock-o"></i> '.Translator::timestampToLocale($record['data_stato_fe']).'
</div>

View File

@ -5,8 +5,6 @@ include_once __DIR__.'/../../core.php';
use Plugins\ImportFE\FatturaElettronica;
use Plugins\ImportFE\Interaction;
$directory = Uploads::getDirectory($id_module);
switch (filter('op')) {
case 'save':
$content = file_get_contents($_FILES['blob']['tmp_name']);
@ -40,6 +38,13 @@ switch (filter('op')) {
break;
case 'delete':
$directory = Plugins\ImportFE\FatturaElettronica::getImportDirectory();
delete($directory.'/'.get('filename'));
break;
case 'generate':
$filename = post('filename');

View File

@ -81,16 +81,22 @@ echo '
</div>
</div>';
if (Interaction::isEnabled()) {
echo '
echo '
<div class="box box-info">
<div class="box-header with-border">
<h3 class="box-title">
'.tr('Importazione automatica').'</span>
</h3>
'.tr('Fatture da importare').'</span>
</h3>';
// Ricerca automatica
if (Interaction::isEnabled()) {
echo '
<button type="button" class="btn btn-primary pull-right" onclick="search(this)">
<i class="fa fa-refresh"></i> '.tr('Ricerca fatture di acquisto').'
</button>
</button>';
}
echo '
</div>
<div class="box-body" id="list">';
@ -110,4 +116,3 @@ function search(button) {
});
}
</script>';
}

View File

@ -5,6 +5,7 @@ include_once __DIR__.'/../../core.php';
use Plugins\ImportFE\Interaction;
$list = Interaction::listToImport();
$directory = Plugins\ImportFE\FatturaElettronica::getImportDirectory();
if (!empty($list)) {
echo '
@ -12,7 +13,7 @@ if (!empty($list)) {
<thead>
<tr>
<th>'.tr('Nome').'</th>
<th width="60" class="text-center">#</th>
<th width="10%" class="text-center">#</th>
</tr>
</thead>
<tbody>';
@ -21,9 +22,18 @@ if (!empty($list)) {
echo '
<tr>
<td>'.$element.'</td>
<td>
<td class="text-center">';
if (file_exists($directory.'/'.$element)) {
echo '
<button type="button" class="btn btn-danger" onclick="delete_fe(this, \''.$element.'\')">
<i class="fa fa-trash"></i>
</button>';
}
echo '
<button type="button" class="btn btn-warning" onclick="download(this, \''.$element.'\')">
<i class="fa fa-download"></i> '.tr('Importa fattura di acquisto').'
<i class="fa fa-download"></i> '.tr('Importa').'
</button>
</td>
</tr>';
@ -70,4 +80,24 @@ function download(button, file) {
}
});
}
function delete_fe(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: "delete",
name: file,
},
success: function(data) {
$("#list").load("'.$structure->fileurl('list.php').'?id_module='.$id_module.'&id_plugin='.$id_plugin.'", function() {
buttonRestore(button, restore);
});
}
});
}
</script>';

View File

@ -45,8 +45,8 @@ echo '
<div class="col-md-6">
<h4>'.$dati_generali['Numero'];
echo '
<a href="'.ROOTDIR.'/view.php?file_id='.get('id').'" class="btn btn-info btn-xs" target="_blank" >
echo '
<a href="'.$structure->fileurl('view.php').'?filename='.get('filename').'" class="btn btn-info btn-xs" target="_blank" >
<i class="fa fa-eye"></i> '.tr('Visualizza').'
</a><br>
<small>

View File

@ -221,7 +221,7 @@ class FatturaElettronica
}
$sconti = $riga['ScontoMaggiorazione'];
if (!empty($sconti)) {
if ($sconti['Percentuale'] || $sconti['Importo']) {
$tipo = !empty($sconti['Percentuale']) ? 'PRC' : 'EUR';
@ -235,7 +235,7 @@ class FatturaElettronica
$obj->tipo_sconto = $tipo;
}
}
// Sconti multipli
else {
$sconto = $sconti[0]['Percentuale'] ? $sconti[0]['Percentuale'] : $sconti['Percentuale'];
@ -244,28 +244,26 @@ class FatturaElettronica
$sconto_totale = 0;
if ($tipo == 'PRC') {
/**
* Trasformo un eventuale sconto percentuale combinato in più
* sconti:
* Esempio:
* 40% + 30% è uno sconto del 42%
*/
* Trasformo un eventuale sconto percentuale combinato in più
* sconti:
* Esempio:
* 40% + 30% è uno sconto del 42%.
*/
$prezzo_intero = $riga['PrezzoUnitario'] * $riga['Quantita'];
$prezzo_scontato = $prezzo_intero;
foreach ($sconti as $scontor) {
$prezzo_scontato -= $prezzo_scontato / 100 * $scontor['Percentuale'];
}
// Ricavo la percentuale finale di sconto con una proporzione
$percentuale_totale = ( 1 - ($prezzo_scontato / $prezzo_intero) ) * 100;
$percentuale_totale = (1 - ($prezzo_scontato / $prezzo_intero)) * 100;
if (!empty($percentuale_totale)) {
$obj->sconto_unitario = $percentuale_totale;
$obj->tipo_sconto = $tipo;
}
}
else {
} else {
// Combino gli sconti tra loro
foreach ($sconti as $sconto) {
$unitario = $sconto['Percentuale'] ?: $sconto['Importo'];
@ -275,7 +273,7 @@ class FatturaElettronica
$sconto_totale += $unitario;
}
if (!empty($unitario)) {
$obj->sconto_unitario = $sconto_totale;
$obj->tipo_sconto = $tipo;

View File

@ -15,33 +15,42 @@ class Interaction extends Connection
{
$directory = FatturaElettronica::getImportDirectory();
$response = static::request('POST', 'get_fatture_da_importare');
$body = static::responseBody($response);
$list = [];
$code = $body['code'];
$files = glob($directory.'/*.xml');
foreach ($files as $file) {
$list[] = basename($file);
}
if ($code == '200') {
$files = $body['results'];
// Ricerca da remoto
if (self::isEnabled()) {
$response = static::request('POST', 'get_fatture_da_importare');
$body = static::responseBody($response);
foreach ($files as $file) {
/*
* Verifico che l'XML (fattura di acquisto) non sia già stato importato nel db, controllo p.iva del fornitore e progressivo invio
* TODO: caricare contenuto xml e verificare anche la data (e magari numero) della fattura. Potrebbe essere che il fornitore l'anno successivo mi genera FE con stesso progressivo invio.
*/
$code = $body['code'];
if (preg_match("/^([A-Z]{2})(.+?)_([^\.]+)\.xml/i", $file, $m)) {
$partita_iva = $m[2];
$progressivo_invio = $m[3];
$fattura = database()->fetchOne('SELECT co_documenti.id FROM (co_documenti INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id) INNER JOIN an_anagrafiche ON co_documenti.idanagrafica=an_anagrafiche.idanagrafica WHERE co_tipidocumento.dir="uscita" AND an_anagrafiche.piva='.prepare($partita_iva).' AND co_documenti.progressivo_invio='.prepare($progressivo_invio));
if ($code == '200') {
$files = $body['results'];
if (!$fattura) {
$list[] = basename($file);
foreach ($files as $file) {
/*
* Verifico che l'XML (fattura di acquisto) non sia già stato importato nel db, controllo p.iva del fornitore e progressivo invio
* TODO: caricare contenuto xml e verificare anche la data (e magari numero) della fattura. Potrebbe essere che il fornitore l'anno successivo mi genera FE con stesso progressivo invio.
*/
if (preg_match("/^([A-Z]{2})(.+?)_([^\.]+)\.xml/i", $file, $m)) {
$partita_iva = $m[2];
$progressivo_invio = $m[3];
$fattura = database()->fetchOne('SELECT co_documenti.id FROM (co_documenti INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id) INNER JOIN an_anagrafiche ON co_documenti.idanagrafica=an_anagrafiche.idanagrafica WHERE co_tipidocumento.dir="uscita" AND an_anagrafiche.piva='.prepare($partita_iva).' AND co_documenti.progressivo_invio='.prepare($progressivo_invio));
if (!$fattura) {
$list[] = basename($file);
}
}
}
}
return array_clean($list);
}
return array_clean($list);
}
public static function getImportXML($name)

22
plugins/importFE/view.php Normal file
View File

@ -0,0 +1,22 @@
<?php
include_once __DIR__.'/../../core.php';
$directory = Plugins\ImportFE\FatturaElettronica::getImportDirectory();
$filename = get('filename');
$content = file_get_contents($directory.'/'.$filename);
// XML
$xml = new DOMDocument();
$xml->loadXML($content);
// XSL
$xsl = new DOMDocument();
$xsl->load(DOCROOT.'/assets/src/xml/fe-stylesheet-1.2.1.xsl');
// XSLT
$xslt = new XSLTProcessor();
$xslt->importStylesheet($xsl);
echo $xslt->transformToXML($xml);

View File

@ -22,6 +22,6 @@ trait UploadTrait
public function uploads($id_record)
{
return $this->hasMany(Upload::class, $this->upload_identifier)->where('id_record', $id_record)->get()->groupBy('category');
return $this->hasMany(Upload::class, $this->upload_identifier)->where('id_record', $id_record)->get();
}
}

View File

@ -190,16 +190,15 @@ class Uploads
/**
* Effettua l'upload di un file nella cartella indicata.
*
* @param array $source
* @param string $directory
* @param array $data
* @param array $options
* @param array $source
* @param array $data
* @param array $options
*
* @return string
*/
public static function upload($source, $data, $options = [])
{
$original = isset($source['name']) ? $source['name'] : $source;
$original = isset($source['name']) ? $source['name'] : basename($source);
$filename = self::getName($original, $data);
$directory = DOCROOT.'/'.self::getDirectory($data['id_module'], $data['id_plugin']);

View File

@ -21,7 +21,7 @@ if ($file->isFatturaElettronica()) {
// XSL
$xsl = new DOMDocument();
$xsl->load(__DIR__.'/assets/src/xml/fe-stylesheet-1.2.1.xsl');
$xsl->load(DOCROOT.'/assets/src/xml/fe-stylesheet-1.2.1.xsl');
// XSLT
$xslt = new XSLTProcessor();