feat: Aggiunta plugin Importazione FE ciclo attivo
This commit is contained in:
parent
b176c8877a
commit
3dedde4675
|
@ -47,9 +47,9 @@ class FatturaElettronica
|
||||||
/** @var Fattura Fattura collegata */
|
/** @var Fattura Fattura collegata */
|
||||||
protected $fattura;
|
protected $fattura;
|
||||||
|
|
||||||
public function __construct($name)
|
public function __construct($name, $directory = null, $plugin = null)
|
||||||
{
|
{
|
||||||
$this->file = static::getImportDirectory().'/'.$name;
|
$this->file = static::getImportDirectory($directory ?: 'Fatture di acquisto', $plugin).'/'.$name;
|
||||||
|
|
||||||
if (string_ends_with($name, '.p7m')) {
|
if (string_ends_with($name, '.p7m')) {
|
||||||
$file = XML::decodeP7M($this->file);
|
$file = XML::decodeP7M($this->file);
|
||||||
|
@ -80,18 +80,17 @@ class FatturaElettronica
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getImportDirectory()
|
public static function getImportDirectory($name = null, $plugin = null)
|
||||||
{
|
{
|
||||||
$module = Module::where('name', 'Fatture di acquisto')->first();
|
$module = Module::where('name', $name ?: 'Fatture di acquisto')->first();
|
||||||
|
|
||||||
$plugins = $module->plugins;
|
$plugins = $module->plugins;
|
||||||
if (!empty($plugins)) {
|
if (!empty($plugins)) {
|
||||||
$plugin = $plugins->first(fn ($value, $key) => $value->getTranslation('title') == 'Fatturazione Elettronica');
|
$plugin = $plugins->first(fn ($value, $key) => $value->getTranslation('title') == ($plugin ?: 'Fatturazione Elettronica'));
|
||||||
|
|
||||||
self::$directory = base_dir().'/'.$plugin->upload_directory;
|
self::$directory = base_dir().'/'.$plugin->upload_directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return self::$directory;
|
return self::$directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,24 +105,24 @@ class FatturaElettronica
|
||||||
return $filename;
|
return $filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function isValid($name)
|
public static function isValid($name, $directory = null, $plugin = null)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
new static($name);
|
new static($name, $directory, $plugin);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (\UnexpectedValueException) {
|
} catch (\UnexpectedValueException) {
|
||||||
$file = static::getImportDirectory().'/'.$name;
|
$file = static::getImportDirectory($directory ?: 'Fatture di acquisto').'/'.$name;
|
||||||
delete($file);
|
delete($file);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function manage($name)
|
public static function manage($name, $directory = null, $plugin = null)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$manager = new FatturaOrdinaria($name);
|
$manager = new FatturaOrdinaria($name, $directory, $plugin);
|
||||||
|
|
||||||
$tipo = $manager->getBody()['DatiGenerali']['DatiGeneraliDocumento']['TipoDocumento'];
|
$tipo = $manager->getBody()['DatiGenerali']['DatiGeneraliDocumento']['TipoDocumento'];
|
||||||
if ($tipo == 'TD06') {
|
if ($tipo == 'TD06') {
|
||||||
|
@ -160,11 +159,11 @@ class FatturaElettronica
|
||||||
return array_clean($result);
|
return array_clean($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function saveAllegati()
|
public function saveAllegati($name = null)
|
||||||
{
|
{
|
||||||
$allegati = $this->getAllegati();
|
$allegati = $this->getAllegati();
|
||||||
|
|
||||||
$id_module = Module::where('name', 'Fatture di acquisto')->first()->id;
|
$id_module = Module::where('name', $name ?: 'Fatture di acquisto')->first()->id;
|
||||||
|
|
||||||
$info = [
|
$info = [
|
||||||
'category' => tr('Fattura Elettronica'),
|
'category' => tr('Fattura Elettronica'),
|
||||||
|
@ -201,9 +200,9 @@ class FatturaElettronica
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function findAnagrafica()
|
public function findAnagrafica($tipo = null)
|
||||||
{
|
{
|
||||||
$info = $this->getAnagrafe();
|
$info = $this->getAnagrafe($tipo);
|
||||||
|
|
||||||
if (!empty($info['partita_iva']) && !empty($info['codice_fiscale'])) {
|
if (!empty($info['partita_iva']) && !empty($info['codice_fiscale'])) {
|
||||||
$anagrafica = Anagrafica::where('piva', $info['partita_iva'])
|
$anagrafica = Anagrafica::where('piva', $info['partita_iva'])
|
||||||
|
@ -233,9 +232,9 @@ class FatturaElettronica
|
||||||
*
|
*
|
||||||
* @return Anagrafica
|
* @return Anagrafica
|
||||||
*/
|
*/
|
||||||
public function saveAnagrafica($type = 'Fornitore')
|
public function saveAnagrafica($type = null)
|
||||||
{
|
{
|
||||||
$anagrafica = $this->findAnagrafica();
|
$anagrafica = $this->findAnagrafica($type);
|
||||||
|
|
||||||
if (!empty($anagrafica)) {
|
if (!empty($anagrafica)) {
|
||||||
return $anagrafica;
|
return $anagrafica;
|
||||||
|
@ -310,12 +309,12 @@ class FatturaElettronica
|
||||||
*
|
*
|
||||||
* @return Fattura
|
* @return Fattura
|
||||||
*/
|
*/
|
||||||
public function saveFattura($id_pagamento, $id_sezionale, $id_tipo, $data_registrazione, $ref_fattura, $is_ritenuta_pagata = false)
|
public function saveFattura($id_pagamento, $id_sezionale, $id_tipo, $data_registrazione, $ref_fattura, $is_ritenuta_pagata = false, $tipo = null)
|
||||||
{
|
{
|
||||||
$dati_generali = $this->getBody()['DatiGenerali']['DatiGeneraliDocumento'];
|
$dati_generali = $this->getBody()['DatiGenerali']['DatiGeneraliDocumento'];
|
||||||
$data = self::parseDate($dati_generali['Data']);
|
$data = self::parseDate($dati_generali['Data']);
|
||||||
|
|
||||||
$fattura = $this->prepareFattura($id_tipo, $data, $data_registrazione, $id_sezionale, $ref_fattura);
|
$fattura = $this->prepareFattura($id_tipo, $data, $data_registrazione, $id_sezionale, $ref_fattura, $tipo);
|
||||||
$this->fattura = $fattura;
|
$this->fattura = $fattura;
|
||||||
|
|
||||||
$numero_esterno = $dati_generali['Numero'];
|
$numero_esterno = $dati_generali['Numero'];
|
||||||
|
@ -385,9 +384,9 @@ class FatturaElettronica
|
||||||
return $this->fattura;
|
return $this->fattura;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function save($info = [])
|
public function save($info = [], $tipo = null)
|
||||||
{
|
{
|
||||||
$this->saveFattura($info['id_pagamento'], $info['id_segment'], $info['id_tipo'], $info['data_registrazione'], $info['ref_fattura'], $info['is_ritenuta_pagata']);
|
$this->saveFattura($info['id_pagamento'], $info['id_segment'], $info['id_tipo'], $info['data_registrazione'], $info['ref_fattura'], $info['is_ritenuta_pagata'], $tipo);
|
||||||
|
|
||||||
$this->saveRighe($info['articoli'], $info['iva'], $info['conto'], $info['movimentazione'], $info['crea_articoli'], $info['tipo_riga_riferimento'], $info['id_riga_riferimento'], $info['tipo_riga_riferimento_vendita'], $info['id_riga_riferimento_vendita'], $info['update_info'], $info['serial']);
|
$this->saveRighe($info['articoli'], $info['iva'], $info['conto'], $info['movimentazione'], $info['crea_articoli'], $info['tipo_riga_riferimento'], $info['id_riga_riferimento'], $info['tipo_riga_riferimento_vendita'], $info['id_riga_riferimento_vendita'], $info['update_info'], $info['serial']);
|
||||||
|
|
||||||
|
@ -403,9 +402,9 @@ class FatturaElettronica
|
||||||
return date('Y-m-d', strtotime((string) $data));
|
return date('Y-m-d', strtotime((string) $data));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function prepareFattura($id_tipo, $data, $data_registrazione, $id_sezionale, $ref_fattura)
|
protected function prepareFattura($id_tipo, $data, $data_registrazione, $id_sezionale, $ref_fattura, $tipo = null)
|
||||||
{
|
{
|
||||||
$anagrafica = $this->saveAnagrafica();
|
$anagrafica = $this->saveAnagrafica($tipo);
|
||||||
|
|
||||||
$tipo = TipoFattura::where('id', $id_tipo)->first();
|
$tipo = TipoFattura::where('id', $id_tipo)->first();
|
||||||
|
|
||||||
|
|
|
@ -37,18 +37,22 @@ use Util\XML;
|
||||||
*/
|
*/
|
||||||
class FatturaOrdinaria extends FatturaElettronica
|
class FatturaOrdinaria extends FatturaElettronica
|
||||||
{
|
{
|
||||||
public function __construct($name)
|
public function __construct($name, $directory = null, $plugin = null)
|
||||||
{
|
{
|
||||||
parent::__construct($name);
|
parent::__construct($name, $directory, $plugin);
|
||||||
|
|
||||||
if ($this->getHeader()['DatiTrasmissione']['FormatoTrasmissione'] == 'FSM10') {
|
if ($this->getHeader()['DatiTrasmissione']['FormatoTrasmissione'] == 'FSM10') {
|
||||||
throw new \UnexpectedValueException();
|
throw new \UnexpectedValueException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAnagrafe()
|
public function getAnagrafe($tipo = null)
|
||||||
{
|
{
|
||||||
|
if ($tipo == 'Cliente') {
|
||||||
|
$dati = $this->getHeader()['CessionarioCommittente'];
|
||||||
|
} else {
|
||||||
$dati = $this->getHeader()['CedentePrestatore'];
|
$dati = $this->getHeader()['CedentePrestatore'];
|
||||||
|
}
|
||||||
|
|
||||||
$anagrafe = $dati['DatiAnagrafici'];
|
$anagrafe = $dati['DatiAnagrafici'];
|
||||||
$rea = $dati['IscrizioneREA'];
|
$rea = $dati['IscrizioneREA'];
|
||||||
|
@ -510,9 +514,9 @@ class FatturaOrdinaria extends FatturaElettronica
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function prepareFattura($id_tipo, $data, $data_registrazione, $id_sezionale, $ref_fattura)
|
protected function prepareFattura($id_tipo, $data, $data_registrazione, $id_sezionale, $ref_fattura, $tipo = null)
|
||||||
{
|
{
|
||||||
$fattura = parent::prepareFattura($id_tipo, $data, $data_registrazione, $id_sezionale, $ref_fattura);
|
$fattura = parent::prepareFattura($id_tipo, $data, $data_registrazione, $id_sezionale, $ref_fattura, $tipo);
|
||||||
$database = database();
|
$database = database();
|
||||||
|
|
||||||
$righe = $this->getRighe();
|
$righe = $this->getRighe();
|
||||||
|
|
|
@ -40,9 +40,13 @@ class FatturaSemplificata extends FatturaElettronica
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAnagrafe()
|
public function getAnagrafe($tipo = null)
|
||||||
{
|
{
|
||||||
|
if ($tipo == 'Cliente') {
|
||||||
|
$anagrafe = $this->getHeader()['CessionarioCommittente'];
|
||||||
|
} else {
|
||||||
$anagrafe = $this->getHeader()['CedentePrestatore'];
|
$anagrafe = $this->getHeader()['CedentePrestatore'];
|
||||||
|
}
|
||||||
|
|
||||||
$rea = $anagrafe['IscrizioneREA'];
|
$rea = $anagrafe['IscrizioneREA'];
|
||||||
$sede = $anagrafe['Sede'];
|
$sede = $anagrafe['Sede'];
|
||||||
|
|
|
@ -34,12 +34,12 @@ class Interaction extends Services
|
||||||
return parent::isEnabled() && self::verificaRisorsaAttiva('Fatturazione Elettronica');
|
return parent::isEnabled() && self::verificaRisorsaAttiva('Fatturazione Elettronica');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getInvoiceList()
|
public static function getInvoiceList($directory = null, $plugin = null)
|
||||||
{
|
{
|
||||||
$list = self::getRemoteList();
|
$list = self::getRemoteList();
|
||||||
|
|
||||||
// Ricerca fisica
|
// Ricerca fisica
|
||||||
$result = self::getFileList($list);
|
$result = self::getFileList($list, $directory, $plugin);
|
||||||
|
|
||||||
// Aggiornamento cache hook
|
// Aggiornamento cache hook
|
||||||
Cache::where('name', 'Fatture Elettroniche')->first()->set($result);
|
Cache::where('name', 'Fatture Elettroniche')->first()->set($result);
|
||||||
|
@ -64,12 +64,12 @@ class Interaction extends Services
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getFileList($list = [])
|
public static function getFileList($list = [], $directory = null, $plugin = null)
|
||||||
{
|
{
|
||||||
$names = array_column($list, 'name');
|
$names = array_column($list, 'name');
|
||||||
|
|
||||||
// Ricerca fisica
|
// Ricerca fisica
|
||||||
$directory = FatturaElettronica::getImportDirectory();
|
$directory = FatturaElettronica::getImportDirectory($directory, $plugin);
|
||||||
|
|
||||||
$files = glob($directory.'/*.xml*');
|
$files = glob($directory.'/*.xml*');
|
||||||
foreach ($files as $id => $file) {
|
foreach ($files as $id => $file) {
|
||||||
|
|
|
@ -40,7 +40,7 @@ class Parcella extends FatturaOrdinaria
|
||||||
*
|
*
|
||||||
* @return Fattura
|
* @return Fattura
|
||||||
*/
|
*/
|
||||||
public function prepareFattura($id_tipo, $data, $data_registrazione, $id_sezionale, $ref_fattura)
|
public function prepareFattura($id_tipo, $data, $data_registrazione, $id_sezionale, $ref_fattura, $tipo = null)
|
||||||
{
|
{
|
||||||
if (empty($ref_fattura)) {
|
if (empty($ref_fattura)) {
|
||||||
return parent::prepareFattura($id_tipo, $data, $data_registrazione, $id_sezionale, $ref_fattura);
|
return parent::prepareFattura($id_tipo, $data, $data_registrazione, $id_sezionale, $ref_fattura);
|
||||||
|
|
|
@ -0,0 +1,769 @@
|
||||||
|
<?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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
include_once __DIR__.'/../../core.php';
|
||||||
|
include __DIR__.'/settings.php';
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Modules\Anagrafiche\Tipo;
|
||||||
|
use Modules\DDT\DDT;
|
||||||
|
use Modules\Fatture\Fattura;
|
||||||
|
use Modules\Fatture\Gestori\Movimenti as GestoreMovimenti;
|
||||||
|
use Modules\Fatture\Stato;
|
||||||
|
use Modules\Ordini\Ordine;
|
||||||
|
use Modules\Pagamenti\Pagamento;
|
||||||
|
use Modules\PrimaNota\Mastrino;
|
||||||
|
use Modules\PrimaNota\Movimento;
|
||||||
|
use Plugins\ImportFE\FatturaElettronica;
|
||||||
|
use Plugins\ImportFE\Interaction;
|
||||||
|
use Util\XML;
|
||||||
|
|
||||||
|
$file = null;
|
||||||
|
switch (filter('op')) {
|
||||||
|
case 'list':
|
||||||
|
$list = Interaction::getRemoteList();
|
||||||
|
|
||||||
|
echo json_encode($list);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'prepare':
|
||||||
|
if (!isset($file)) {
|
||||||
|
$name = filter('name');
|
||||||
|
$file = Interaction::getInvoiceFile($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!FatturaElettronica::isValid($file, 'Fatture di vendita', 'Importazione FE')) {
|
||||||
|
echo json_encode([
|
||||||
|
'already' => 1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (Exception) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Individuazione ID fisico
|
||||||
|
$files = Interaction::getFileList([], 'Fatture di vendita', 'Importazione FE');
|
||||||
|
foreach ($files as $key => $value) {
|
||||||
|
if ($value['name'] == $file) {
|
||||||
|
$index = $key;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'id' => $index + 1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
case 'save':
|
||||||
|
$directory = FatturaElettronica::getImportDirectory('Fatture di vendita', 'Importazione FE');
|
||||||
|
|
||||||
|
if (!$file) {
|
||||||
|
$temp_name = $_FILES['blob1']['tmp_name'];
|
||||||
|
$name = $_FILES['blob1']['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setting('Metodo di importazione XML fatture di vendita') == 'Automatico') {
|
||||||
|
if (string_ends_with($name, '.zip')) {
|
||||||
|
Util\Zip::extract($temp_name, $directory);
|
||||||
|
|
||||||
|
// Redirect forzato per l'importazione
|
||||||
|
echo json_encode([
|
||||||
|
'id' => 1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$files_xml = scandir($directory);
|
||||||
|
} else {
|
||||||
|
$files_xml[] = $file ?: $files;
|
||||||
|
}
|
||||||
|
|
||||||
|
$i = 1;
|
||||||
|
foreach ($files_xml as $xml) {
|
||||||
|
if ($xml != '.' && $xml != '..' && is_file($directory.'/'.$xml)) {
|
||||||
|
if (FatturaElettronica::isValid($xml, 'Fatture di vendita', 'Importazione FE')) {
|
||||||
|
if (string_ends_with($xml, '.p7m')) {
|
||||||
|
$file = XML::decodeP7M($directory.'/'.$xml);
|
||||||
|
} else {
|
||||||
|
$file = XML::readFile($directory.'/'.$xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $file['FatturaElettronicaBody']['DatiGenerali']['DatiGeneraliDocumento']['Data'];
|
||||||
|
|
||||||
|
$fattura_pa = FatturaElettronica::manage($xml, 'Fattura di vendita', 'Importazione FE');
|
||||||
|
|
||||||
|
// Tipo documento
|
||||||
|
$fattura_body = $fattura_pa->getBody();
|
||||||
|
$dati_generali = $fattura_body['DatiGenerali']['DatiGeneraliDocumento'];
|
||||||
|
$id_tipo = $database->fetchOne('SELECT id FROM co_tipidocumento WHERE dir = "entrata" AND codice_tipo_documento_fe = '.prepare($dati_generali['TipoDocumento']))['id'];
|
||||||
|
|
||||||
|
// Tipo pagamento
|
||||||
|
$pagamenti = [];
|
||||||
|
if (isset($fattura_body['DatiPagamento'])) {
|
||||||
|
$pagamenti = $fattura_body['DatiPagamento'];
|
||||||
|
$pagamenti = isset($pagamenti[0]) ? $pagamenti : [$pagamenti];
|
||||||
|
}
|
||||||
|
$metodi = isset($pagamenti[0]['DettaglioPagamento']) ? $pagamenti[0]['DettaglioPagamento'] : [];
|
||||||
|
$metodi = isset($metodi[0]) ? $metodi : [$metodi];
|
||||||
|
$codice_modalita_pagamento = $metodi[0]['ModalitaPagamento'];
|
||||||
|
$pagamento = Pagamento::where('codice_modalita_pagamento_fe', $codice_modalita_pagamento)->where('predefined', '1')->first();
|
||||||
|
|
||||||
|
if (!empty($pagamento)) {
|
||||||
|
$id_pagamento = $pagamento->id;
|
||||||
|
} else {
|
||||||
|
$id_pagamento = $settings['id_pagamento'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$fattura_pa->saveFattura($id_pagamento, $settings['id_segment'], $id_tipo, $data, false, false, 'Cliente');
|
||||||
|
|
||||||
|
$righe = $fattura_pa->getRighe();
|
||||||
|
|
||||||
|
$articoli = [];
|
||||||
|
$iva = [];
|
||||||
|
$conti = [];
|
||||||
|
|
||||||
|
foreach ($righe as $key => $riga) {
|
||||||
|
$articoli[$key] = 0;
|
||||||
|
|
||||||
|
$aliquota_iva = $riga['AliquotaIVA'];
|
||||||
|
|
||||||
|
$iva[$key] = $settings['iva'][$aliquota_iva];
|
||||||
|
|
||||||
|
$conti[$key] = $settings['id_conto'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$fattura_pa->saveRighe($articoli, $iva, $conti);
|
||||||
|
|
||||||
|
$fattura_pa->saveAllegati('Fatture di vendita');
|
||||||
|
|
||||||
|
$id_record = $fattura_pa->getFattura()->id;
|
||||||
|
$fattura = Fattura::find($id_record);
|
||||||
|
$fattura->gestoreMovimenti = new GestoreMovimenti($fattura);
|
||||||
|
|
||||||
|
// Registrazione scadenze
|
||||||
|
$fattura->registraScadenze(false);
|
||||||
|
|
||||||
|
// Registrazione movimenti
|
||||||
|
|
||||||
|
$fattura->gestoreMovimenti->registra();
|
||||||
|
|
||||||
|
// Imposto lo stato in GEN
|
||||||
|
$dbo->query("UPDATE co_documenti SET codice_stato_fe='GEN', data_stato_fe=NOW() WHERE id=".prepare($id_record));
|
||||||
|
delete($directory.'/'.$xml);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (string_ends_with($name, '.zip')) {
|
||||||
|
$directory = FatturaElettronica::getImportDirectory('Fatture di vendita', 'Importazione FE');
|
||||||
|
|
||||||
|
Util\Zip::extract($temp_name, $directory);
|
||||||
|
|
||||||
|
// Redirect forzato per l'importazione
|
||||||
|
echo json_encode([
|
||||||
|
'id' => 1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
exit;
|
||||||
|
} else {
|
||||||
|
$files_xml[] = $file ?: $files;
|
||||||
|
|
||||||
|
$i = 1;
|
||||||
|
foreach ($files_xml as $xml) {
|
||||||
|
if ($xml != '.' && $xml != '..' && is_file($directory.'/'.$xml)) {
|
||||||
|
if (FatturaElettronica::isValid($xml, 'Fatture di vendita', 'Importazione FE')) {
|
||||||
|
if (string_ends_with($xml, '.p7m')) {
|
||||||
|
$file = XML::decodeP7M($directory.'/'.$xml);
|
||||||
|
} else {
|
||||||
|
$file = XML::readFile($directory.'/'.$xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = FatturaElettronica::store($xml, $content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'delete':
|
||||||
|
$file_id = get('file_id');
|
||||||
|
|
||||||
|
$directory = FatturaElettronica::getImportDirectory('Fatture di vendita', 'Importazione FE');
|
||||||
|
$files = Interaction::getFileList([], 'Fatture di vendita', 'Importazione FE');
|
||||||
|
$file = $files[$file_id];
|
||||||
|
|
||||||
|
if (!empty($file)) {
|
||||||
|
delete($directory.'/'.$file['name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'download':
|
||||||
|
$file_id = get('file_id');
|
||||||
|
|
||||||
|
$directory = FatturaElettronica::getImportDirectory('Fatture di vendita');
|
||||||
|
$files = Interaction::getFileList([], 'Fatture di vendita', 'Importazione FE');
|
||||||
|
$file = $files[$file_id];
|
||||||
|
|
||||||
|
if (!empty($file)) {
|
||||||
|
download($directory.'/'.$file['name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'generate':
|
||||||
|
$filename = post('filename');
|
||||||
|
|
||||||
|
$info = [
|
||||||
|
'id_pagamento' => post('pagamento'),
|
||||||
|
'id_segment' => post('id_segment'),
|
||||||
|
'id_tipo' => post('id_tipo'),
|
||||||
|
'ref_fattura' => post('ref_fattura'),
|
||||||
|
'data_registrazione' => post('data_registrazione'),
|
||||||
|
'articoli' => post('articoli'),
|
||||||
|
'iva' => post('iva'),
|
||||||
|
'conto' => post('conto'),
|
||||||
|
'tipo_riga_riferimento' => post('tipo_riga_riferimento'),
|
||||||
|
'id_riga_riferimento' => post('id_riga_riferimento'),
|
||||||
|
'tipo_riga_riferimento_vendita' => post('tipo_riga_riferimento_vendita'),
|
||||||
|
'id_riga_riferimento_vendita' => post('id_riga_riferimento_vendita'),
|
||||||
|
'movimentazione' => post('movimentazione'),
|
||||||
|
'crea_articoli' => post('crea_articoli'),
|
||||||
|
'is_ritenuta_pagata' => post('is_ritenuta_pagata'),
|
||||||
|
'update_info' => post('update_info'),
|
||||||
|
'serial' => post('flag_crea_seriali') ? post('serial') : [],
|
||||||
|
];
|
||||||
|
|
||||||
|
$fattura_pa = FatturaElettronica::manage($filename, 'Fatture di vendita', 'Importazione FE');
|
||||||
|
$id_fattura = $fattura_pa->save($info, 'Cliente');
|
||||||
|
$fattura_pa->delete();
|
||||||
|
$fattura = Fattura::find($id_fattura);
|
||||||
|
$id_autofattura = post('autofattura');
|
||||||
|
$new_stato = Stato::where('name', 'Pagato')->first()->id;
|
||||||
|
|
||||||
|
if ($fattura->isAutofattura() && !empty($id_autofattura)) {
|
||||||
|
$autofattura_collegata = Fattura::find($id_autofattura);
|
||||||
|
$fattura->registraScadenze(true);
|
||||||
|
$autofattura_collegata->registraScadenze(true);
|
||||||
|
|
||||||
|
$fattura->stato()->associate($new_stato);
|
||||||
|
$autofattura_collegata->stato()->associate($new_stato);
|
||||||
|
|
||||||
|
$mastrino = Mastrino::build('Compensazione autofattura', $fattura->data, false, true);
|
||||||
|
|
||||||
|
$movimento1 = Movimento::build($mastrino, $fattura->anagrafica->idconto_cliente);
|
||||||
|
$movimento1->setTotale($fattura->totale, 0);
|
||||||
|
$movimento1->save();
|
||||||
|
|
||||||
|
$movimento2 = Movimento::build($mastrino, $fattura->anagrafica->idconto_fornitore);
|
||||||
|
$movimento2->setTotale(0, $fattura->totale);
|
||||||
|
$movimento2->save();
|
||||||
|
|
||||||
|
$fattura->id_autofattura = $id_autofattura;
|
||||||
|
$fattura->save();
|
||||||
|
$autofattura_collegata->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aggiorno la tipologia di anagrafica cliente
|
||||||
|
$anagrafica = $database->fetchOne('SELECT `idanagrafica` FROM `co_documenti` WHERE `co_documenti`.`id`='.prepare($id_fattura));
|
||||||
|
$id_tipo = Tipo::where('name', 'Cliente')->first()->id;
|
||||||
|
$rs_t = $database->fetchOne('SELECT * FROM `an_tipianagrafiche_anagrafiche` WHERE `idtipoanagrafica`='.prepare($id_tipo).' AND `idanagrafica`='.prepare($anagrafica['idanagrafica']));
|
||||||
|
|
||||||
|
// Se non trovo corrispondenza aggiungo all'anagrafica la tipologia cliente
|
||||||
|
if (empty($rs_t)) {
|
||||||
|
$database->query("INSERT INTO `an_tipianagrafiche_anagrafiche` (`idtipoanagrafica`, `idanagrafica`) VALUES ($id_tipo, ".prepare($anagrafica['idanagrafica']).')');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Processo il file ricevuto
|
||||||
|
if (Interaction::isEnabled()) {
|
||||||
|
$process_result = Interaction::processInvoice($filename);
|
||||||
|
if ($process_result != '') {
|
||||||
|
flash()->error($process_result);
|
||||||
|
redirect(base_path().'/controller.php?id_module='.$id_module);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$files = Interaction::getFileList([], 'Fatture di vendita', 'Importazione FE');
|
||||||
|
$file = $files[$id_record - 1];
|
||||||
|
|
||||||
|
if (get('sequence') == null) {
|
||||||
|
redirect(base_path().'/editor.php?id_module='.$id_module.'&id_record='.$id_fattura);
|
||||||
|
} elseif (!empty($file)) {
|
||||||
|
redirect(base_path().'/editor.php?id_module='.$id_module.'&id_plugin='.$id_plugin.'&id_record='.$id_record.'&sequence=1');
|
||||||
|
flash()->info(tr('La fattura numero _NUM_ del _DATA_ (_ANAGRAFICA_) è stata importata correttamente', [
|
||||||
|
'_NUM_' => $fattura->numero,
|
||||||
|
'_DATA_' => dateFormat($fattura->data),
|
||||||
|
'_ANAGRAFICA_' => $fattura->anagrafica->ragione_sociale,
|
||||||
|
]));
|
||||||
|
} else {
|
||||||
|
flash()->info(tr('Tutte le fatture salvate sono state importate!'));
|
||||||
|
redirect(base_path().'/controller.php?id_module='.$id_module);
|
||||||
|
}
|
||||||
|
|
||||||
|
$record = null;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'process':
|
||||||
|
$name = get('name');
|
||||||
|
|
||||||
|
// Processo il file ricevuto
|
||||||
|
if (Interaction::isEnabled()) {
|
||||||
|
$process_result = Interaction::processInvoice($name);
|
||||||
|
if (!empty($process_result)) {
|
||||||
|
flash()->error($process_result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'compile':
|
||||||
|
// Gestione del caso di anagrafica inesistente
|
||||||
|
if (empty($anagrafica)) {
|
||||||
|
echo json_encode([]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fatture = $anagrafica->fattureAcquisto()
|
||||||
|
->contabile()
|
||||||
|
->orderBy('created_at', 'DESC')
|
||||||
|
->take(10)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
$righe = collect();
|
||||||
|
foreach ($fatture as $fattura) {
|
||||||
|
$righe->push($fattura->righe);
|
||||||
|
$righe->push($fattura->articoli);
|
||||||
|
}
|
||||||
|
$righe = $righe->flatten();
|
||||||
|
|
||||||
|
// Gestione del caso di anagrafica senza fatture o con fatture senza righe
|
||||||
|
if ($fatture->isEmpty() || $righe->isEmpty()) {
|
||||||
|
echo json_encode([]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ricerca del tipo di documento più utilizzato
|
||||||
|
$tipi = $fatture->groupBy(fn ($item, $key) => $item->tipo->id)->transform(fn ($item, $key) => $item->count());
|
||||||
|
$id_tipo = $tipi->sort()->keys()->last();
|
||||||
|
|
||||||
|
// Ricerca del conto più utilizzato
|
||||||
|
$conti = $righe->groupBy(fn ($item, $key) => $item->idconto)->transform(fn ($item, $key) => $item->count());
|
||||||
|
$id_conto = $conti->sort()->keys()->last();
|
||||||
|
$conto = $database->fetchOne('SELECT * FROM co_pianodeiconti3 WHERE id = '.prepare($id_conto));
|
||||||
|
|
||||||
|
// Ricerca dell'IVA più utilizzata secondo percentuali
|
||||||
|
$iva = [];
|
||||||
|
$percentuali_iva = $righe->groupBy(fn ($item, $key) => $item->aliquota->percentuale);
|
||||||
|
foreach ($percentuali_iva as $key => $values) {
|
||||||
|
$aliquote = $values->mapToGroups(fn ($item, $key) => [$item->aliquota->id => $item->aliquota]);
|
||||||
|
$id_aliquota = $aliquote->map(fn ($item, $key) => $item->count())->sort()->keys()->last();
|
||||||
|
$aliquota = $aliquote[$id_aliquota]->first();
|
||||||
|
|
||||||
|
$iva[$key] = [
|
||||||
|
'id' => $aliquota->id,
|
||||||
|
'descrizione' => $aliquota->getTranslation('title'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'id_tipo' => $id_tipo,
|
||||||
|
'conto' => [
|
||||||
|
'id' => $conto['id'],
|
||||||
|
'descrizione' => $conto['descrizione'],
|
||||||
|
],
|
||||||
|
'iva' => $iva,
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'riferimenti-automatici':
|
||||||
|
if (empty($anagrafica)) {
|
||||||
|
echo json_encode([]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$results = [];
|
||||||
|
|
||||||
|
// Dati ordini
|
||||||
|
$DatiOrdini = XML::forceArray($fattura_pa->getBody()['DatiGenerali']['DatiOrdineAcquisto']);
|
||||||
|
$DatiDDT = XML::forceArray($fattura_pa->getBody()['DatiGenerali']['DatiDDT']);
|
||||||
|
|
||||||
|
$replaces = ['n ', 'N ', 'n. ', 'N. ', 'nr ', 'NR ', 'nr. ', 'NR. ', 'num ', 'NUM ', 'num. ', 'NUM. ', 'numero ', 'NUMERO '];
|
||||||
|
|
||||||
|
// Riorganizzazione dati ordini per numero di riga
|
||||||
|
$dati_ordini = [];
|
||||||
|
foreach ($DatiOrdini as $dato) {
|
||||||
|
if (is_array($dato['RiferimentoNumeroLinea'])) {
|
||||||
|
foreach ($dato['RiferimentoNumeroLinea'] as $dati => $linea) {
|
||||||
|
foreach ($replaces as $replace) {
|
||||||
|
if (string_starts_with($dato['IdDocumento'], $replace)) {
|
||||||
|
$dato['IdDocumento'] = str_replace($replace, '', $dato['IdDocumento']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$dati_ordini[(int) $linea] = [
|
||||||
|
'numero' => $dato['IdDocumento'],
|
||||||
|
'anno' => (new Carbon($dato['Data']))->format('Y'),
|
||||||
|
];
|
||||||
|
} catch (Exception) {
|
||||||
|
$dati_ordini[(int) $linea] = [
|
||||||
|
'numero' => $dato['IdDocumento'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach ($replaces as $replace) {
|
||||||
|
if (string_starts_with($dato['IdDocumento'], $replace)) {
|
||||||
|
$dato['IdDocumento'] = str_replace($replace, '', $dato['IdDocumento']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$dati_ordini[(int) $dato['RiferimentoNumeroLinea']] = [
|
||||||
|
'numero' => $dato['IdDocumento'],
|
||||||
|
'anno' => (new Carbon($dato['Data']))->format('Y'),
|
||||||
|
];
|
||||||
|
} catch (Exception) {
|
||||||
|
$dati_ordini[(int) $dato['RiferimentoNumeroLinea']] = [
|
||||||
|
'numero' => $dato['IdDocumento'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Riorganizzazione dati ddt per numero di riga
|
||||||
|
$dati_ddt = [];
|
||||||
|
foreach ($DatiDDT as $dato) {
|
||||||
|
if (is_array($dato['RiferimentoNumeroLinea'])) {
|
||||||
|
foreach ($dato['RiferimentoNumeroLinea'] as $dati => $linea) {
|
||||||
|
foreach ($replaces as $replace) {
|
||||||
|
if (string_starts_with($dato['NumeroDDT'], $replace)) {
|
||||||
|
$dato['NumeroDDT'] = str_replace($replace, '', $dato['NumeroDDT']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$dati_ddt[(int) $linea] = [
|
||||||
|
'numero' => $dato['NumeroDDT'],
|
||||||
|
'anno' => (new Carbon($dato['DataDDT']))->format('Y'),
|
||||||
|
];
|
||||||
|
} catch (Exception) {
|
||||||
|
$dati_ddt[(int) $linea] = [
|
||||||
|
'numero' => $dato['NumeroDDT'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach ($replaces as $replace) {
|
||||||
|
if (string_starts_with($dato['NumeroDDT'], $replace)) {
|
||||||
|
$dato['NumeroDDT'] = str_replace($replace, '', $dato['NumeroDDT']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
$dati_ddt[(int) $dato['RiferimentoNumeroLinea']] = [
|
||||||
|
'numero' => $dato['NumeroDDT'],
|
||||||
|
'anno' => (new Carbon($dato['DataDDT']))->format('Y'),
|
||||||
|
];
|
||||||
|
} catch (Exception) {
|
||||||
|
$dati_ddt[(int) $dato['RiferimentoNumeroLinea']] = [
|
||||||
|
'numero' => $dato['NumeroDDT'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterazione sulle singole righe
|
||||||
|
$righe = $fattura_pa->getRighe();
|
||||||
|
foreach ($righe as $key => $riga) {
|
||||||
|
// Se la riga è descrittiva non la collego a documenti
|
||||||
|
if ($riga['PrezzoTotale'] == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$collegamento = null;
|
||||||
|
$match_documento_da_fe = true;
|
||||||
|
|
||||||
|
$numero_linea = (int) $riga['NumeroLinea'];
|
||||||
|
|
||||||
|
// Visualizzazione codici articoli
|
||||||
|
$codici = $riga['CodiceArticolo'] ?: [];
|
||||||
|
$codici = !empty($codici) && !isset($codici[0]) ? [$codici] : $codici;
|
||||||
|
|
||||||
|
// Ricerca dell'articolo collegato a ogni codice associato alla riga
|
||||||
|
$id_articolo = null;
|
||||||
|
foreach ($codici as $codice) {
|
||||||
|
if (!empty($anagrafica) && empty($id_articolo)) {
|
||||||
|
$id_articolo = $database->fetchOne('SELECT id_articolo AS id FROM mg_fornitore_articolo WHERE codice_fornitore = '.prepare($codice['CodiceValore']).' AND id_fornitore = '.prepare($anagrafica->id))['id'];
|
||||||
|
|
||||||
|
if (empty($id_articolo)) {
|
||||||
|
$id_articolo = $database->fetchOne('SELECT id_articolo AS id FROM mg_fornitore_articolo WHERE REPLACE(codice_fornitore, " ", "") = '.prepare($codice['CodiceValore']).' AND id_fornitore = '.prepare($anagrafica->id))['id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($id_articolo)) {
|
||||||
|
$id_articolo = $database->fetchOne('SELECT `id` FROM `mg_articoli` WHERE `codice` = '.prepare($codice['CodiceValore']).' AND `deleted_at` IS NULL')['id'];
|
||||||
|
|
||||||
|
if (empty($id_articolo)) {
|
||||||
|
$id_articolo = $database->fetchOne('SELECT `id` FROM `mg_articoli` WHERE REPLACE(`codice`, " ", "") = '.prepare($codice['CodiceValore']).' AND `deleted_at` IS NULL')['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Controllo se esistono articoli con barcode corrispondente al codice
|
||||||
|
if (empty($id_articolo)) {
|
||||||
|
$id_articolo = $database->fetchOne('SELECT `id` FROM `mg_articoli` WHERE `barcode` = '.prepare($codice['CodiceValore']).' AND `deleted_at` IS NULL')['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($id_articolo)) {
|
||||||
|
$id_articolo = $database->fetchOne('SELECT `id` FROM `mg_articoli` WHERE REPLACE(`barcode`, " ", "") = '.prepare($codice['CodiceValore']).' AND `deleted_at` IS NULL')['id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($id_articolo)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Se nella fattura elettronica è indicato un DDT cerco quel documento specifico
|
||||||
|
$ddt = $dati_ddt[$numero_linea];
|
||||||
|
$query = "SELECT
|
||||||
|
`dt_righe_ddt`.`id`,
|
||||||
|
`dt_righe_ddt`.`idddt` AS id_documento,
|
||||||
|
`dt_righe_ddt`.`is_descrizione`,
|
||||||
|
`dt_righe_ddt`.`idarticolo`,
|
||||||
|
`dt_righe_ddt`.`is_sconto`, 'ddt' AS ref,
|
||||||
|
CONCAT('DDT num. ', IF(`numero_esterno` != '', `numero_esterno`, `numero`), ' del ', DATE_FORMAT(`data`, '%d/%m/%Y'), ' [', `dt_statiddt_lang`.`title`, ']') AS opzione
|
||||||
|
FROM
|
||||||
|
`dt_righe_ddt`
|
||||||
|
INNER JOIN `dt_ddt` ON `dt_ddt`.`id` = `dt_righe_ddt`.`idddt`
|
||||||
|
INNER JOIN `dt_statiddt` ON `dt_statiddt`.`id` = `dt_ddt`.`idstatoddt`
|
||||||
|
LEFT JOIN `dt_statiddt_lang` ON `dt_statiddt_lang`.`id_record` = `dt_statiddt`.`id` AND `dt_statiddt_lang`.`id_lang` = ".prepare(Models\Locale::getDefault()->id).'
|
||||||
|
WHERE
|
||||||
|
`dt_ddt`.`numero_esterno` = '.prepare($ddt['numero']).' AND
|
||||||
|
YEAR(`dt_ddt`.`data`) = '.prepare($ddt['anno']).' AND
|
||||||
|
`dt_ddt`.`idanagrafica` = '.prepare($anagrafica->id).' AND
|
||||||
|
`dt_righe_ddt`.`qta` > `dt_righe_ddt`.`qta_evasa` AND
|
||||||
|
|where|';
|
||||||
|
|
||||||
|
// Ricerca di righe DDT con stesso Articolo
|
||||||
|
if (!empty($id_articolo)) {
|
||||||
|
$query_articolo = replace($query, [
|
||||||
|
'|where|' => '`dt_righe_ddt`.`idarticolo` = '.prepare($id_articolo),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$collegamento = $database->fetchOne($query_articolo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ricerca di righe DDT per stessa descrizione
|
||||||
|
if (empty($collegamento)) {
|
||||||
|
$query_descrizione = replace($query, [
|
||||||
|
'|where|' => '`dt_righe_ddt`.`descrizione` = '.prepare($riga['Descrizione']),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$collegamento = $database->fetchOne($query_descrizione);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Se nella fattura elettronica NON è indicato un DDT ed è indicato anche un ordine
|
||||||
|
// cerco per quell'ordine
|
||||||
|
if (empty($collegamento)) {
|
||||||
|
$ordine = $dati_ordini[$numero_linea];
|
||||||
|
$query = "SELECT
|
||||||
|
`or_righe_ordini`.`id`,
|
||||||
|
`or_righe_ordini`.`idordine` AS id_documento,
|
||||||
|
`or_righe_ordini`.`is_descrizione`,
|
||||||
|
`or_righe_ordini`.`idarticolo`,
|
||||||
|
`or_righe_ordini`.`is_sconto`,
|
||||||
|
'ordine' AS ref,
|
||||||
|
CONCAT('Ordine num. ', IF(`numero_esterno` != '', `numero_esterno`, `numero`), ' del ', DATE_FORMAT(`data`, '%d/%m/%Y'), ' [', `or_statiordine_lang`.`title` , ']') AS opzione
|
||||||
|
FROM `or_righe_ordini`
|
||||||
|
INNER JOIN `or_ordini` ON `or_ordini`.`id` = `or_righe_ordini`.`idordine`
|
||||||
|
INNER JOIN `or_statiordine` ON `or_statiordine`.`id` = `or_ordini`.`idstatoordine`
|
||||||
|
LEFT JOIN `or_statiordine_lang` ON `or_statiordine_lang`.`id_record` = `or_statiordine`.`id` AND `or_statiordine_lang`.`id_lang` = ".prepare(Models\Locale::getDefault()->id).'
|
||||||
|
WHERE
|
||||||
|
`or_ordini`.`numero_esterno` = '.prepare($ordine['numero']).'
|
||||||
|
AND YEAR(`or_ordini`.`data`) = '.prepare($ordine['anno']).'
|
||||||
|
AND `or_ordini`.`idanagrafica` = '.prepare($anagrafica->id).'
|
||||||
|
AND `or_righe_ordini`.`qta` > `or_righe_ordini`.`qta_evasa`
|
||||||
|
AND |where|';
|
||||||
|
|
||||||
|
// Ricerca di righe Ordine con stesso Articolo
|
||||||
|
if (!empty($id_articolo)) {
|
||||||
|
$query_articolo = replace($query, [
|
||||||
|
'|where|' => '`or_righe_ordini`.`idarticolo` = '.prepare($id_articolo),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$collegamento = $database->fetchOne($query_articolo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ricerca di righe Ordine per stessa descrizione
|
||||||
|
if (empty($collegamento)) {
|
||||||
|
$query_descrizione = replace($query, [
|
||||||
|
'|where|' => '`or_righe_ordini`.`descrizione` = '.prepare($riga['Descrizione']),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$collegamento = $database->fetchOne($query_descrizione);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TENTATIVO 2: ricerca solo per articolo o descrizione su documenti
|
||||||
|
* non referenziati nella fattura elettronica
|
||||||
|
*/
|
||||||
|
// Se non ci sono Ordini o DDT cerco per contenuto
|
||||||
|
if (empty($collegamento)) {
|
||||||
|
$match_documento_da_fe = false;
|
||||||
|
$query = "SELECT
|
||||||
|
`dt_righe_ddt`.`id`,
|
||||||
|
`dt_righe_ddt`.`idddt` AS id_documento,
|
||||||
|
`dt_righe_ddt`.`is_descrizione`,
|
||||||
|
`dt_righe_ddt`.`idarticolo`,
|
||||||
|
`dt_righe_ddt`.`is_sconto`,
|
||||||
|
'ddt' AS ref,
|
||||||
|
CONCAT('DDT num. ', IF(`numero_esterno` != '', `numero_esterno`, `numero`), ' del ', DATE_FORMAT(`data`, '%d/%m/%Y'), ' [', `dt_statiddt_lang`.`title`, ']') AS opzione
|
||||||
|
FROM
|
||||||
|
`dt_righe_ddt`
|
||||||
|
INNER JOIN `dt_ddt` ON `dt_ddt`.`id` = `dt_righe_ddt`.`idddt`
|
||||||
|
INNER JOIN `dt_statiddt` ON `dt_statiddt`.`id` = `dt_ddt`.`idstatoddt`
|
||||||
|
LEFT JOIN `dt_statiddt_lang` ON (`dt_statiddt_lang`.`id_record` = `dt_statiddt`.`id` AND `dt_statiddt_lang`.`id_lang` = ".prepare(Models\Locale::getDefault()->id).')
|
||||||
|
INNER JOIN `dt_tipiddt` ON `dt_ddt`.`idtipoddt` = `dt_tipiddt`.`id`
|
||||||
|
WHERE
|
||||||
|
`dt_ddt`.`idanagrafica` = '.prepare($anagrafica->id)." AND
|
||||||
|
|where_ddt| AND
|
||||||
|
`dt_righe_ddt`.`qta` > `dt_righe_ddt`.`qta_evasa` AND
|
||||||
|
`dt_statiddt_lang`.`title` != 'Fatturato' AND
|
||||||
|
`dt_tipiddt`.`dir` = 'entrata'
|
||||||
|
UNION
|
||||||
|
SELECT
|
||||||
|
`or_righe_ordini`.`id`,
|
||||||
|
`or_righe_ordini`.`idordine` AS id_documento,
|
||||||
|
`or_righe_ordini`.`is_descrizione`,
|
||||||
|
`or_righe_ordini`.`idarticolo`,
|
||||||
|
`or_righe_ordini`.`is_sconto`,
|
||||||
|
'ordine' AS ref,
|
||||||
|
CONCAT('Ordine num. ', IF(`numero_esterno` != '', `numero_esterno`, `numero`), ' del ', DATE_FORMAT(`data`, '%d/%m/%Y'), ' [', (SELECT `descrizione` FROM or_stati`ordine WHERE `id` = `idstatoordine`) , ']') AS opzione
|
||||||
|
FROM
|
||||||
|
`or_righe_ordini`
|
||||||
|
INNER JOIN `or_ordini` ON `or_ordini`.`id` = `or_righe_ordini`.`idordine`
|
||||||
|
INNER JOIN `or_statiordine` ON `or_statiordine`.`id` = `or_ordini`.`idstatoordine`
|
||||||
|
LEFT JOIN `or_statiordine_lang` ON (`or_statiordine_lang`.`id_record` = `or_statiordine`.`id` AND `or_statiordine_lang`.`id_lang` = ".prepare(Models\Locale::getDefault()->id).')
|
||||||
|
INNER JOIN `or_tipiordine` ON `or_ordini`.`idtipoordine` = `or_tipiordine`.`id`
|
||||||
|
WHERE
|
||||||
|
`or_ordini`.`idanagrafica` = '.prepare($anagrafica->id)." AND
|
||||||
|
|where_ordini| AND
|
||||||
|
`or_righe_ordini`.`qta` > `or_righe_ordini`.`qta_evasa` AND
|
||||||
|
`or_statiordine_lang` WHERE `title` != 'Fatturato' AND
|
||||||
|
`or_tipiordine`.`dir` ='entrata'";
|
||||||
|
|
||||||
|
// Ricerca di righe DDT/Ordine con stesso Articolo
|
||||||
|
if (!empty($id_articolo)) {
|
||||||
|
$query_articolo = replace($query, [
|
||||||
|
'|where_ddt|' => '`dt_righe_ddt`.`idarticolo` = '.prepare($id_articolo),
|
||||||
|
'|where_ordini|' => '`or_righe_ordini`.`idarticolo` = '.prepare($id_articolo),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$collegamento = $database->fetchOne($query_articolo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ricerca di righe DDT/Ordine per stessa descrizione
|
||||||
|
if (empty($collegamento)) {
|
||||||
|
$query_descrizione = replace($query, [
|
||||||
|
'|where_ddt|' => '`dt_righe_ddt`.`descrizione` = '.prepare($riga['Descrizione']),
|
||||||
|
'|where_ordini|' => '`or_righe_ordini`.`descrizione` = '.prepare($riga['Descrizione']),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$collegamento = $database->fetchOne($query_descrizione);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ricerca di righe DDT/Ordine per stesso importo
|
||||||
|
if (empty($collegamento)) {
|
||||||
|
$query_descrizione = replace($query, [
|
||||||
|
'|where_ddt|' => '`dt_righe_ddt`.`prezzo_unitario` = '.prepare($riga['PrezzoUnitario']),
|
||||||
|
'|where_ordini|' => '`or_righe_ordini`.`prezzo_unitario` = '.prepare($riga['PrezzoUnitario']),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$collegamento = $database->fetchOne($query_descrizione);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($collegamento)) {
|
||||||
|
// Individuazione del documento
|
||||||
|
$documento = $collegamento['ref'] == 'ddt' ? DDT::find($collegamento['id_documento']) : Ordine::find($collegamento['id_documento']);
|
||||||
|
|
||||||
|
// Individuazione della classe di gestione per la riga
|
||||||
|
$namespace = $collegamento['ref'] == 'ddt' ? 'Modules\\DDT\\Components\\' : 'Modules\\Ordini\\Components\\';
|
||||||
|
if (!empty($collegamento['idarticolo'])) {
|
||||||
|
$type = 'Articolo';
|
||||||
|
} elseif (!empty($collegamento['is_sconto'])) {
|
||||||
|
$type = 'Sconto';
|
||||||
|
} elseif (!empty($collegamento['is_descrizione'])) {
|
||||||
|
$type = 'Descrizione';
|
||||||
|
} else {
|
||||||
|
$type = 'Riga';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ricerca della riga
|
||||||
|
$riga = $documento->getRiga($namespace.$type, $collegamento['id']);
|
||||||
|
$riga_origine = $riga->getOriginalComponent();
|
||||||
|
|
||||||
|
if (!empty($riga->idarticolo)) {
|
||||||
|
$desc_conto = $dbo->fetchOne('SELECT CONCAT( co_pianodeiconti2.numero, ".", co_pianodeiconti3.numero, " ", co_pianodeiconti3.descrizione ) AS descrizione FROM co_pianodeiconti3 INNER JOIN co_pianodeiconti2 ON co_pianodeiconti3.idpianodeiconti2=co_pianodeiconti2.id WHERE co_pianodeiconti3.id = '.prepare($riga->articolo->idconto_acquisto))['descrizione'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compilazione dei dati
|
||||||
|
$results[$key] = [
|
||||||
|
'documento' => [
|
||||||
|
'tipo' => $collegamento['ref'],
|
||||||
|
'id' => $collegamento['id_documento'],
|
||||||
|
'descrizione' => reference($documento, tr('Origine')),
|
||||||
|
'opzione' => $collegamento['opzione'],
|
||||||
|
'match_documento_da_fe' => $match_documento_da_fe,
|
||||||
|
],
|
||||||
|
'riga' => [
|
||||||
|
'tipo' => $riga::class,
|
||||||
|
'id' => $riga->id,
|
||||||
|
'descrizione' => $riga->descrizione,
|
||||||
|
'qta' => $riga->qta,
|
||||||
|
'um' => $riga->um,
|
||||||
|
'prezzo_unitario' => $riga->prezzo_unitario ?: $riga_origine->prezzo_unitario,
|
||||||
|
'id_iva' => $riga->id_iva,
|
||||||
|
'iva_percentuale' => $riga->aliquota->percentuale,
|
||||||
|
'id_articolo' => $riga->idarticolo,
|
||||||
|
'desc_articolo' => str_replace(' ', '_', $riga->articolo->codice.' - '.$riga->articolo->getTranslation('title')),
|
||||||
|
'id_conto' => $riga->articolo->idconto_acquisto,
|
||||||
|
'desc_conto' => str_replace(' ', '_', $desc_conto),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode($results);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
<?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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<div class="tip" data-widget="tooltip" title="'.tr('Tenta la compilazione automatica delle informazioni delle fattura elettronica sulla base delle precedenti fatture del Fornitore').'.">
|
||||||
|
<button type="button" class="btn btn-primary" '.(!empty($anagrafica) ? '' : 'disabled').' id="compilazione_automatica" onclick="compile(this)" >
|
||||||
|
<i class="fa fa-address-book"></i> '.tr('Compila automaticamente').'
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tip" data-widget="tooltip" title="'.tr('Tenta il completamento automatico dei riferimenti per le righe delle fattura elettronica sulla base di Ordini e DDT registrati nel gestionale per il Fornitore').'.">
|
||||||
|
<button type="button" class="btn btn-primary" '.(!empty($anagrafica) ? '' : 'disabled').' onclick="compilaRiferimenti(this)" >
|
||||||
|
<i class="fa fa-list"></i> '.tr('Cerca riferimenti').'
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
var btn = $("#compilazione_automatica");
|
||||||
|
|
||||||
|
if (!$("#compilazione_automatica").not("disabled")) {
|
||||||
|
btn.click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function compile(btn) {
|
||||||
|
let restore = buttonLoading(btn);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: globals.rootdir + "/actions.php",
|
||||||
|
cache: false,
|
||||||
|
type: "GET",
|
||||||
|
dataType: "json",
|
||||||
|
data: {
|
||||||
|
id_module: "'.$id_module.'",
|
||||||
|
id_plugin: "'.$id_plugin.'",
|
||||||
|
id_record: "'.$id_record.'",
|
||||||
|
op: "compile",
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
buttonRestore(btn, restore);
|
||||||
|
if (response.length === 0){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$("#id_tipo").val()) {
|
||||||
|
$("#id_tipo").selectSet(response.id_tipo);
|
||||||
|
}
|
||||||
|
|
||||||
|
$("select[name^=iva]").each(function(){
|
||||||
|
var aliquota = $(this).closest("tr").find("[id^=aliquota]").text();
|
||||||
|
if (response.iva[aliquota] !== undefined && !$(this).val()){
|
||||||
|
$(this).selectSet(response.iva[aliquota].id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("select[name^=conto]").each(function(){
|
||||||
|
if (!$(this).val()){
|
||||||
|
$(this).selectSetNew(response.conto.id, response.conto.descrizione);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: function(data) {
|
||||||
|
swal("'.tr('Errore').'", "'.tr('La compilazione automatica dei campi non è andata a buon fine').'.", "error");
|
||||||
|
|
||||||
|
buttonRestore(btn, restore);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function compilaRiferimenti(btn) {
|
||||||
|
let restore = buttonLoading(btn);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: globals.rootdir + "/actions.php",
|
||||||
|
cache: false,
|
||||||
|
type: "GET",
|
||||||
|
dataType: "json",
|
||||||
|
data: {
|
||||||
|
id_module: "'.$id_module.'",
|
||||||
|
id_plugin: "'.$id_plugin.'",
|
||||||
|
id_record: "'.$id_record.'",
|
||||||
|
op: "riferimenti-automatici",
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
buttonRestore(btn, restore);
|
||||||
|
if (response.length === 0){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (id_riga in response) {
|
||||||
|
data = response[id_riga];
|
||||||
|
|
||||||
|
// Selezione dinamica
|
||||||
|
$("#selezione_riferimento" + id_riga).addClass("already-loaded").selectSetNew(data.documento.id, data.documento.opzione).removeClass("already-loaded");
|
||||||
|
|
||||||
|
// Impostazione del riferimento
|
||||||
|
impostaRiferimento(id_riga, data.documento, data.riga);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(data) {
|
||||||
|
swal("'.tr('Errore').'", "'.tr('La ricerca automatica dei riferimenti per le righe non è andata a buon fine').'.", "error");
|
||||||
|
|
||||||
|
buttonRestore(btn, restore);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>';
|
|
@ -0,0 +1,266 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
include_once __DIR__.'/../../core.php';
|
||||||
|
|
||||||
|
use Plugins\ImportFE\Interaction;
|
||||||
|
|
||||||
|
if (setting('Metodo di importazione XML fatture di vendita') == 'Automatico') {
|
||||||
|
echo '
|
||||||
|
<script>
|
||||||
|
function upload1(btn) {
|
||||||
|
if ($("#blob1").val()) {
|
||||||
|
swal({
|
||||||
|
title: "'.tr('Avviare la procedura?').'",
|
||||||
|
type: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: "'.tr('Sì').'"
|
||||||
|
}).then(function (result) {
|
||||||
|
var restore = buttonLoading(btn);
|
||||||
|
|
||||||
|
$("#upload1").ajaxSubmit({
|
||||||
|
url: globals.rootdir + "/actions.php",
|
||||||
|
data: {
|
||||||
|
op: "save",
|
||||||
|
id_module: "'.$id_module.'",
|
||||||
|
id_plugin: "'.$id_plugin.'",
|
||||||
|
},
|
||||||
|
type: "post",
|
||||||
|
success: function(data){
|
||||||
|
|
||||||
|
swal("Caricamento completato!", "", "success");
|
||||||
|
|
||||||
|
$("#blob1").val("");
|
||||||
|
buttonRestore(btn, restore);
|
||||||
|
},
|
||||||
|
error: function(xhr) {
|
||||||
|
alert("'.tr('Errore').': " + xhr.responseJSON.error.message);
|
||||||
|
|
||||||
|
buttonRestore(btn, restore);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
swal({
|
||||||
|
title: "'.tr('Selezionare un file!').'",
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>';
|
||||||
|
} else {
|
||||||
|
if (!empty($record)) {
|
||||||
|
include $structure->filepath('generate.php');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
echo '
|
||||||
|
<script>
|
||||||
|
function upload1(btn) {
|
||||||
|
if ($("#blob1").val()) {
|
||||||
|
swal({
|
||||||
|
title: "'.tr('Avviare la procedura?').'",
|
||||||
|
type: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: "'.tr('Sì').'"
|
||||||
|
}).then(function (result) {
|
||||||
|
var restore = buttonLoading(btn);
|
||||||
|
|
||||||
|
$("#upload1").ajaxSubmit({
|
||||||
|
url: globals.rootdir + "/actions.php",
|
||||||
|
data: {
|
||||||
|
op: "save",
|
||||||
|
id_module: "'.$id_module.'",
|
||||||
|
id_plugin: "'.$id_plugin.'",
|
||||||
|
},
|
||||||
|
type: "post",
|
||||||
|
success: function(data){
|
||||||
|
data = JSON.parse(data);
|
||||||
|
|
||||||
|
if (!data.already) {
|
||||||
|
redirect(globals.rootdir + "/editor.php?id_module=" + globals.id_module + "&id_plugin=" + '.$id_plugin.' + "&id_record=" + data.id);
|
||||||
|
} else {
|
||||||
|
swal({
|
||||||
|
title: "'.tr('Fattura già importata').'.",
|
||||||
|
type: "info",
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#blob1").val("");
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonRestore(btn, restore);
|
||||||
|
},
|
||||||
|
error: function(xhr) {
|
||||||
|
alert("'.tr('Errore').': " + xhr.responseJSON.error.message);
|
||||||
|
|
||||||
|
buttonRestore(btn, restore);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
swal({
|
||||||
|
title: "'.tr('Selezionare un file!').'",
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<div class="card card-success">
|
||||||
|
<div class="card-header with-border">
|
||||||
|
<h3 class="card-title">
|
||||||
|
'.tr('Carica un file ZIP contenente i file XML').'
|
||||||
|
|
||||||
|
<span class="tip" title="'.tr('Formati supportati: ZIP').'.">
|
||||||
|
<i class="fa fa-question-circle-o"></i>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body" id="upload1">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-9">
|
||||||
|
<label><input type="file" name="blob1" id="blob1"></label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
<button type="button" class="btn btn-primary pull-right" onclick="upload1(this)">
|
||||||
|
<i class="fa fa-upload"></i> '.tr('Carica documenti').'
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>';
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<div class="card card-info">
|
||||||
|
<div class="card-header with-border">
|
||||||
|
<h3 class="card-title">
|
||||||
|
'.tr('Fatture da importare').'</span>
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div class="float-right d-none d-sm-inline">
|
||||||
|
<button type="button" class="btn btn-warning" onclick="importAll(this)">
|
||||||
|
<i class="fa fa-cloud-download"></i> '.tr('Importa tutte').'
|
||||||
|
</button>';
|
||||||
|
|
||||||
|
// Ricerca automatica
|
||||||
|
if (Interaction::isEnabled()) {
|
||||||
|
echo '
|
||||||
|
<button type="button" class="btn btn-primary" onclick="search(this)">
|
||||||
|
<i class="fa fa-refresh"></i> '.tr('Ricerca fatture di acquisto').'
|
||||||
|
</button>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body" id="list">';
|
||||||
|
|
||||||
|
if (Interaction::isEnabled()) {
|
||||||
|
echo '
|
||||||
|
<p>'.tr('Per vedere le fatture da importare utilizza il pulsante _BUTTON_', [
|
||||||
|
'_BUTTON_' => '<b>"'.tr('Ricerca fatture di acquisto').'"</b>',
|
||||||
|
]).'.</p>';
|
||||||
|
} else {
|
||||||
|
include $structure->filepath('list.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
$($.fn.dataTable.tables(true)).DataTable().columns.adjust();
|
||||||
|
$($.fn.dataTable.tables(true)).DataTable().scroller.measure();
|
||||||
|
});';
|
||||||
|
|
||||||
|
if (Interaction::isEnabled()) {
|
||||||
|
echo '
|
||||||
|
function importAll(btn) {
|
||||||
|
swal({
|
||||||
|
title: "'.tr('Importare tutte le fatture?').'",
|
||||||
|
html: "'.tr('Verranno scaricate tutte le fatture da importare, e non sarà più possibile visualizzare altre informazioni oltre al nome per le fatture che non verranno importate completamente. Continuare?').'",
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: "'.tr('Procedi').'",
|
||||||
|
type: "info",
|
||||||
|
}).then(function (result) {
|
||||||
|
var restore = buttonLoading(btn);
|
||||||
|
$("#main_loading").show();
|
||||||
|
|
||||||
|
$.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;
|
||||||
|
counter = 0;
|
||||||
|
data.forEach(function(element) {
|
||||||
|
$.ajax({
|
||||||
|
url: globals.rootdir + "/actions.php",
|
||||||
|
type: "get",
|
||||||
|
data: {
|
||||||
|
id_module: "'.$id_module.'",
|
||||||
|
id_plugin: "'.$id_plugin.'",
|
||||||
|
op: "prepare",
|
||||||
|
name: element.name,
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
counter ++;
|
||||||
|
|
||||||
|
importComplete(count, counter, btn, restore);
|
||||||
|
},
|
||||||
|
error: function(data) {
|
||||||
|
counter ++;
|
||||||
|
|
||||||
|
importComplete(count, counter, btn, restore);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
importComplete(count, counter, btn, restore);
|
||||||
|
},
|
||||||
|
error: function(data) {
|
||||||
|
alert("'.tr('Errore').': " + data);
|
||||||
|
|
||||||
|
$("#main_loading").fadeOut();
|
||||||
|
buttonRestore(btn, restore);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function importComplete(count, counter, btn, restore) {
|
||||||
|
if(counter == count){
|
||||||
|
$("#main_loading").fadeOut();
|
||||||
|
buttonRestore(btn, restore);
|
||||||
|
|
||||||
|
redirect(globals.rootdir + "/editor.php?id_module=" + globals.id_module + "&id_plugin=" + '.$id_plugin.' + "&id_record=1&sequence=1");
|
||||||
|
}
|
||||||
|
}';
|
||||||
|
} else {
|
||||||
|
echo '
|
||||||
|
function importAll(btn) {
|
||||||
|
redirect(globals.rootdir + "/editor.php?id_module=" + globals.id_module + "&id_plugin=" + '.$id_plugin.' + "&id_record=1&sequence=1");
|
||||||
|
}';
|
||||||
|
}
|
||||||
|
echo '
|
||||||
|
|
||||||
|
function search(btn) {
|
||||||
|
var restore = buttonLoading(btn);
|
||||||
|
|
||||||
|
$("#list").load("'.$structure->fileurl('list.php').'?id_module='.$id_module.'&id_plugin='.$id_plugin.'", function() {
|
||||||
|
buttonRestore(btn, restore);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>';
|
|
@ -0,0 +1,980 @@
|
||||||
|
<?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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Models\Module;
|
||||||
|
use Modules\Fatture\Fattura;
|
||||||
|
use Modules\Pagamenti\Pagamento;
|
||||||
|
use Plugins\ImportFE\FatturaElettronica;
|
||||||
|
use Util\XML;
|
||||||
|
|
||||||
|
include_once __DIR__.'/../../core.php';
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
$("#save-buttons").hide();
|
||||||
|
|
||||||
|
// Visualizza input seriali se abilita serial dell\'articolo selezionato è attivo
|
||||||
|
let articoli = $("select[name^=articoli]");
|
||||||
|
articoli.each(function() {
|
||||||
|
verificaSerial($(this));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Disabilita input seriali se flag crea serialzi è disattivato
|
||||||
|
if (!$("#flag_crea_seriali").is(":checked")) {
|
||||||
|
$("[id^=\'serial\']").attr("disabled", true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>';
|
||||||
|
|
||||||
|
$skip_link = $has_next && post('sequence') ? base_path().'/editor.php?id_module='.$id_module.'&id_plugin='.$id_plugin.'&id_record='.($id_record + 1).'&sequence='.get('sequence') : base_path().'/editor.php?id_module='.$id_module;
|
||||||
|
|
||||||
|
if (empty($fattura)) {
|
||||||
|
if (!empty($error)) {
|
||||||
|
echo '
|
||||||
|
<p>'.tr("Errore durante l'apertura della fattura elettronica _NAME_", [
|
||||||
|
'_NAME_' => $record['name'],
|
||||||
|
]).'.</p>';
|
||||||
|
} elseif (!empty($imported)) {
|
||||||
|
echo '
|
||||||
|
<p>'.tr('La fattura elettronica _NAME_ è già stata importata in passato', [
|
||||||
|
'_NAME_' => $record['name'],
|
||||||
|
]).'.</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12 text-right">';
|
||||||
|
|
||||||
|
if (!empty($imported)) {
|
||||||
|
echo '
|
||||||
|
<button type="button" class="btn btn-danger" onclick="cleanup()">
|
||||||
|
<i class="fa fa-trash-o"></i> '.tr('Processa e rimuovi').'
|
||||||
|
</button>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<button type="button" class="btn btn-warning" onclick="skip()">
|
||||||
|
<i class="fa fa-ban "></i> '.tr('Salta fattura').'
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function skip() {
|
||||||
|
redirect("'.$skip_link.'");
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanup(){
|
||||||
|
$.ajax({
|
||||||
|
url: globals.rootdir + "/actions.php",
|
||||||
|
type: "get",
|
||||||
|
data: {
|
||||||
|
id_module: "'.$id_module.'",
|
||||||
|
id_plugin: "'.$id_plugin.'",
|
||||||
|
op: "delete",
|
||||||
|
name: "'.$record['name'].'",
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: globals.rootdir + "/actions.php",
|
||||||
|
type: "get",
|
||||||
|
data: {
|
||||||
|
id_module: "'.$id_module.'",
|
||||||
|
id_plugin: "'.$id_plugin.'",
|
||||||
|
op: "process",
|
||||||
|
name: "'.$record['name'].'",
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
skip();
|
||||||
|
}
|
||||||
|
</script>';
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cliente
|
||||||
|
$cliente = $fattura->getAnagrafe('Cliente');
|
||||||
|
|
||||||
|
$ragione_sociale = $cliente['ragione_sociale'] ?: $cliente['cognome'].' '.$cliente['nome'];
|
||||||
|
$codice_fiscale = $cliente['codice_fiscale'];
|
||||||
|
$partita_iva = $cliente['partita_iva'];
|
||||||
|
|
||||||
|
$sede = $cliente['sede'];
|
||||||
|
|
||||||
|
$cap = $sede['cap'];
|
||||||
|
$citta = $sede['comune'];
|
||||||
|
$provincia = $sede['provincia'];
|
||||||
|
|
||||||
|
// Dati generali
|
||||||
|
$fattura_body = $fattura->getBody();
|
||||||
|
$dati_generali = $fattura_body['DatiGenerali']['DatiGeneraliDocumento'];
|
||||||
|
|
||||||
|
$tipo_documento = $database->fetchOne('SELECT CONCAT("(", `codice`, ") ", `title`) AS descrizione FROM `fe_tipi_documento` LEFT JOIN `fe_tipi_documento_lang` ON (`fe_tipi_documento_lang`.`id_record` = `fe_tipi_documento`.`codice` AND `fe_tipi_documento_lang`.`id_lang` = '.prepare(Models\Locale::getDefault()->id).') WHERE codice = '.prepare($dati_generali['TipoDocumento']))['descrizione'];
|
||||||
|
|
||||||
|
// Gestione per fattura elettroniche senza pagamento definito
|
||||||
|
$pagamenti = [];
|
||||||
|
if (isset($fattura_body['DatiPagamento'])) {
|
||||||
|
$pagamenti = $fattura_body['DatiPagamento'];
|
||||||
|
$pagamenti = isset($pagamenti[0]) ? $pagamenti : [$pagamenti];
|
||||||
|
}
|
||||||
|
|
||||||
|
$is_autofattura = false;
|
||||||
|
if (in_array($dati_generali['TipoDocumento'], ['TD16', 'TD17', 'TD18', 'TD19', 'TD20', 'TD21', 'TD28'])) {
|
||||||
|
$is_autofattura = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Individuazione metodo di pagamento di base
|
||||||
|
$metodi = $pagamenti[0]['DettaglioPagamento'] ?? [];
|
||||||
|
$metodi = isset($metodi[0]) ? $metodi : [$metodi];
|
||||||
|
|
||||||
|
$codice_modalita_pagamento = $metodi[0]['ModalitaPagamento'];
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<form action="" method="post">
|
||||||
|
<input type="hidden" name="filename" value="'.$record['name'].'">
|
||||||
|
<input type="hidden" name="op" value="generate">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3">
|
||||||
|
<h4>
|
||||||
|
'.$ragione_sociale.'
|
||||||
|
|
||||||
|
'.(empty($anagrafica) ? '<span class="badge bg-warning">'.tr('Nuova anagrafica').'</span>' : '<small>'.Modules::link('Anagrafiche', $anagrafica->id, '', null, '').'</small>').'<br>
|
||||||
|
|
||||||
|
<small>
|
||||||
|
'.(!empty($codice_fiscale) ? (tr('Codice Fiscale').': '.$codice_fiscale.'<br>') : '').'
|
||||||
|
'.(!empty($partita_iva) ? (tr('Partita IVA').': '.$partita_iva.'<br>') : '').'
|
||||||
|
'.$cap.' '.$citta.' ('.$provincia.')<br>
|
||||||
|
</small>
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
<h4>
|
||||||
|
'.$dati_generali['Numero'].'
|
||||||
|
|
||||||
|
<a href="'.$structure->fileurl('view.php').'?filename='.$record['name'].'" class="btn btn-info btn-xs" target="_blank" >
|
||||||
|
<i class="fa fa-eye"></i> '.tr('Visualizza').'
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<br><small>
|
||||||
|
'.$tipo_documento.'
|
||||||
|
<br>'.Translator::dateToLocale($dati_generali['Data']).'
|
||||||
|
<br>'.$dati_generali['Divisa'].'
|
||||||
|
</small>
|
||||||
|
</h4>
|
||||||
|
</div>';
|
||||||
|
|
||||||
|
// Blocco DatiPagamento è valorizzato (opzionale)
|
||||||
|
if (!empty($pagamenti)) {
|
||||||
|
echo '
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h4>'.tr('Pagamento').'</h4>
|
||||||
|
|
||||||
|
<p>'.tr('La fattura importata presenta _NUM_ rat_E_ di pagamento con le seguenti scadenze', [
|
||||||
|
'_NUM_' => count($metodi),
|
||||||
|
'_E_' => ((count($metodi) > 1) ? 'e' : 'a'),
|
||||||
|
]).':</p>
|
||||||
|
<ol>';
|
||||||
|
|
||||||
|
foreach ($pagamenti as $pagamento) {
|
||||||
|
$rate = $pagamento['DettaglioPagamento'];
|
||||||
|
$rate = isset($rate[0]) ? $rate : [$rate];
|
||||||
|
|
||||||
|
// Scadenze di pagamento
|
||||||
|
foreach ($rate as $rata) {
|
||||||
|
$descrizione = !empty($rata['ModalitaPagamento']) ? $database->fetchOne('SELECT `title` FROM `fe_modalita_pagamento` LEFT JOIN `fe_modalita_pagamento_lang` ON (`fe_modalita_pagamento_lang`.`id_record`=`fe_modalita_pagamento`.`codice` AND `fe_modalita_pagamento_lang`.`id_lang`='.prepare(Models\Locale::getDefault()->id).') WHERE `codice` = '.prepare($rata['ModalitaPagamento']))['descrizione'] : '';
|
||||||
|
$data = !empty($rata['DataScadenzaPagamento']) ? FatturaElettronica::parseDate($rata['DataScadenzaPagamento']) : '';
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<li>
|
||||||
|
'.dateFormat($data).'
|
||||||
|
'.moneyFormat($rata['ImportoPagamento']).'
|
||||||
|
('.$descrizione.')
|
||||||
|
</li>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
</ol>
|
||||||
|
</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
</div>';
|
||||||
|
|
||||||
|
// Tipo del documento
|
||||||
|
$query = "SELECT `co_tipidocumento`.`id`, CONCAT('(', `codice_tipo_documento_fe`, ') ', `title`) AS descrizione FROM `co_tipidocumento` LEFT JOIN `co_tipidocumento_lang` ON (`co_tipidocumento_lang`.`id_record` = `co_tipidocumento`.`id` AND `co_tipidocumento_lang`.`id_lang` = ".prepare(Models\Locale::getDefault()->id).") WHERE `dir` = 'entrata'";
|
||||||
|
$query_tipo = $query.' AND `codice_tipo_documento_fe` = '.prepare($dati_generali['TipoDocumento']);
|
||||||
|
$numero_tipo = $database->fetchNum($query_tipo);
|
||||||
|
if (!empty($numero_tipo)) {
|
||||||
|
$query = $query_tipo;
|
||||||
|
}
|
||||||
|
|
||||||
|
$id_tipodocumento = $database->fetchOne($query_tipo)['id'];
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3">
|
||||||
|
{[ "type": "select", "label": "'.tr('Tipo fattura').'", "name": "id_tipo", "required": 1, "values": "query='.$query.'", "value": "'.($numero_tipo != 1 ? $id_tipodocumento : '').'" ]}
|
||||||
|
</div>';
|
||||||
|
|
||||||
|
// Sezionale
|
||||||
|
$id_segment = $database->table('co_tipidocumento')->where('id', '=', $id_tipodocumento)->value('id_segment');
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<div class="col-md-3">
|
||||||
|
{[ "type": "select", "label": "'.tr('Sezionale').'", "name": "id_segment", "required": 1, "ajax-source": "segmenti", "select-options": '.json_encode(['id_module' => $id_module, 'is_fiscale' => 1, 'is_sezionale' => 1, 'for_fe' => 1]).', "value": "'.$id_segment.'" ]}
|
||||||
|
</div>';
|
||||||
|
|
||||||
|
// Data di registrazione
|
||||||
|
$data_registrazione = get('data_registrazione');
|
||||||
|
$data_registrazione = new Carbon($data_registrazione);
|
||||||
|
echo '
|
||||||
|
<div class="col-md-3">
|
||||||
|
{[ "type": "date", "label": "'.tr('Data di registrazione').'", "name": "data_registrazione", "required": 1, "value": "'.($data_registrazione ?: $dati_generali['Data']).'", "max-date": "-now-", "min-date": "'.$dati_generali['Data'].'" ]}
|
||||||
|
</div>';
|
||||||
|
|
||||||
|
if (!empty($anagrafica)) {
|
||||||
|
$query = "SELECT
|
||||||
|
`co_documenti`.`id`,
|
||||||
|
CONCAT('Fattura num. ', `co_documenti`.`numero_esterno`, ' del ', DATE_FORMAT(`co_documenti`.`data`, '%d/%m/%Y')) AS descrizione
|
||||||
|
FROM `co_documenti`
|
||||||
|
INNER JOIN `co_tipidocumento` ON `co_tipidocumento`.`id` = `co_documenti`.`idtipodocumento`
|
||||||
|
WHERE
|
||||||
|
`co_tipidocumento`.`dir` = 'entrata' AND
|
||||||
|
(`co_documenti`.`data` BETWEEN NOW() - INTERVAL 1 YEAR AND NOW()) AND
|
||||||
|
`co_documenti`.`idstatodocumento` IN (SELECT `id_record` FROM `co_statidocumento_lang` WHERE `title` != 'Bozza') AND
|
||||||
|
`co_documenti`.`idanagrafica` = ".prepare($anagrafica->id);
|
||||||
|
|
||||||
|
// Riferimenti ad altre fatture
|
||||||
|
if (in_array($dati_generali['TipoDocumento'], ['TD04', 'TD05'])) {
|
||||||
|
echo '
|
||||||
|
<div class="col-md-3">
|
||||||
|
{[ "type": "select", "label": "'.tr('Fattura collegata').'", "name": "ref_fattura", "required": 0, "values": "query='.$query.'" ]}
|
||||||
|
</div>';
|
||||||
|
} elseif ($dati_generali['TipoDocumento'] == 'TD06') {
|
||||||
|
$query .= 'AND `co_documenti`.`id_segment` = (SELECT `zz_segments`.`id` FROM `zz_segments` LEFT JOIN `zz_segments_lang` ON (`zz_segments_lang`.`id_record` = `zz_segments`.`id` AND `zz_segments_lang`.`id_lang` = '.prepare(Models\Locale::getDefault()->id).") WHERE `title` = 'Fatture pro-forma' AND `id_module` = ".prepare($id_module).')';
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<div class="col-md-3">
|
||||||
|
{[ "type": "select", "label": "'.tr('Collega a fattura pro-forma').'", "name": "ref_fattura", "values": "query='.$query.'" ]}
|
||||||
|
</div>';
|
||||||
|
} elseif ($is_autofattura) {
|
||||||
|
$query = "SELECT
|
||||||
|
`co_documenti`.`id`,
|
||||||
|
CONCAT('Fattura num. ', `co_documenti`.`numero_esterno`, ' del ', DATE_FORMAT(`co_documenti`.`data`, '%d/%m/%Y')) AS descrizione
|
||||||
|
FROM `co_documenti`
|
||||||
|
INNER JOIN `co_tipidocumento` ON `co_tipidocumento`.`id` = `co_documenti`.`idtipodocumento`
|
||||||
|
WHERE
|
||||||
|
`co_tipidocumento`.`dir` = 'entrata' AND
|
||||||
|
`co_tipidocumento`.`codice_tipo_documento_fe` IN('TD16', 'TD17', 'TD18', 'TD19', 'TD20', 'TD21', 'TD28') AND
|
||||||
|
(`co_documenti`.`data` BETWEEN NOW() - INTERVAL 1 YEAR AND NOW()) AND
|
||||||
|
`co_documenti`.`idstatodocumento` IN (SELECT `id_record` FROM `co_statidocumento_lang` WHERE `title` != 'Bozza') AND
|
||||||
|
`co_documenti`.`idanagrafica` = ".prepare($anagrafica->id);
|
||||||
|
|
||||||
|
$autofattura_collegata = Fattura::where('progressivo_invio', '=', $fattura->getHeader()['DatiTrasmissione']['ProgressivoInvio'])->first();
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<div class="col-md-3">
|
||||||
|
{[ "type": "select", "label": "'.tr('Autofattura collegata').'", "name": "autofattura", "values": "query='.$query.'", "value": "'.$autofattura_collegata->id.'" ]}
|
||||||
|
</div>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
</div>';
|
||||||
|
|
||||||
|
// Pagamento
|
||||||
|
$pagamento = Pagamento::where('codice_modalita_pagamento_fe', $codice_modalita_pagamento)->where('predefined', '1')->first();
|
||||||
|
echo '
|
||||||
|
<div class="row" >
|
||||||
|
<div class="col-md-3">
|
||||||
|
<button type="button" class="btn btn-info btn-xs pull-right" onclick="updateSelectOption(\'codice_modalita_pagamento_fe\', \'\')">
|
||||||
|
<i class="fa fa-refresh"></i> '.tr('Visualizza tutte le modalità').'
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{[ "type": "select", "label": "'.tr('Pagamento').'", "name": "pagamento", "required": 1, "ajax-source": "pagamenti", "select-options": '.json_encode(['codice_modalita_pagamento_fe' => $codice_modalita_pagamento]).', "value": "'.$pagamento->id.'" ]}
|
||||||
|
</div>';
|
||||||
|
|
||||||
|
// Movimentazioni
|
||||||
|
echo '
|
||||||
|
<div class="col-md-3">
|
||||||
|
{[ "type": "checkbox", "label": "'.tr('Movimenta gli articoli').'", "name": "movimentazione", "value": "'.setting('Movimenta magazzino da fatture di acquisto').'" ]}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
{[ "type": "checkbox", "label": "'.tr('Creazione automatica articoli').'", "name": "flag_crea_articoli", "value": 0, "help": "'.tr('Nel caso di righe con almeno un nodo \'CodiceArticolo\', il gestionale procede alla creazione dell\'articolo se la riga non risulta assegnata manualmente').'." ]}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
{[ "type": "checkbox", "label": "'.tr('Creazione seriali').'", "name": "flag_crea_seriali", "value": "'.setting('Creazione seriali in import FE').'", "help": "'.tr('Nel caso di righe contenenti serial number, il gestionale procede alla loro registrazione. Controllare che l\'XML della fattura di acquisto contenga il nodo \'CodiceTipo\' valorizzato con \'serial\' o \'Serial\' ').'." ]}
|
||||||
|
</div>';
|
||||||
|
|
||||||
|
$ritenuta = $dati_generali['DatiRitenuta'];
|
||||||
|
|
||||||
|
if (!empty($ritenuta)) {
|
||||||
|
echo '
|
||||||
|
<div class="col-md-3">
|
||||||
|
{[ "type": "checkbox", "label": "'.tr('Ritenuta pagata dal cliente').'", "name": "is_ritenuta_pagata", "value": 0, "help": "'.tr('Attivare se la ritenuta è stata pagata dal cliente').'" ]}
|
||||||
|
</div>';
|
||||||
|
}
|
||||||
|
echo '
|
||||||
|
</div>';
|
||||||
|
|
||||||
|
// Righe
|
||||||
|
if (setting('Aggiorna info di acquisto') == 'Non aggiornare') {
|
||||||
|
$update_info = 'update_not';
|
||||||
|
} elseif (setting('Aggiorna info di acquisto') == 'Aggiorna prezzo di listino') {
|
||||||
|
$update_info = 'update_price';
|
||||||
|
} else {
|
||||||
|
$update_info = 'update_all';
|
||||||
|
}
|
||||||
|
|
||||||
|
$righe = $fattura->getRighe();
|
||||||
|
if (!empty($righe)) {
|
||||||
|
echo '
|
||||||
|
<h4>
|
||||||
|
'.tr('Righe').'
|
||||||
|
<button type="button" class="btn btn-info btn-sm pull-right" onclick="copia()" style="margin-left:5px;"><i class="fa fa-copy"></i> '.tr('Copia dati contabili dalla prima riga valorizzata').'</button>
|
||||||
|
<button type="button" class="btn btn-info btn-sm pull-right" onclick="copy_rif()"><i class="fa fa-copy"></i> '.tr('Copia il riferimento vendita dalla prima riga valorizzata').'</button>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped table-hover table-sm table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>'.tr('Descrizione').'</th>
|
||||||
|
<th class="text-center" width="10%">'.tr('Quantità').'</th>
|
||||||
|
<th class="text-center" width="10%">'.tr('Prezzo unitario').'</th>
|
||||||
|
<th class="text-center" width="10%">'.tr('Aliquota').'</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>';
|
||||||
|
|
||||||
|
// Dati ordini
|
||||||
|
$DatiOrdini = XML::forceArray($fattura->getBody()['DatiGenerali']['DatiOrdineAcquisto']);
|
||||||
|
$DatiDDT = XML::forceArray($fattura->getBody()['DatiGenerali']['DatiDDT']);
|
||||||
|
|
||||||
|
// Riorganizzazione dati ordini per numero di riga
|
||||||
|
$dati_ordini = [];
|
||||||
|
foreach ($DatiOrdini as $dato) {
|
||||||
|
foreach ($dato['RiferimentoNumeroLinea'] as $dati => $linea) {
|
||||||
|
$dati_ordini[(int) $linea] = [
|
||||||
|
'numero' => $dato['IdDocumento'],
|
||||||
|
'data' => (new Carbon($dato['Data']))->format('d/m/Y'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Riorganizzazione dati ordini per numero di riga
|
||||||
|
$dati_ddt = [];
|
||||||
|
foreach ($DatiDDT as $dato) {
|
||||||
|
foreach ($dato['RiferimentoNumeroLinea'] as $dati => $linea) {
|
||||||
|
$dati_ddt[(int) $linea] = [
|
||||||
|
'numero' => $dato['NumeroDDT'],
|
||||||
|
'data' => (new Carbon($dato['DataDDT']))->format('d/m/Y'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($righe as $key => $riga) {
|
||||||
|
$query = "SELECT `co_iva`.`id`, IF(`codice` IS NULL, `title`, CONCAT(`codice`, ' - ', `title`)) AS descrizione FROM `co_iva` LEFT JOIN `co_iva_lang` ON (`co_iva`.`id` = `co_iva_lang`.`id_record` AND `co_iva_lang`.`id_lang` = ".prepare(Models\Locale::getDefault()->id).') WHERE `deleted_at` IS NULL AND `percentuale` = '.prepare($riga['AliquotaIVA']);
|
||||||
|
$start_query = $query;
|
||||||
|
|
||||||
|
if (!empty($riga['Natura'])) {
|
||||||
|
$query .= ' AND `codice_natura_fe` = '.prepare($riga['Natura']);
|
||||||
|
|
||||||
|
// Fallback per natura iva mancante
|
||||||
|
if (empty($dbo->fetchArray($query))) {
|
||||||
|
$query = $start_query;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$query .= ' ORDER BY `descrizione` ASC';
|
||||||
|
|
||||||
|
// Visualizzazione codici articoli
|
||||||
|
$codici = $riga['CodiceArticolo'] ?: [];
|
||||||
|
$codici = !empty($codici) && !isset($codici[0]) ? [$codici] : $codici;
|
||||||
|
|
||||||
|
$codici_articoli = [];
|
||||||
|
$serial = [];
|
||||||
|
$i = 0;
|
||||||
|
foreach ($codici as $codice) {
|
||||||
|
$codici_articoli[] = (($i == 0) ? '<b>' : '').$codice['CodiceValore'].' ('.$codice['CodiceTipo'].')'.(($i == 0) ? '</b>' : '');
|
||||||
|
if (str_contains((string) $codice['CodiceTipo'], 'serial') || str_contains((string) $codice['CodiceTipo'], 'Serial')) {
|
||||||
|
$serial[] = $codice['CodiceValore'];
|
||||||
|
}
|
||||||
|
++$i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Individuazione articolo con codice relativo
|
||||||
|
$id_articolo = null;
|
||||||
|
// Prendo il codice articolo dal primo nodo CodiceValore che trovo
|
||||||
|
$codice_principale = $codici[0]['CodiceValore'];
|
||||||
|
if (!empty($codice_principale)) {
|
||||||
|
if (empty($id_articolo)) {
|
||||||
|
$id_articolo = $database->fetchOne('SELECT `id` FROM `mg_articoli` WHERE `codice` = '.prepare($codice_principale))['id'];
|
||||||
|
if (empty($id_articolo)) {
|
||||||
|
$id_articolo = $database->fetchOne('SELECT `id` FROM `mg_articoli` WHERE REPLACE(`codice`, " ", "") = '.prepare($codice_principale))['id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$idconto_acquisto = $database->fetchOne('SELECT `idconto_acquisto` FROM `mg_articoli` WHERE `id` = '.prepare($id_articolo))['idconto_acquisto'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$idconto_acquisto = $is_autofattura ? setting('Conto per autofattura') : $idconto_acquisto;
|
||||||
|
$qta = $riga['Quantita'];
|
||||||
|
$um = $riga['UnitaMisura'];
|
||||||
|
$prezzo_unitario = $riga['PrezzoUnitario'] ?: $riga['Importo'];
|
||||||
|
$is_descrizione = empty((float) $riga['Quantita']) && empty((float) $prezzo_unitario);
|
||||||
|
|
||||||
|
$sconto_unitario = 0;
|
||||||
|
$sconti = $riga['ScontoMaggiorazione'] ?: 0;
|
||||||
|
if (!empty($sconti)) {
|
||||||
|
$tot_sconto_calcolato = 0;
|
||||||
|
$sconto_unitario = 0;
|
||||||
|
$sconti = $sconti[0] ? $sconti : [$sconti];
|
||||||
|
|
||||||
|
// Determina il tipo di sconto in caso di sconti misti UNT e PRC
|
||||||
|
foreach ($sconti as $sconto) {
|
||||||
|
$tipo_sconto = !empty($sconto['Importo']) ? '€' : '%';
|
||||||
|
if (!empty($tipo) && $tipo_sconto != $tipo) {
|
||||||
|
$tipo = '€';
|
||||||
|
} else {
|
||||||
|
$tipo = $tipo_sconto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($sconti as $sconto) {
|
||||||
|
$unitario = $sconto['Importo'] ?: $sconto['Percentuale'];
|
||||||
|
|
||||||
|
// Sconto o Maggiorazione
|
||||||
|
$sconto_riga = ($sconto['Tipo'] == 'SC') ? $unitario : -$unitario;
|
||||||
|
|
||||||
|
$tipo_sconto = !empty($sconto['Importo']) ? '€' : '%';
|
||||||
|
if ($tipo_sconto == '%') {
|
||||||
|
$sconto_calcolato = calcola_sconto([
|
||||||
|
'sconto' => $sconto_riga,
|
||||||
|
'prezzo' => $sconto_unitario ? $prezzo_unitario - ($tot_sconto_calcolato / ($qta ?: 1)) : $prezzo_unitario,
|
||||||
|
'tipo' => 'PRC',
|
||||||
|
'qta' => $qta,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($tipo == '%') {
|
||||||
|
$tot_sconto = ($prezzo_unitario * $qta != 0 ? $sconto_calcolato * 100 / ($prezzo_unitario * $qta) : 0);
|
||||||
|
} else {
|
||||||
|
$tot_sconto = $sconto_calcolato;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$tot_sconto = $sconto_riga;
|
||||||
|
}
|
||||||
|
|
||||||
|
$tot_sconto_calcolato += $sconto_calcolato;
|
||||||
|
$sconto_unitario += $tot_sconto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$riferimento_fe = '';
|
||||||
|
|
||||||
|
if ($dati_ddt[(int) $riga['NumeroLinea']]) {
|
||||||
|
$riferimento_fe = tr('DDT _NUMERO_ del _DATA_',
|
||||||
|
[
|
||||||
|
'_NUMERO_' => $dati_ddt[(int) $riga['NumeroLinea']]['numero'],
|
||||||
|
'_DATA_' => $dati_ddt[(int) $riga['NumeroLinea']]['data'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<tr data-id="'.$key.'" data-qta="'.$qta.'" data-descrizione="'.$riga['Descrizione'].'" data-prezzo_unitario="'.$prezzo_unitario.'" data-iva_percentuale="'.$riga['AliquotaIVA'].'">
|
||||||
|
<td>
|
||||||
|
'.(empty($codice_principale) ? '<div style="padding:7px;" class="badge badge-warning pull-right text-muted articolo-warning hidden">'.tr('Creazione automatica articolo non disponibile').'</div>' : '<label class="badge badge-success pull-right text-muted articolo-warning hidden"><input class="check" type="checkbox" name="crea_articoli['.$key.']"/> <span style="position:relative;top:-2px;" >'.tr('Crea automaticamente questo articolo').'</span></label>').'
|
||||||
|
<small class="pull-right text-muted" id="riferimento_'.$key.'"></small><br>
|
||||||
|
<small class="pull-right text-muted">'.$riferimento_fe.'</small>
|
||||||
|
|
||||||
|
|
||||||
|
'.$riga['Descrizione'].'<br>
|
||||||
|
|
||||||
|
'.(!empty($codici_articoli) ? '<small>'.implode(', ', $codici_articoli).'</small><br>' : '').'
|
||||||
|
|
||||||
|
<b id="riferimento_'.$key.'_descrizione"></b>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="text-center">
|
||||||
|
'.numberFormat($qta, 'qta').' '.$um.'
|
||||||
|
<span id="riferimento_'.$key.'_qta"></span>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="text-right">
|
||||||
|
'.moneyFormat($prezzo_unitario);
|
||||||
|
if (abs($sconto_unitario) > 0) {
|
||||||
|
$text = ($prezzo_unitario >= 0 && $sconto_unitario > 0) || ($prezzo_unitario < 0 && $sconto_unitario < 0) ? tr('sconto _TOT_ _TYPE_', ['_TOT_' => Translator::numberToLocale(abs($sconto_unitario)), '_TYPE_' => $tipo]) : tr('maggiorazione _TOT__TYPE_', ['_TOT_' => Translator::numberToLocale(abs($sconto_unitario)), '_TYPE_' => $tipo]);
|
||||||
|
echo '
|
||||||
|
<br> <span class="right badge badge-danger">'.$text.'</small>';
|
||||||
|
}
|
||||||
|
echo '
|
||||||
|
<span id="riferimento_'.$key.'_prezzo"></span>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="text-right">
|
||||||
|
'.replace('_VALUE_ _DESC_', [
|
||||||
|
'_VALUE_' => empty($riga['Natura']) ? numberFormat($riga['AliquotaIVA'], 0).'%' : $riga['Natura'],
|
||||||
|
'_DESC_' => $riga['RiferimentoNormativo'] ? ' - '.$riga['RiferimentoNormativo'] : '',
|
||||||
|
]).'
|
||||||
|
<span id="riferimento_'.$key.'_iva"></span>
|
||||||
|
</td>
|
||||||
|
</tr>';
|
||||||
|
|
||||||
|
if (!$is_descrizione) {
|
||||||
|
echo '
|
||||||
|
<tr id="dati_'.$key.'">
|
||||||
|
<td class="row">
|
||||||
|
<span class="hide" id="aliquota['.$key.']">'.$riga['AliquotaIVA'].'</span>
|
||||||
|
<input type="hidden" name="qta_riferimento['.$key.']" id="qta_riferimento_'.$key.'" value="'.$riga['Quantita'].'">
|
||||||
|
|
||||||
|
<input type="hidden" name="tipo_riferimento['.$key.']" id="tipo_riferimento_'.$key.'" value="">
|
||||||
|
<input type="hidden" name="id_riferimento['.$key.']" id="id_riferimento_'.$key.'" value="">
|
||||||
|
<input type="hidden" name="id_riga_riferimento['.$key.']" id="id_riga_riferimento_'.$key.'" value="">
|
||||||
|
<input type="hidden" name="tipo_riga_riferimento['.$key.']" id="tipo_riga_riferimento_'.$key.'" value="">
|
||||||
|
|
||||||
|
<input type="hidden" name="tipo_riferimento_vendita['.$key.']" id="tipo_riferimento_vendita_'.$key.'" value="">
|
||||||
|
<input type="hidden" name="id_riferimento_vendita['.$key.']" id="id_riferimento_vendita_'.$key.'" value="">
|
||||||
|
<input type="hidden" name="id_riga_riferimento_vendita['.$key.']" id="id_riga_riferimento_vendita_'.$key.'" value="">
|
||||||
|
<input type="hidden" name="tipo_riga_riferimento_vendita['.$key.']" id="tipo_riga_riferimento_vendita_'.$key.'" value="">
|
||||||
|
|
||||||
|
<div class="card collapsed-card card-lg" style="background:#eeeeee;">
|
||||||
|
<div class="card-header">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-5">
|
||||||
|
{["type": "select", "name": "articoli['.$key.']", "ajax-source": "articoli", "select-options": '.json_encode(['permetti_movimento_a_zero' => 1, 'dir' => 'entrata', 'idanagrafica' => $anagrafica ? $anagrafica->id : '']).', "icon-after": "add|'.Module::where('name', 'Articoli')->first()->id.'|codice='.($codice_principale ? urlencode((string) $codice_principale) : '').'&descrizione='.($riga['Descrizione'] ? urlencode((string) $riga['Descrizione']) : '').'&prezzo_acquisto='.($riga['PrezzoUnitario'] ? urlencode((string) $riga['PrezzoUnitario']) : '').'", "value": "'.$id_articolo.'", "label": "'.tr('Articolo').'","extra": "data-id=\''.$key.'\'" ]}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
{[ "type": "select", "name": "conto['.$key.']", "id": "conto-'.$key.'", "ajax-source": "conti-acquisti", "required": 1, "label": "'.tr('Conto acquisti').'", "value": "'.$idconto_acquisto.'" ]}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
{[ "type": "select", "name": "iva['.$key.']", "values": '.json_encode('query='.$query).', "required": 1, "label": "'.tr('Aliquota IVA').'" ]}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-1 card-tools">
|
||||||
|
<br>
|
||||||
|
<button type="button" class="btn btn-lg" data-card-widget="collapse" onclick="$(this).find(\'i\').toggleClass(\'fa-plus\').toggleClass(\'fa-minus\');">
|
||||||
|
<i class="fa fa-plus"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3">
|
||||||
|
{[ "type": "select", "name": "selezione_riferimento['.$key.']", "ajax-source": "riferimenti-fe", "select-options": '.json_encode(['id_anagrafica' => $anagrafica ? $anagrafica->id : '']).', "label": "'.tr('Riferimento acquisto').'", "icon-after": '.json_encode('<button type="button" onclick="rimuoviRiferimento(this)" class="btn btn-danger disabled" id="rimuovi_riferimento_'.$key.'"><i class="fa fa-close"></i></button>').', "help": "'.tr('Articoli contenuti in Ordini o DDT del cliente').'" ]}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
{[ "type": "select", "name": "selezione_riferimento_vendita['.$key.']", "ajax-source": "riferimenti-vendita-fe", "select-options": '.json_encode(['id_articolo' => $id_articolo]).', "label": "'.tr('Riferimento vendita').'", "icon-after": '.json_encode('<button type="button" onclick="rimuoviRiferimentoVendita(this)" class="btn btn-danger disabled" id="rimuovi_riferimento_vendita_'.$key.'"><i class="fa fa-close"></i></button>').', "help": "'.tr('Articoli contenuti in Ordini Cliente').'" ]}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
{[ "type": "select", "name": "update_info['.$key.']", "values": "list=\"update_not\":\"Nessuna operazione\", \"update_price\":\"Crea listino del cliente (se non presente) e aggiorna il prezzo di acquisto\", \"update_all\":\"Crea listino del cliente (se non presente) aggiorna prezzo di acquisto e imposta cliente come predefinito\"", "label": "'.tr('Aggiorna informazioni di acquisto').'", "value": "'.$update_info.'", "help": "'.tr('Creazione automatica articolo deve essere attiva o l\'articolo deve essere selezionato affinché questa impostazione abbia effetto').'.", "readonly": "'.(empty($codice_principale) ? 1 : 0).'" ]}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">';
|
||||||
|
if (setting('Creazione seriali in import FE') && $serial) {
|
||||||
|
for ($i = 0; $i < $qta; ++$i) {
|
||||||
|
echo '
|
||||||
|
<div class="col-md-3">
|
||||||
|
{[ "type": "text", "label": "'.tr('Serial').'", "name": "serial['.$key.'][]", "value": "'.$serial[$i].'" ]}
|
||||||
|
</div>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo '
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>';
|
||||||
|
} else {
|
||||||
|
echo '
|
||||||
|
<input type="hidden" name="qta_riferimento['.$key.']" id="qta_riferimento_'.$key.'" value="'.$riga['Quantita'].'">
|
||||||
|
|
||||||
|
<input type="hidden" name="tipo_riferimento['.$key.']" id="tipo_riferimento_'.$key.'" value="">
|
||||||
|
<input type="hidden" name="id_riferimento['.$key.']" id="id_riferimento_'.$key.'" value="">
|
||||||
|
<input type="hidden" name="id_riga_riferimento['.$key.']" id="id_riga_riferimento_'.$key.'" value="">
|
||||||
|
<input type="hidden" name="tipo_riga_riferimento['.$key.']" id="tipo_riga_riferimento_'.$key.'" value="">
|
||||||
|
|
||||||
|
<input type="hidden" name="tipo_riferimento_vendita['.$key.']" id="tipo_riferimento_vendita_'.$key.'" value="">
|
||||||
|
<input type="hidden" name="id_riferimento_vendita['.$key.']" id="id_riferimento_vendita_'.$key.'" value="">
|
||||||
|
<input type="hidden" name="id_riga_riferimento_vendita['.$key.']" id="id_riga_riferimento_vendita_'.$key.'" value="">
|
||||||
|
<input type="hidden" name="tipo_riga_riferimento_vendita['.$key.']" id="tipo_riga_riferimento_vendita_'.$key.'" value="">
|
||||||
|
|
||||||
|
<input type="hidden" name="conto['.$key.']" value="">
|
||||||
|
<input type="hidden" name="iva['.$key.']" value="">
|
||||||
|
<input type="hidden" name="update_info['.$key.']" value="">';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>';
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<script>
|
||||||
|
function copia() {
|
||||||
|
let aliquote = $("select[name^=iva]");
|
||||||
|
let conti = $("select[name^=conto]");
|
||||||
|
|
||||||
|
// Individuazione della prima IVA selezionata
|
||||||
|
let iva_selezionata = null;
|
||||||
|
for (const aliquota of aliquote) {
|
||||||
|
const data = $(aliquota).selectData();
|
||||||
|
if (data && data.id) {
|
||||||
|
iva_selezionata = data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Individuazione del primo conto selezionato
|
||||||
|
let conto_selezionato = null;
|
||||||
|
for (const conto of conti) {
|
||||||
|
const data = $(conto).selectData();
|
||||||
|
if (data && data.id) {
|
||||||
|
conto_selezionato = data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selezione generale per l\'IVA
|
||||||
|
if (iva_selezionata) {
|
||||||
|
aliquote.each(function() {
|
||||||
|
$(this).selectSet(iva_selezionata.id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selezione generale per il conto
|
||||||
|
if (conto_selezionato) {
|
||||||
|
conti.each(function() {
|
||||||
|
$(this).selectSetNew(conto_selezionato.id, conto_selezionato.text, conto_selezionato);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>';
|
||||||
|
} else {
|
||||||
|
echo '
|
||||||
|
<p>'.tr('Non ci sono righe nella fattura').'.</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12 text-right">
|
||||||
|
<a href="'.$skip_link.'" class="btn btn-warning">
|
||||||
|
<i class="fa fa-ban "></i> '.tr('Salta fattura').'
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary">
|
||||||
|
<i class="fa fa-arrow-right"></i> '.tr('Continua').'...
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
input("flag_crea_articoli").on("change", function (){
|
||||||
|
if (input("flag_crea_articoli").get()) {
|
||||||
|
$(".articolo-warning").removeClass("hidden");
|
||||||
|
$(".check").each(function(){
|
||||||
|
if( !$(this).is(":checked") ){
|
||||||
|
$(this).trigger("click");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$(".articolo-warning").addClass("hidden");
|
||||||
|
$(".check").each(function(){
|
||||||
|
if( $(this).is(":checked") ){
|
||||||
|
$(this).trigger("click");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("select[name^=selezione_riferimento]").change(function() {
|
||||||
|
if (!$(this).hasClass("already-loaded")) {
|
||||||
|
let $this = $(this);
|
||||||
|
let data = $this.selectData();
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
let riga = $this.closest("tr").prev();
|
||||||
|
selezionaRiferimento(riga, data.tipo, data.id, data.dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function rimuoviRiferimento(button) {
|
||||||
|
let riga = $(button).closest("tr").prev();
|
||||||
|
let id_riga = riga.data("id");
|
||||||
|
|
||||||
|
impostaRiferimento(id_riga, {}, {});
|
||||||
|
|
||||||
|
input("selezione_riferimento[" + id_riga + "]").enable()
|
||||||
|
.getElement().selectReset();
|
||||||
|
$(button).addClass("disabled");
|
||||||
|
riga.removeClass("success").removeClass("warning");
|
||||||
|
}
|
||||||
|
|
||||||
|
function selezionaRiferimento(riga, tipo_documento, id_documento, dir) {
|
||||||
|
let id_riga = riga.data("id");
|
||||||
|
let qta = riga.data("qta");
|
||||||
|
let descrizione = riga.data("descrizione");
|
||||||
|
let prezzo_unitario = riga.data("prezzo_unitario");
|
||||||
|
|
||||||
|
let riferimenti = getRiferimenti();
|
||||||
|
let query = {
|
||||||
|
id_module: "'.$id_module.'",
|
||||||
|
id_record: "'.$id_record.'",
|
||||||
|
qta: qta,
|
||||||
|
descrizione: descrizione,
|
||||||
|
prezzo_unitario: prezzo_unitario,
|
||||||
|
id_riga: id_riga,
|
||||||
|
id_documento: id_documento,
|
||||||
|
tipo_documento: tipo_documento,
|
||||||
|
righe_ddt: riferimenti.ddt,
|
||||||
|
righe_ordini: riferimenti.ordini,
|
||||||
|
dir: dir,
|
||||||
|
};
|
||||||
|
|
||||||
|
let url = "'.$structure->fileurl('riferimento.php').'?" + $.param(query);
|
||||||
|
|
||||||
|
openModal("'.tr('Selezione riferimento').'", url);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRiferimenti() {
|
||||||
|
let righe_ordini = {};
|
||||||
|
let righe_ddt = {};
|
||||||
|
|
||||||
|
$("[id^=tipo_riferimento_]").each(function(index, item) {
|
||||||
|
let tipo = $(item).val();
|
||||||
|
let riga = $(item).closest("tr");
|
||||||
|
|
||||||
|
let qta = parseFloat(riga.find("[id^=qta_riferimento_]").val());
|
||||||
|
let id_riga = riga.find("[id^=id_riga_riferimento_]").val();
|
||||||
|
if (tipo === "ordine") {
|
||||||
|
righe_ordini[id_riga] = righe_ordini[id_riga] ? righe_ordini[id_riga] : 0;
|
||||||
|
righe_ordini[id_riga] += qta;
|
||||||
|
} else if (tipo === "ddt") {
|
||||||
|
righe_ddt[id_riga] = righe_ddt[id_riga] ? righe_ddt[id_riga] : 0;
|
||||||
|
righe_ddt[id_riga] += qta;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
ordini: righe_ordini,
|
||||||
|
ddt: righe_ddt,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param id_riga
|
||||||
|
* @param documento = {tipo, id, descrizione }
|
||||||
|
* @param riga = {tipo, id, descrizione, qta, prezzo_unitario}
|
||||||
|
*/
|
||||||
|
function impostaRiferimento(id_riga, documento, riga) {
|
||||||
|
// Informazioni interne per il riferimento
|
||||||
|
$("#tipo_riferimento_" + id_riga).val(documento.tipo);
|
||||||
|
$("#id_riferimento_" + id_riga).val(documento.id);
|
||||||
|
$("#tipo_riga_riferimento_" + id_riga).val(riga.tipo);
|
||||||
|
$("#id_riga_riferimento_" + id_riga).val(riga.id);
|
||||||
|
|
||||||
|
// Gestione della selezione
|
||||||
|
input("selezione_riferimento[" + id_riga + "]").disable();
|
||||||
|
$("#rimuovi_riferimento_" + id_riga).removeClass("disabled");
|
||||||
|
|
||||||
|
let riga_fe = $("#id_riga_riferimento_" + id_riga).closest("tr").prev();
|
||||||
|
|
||||||
|
// Informazioni visibili sulla quantità
|
||||||
|
impostaContenuto(riga_fe.data("qta"), riga.qta, (riga.um ? " " + riga.um : ""), "#riferimento_" + id_riga + "_qta", true);
|
||||||
|
|
||||||
|
// Informazioni visibili sul prezzo unitario
|
||||||
|
impostaContenuto(riga_fe.data("prezzo_unitario"), riga.prezzo_unitario, " " + globals.currency, "#riferimento_" + id_riga + "_prezzo", true);
|
||||||
|
|
||||||
|
// Informazioni visibili sull\'aliquota IVA
|
||||||
|
impostaContenuto(riga_fe.data("iva_percentuale"), parseInt(riga.iva_percentuale), "%", "#riferimento_" + id_riga + "_iva", false);
|
||||||
|
|
||||||
|
$("#riferimento_" + id_riga).html(documento.descrizione ? documento.descrizione : "");
|
||||||
|
|
||||||
|
var descrizione = riga.descrizione;
|
||||||
|
if(typeof descrizione !== "undefined"){
|
||||||
|
descrizione = descrizione.replace(/_/g, " ").replace(/\n/g, "<br>");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dettagli del documento trovato
|
||||||
|
icona_documento = documento.match_documento_da_fe ? "fa-check-circle text-success" : "fa-question-circle text-orange";
|
||||||
|
tooltip_icona = documento.match_documento_da_fe ? "La corrispondenza trovata è avvenuta in base a quanto ha specificato il cliente nella fattura elettronica" : "Nessuna corrispondenza con quanto ha specificato il cliente nella fattura elettronica, il riferimento potrebbe non essere corretto";
|
||||||
|
|
||||||
|
$("#riferimento_" + id_riga + "_descrizione").html("<br><b class=\"tip\" title=\"" + tooltip_icona + "\"><i class=\"fa " + icona_documento + "\"></i> " + documento.opzione + "</b><br>");
|
||||||
|
|
||||||
|
// Dettagli della riga trovata
|
||||||
|
$("#riferimento_" + id_riga + "_descrizione").append(descrizione ? descrizione : "");
|
||||||
|
|
||||||
|
// Colorazione dell\'intera riga
|
||||||
|
let warnings = riga_fe.find(".text-warning");
|
||||||
|
if (warnings.length === 0) {
|
||||||
|
riga_fe.addClass("success").removeClass("warning");
|
||||||
|
} else {
|
||||||
|
riga_fe.removeClass("success").addClass("warning");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (riga.id_articolo) {
|
||||||
|
input("articoli["+id_riga+"]").getElement().selectSetNew(riga.id_articolo, riga.desc_articolo.replace(/_/g, " ").replace(/\n/g, "<br>"));
|
||||||
|
if (riga.id_conto) {
|
||||||
|
input("conto["+id_riga+"]").getElement().selectSetNew(riga.id_conto, riga.desc_conto.replace(/_/g, " ").replace(/\n/g, "<br>"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Informazioni visibili sull\'aliquota IVA
|
||||||
|
function impostaContenuto(valore_riga, valore_riferimento, contenuto_successivo, id_elemento, parse_riferimento) {
|
||||||
|
let elemento = $(id_elemento);
|
||||||
|
if (valore_riferimento === undefined) {
|
||||||
|
elemento.html("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
valore_riga = parseFloat(valore_riga);
|
||||||
|
valore_riferimento = parseFloat(valore_riferimento);
|
||||||
|
|
||||||
|
let contenuto = (parse_riferimento ? valore_riferimento.toLocale() + contenuto_successivo : valore_riferimento + contenuto_successivo);
|
||||||
|
if (valore_riferimento === valore_riga) {
|
||||||
|
contenuto = `<i class="fa fa-check"></i> ` + contenuto;
|
||||||
|
elemento.addClass("text-success").removeClass("text-warning");
|
||||||
|
} else {
|
||||||
|
contenuto = `<i class="fa fa-warning"></i> ` + contenuto;
|
||||||
|
elemento.removeClass("text-success").addClass("text-warning");
|
||||||
|
}
|
||||||
|
|
||||||
|
elemento.html("<br>" + contenuto);
|
||||||
|
}
|
||||||
|
|
||||||
|
function impostaRiferimentoVendita(id_riga, documento, riga) {
|
||||||
|
// Informazioni interne per il riferimento
|
||||||
|
$("#tipo_riferimento_vendita_" + id_riga).val(documento.tipo);
|
||||||
|
$("#id_riferimento_vendita_" + id_riga).val(documento.id);
|
||||||
|
$("#tipo_riga_riferimento_vendita_" + id_riga).val(riga.tipo);
|
||||||
|
$("#id_riga_riferimento_vendita_" + id_riga).val(riga.id);
|
||||||
|
|
||||||
|
// Gestione della selezione
|
||||||
|
input("selezione_riferimento_vendita[" + id_riga + "]").disable();
|
||||||
|
$("#rimuovi_riferimento_vendita_" + id_riga).removeClass("disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
function rimuoviRiferimentoVendita(button) {
|
||||||
|
let riga = $(button).closest("tr").prev();
|
||||||
|
let id_riga = riga.data("id");
|
||||||
|
|
||||||
|
impostaRiferimentoVendita(id_riga, {}, {});
|
||||||
|
|
||||||
|
input("selezione_riferimento_vendita[" + id_riga + "]").enable()
|
||||||
|
.getElement().selectReset();
|
||||||
|
$(button).addClass("disabled");
|
||||||
|
riga.removeClass("success").removeClass("warning");
|
||||||
|
}
|
||||||
|
|
||||||
|
$("[id^=\'articoli\']").change(function() {
|
||||||
|
$("#conto-"+$(this).data("id")).selectReset();
|
||||||
|
updateSelectOption("id_articolo", $(this).val());
|
||||||
|
let data = $(this).selectData();
|
||||||
|
if(data!==undefined){
|
||||||
|
$("#conto-"+$(this).data("id")).selectSetNew(data.idconto_acquisto, data.idconto_acquisto_title);
|
||||||
|
}
|
||||||
|
|
||||||
|
verificaSerial($(this));
|
||||||
|
|
||||||
|
|
||||||
|
if($(this).val()){
|
||||||
|
$("#update_info"+$(this).data("id")).prop(\'disabled\', false);
|
||||||
|
}else{
|
||||||
|
$("#update_info"+$(this).data("id")).prop(\'disabled\', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
function copy_rif() {
|
||||||
|
let rif_vendite = $("select[name^=selezione_riferimento_vendita]");
|
||||||
|
|
||||||
|
// Individuazione della prima IVA selezionata
|
||||||
|
let iva_selezionata = null;
|
||||||
|
for (const rif_vendita of rif_vendite) {
|
||||||
|
const data = $(rif_vendita).selectData();
|
||||||
|
if (data && data.id) {
|
||||||
|
rif_vendita_selezionata = data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selezione generale per il conto
|
||||||
|
if (rif_vendita_selezionata) {
|
||||||
|
rif_vendite.each(function() {
|
||||||
|
$(this).selectSetNew(rif_vendita_selezionata.id, rif_vendita_selezionata.text, rif_vendita_selezionata);
|
||||||
|
|
||||||
|
id = $(this).attr("id").toString();
|
||||||
|
var matches = id.match(/(\d+)/);
|
||||||
|
id_riga = matches[0];
|
||||||
|
|
||||||
|
$("#tipo_riferimento_vendita_" + id_riga).val("ordine");
|
||||||
|
$("#id_riferimento_vendita_" + id_riga).val(rif_vendita_selezionata.id);
|
||||||
|
$("#id_riga_riferimento_vendita_" + id_riga).val("new-ordine-"+rif_vendita_selezionata.id);
|
||||||
|
|
||||||
|
$("#rimuovi_riferimento_vendita_" + id_riga).removeClass("disabled");
|
||||||
|
$(this).prop("disabled", true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Visualizza input seriali se abilita serial dell\'articolo selezionato è attivo
|
||||||
|
function verificaSerial(riga) {
|
||||||
|
if (riga.val()) {
|
||||||
|
let data = riga.selectData();
|
||||||
|
if (data.abilita_serial) {
|
||||||
|
$("#serial"+riga.data("id")).parent().parent().parent().removeClass("hidden");
|
||||||
|
} else {
|
||||||
|
$("#serial"+riga.data("id")).parent().parent().parent().addClass("hidden");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$("#serial"+riga.data("id")).parent().parent().parent().addClass("hidden");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disabilita input seriali se flag crea seriali è disattivato
|
||||||
|
$("#flag_crea_seriali").on("change", function() {
|
||||||
|
if ($(this).is(":checked")) {
|
||||||
|
$("[id^=\'serial\']").attr("disabled", false);
|
||||||
|
} else {
|
||||||
|
$("[id^=\'serial\']").attr("disabled", true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>';
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
include_once __DIR__.'/../../core.php';
|
||||||
|
|
||||||
|
use Plugins\ImportFE\FatturaElettronica;
|
||||||
|
use Plugins\ImportFE\Interaction;
|
||||||
|
|
||||||
|
if (!empty($id_record)) {
|
||||||
|
$files = Interaction::getFileList([], 'Fatture di vendita', 'Importazione FE');
|
||||||
|
$record = $files[$id_record - 1] ?? null;
|
||||||
|
|
||||||
|
$has_next = !empty($files[$id_record]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$fattura = FatturaElettronica::manage($record['name'] ?? '', 'Fatture di vendita', 'Importazione FE');
|
||||||
|
$anagrafica = $fattura->findAnagrafica('Cliente');
|
||||||
|
} catch (UnexpectedValueException) {
|
||||||
|
$imported = true;
|
||||||
|
} catch (Exception) {
|
||||||
|
$error = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rimozione .p7m dal nome del file (causa eventuale estrazione da ZIP)
|
||||||
|
$record['name'] = preg_replace('/(.+)\.p7m$/i', '$1', $record['name'] ?? '');
|
||||||
|
|
||||||
|
if (empty($record)) {
|
||||||
|
flash()->warning(tr('Nessuna fattura da importare!'));
|
||||||
|
|
||||||
|
redirect(base_path().'/controller.php?id_module='.$id_module);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,239 @@
|
||||||
|
<?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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
include_once __DIR__.'/../../core.php';
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Plugins\ImportFE\Interaction;
|
||||||
|
use Util\XML;
|
||||||
|
|
||||||
|
$list = Interaction::getInvoiceList('Fatture di vendita', 'Importazione FE');
|
||||||
|
|
||||||
|
$directory = Plugins\ImportFE\FatturaElettronica::getImportDirectory('Fatture di vendita', 'Importazione FE');
|
||||||
|
|
||||||
|
if (!empty($list)) {
|
||||||
|
echo '
|
||||||
|
<table class="table table-striped table-hover table-sm table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>'.tr('Descrizione').'</th>
|
||||||
|
<th class="text-center">'.tr('Cliente').'</th>
|
||||||
|
<th class="text-center">'.tr('Data di registrazione').'</th>
|
||||||
|
<th class="text-center">'.tr('Totale imponibile').'</th>
|
||||||
|
<th width="20%" class="text-center">#</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>';
|
||||||
|
|
||||||
|
foreach ($list as $element) {
|
||||||
|
$name = $element['name'];
|
||||||
|
$file = XML::readFile($directory.'/'.$name);
|
||||||
|
$date = $file['FatturaElettronicaBody']['DatiGenerali']['DatiGeneraliDocumento']['Data'];
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<tr>';
|
||||||
|
|
||||||
|
if (!empty($element['file'])) {
|
||||||
|
echo '
|
||||||
|
<td>
|
||||||
|
<p>'.$name.'</p>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="text-center">-</td>
|
||||||
|
<td class="text-center">-</td>
|
||||||
|
<td class="text-center">-</td>
|
||||||
|
|
||||||
|
<td class="text-center">
|
||||||
|
<button type="button" class="btn btn-danger" onclick="delete_fe(this, \''.$element['id'].'\')">
|
||||||
|
<i class="fa fa-trash"></i>
|
||||||
|
</button>';
|
||||||
|
} else {
|
||||||
|
$date = new DateTime($element['date']);
|
||||||
|
|
||||||
|
$descrizione = '';
|
||||||
|
if ($element['type'] == 'TD01') {
|
||||||
|
$descrizione = tr('Fattura num. _NUM_ del _DATE_', [
|
||||||
|
'_NUM_' => $element['number'],
|
||||||
|
'_DATE_' => dateFormat($date),
|
||||||
|
]);
|
||||||
|
} elseif ($element['type'] == 'TD04') {
|
||||||
|
$descrizione = tr('Nota di credito num. _NUM_ del _DATE_', [
|
||||||
|
'_NUM_' => $element['number'],
|
||||||
|
'_DATE_' => dateFormat($date),
|
||||||
|
]);
|
||||||
|
} elseif ($element['type'] == 'TD05') {
|
||||||
|
$descrizione = tr('Nota di debito num. _NUM_ del _DATE_', [
|
||||||
|
'_NUM_' => $element['number'],
|
||||||
|
'_DATE_' => dateFormat($date),
|
||||||
|
]);
|
||||||
|
} elseif ($element['type'] == 'TD06') {
|
||||||
|
$descrizione = tr('Parcella num. _NUM_ del _DATE_', [
|
||||||
|
'_NUM_' => $element['number'],
|
||||||
|
'_DATE_' => dateFormat($date),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$date = new DateTime($element['date']);
|
||||||
|
$date = $date->format('Y-m-d');
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<td>
|
||||||
|
'.$descrizione.' <small>['.$name.']</small>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>'.$element['sender'].'</td>
|
||||||
|
<td class="text-center">'.dateFormat(new Carbon($element['date_sent'])).'</td>
|
||||||
|
<td class="text-right">'.moneyFormat($element['amount']).'</td>
|
||||||
|
|
||||||
|
<td class="text-center">
|
||||||
|
<button type="button" class="btn btn-info tip" onclick="process_fe(this, \''.$name.'\')" title="'.tr('Segna la fattura come processata').'">
|
||||||
|
<i class="fa fa-upload"></i>
|
||||||
|
</button>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_exists($directory.'/'.$name)) {
|
||||||
|
echo '
|
||||||
|
<button type="button" class="btn btn-primary tip" onclick="download_fe(this, \''.$element['id'].'\')" title="'.tr('Scarica la fattura').'">
|
||||||
|
<i class="fa fa-download"></i>
|
||||||
|
</button>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-warning tip" '.((!extension_loaded('openssl') && str_ends_with(strtolower((string) $name), '.p7m')) ? 'disabled' : '').' onclick="import_fe(this, \''.$name.'\', \''.$date.'\')" title="'.tr('Importa la fattura nel gestionale').'">
|
||||||
|
<i class="fa fa-cloud-download"></i> '.tr('Importa').'
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
</tbody>
|
||||||
|
</table>';
|
||||||
|
} else {
|
||||||
|
echo '
|
||||||
|
<p>'.tr('Nessuna fattura da importare').'.</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<script>
|
||||||
|
function import_fe(button, file, data_registrazione) {
|
||||||
|
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) {
|
||||||
|
redirect(globals.rootdir + "/editor.php?id_module=" + globals.id_module + "&id_plugin=" + '.$id_plugin.' + "&id_record=" + data.id + "&data_registrazione=" + data_registrazione);
|
||||||
|
} else {
|
||||||
|
swal({
|
||||||
|
title: "'.tr('Fattura già importata.').'",
|
||||||
|
type: "info",
|
||||||
|
});
|
||||||
|
|
||||||
|
$(button).prop("disabled", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonRestore(button, restore);
|
||||||
|
},
|
||||||
|
error: function(xhr) {
|
||||||
|
alert("'.tr('Errore').': " + xhr.responseJSON.error.message);
|
||||||
|
|
||||||
|
buttonRestore(button, restore);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function process_fe(button, file) {
|
||||||
|
swal({
|
||||||
|
title: "'.tr('Segnare la fattura come processata?').'",
|
||||||
|
html: "'.tr("Non sarà possibile individuarla nuovamente in modo automatico: l'unico modo per recuperarla sarà contattare l'assistenza").'",
|
||||||
|
type: "info",
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: "'.tr('Sì').'"
|
||||||
|
}).then(function (result) {
|
||||||
|
var restore = buttonLoading(button);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: globals.rootdir + "/actions.php",
|
||||||
|
type: "get",
|
||||||
|
data: {
|
||||||
|
id_module: globals.id_module,
|
||||||
|
id_plugin: '.$id_plugin.',
|
||||||
|
op: "process",
|
||||||
|
name: file,
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
$("#list").load("'.$structure->fileurl('list.php').'?id_module='.$id_module.'&id_plugin='.$id_plugin.'", function() {
|
||||||
|
buttonRestore(button, restore);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete_fe(button, file_id) {
|
||||||
|
swal({
|
||||||
|
title: "'.tr('Rimuovere la fattura salvata localmente?').'",
|
||||||
|
html: "'.tr('Sarà possibile inserirla nuovamente nel gestionale attraverso il caricamento').'",
|
||||||
|
type: "error",
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: "'.tr('Sì').'"
|
||||||
|
}).then(function (result) {
|
||||||
|
var restore = buttonLoading(button);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: globals.rootdir + "/actions.php",
|
||||||
|
type: "get",
|
||||||
|
data: {
|
||||||
|
id_module: globals.id_module,
|
||||||
|
id_plugin: '.$id_plugin.',
|
||||||
|
op: "delete",
|
||||||
|
file_id: file_id,
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
$("#list").load("'.$structure->fileurl('list.php').'?id_module='.$id_module.'&id_plugin='.$id_plugin.'", function() {
|
||||||
|
buttonRestore(button, restore);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function download_fe(button, file_id) {
|
||||||
|
redirect(globals.rootdir + "/actions.php", {
|
||||||
|
id_module: globals.id_module,
|
||||||
|
id_plugin: '.$id_plugin.',
|
||||||
|
op: "download",
|
||||||
|
file_id: file_id,
|
||||||
|
}, "get", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
start_local_datatables();
|
||||||
|
init();
|
||||||
|
</script>';
|
|
@ -0,0 +1,145 @@
|
||||||
|
<?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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Modules\DDT\DDT;
|
||||||
|
use Modules\Ordini\Ordine;
|
||||||
|
|
||||||
|
include_once __DIR__.'/../../core.php';
|
||||||
|
include_once __DIR__.'/init.php';
|
||||||
|
|
||||||
|
$direzione = 'entrata';
|
||||||
|
$id_riga = get('id_riga');
|
||||||
|
$qta = get('qta');
|
||||||
|
$descrizione = get('descrizione');
|
||||||
|
$prezzo_unitario = get('prezzo_unitario');
|
||||||
|
|
||||||
|
$id_documento = get('id_documento');
|
||||||
|
$tipo_documento = get('tipo_documento');
|
||||||
|
$dir = get('dir');
|
||||||
|
if ($tipo_documento == 'ordine') {
|
||||||
|
$documento = Ordine::find($id_documento);
|
||||||
|
$righe_utilizzate = get('righe_ordini');
|
||||||
|
} else {
|
||||||
|
$documento = DDT::find($id_documento);
|
||||||
|
$righe_utilizzate = get('righe_ddt');
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8">
|
||||||
|
Riga: <strong>'.$descrizione.'</strong>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 text-right">
|
||||||
|
Quantità: <strong>'.$qta.'</strong> - Prezzo unitario: <strong>'.number_format($prezzo_unitario, 2, ',', '.').'</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<table class="table table-striped table-hover table-sm table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th>'.tr('Descrizione').'</th>
|
||||||
|
<th class="text-center" width="120">
|
||||||
|
'.tr('Q.tà').' <i title="'.tr('da evadere').' / '.tr('totale').'" class="tip fa fa-question-circle-o"></i>
|
||||||
|
</th>
|
||||||
|
<th class="text-center" width="120">'.tr('Prezzo unitario').'</th>
|
||||||
|
<th class="text-center" width="60">#</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tbody>';
|
||||||
|
|
||||||
|
$id_riferimento = get('id_riferimento');
|
||||||
|
$righe = $documento->getRighe();
|
||||||
|
foreach ($righe as $riga) {
|
||||||
|
$qta_rimanente = $riga->qta_rimanente - (float) $righe_utilizzate[$riga->id];
|
||||||
|
$riga_origine = $riga->getOriginalComponent();
|
||||||
|
|
||||||
|
if (!empty($riga->idarticolo)) {
|
||||||
|
$desc_conto = $dbo->fetchOne('SELECT CONCAT( co_pianodeiconti2.numero, ".", co_pianodeiconti3.numero, " ", co_pianodeiconti3.descrizione ) AS descrizione FROM co_pianodeiconti3 INNER JOIN co_pianodeiconti2 ON co_pianodeiconti3.idpianodeiconti2=co_pianodeiconti2.id WHERE co_pianodeiconti3.id = '.prepare($riga->articolo->idconto_acquisto))['descrizione'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$dettagli = [
|
||||||
|
'tipo' => $riga::class,
|
||||||
|
'id' => $riga->id,
|
||||||
|
'descrizione' => str_replace(' ', '_', $riga->descrizione),
|
||||||
|
'qta' => $riga->qta,
|
||||||
|
'um' => $riga->um,
|
||||||
|
'prezzo_unitario' => $riga->prezzo_unitario ?: $riga_origine->prezzo_unitario,
|
||||||
|
'id_iva' => $riga->id_iva,
|
||||||
|
'iva_percentuale' => $riga->aliquota->percentuale,
|
||||||
|
'id_articolo' => $riga->idarticolo,
|
||||||
|
'desc_articolo' => str_replace(' ', '_', $riga->articolo->codice.' - '.$riga->articolo->getTranslation('title')),
|
||||||
|
'id_conto' => $riga->articolo->idconto_acquisto,
|
||||||
|
'desc_conto' => $desc_conto ? str_replace(' ', '_', $desc_conto) : null,
|
||||||
|
];
|
||||||
|
|
||||||
|
echo '
|
||||||
|
<tr '.($id_riferimento == $riga->id ? 'class="success"' : '').' data-dettagli='.json_encode($dettagli).'>
|
||||||
|
<td>'.(!empty($riga->codice) ? $riga->codice.' - ' : '').$riga->descrizione.'</td>
|
||||||
|
<td>'.numberFormat($qta_rimanente, 'qta').' / '.numberFormat($riga->qta, 'qta').' '.$riga->um.'</td>
|
||||||
|
<td class="text-right">'.moneyFormat($riga->prezzo_unitario_corrente).'</td>
|
||||||
|
<td class="text-center">';
|
||||||
|
|
||||||
|
if ($qta_rimanente >= $qta || !empty(setting('Permetti il superamento della soglia quantità dei documenti di origine'))) {
|
||||||
|
echo '
|
||||||
|
<button type="button" class="btn btn-info btn-xs" onclick="selezionaRiga(this)">
|
||||||
|
<i class="fa fa-check"></i>
|
||||||
|
</button>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
</td>
|
||||||
|
</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo '
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<script>$(document).ready(init)</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var documento_importazione = {
|
||||||
|
tipo: "'.$tipo_documento.'",
|
||||||
|
id: "'.$id_documento.'",
|
||||||
|
descrizione: '.json_encode(reference($documento, tr('Origine'))).',
|
||||||
|
opzione: "'.($tipo_documento == 'ordine' ? 'Ordine' : 'DDT').' num. '.($documento->numero_esterno ?: $documento->numero).' del '.Translator::dateToLocale($documento->data).'",
|
||||||
|
};
|
||||||
|
|
||||||
|
function selezionaRiga(button) {
|
||||||
|
let riga = $(button).closest("tr");
|
||||||
|
|
||||||
|
let dettagli_riga = riga.data("dettagli");
|
||||||
|
|
||||||
|
if("'.$dir.'"=="entrata"){
|
||||||
|
impostaRiferimentoVendita("'.$id_riga.'", documento_importazione, dettagli_riga);
|
||||||
|
}else{
|
||||||
|
impostaRiferimento("'.$id_riga.'", documento_importazione, dettagli_riga);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$(button).closest(".modal").modal("hide");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deselezione del riferimento in caso di selezione riga non effettuata
|
||||||
|
$("#modals > div").on("hidden.bs.modal", function () {
|
||||||
|
if(!$("#id_riferimento_'.$id_riga.'").val()) {
|
||||||
|
input("selezione_riferimento['.$id_riga.']").enable()
|
||||||
|
.getElement().selectReset();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>';
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$settings = [
|
||||||
|
'id_tipo' => 2,
|
||||||
|
'id_segment' => 1,
|
||||||
|
'id_pagamento' => 113,
|
||||||
|
'iva' => [
|
||||||
|
'22.00' => 171,
|
||||||
|
'10.00' => 167,
|
||||||
|
'5.00' => 164,
|
||||||
|
'4.00' => 163,
|
||||||
|
'' => 254,
|
||||||
|
'0.00' => 254,
|
||||||
|
],
|
||||||
|
'id_conto' => 94,
|
||||||
|
];
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
include_once __DIR__.'/../../core.php';
|
||||||
|
use Plugins\ImportFE\FatturaElettronica;
|
||||||
|
|
||||||
|
$directory = FatturaElettronica::getImportDirectory('Fatture di vendita', 'Importazione FE');
|
||||||
|
$filename = get('filename');
|
||||||
|
|
||||||
|
$content = file_get_contents($directory.'/'.$filename);
|
||||||
|
|
||||||
|
// XML
|
||||||
|
$xml = new DOMDocument();
|
||||||
|
$xml->loadXML($content);
|
||||||
|
|
||||||
|
// XSL
|
||||||
|
$xsl = new DOMDocument();
|
||||||
|
$xsl->load(base_dir().'/plugins/xml/asso-invoice.xsl');
|
||||||
|
|
||||||
|
// XSLT
|
||||||
|
$xslt = new XSLTProcessor();
|
||||||
|
$xslt->importStylesheet($xsl);
|
||||||
|
|
||||||
|
echo $xslt->transformToXML($xml);
|
|
@ -103,3 +103,19 @@ INSERT INTO `zz_api_resources` (`id`, `version`, `type`, `resource`, `class`, `e
|
||||||
|
|
||||||
-- Aggiunto spedizione porto e vettore in ordini
|
-- Aggiunto spedizione porto e vettore in ordini
|
||||||
ALTER TABLE `or_ordini` ADD `idspedizione` TINYINT NULL AFTER `codice_commessa`, ADD `idporto` TINYINT NULL AFTER `idspedizione`, ADD `idvettore` INT NULL AFTER `idporto`;
|
ALTER TABLE `or_ordini` ADD `idspedizione` TINYINT NULL AFTER `codice_commessa`, ADD `idporto` TINYINT NULL AFTER `idspedizione`, ADD `idvettore` INT NULL AFTER `idporto`;
|
||||||
|
|
||||||
|
-- Aggiunta del plugin Importazione FE
|
||||||
|
SELECT @id_module := `id` FROM `zz_modules` WHERE `name` = 'Fatture di vendita';
|
||||||
|
INSERT INTO `zz_plugins` (`name`, `idmodule_from`, `idmodule_to`, `position`, `script`, `enabled`, `default`, `order`, `compatibility`, `version`, `options2`, `options`, `directory`, `help`) VALUES
|
||||||
|
('Importazione FE', @id_module, @id_module, 'tab_main', '', 1, 1, 0, '2.6.*', '2.0', NULL, 'custom', 'importFE_ZIP', '');
|
||||||
|
|
||||||
|
INSERT INTO `zz_plugins_lang` (`id_lang`, `id_record`, `title`)
|
||||||
|
VALUES
|
||||||
|
(1, LAST_INSERT_ID(), 'Importazione FE'),
|
||||||
|
(2, LAST_INSERT_ID(), 'Importazione FE');
|
||||||
|
|
||||||
|
-- Aggiunta impostazione per metodo di importazione XML fatture
|
||||||
|
INSERT INTO `zz_settings` (`nome`, `valore`, `tipo`, `editable`, `sezione`, `order`) VALUES ('Metodo di importazione XML fatture di vendita', 'Automatico', 'list[Automatico,Manuale]', '1', 'Fatturazione', NULL);
|
||||||
|
INSERT INTO `zz_settings_lang` (`id_record`, `id_lang`, `title`) VALUES
|
||||||
|
(LAST_INSERT_ID(), 1, 'Metodo di importazione XML fatture di vendita'),
|
||||||
|
(LAST_INSERT_ID(), 2, 'Metodo di importazione XML fatture di vendita');
|
||||||
|
|
Loading…
Reference in New Issue