diff --git a/CHANGELOG.md b/CHANGELOG.md
index 81f143a90..f15b53fb4 100755
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@ Tutti i maggiori cambiamenti di questo progetto saranno documentati in questo fi
Il formato utilizzato è basato sulle linee guida di [Keep a Changelog](http://keepachangelog.com/), e il progetto segue il [Semantic Versioning](http://semver.org/) per definire le versioni delle release.
+- [2.4.50 (2023-10-06)](#2450-2023-10-06)
- [2.4.49 (2023-09-22)](#2449-2023-09-25)
- [2.4.48 (2023-08-01)](#2448-2023-08-01)
- [2.4.47 (2023-06-30)](#2447-2023-06-30)
@@ -60,6 +61,35 @@ Il formato utilizzato è basato sulle linee guida di [Keep a Changelog](http://k
- [2.2 (2016-11-10)](#22-2016-11-10)
- [2.1 (2015-04-02)](#21-2015-04-02)
+
+## 2.4.50 (2023-10-06)
+### Aggiunto (Added)
+- Aggiunta funzionalità Aggiorna prezzi in row-list dei documenti
+- Aggiunta mappa nei moduli DDT
+- Aggiunta colore nei record in base allo stato del documento
+- Aggiunta colonna Sezionale in Tipi documento
+- Aggiunta gestione fatture con più ritenute
+- Aggiunti i preventivi in attesa di conferma in Informazioni Aggiuntive
+- Aggiunta l'importazione dei seriali da fatture di acquisto
+- Aggiunta creazione del tipo di anagrafica se mancante in import anagrafiche
+- Aggiunta gestione inline dei campi Costo e Prezzo unitario nei documenti
+- Aggiunto il login amministratore da app
+- Aggiunta l'esportazione xml delle scadenze di bonifici per la banca
+### Modificato (Changed)
+- Aggiornato il modello Asso Invoice
+- Eliminata la cartella tests
+- Disabilitato il tasto Elimina documento nel caso siano selezionate delle righe
+### Fixed
+- Corretto il campo RiferimentoAmministrazione in generazione XML
+- Corretta la visualizzazione della dicitura fissa in fattura
+- Corretta la visualizzazione della tabella del modulo Listini cliente
+- Corretta l'importazione delle anagrafiche con chiave primaria rientrante in campi_sede
+- Corretto il template sollecito di pagamento raggruppato per anagrafica
+- Corretta la visualizzazione del tasto sms
+- Corretta la generazione dell'autofattura in presenza di articoli
+- Corretto il campo RiferimentoNumeroLinea in fase di generazione XML
+- Corretta la duplicazione delle fatture
+- Corretta la query dei documenti collegati
## 2.4.49 (2023-09-25)
### Aggiunto (Added)
- Aggiunto avviso in caso di impossibilità di caricare la mappa
diff --git a/modules/anagrafiche/src/Import/CSV.php b/modules/anagrafiche/src/Import/CSV.php
index 780f44f7e..135242ac0 100644
--- a/modules/anagrafiche/src/Import/CSV.php
+++ b/modules/anagrafiche/src/Import/CSV.php
@@ -262,13 +262,13 @@ class CSV extends CSVImporter
$tipo_anagrafica = $database->fetchOne('SELECT idtipoanagrafica FROM an_tipianagrafiche WHERE lower(descrizione) = LOWER('.prepare($tipo).') OR idtipoanagrafica = '.prepare($tipo))['idtipoanagrafica'];
}
-
+
$tipologie[] = $tipo_anagrafica;
}
}
unset($record['idtipoanagrafica']);
- $tipi_selezionati = [];
+ $tipi_selezionati = [];
if (!empty($record['tipo'])) {
$tipi_selezionati = explode(',', $record['tipo']);
}
diff --git a/modules/articoli/edit.php b/modules/articoli/edit.php
index c30f3b14f..7988051cc 100755
--- a/modules/articoli/edit.php
+++ b/modules/articoli/edit.php
@@ -392,11 +392,11 @@ $("#scorporaIva").click( function() {
// Collegamenti diretti
// Fatture, ddt, preventivi collegati a questo articolo
-$elementi = $dbo->fetchArray('SELECT `co_documenti`.`id`, `co_documenti`.`data`, `co_documenti`.`numero`, `co_documenti`.`numero_esterno`, `co_tipidocumento`.`descrizione` AS tipo_documento, `co_tipidocumento`.`dir`, SUM(co_righe_documenti.qta) AS qta_totale, ((SUM(co_righe_documenti.prezzo_unitario)-SUM(co_righe_documenti.sconto_unitario))/SUM(co_righe_documenti.qta)) AS prezzo_unitario, SUM(co_righe_documenti.prezzo_unitario)-SUM(co_righe_documenti.sconto_unitario) AS prezzo_totale FROM `co_documenti` JOIN `co_tipidocumento` ON `co_tipidocumento`.`id` = `co_documenti`.`idtipodocumento` INNER JOIN `co_righe_documenti` ON `co_documenti`.`id`=`co_righe_documenti`.`iddocumento` WHERE `co_righe_documenti`.`idarticolo` = '.prepare($id_record).' GROUP BY co_documenti.id
+$elementi = $dbo->fetchArray('SELECT `co_documenti`.`id`, `co_documenti`.`data`, `co_documenti`.`numero`, `co_documenti`.`numero_esterno`, `co_tipidocumento`.`descrizione` AS tipo_documento, `co_tipidocumento`.`dir`, SUM(co_righe_documenti.qta) AS qta_totale, ((SUM(co_righe_documenti.prezzo_unitario)-SUM(co_righe_documenti.sconto_unitario))*SUM(co_righe_documenti.qta)) AS prezzo_totale, SUM(co_righe_documenti.prezzo_unitario)-SUM(co_righe_documenti.sconto_unitario) AS prezzo_unitario FROM `co_documenti` JOIN `co_tipidocumento` ON `co_tipidocumento`.`id` = `co_documenti`.`idtipodocumento` INNER JOIN `co_righe_documenti` ON `co_documenti`.`id`=`co_righe_documenti`.`iddocumento` WHERE `co_righe_documenti`.`idarticolo` = '.prepare($id_record).' GROUP BY co_documenti.id
-UNION SELECT `dt_ddt`.`id`, `dt_ddt`.`data`, `dt_ddt`.`numero`, `dt_ddt`.`numero_esterno`, `dt_tipiddt`.`descrizione` AS tipo_documento, `dt_tipiddt`.`dir`, SUM(dt_righe_ddt.qta) AS qta_totale, ((SUM(dt_righe_ddt.prezzo_unitario)-SUM(dt_righe_ddt.sconto_unitario))/SUM(dt_righe_ddt.qta)) AS prezzo_unitario, SUM(dt_righe_ddt.prezzo_unitario)-SUM(dt_righe_ddt.sconto_unitario) AS prezzo_totale FROM `dt_ddt` JOIN `dt_tipiddt` ON `dt_tipiddt`.`id` = `dt_ddt`.`idtipoddt` INNER JOIN `dt_righe_ddt` ON `dt_ddt`.`id`=`dt_righe_ddt`.`idddt` WHERE `dt_righe_ddt`.`idarticolo` = '.prepare($id_record).' GROUP BY dt_ddt.id
+UNION SELECT `dt_ddt`.`id`, `dt_ddt`.`data`, `dt_ddt`.`numero`, `dt_ddt`.`numero_esterno`, `dt_tipiddt`.`descrizione` AS tipo_documento, `dt_tipiddt`.`dir`, SUM(dt_righe_ddt.qta) AS qta_totale, ((SUM(dt_righe_ddt.prezzo_unitario)-SUM(dt_righe_ddt.sconto_unitario))*SUM(dt_righe_ddt.qta)) AS prezzo_totale, SUM(dt_righe_ddt.prezzo_unitario)-SUM(dt_righe_ddt.sconto_unitario) AS prezzo_unitario FROM `dt_ddt` JOIN `dt_tipiddt` ON `dt_tipiddt`.`id` = `dt_ddt`.`idtipoddt` INNER JOIN `dt_righe_ddt` ON `dt_ddt`.`id`=`dt_righe_ddt`.`idddt` WHERE `dt_righe_ddt`.`idarticolo` = '.prepare($id_record).' GROUP BY dt_ddt.id
-UNION SELECT `co_preventivi`.`id`, `co_preventivi`.`data_bozza`, `co_preventivi`.`numero`, 0 AS numero_esterno , "Preventivo" AS tipo_documento, 0 AS dir, SUM(co_righe_preventivi.qta) AS qta_totale, ((SUM(co_righe_preventivi.prezzo_unitario)-SUM(co_righe_preventivi.sconto_unitario))/SUM(co_righe_preventivi.qta)) AS prezzo_unitario, SUM(co_righe_preventivi.prezzo_unitario)-SUM(co_righe_preventivi.sconto_unitario) AS prezzo_totale FROM `co_preventivi` INNER JOIN `co_righe_preventivi` ON `co_preventivi`.`id`=`co_righe_preventivi`.`idpreventivo` WHERE `co_righe_preventivi`.`idarticolo` = '.prepare($id_record).' GROUP BY co_preventivi.id ORDER BY `data`');
+UNION SELECT `co_preventivi`.`id`, `co_preventivi`.`data_bozza`, `co_preventivi`.`numero`, 0 AS numero_esterno , "Preventivo" AS tipo_documento, 0 AS dir, SUM(co_righe_preventivi.qta) AS qta_totale, ((SUM(co_righe_preventivi.prezzo_unitario)-SUM(co_righe_preventivi.sconto_unitario))*SUM(co_righe_preventivi.qta)) AS prezzo_totale, SUM(co_righe_preventivi.prezzo_unitario)-SUM(co_righe_preventivi.sconto_unitario) AS prezzo_unitario FROM `co_preventivi` INNER JOIN `co_righe_preventivi` ON `co_preventivi`.`id`=`co_righe_preventivi`.`idpreventivo` WHERE `co_righe_preventivi`.`idarticolo` = '.prepare($id_record).' GROUP BY co_preventivi.id ORDER BY `data`');
if (!empty($elementi)) {
echo '
diff --git a/modules/dashboard/ajax.php b/modules/dashboard/ajax.php
index 187e5b297..4c89f0e8a 100644
--- a/modules/dashboard/ajax.php
+++ b/modules/dashboard/ajax.php
@@ -142,11 +142,11 @@ switch (filter('op')) {
)';
$preventivi = $dbo->fetchArray($query);
-
+
foreach ($preventivi as $preventivo) {
if ($preventivo['is_pianificabile'] == 1 || $preventivo['stato'] = 'In attesa di conferma') {
if (!empty($preventivo['data_accettazione']) && $preventivo['data_accettazione'] != '0000-00-00') {
- $query."AND co_statipreventivi.is_pianificabile=1";
+ $query.'AND co_statipreventivi.is_pianificabile=1';
$results[] = [
'id' => 'A_'.$modulo_preventivi->id.'_'.$preventivo['id'],
'idintervento' => $preventivo['id'],
diff --git a/modules/ddt/row-list.php b/modules/ddt/row-list.php
index 725ad3c91..483f39fd9 100755
--- a/modules/ddt/row-list.php
+++ b/modules/ddt/row-list.php
@@ -139,10 +139,10 @@ foreach ($righe as $riga) {
if ($riga->isDescrizione()) {
echo '
| ';
- if ($dir == 'entrata') {
- echo ' | ';
- }
- echo '
+ if ($dir == 'entrata') {
+ echo ' | ';
+ }
+ echo '
|
|
| ';
diff --git a/modules/fatture/actions.php b/modules/fatture/actions.php
index 700817726..c38bc29ea 100755
--- a/modules/fatture/actions.php
+++ b/modules/fatture/actions.php
@@ -856,12 +856,19 @@ switch ($op) {
$tipo = Tipo::find(post('idtipodocumento'));
$iva = Aliquota::find(setting('Iva predefinita'));
- $imponibile += Riga::join('co_iva', 'co_iva.id', '=', 'co_righe_documenti.idiva')
+ $imponibile = $database->table('co_righe_documenti')
+ ->join('co_iva', 'co_iva.id', '=', 'co_righe_documenti.idiva')
->where('co_iva.codice_natura_fe', 'LIKE', 'N3%')
->where('co_righe_documenti.iddocumento', $fattura->id)
->sum('subtotale');
- $totale_imponibile = setting('Utilizza prezzi di vendita comprensivi di IVA') ? $imponibile + ($imponibile * $iva->percentuale / 100) : $imponibile;
+ $sconto = $database->table('co_righe_documenti')
+ ->join('co_iva', 'co_iva.id', '=', 'co_righe_documenti.idiva')
+ ->where('co_iva.codice_natura_fe', 'LIKE', 'N3%')
+ ->where('co_righe_documenti.iddocumento', $fattura->id)
+ ->sum('sconto');
+
+ $totale_imponibile = setting('Utilizza prezzi di vendita comprensivi di IVA') ? ($imponibile - $sconto) + (($imponibile - $sconto) * $iva->percentuale / 100) : ($imponibile - $sconto);
$totale_imponibile = $fattura->tipo->reversed == 1 ? -$totale_imponibile : $totale_imponibile;
$autofattura = Fattura::build($anagrafica, $tipo, $data, $id_segment);
@@ -1185,7 +1192,7 @@ switch ($op) {
flash()->info(tr('Riga aggiornata!'));
}
- break;
+ break;
}
// Nota di debito
diff --git a/modules/fatture/row-list.php b/modules/fatture/row-list.php
index d3a78b8b5..84a20a7ef 100755
--- a/modules/fatture/row-list.php
+++ b/modules/fatture/row-list.php
@@ -188,7 +188,7 @@ foreach ($righe as $riga) {
if ($dir == 'entrata') {
echo ' | ';
}
- echo '
+ echo '
|
|
|
diff --git a/modules/ordini/row-list.php b/modules/ordini/row-list.php
index 535856110..c11f6d96a 100755
--- a/modules/ordini/row-list.php
+++ b/modules/ordini/row-list.php
@@ -193,10 +193,10 @@ foreach ($righe as $riga) {
if ($riga->isDescrizione()) {
echo '
| ';
- if ($dir == 'entrata') {
- echo ' | ';
- }
- echo '
+ if ($dir == 'entrata') {
+ echo ' | ';
+ }
+ echo '
|
|
| ';
diff --git a/plugins/exportFE/src/FatturaElettronica.php b/plugins/exportFE/src/FatturaElettronica.php
index 2687a598c..fdd4bd8d6 100755
--- a/plugins/exportFE/src/FatturaElettronica.php
+++ b/plugins/exportFE/src/FatturaElettronica.php
@@ -849,7 +849,6 @@ class FatturaElettronica
'Sede' => static::getSede($cliente),
];
-
return $result;
}
@@ -1132,7 +1131,7 @@ class FatturaElettronica
$dati = [];
if (!empty($element['riferimento_linea'])) {
- $dati['RiferimentoNumeroLinea'] = $element['riferimento_linea'];
+ $dati['RiferimentoNumeroLinea'] = $element['riferimento_linea']['id'];
}
$dati['IdDocumento'] = $element['id_documento'];
diff --git a/plugins/importFE/actions.php b/plugins/importFE/actions.php
index 8379b9c61..ae016bce0 100755
--- a/plugins/importFE/actions.php
+++ b/plugins/importFE/actions.php
@@ -139,7 +139,7 @@ switch (filter('op')) {
'crea_articoli' => post('crea_articoli'),
'is_ritenuta_pagata' => post('is_ritenuta_pagata'),
'update_info' => post('update_info'),
- 'serial' => post('flag_crea_seriali') ? post('serial') : [],
+ 'serial' => post('flag_crea_seriali') ? post('serial') : [],
];
$fattura_pa = FatturaElettronica::manage($filename);
diff --git a/plugins/importFE/generate.php b/plugins/importFE/generate.php
index 6fed05a94..0429c7eba 100755
--- a/plugins/importFE/generate.php
+++ b/plugins/importFE/generate.php
@@ -326,7 +326,7 @@ echo '
- {[ "type": "checkbox", "label": "'.tr('Creazione seriali').'", "name": "flag_crea_seriali", "value": 0, "help": "'.tr("Nel caso di righe contenenti serial, il gestionale procede alla registrazione del serial").'" ]}
+ {[ "type": "checkbox", "label": "'.tr('Creazione seriali').'", "name": "flag_crea_seriali", "value": 0, "help": "'.tr('Nel caso di righe contenenti serial, il gestionale procede alla registrazione del serial').'" ]}
';
$ritenuta = $dati_generali['DatiRitenuta'];
@@ -421,7 +421,7 @@ if (!empty($righe)) {
$serial = [];
foreach ($codici as $codice) {
$codici_articoli[] = $codice['CodiceValore'].' ('.$codice['CodiceTipo'].')';
- if (str_contains($codice['CodiceTipo'], 'serial') || str_contains($codice['CodiceTipo'], 'Serial')) {
+ if (str_contains($codice['CodiceTipo'], 'serial') || str_contains($codice['CodiceTipo'], 'Serial')) {
$serial[] = $codice['CodiceValore'];
}
}
@@ -605,13 +605,13 @@ if (!empty($righe)) {
';
- for ($i = 0; $i < $qta; $i++) {
- echo '
+ for ($i = 0; $i < $qta; ++$i) {
+ echo '
{[ "type": "text", "label": "'.tr('Serial').'", "name": "serial['.$key.'][]", "value": "'.$serial[$i].'" ]}
';
- }
- echo '
+ }
+ echo '
diff --git a/plugins/importFE/src/FatturaOrdinaria.php b/plugins/importFE/src/FatturaOrdinaria.php
index aa890db0b..f7e9d6bac 100755
--- a/plugins/importFE/src/FatturaOrdinaria.php
+++ b/plugins/importFE/src/FatturaOrdinaria.php
@@ -385,7 +385,7 @@ class FatturaOrdinaria extends FatturaElettronica
// Arrotondamenti differenti nella fattura XML
$diff = round(abs($totale_righe) + $totale_arrotondamento - abs($fattura->totale_imponibile), 2);
// Aggiunta della riga di arrotondamento nel caso in cui ci sia una differenza tra i totali, o tra l'imponibile dell'XML e quello ricavato dalla somma delle righe
-
+
if (($diff != 0 && $diff != $totale_arrotondamento) || (($fattura->totale_imponibile + $fattura->rivalsa_inps) != $totale_imp)) {
// Rimozione dell'IVA calcolata automaticamente dal gestionale
$iva_arrotondamento = database()->fetchOne('SELECT * FROM co_iva WHERE percentuale=0 AND deleted_at IS NULL');
diff --git a/plugins/presentazioni_bancarie/src/Gestore.php b/plugins/presentazioni_bancarie/src/Gestore.php
index 51b2a3c0b..f99c99555 100644
--- a/plugins/presentazioni_bancarie/src/Gestore.php
+++ b/plugins/presentazioni_bancarie/src/Gestore.php
@@ -128,6 +128,7 @@ class Gestore
$intestazione->ragione_sociale_creditore = strtoupper($this->azienda->ragione_sociale);
$intestazione->indirizzo_creditore = strtoupper($this->azienda['indirizzo']);
$intestazione->partita_iva_o_codice_fiscale_creditore = !empty($this->azienda->partita_iva) ? $this->azienda->partita_iva : $this->azienda->codice_fiscale;
+ $intestazione->identificativo_creditore = !empty($this->azienda->partita_iva) ? $this->azienda->partita_iva : $this->azienda->codice_fiscale;
$intestazione->descrizione_banca = $descrizione_banca;
$this->bonifico = new CbiSepa($intestazione);
diff --git a/src/API/App/v1/Checklists.php b/src/API/App/v1/Checklists.php
old mode 100644
new mode 100755
index c480fe788..c2e5b875a
--- a/src/API/App/v1/Checklists.php
+++ b/src/API/App/v1/Checklists.php
@@ -22,8 +22,8 @@ namespace API\App\v1;
use API\App\AppResource;
use Auth;
use Carbon\Carbon;
-use Models\User;
use Modules\Checklists\Check;
+use Models\User;
class Checklists extends AppResource
{
@@ -37,7 +37,6 @@ class Checklists extends AppResource
// Informazioni sull'utente
$user = Auth::user();
- $id_tecnico = $user->id_anagrafica;
// Elenco di interventi di interesse
$risorsa_interventi = $this->getRisorsaInterventi();
@@ -46,24 +45,46 @@ class Checklists extends AppResource
// Elenco sessioni degli interventi da rimuovere
$da_interventi = [];
if (!empty($interventi)) {
- $query = 'SELECT zz_checks.id
- FROM zz_checks
- INNER JOIN in_interventi ON zz_checks.id_record = in_interventi.id
- INNER JOIN in_interventi_tecnici ON in_interventi_tecnici.idintervento = in_interventi.id
- INNER JOIN zz_modules ON zz_checks.id_module = zz_modules.id
- INNER JOIN zz_check_user ON zz_checks.id = zz_check_user.id_check
- WHERE
- zz_modules.name="Interventi"
- AND
- zz_check_user.id_utente = :id_tecnico
- AND
- in_interventi.id IN ('.implode(',', $interventi).')
- OR (orario_fine NOT BETWEEN :period_start AND :period_end)';
- $records = database()->fetchArray($query, [
- ':period_end' => $end,
- ':period_start' => $start,
- ':id_tecnico' => $user->id,
- ]);
+ if($user->is_admin){
+ $query = '
+ SELECT zz_checks.id
+ FROM zz_checks
+ INNER JOIN in_interventi ON zz_checks.id_record = in_interventi.id
+ INNER JOIN in_interventi_tecnici ON in_interventi_tecnici.idintervento = in_interventi.id
+ INNER JOIN zz_modules ON zz_checks.id_module = zz_modules.id
+ INNER JOIN zz_check_user ON zz_checks.id = zz_check_user.id_check
+ WHERE
+ zz_modules.name="Interventi"
+ AND
+ in_interventi.id IN ('.implode(',', $interventi).')
+ OR (orario_fine NOT BETWEEN :period_start AND :period_end)';
+
+ $records = database()->fetchArray($query, [
+ ':period_end' => $end,
+ ':period_start' => $start,
+ ]);
+ }else{
+ $query = '
+ SELECT zz_checks.id
+ FROM zz_checks
+ INNER JOIN in_interventi ON zz_checks.id_record = in_interventi.id
+ INNER JOIN in_interventi_tecnici ON in_interventi_tecnici.idintervento = in_interventi.id
+ INNER JOIN zz_modules ON zz_checks.id_module = zz_modules.id
+ INNER JOIN zz_check_user ON zz_checks.id = zz_check_user.id_check
+ WHERE
+ zz_modules.name="Interventi"
+ AND
+ zz_check_user.id_utente = :id_tecnico
+ AND
+ in_interventi.id IN ('.implode(',', $interventi).')
+ OR (orario_fine NOT BETWEEN :period_start AND :period_end)';
+
+ $records = database()->fetchArray($query, [
+ ':period_end' => $end,
+ ':period_start' => $start,
+ ':id_tecnico' => $user->id
+ ]);
+ }
$da_interventi = array_column($records, 'id');
}
@@ -90,30 +111,47 @@ class Checklists extends AppResource
}
$user = Auth::user();
- $id_tecnico = $user->id_anagrafica;
$id_interventi = array_keys($interventi);
- $query = 'SELECT zz_checks.id
- FROM zz_checks
- INNER JOIN in_interventi ON zz_checks.id_record = in_interventi.id
- INNER JOIN in_interventi_tecnici ON in_interventi_tecnici.idintervento = in_interventi.id
- INNER JOIN zz_modules ON zz_checks.id_module = zz_modules.id
- INNER JOIN zz_check_user ON zz_checks.id = zz_check_user.id_check
- WHERE
- zz_modules.name="Interventi"
- AND zz_check_user.id_utente = :id_tecnico
- AND in_interventi.id IN ('.implode(',', $id_interventi).')
- AND (orario_fine BETWEEN :period_start AND :period_end)';
+ if($user->is_admin){
+ $query = 'SELECT zz_checks.id
+ FROM zz_checks
+ INNER JOIN in_interventi ON zz_checks.id_record = in_interventi.id
+ INNER JOIN zz_modules ON zz_checks.id_module = zz_modules.id
+ INNER JOIN zz_check_user ON zz_checks.id = zz_check_user.id_check
+ WHERE
+ zz_modules.name="Interventi"
+ AND in_interventi.id IN ('.implode(',', $id_interventi).')';
- // Filtro per data
- if ($last_sync_at) {
- $query .= ' AND zz_checks.updated_at > '.prepare($last_sync_at);
+ // Filtro per data
+ if ($last_sync_at) {
+ $query .= ' AND zz_checks.updated_at > '.prepare($last_sync_at);
+ }
+
+ $records = database()->fetchArray($query);
+ }else{
+ $query = 'SELECT zz_checks.id
+ FROM zz_checks
+ INNER JOIN in_interventi ON zz_checks.id_record = in_interventi.id
+ INNER JOIN in_interventi_tecnici ON in_interventi_tecnici.idintervento = in_interventi.id
+ INNER JOIN zz_modules ON zz_checks.id_module = zz_modules.id
+ INNER JOIN zz_check_user ON zz_checks.id = zz_check_user.id_check
+ WHERE
+ zz_modules.name="Interventi"
+ AND zz_check_user.id_utente = :id_tecnico
+ AND in_interventi.id IN ('.implode(',', $id_interventi).')
+ AND (orario_fine BETWEEN :period_start AND :period_end)';
+
+ // Filtro per data
+ if ($last_sync_at) {
+ $query .= ' AND zz_checks.updated_at > '.prepare($last_sync_at);
+ }
+ $records = database()->fetchArray($query, [
+ ':period_start' => $start,
+ ':period_end' => $end,
+ ':id_tecnico' => $user->id
+ ]);
}
- $records = database()->fetchArray($query, [
- ':period_start' => $start,
- ':period_end' => $end,
- ':id_tecnico' => $user->id,
- ]);
return $this->mapModifiedRecords($records);
}
@@ -121,17 +159,16 @@ class Checklists extends AppResource
public function retrieveRecord($id)
{
// Gestione della visualizzazione dei dettagli del record
- $query = 'SELECT zz_checks.id,
+ $query = "SELECT zz_checks.id,
zz_checks.id_record AS id_intervento,
zz_checks.checked_at,
zz_checks.content,
zz_checks.note,
IF(zz_checks.id_parent IS NULL, 0, zz_checks.id_parent) AS id_parent,
zz_checks.checked_by,
- zz_checks.order AS ordine,
- zz_checks.is_titolo
+ zz_checks.order AS ordine
FROM zz_checks
- WHERE zz_checks.id = '.prepare($id);
+ WHERE zz_checks.id = ".prepare($id);
$record = database()->fetchOne($query);
@@ -142,11 +179,11 @@ class Checklists extends AppResource
{
$check = Check::find($data['id']);
- $check->checked_at = (!empty($data['checked_at']) ? $data['checked_at'] : null);
+ $check->checked_at = (!empty($data['checked_at']) ? $data['checked_at'] : NULL);
$check->content = $data['content'];
$check->note = $data['note'];
$user = User::where('idanagrafica', $data['checked_by'])->first();
- if (!empty($user)) {
+ if(!empty($user)){
$check->checked_by = $user->id;
}
@@ -159,4 +196,4 @@ class Checklists extends AppResource
{
return new Interventi();
}
-}
+}
\ No newline at end of file
diff --git a/src/API/App/v1/Impianti.php b/src/API/App/v1/Impianti.php
old mode 100644
new mode 100755
index ab491d282..1861ac7aa
--- a/src/API/App/v1/Impianti.php
+++ b/src/API/App/v1/Impianti.php
@@ -22,6 +22,7 @@ namespace API\App\v1;
use API\App\AppResource;
use Illuminate\Database\Eloquent\Builder;
use Modules\Impianti\Impianto;
+use Auth;
class Impianti extends AppResource
{
@@ -32,11 +33,26 @@ class Impianti extends AppResource
public function getModifiedRecords($last_sync_at)
{
- $statement = Impianto::select('id', 'updated_at')
+ $statement = Impianto::select('id', 'updated_at', 'idtecnico')
->whereHas('anagrafica.tipi', function (Builder $query) {
$query->where('descrizione', '=', 'Cliente');
});
+ //Limite impianti visualizzabili dal tecnico
+ $limite_impianti = setting("Limita la visualizzazione degli impianti a quelli gestiti dal tecnico");
+
+ if($limite_impianti == 1 && !Auth::user()->is_admin){
+ $id_tecnico = Auth::user()->id_anagrafica;
+
+ // Elenco di interventi di interesse
+ $risorsa_interventi = $this->getRisorsaInterventi();
+ // Da applicazione, i Clienti sono sincronizzati prima degli Interventi: last_sync_at permette di identificare le stesse modifiche
+ $interventi = $risorsa_interventi->getModifiedRecords(null);
+ $id_interventi = array_keys($interventi);
+
+ $statement->where('idtecnico', $id_tecnico)->orWhere('id', 'IN', ('SELECT idimpianto FROM my_impianti_interventi WHERE idintervento IN ('.implode(',', $id_interventi).')'));
+ }
+
// Filtro per data
if ($last_sync_at) {
$statement = $statement->where('updated_at', '>', $last_sync_at);
@@ -73,4 +89,8 @@ class Impianti extends AppResource
return $record;
}
+ protected function getRisorsaInterventi()
+ {
+ return new Interventi();
+ }
}
diff --git a/src/API/App/v1/Interventi.php b/src/API/App/v1/Interventi.php
old mode 100644
new mode 100755
index 2480f96e2..bcede684b
--- a/src/API/App/v1/Interventi.php
+++ b/src/API/App/v1/Interventi.php
@@ -58,7 +58,31 @@ class Interventi extends AppResource
// Informazioni sull'utente
$id_tecnico = Auth::user()->id_anagrafica;
- $query = 'SELECT in_interventi.id FROM in_interventi WHERE
+ if(Auth::user()->is_admin){
+ $query = 'SELECT in_interventi.id FROM in_interventi WHERE
+ deleted_at IS NOT NULL
+ OR (
+ in_interventi.id NOT IN (
+ SELECT idintervento FROM in_interventi_tecnici
+ WHERE in_interventi_tecnici.idintervento = in_interventi.id
+ AND in_interventi_tecnici.orario_fine BETWEEN :period_start AND :period_end
+ )
+ AND in_interventi.id IN (
+ SELECT idintervento FROM in_interventi_tecnici
+ WHERE in_interventi_tecnici.idintervento = in_interventi.id
+ AND in_interventi_tecnici.orario_fine BETWEEN :remove_period_start AND :remove_period_end
+ )
+ )';
+
+ $records = database()->fetchArray($query, [
+ ':period_end' => $end,
+ ':period_start' => $start,
+ ':remove_period_end' => $remove_end,
+ ':remove_period_start' => $remove_start,
+ ]);
+
+ }else{
+ $query = 'SELECT in_interventi.id FROM in_interventi WHERE
deleted_at IS NOT NULL
OR (
in_interventi.id NOT IN (
@@ -74,15 +98,17 @@ class Interventi extends AppResource
AND in_interventi_tecnici.idtecnico = :id_tecnico_q2
)
)';
- $records = database()->fetchArray($query, [
+
+ $records = database()->fetchArray($query, [
':period_end' => $end,
':period_start' => $start,
':remove_period_end' => $remove_end,
':remove_period_start' => $remove_start,
':id_tecnico_q1' => $id_tecnico,
':id_tecnico_q2' => $id_tecnico,
- ]);
-
+ ]);
+ }
+
$interventi = array_column($records, 'id');
$mancanti = $this->getMissingIDs('in_interventi', 'id', $last_sync_at);
@@ -100,52 +126,96 @@ class Interventi extends AppResource
$id_tecnico = Auth::user()->id_anagrafica;
if (setting('Visualizza solo promemoria assegnati') == 1) {
- $query = '
- SELECT
- in_interventi.id,
- in_interventi.updated_at
- FROM
- in_interventi
- WHERE
- deleted_at IS NULL AND (
- in_interventi.id IN (
- SELECT idintervento FROM in_interventi_tecnici
- WHERE in_interventi_tecnici.idintervento = in_interventi.id
- AND in_interventi_tecnici.orario_fine BETWEEN :period_start AND :period_end
- AND in_interventi_tecnici.idtecnico = :id_tecnico_q1
- )
- OR (
- in_interventi.id NOT IN (
- SELECT idintervento FROM in_interventi_tecnici
- )
- AND in_interventi.idstatointervento IN (SELECT idstatointervento FROM in_statiintervento WHERE is_completato = 0 AND in_interventi.id IN (
- SELECT id_intervento FROM in_interventi_tecnici_assegnati WHERE in_interventi_tecnici_assegnati.id_tecnico = :id_tecnico_q2)
- )
- )
- )';
- } else {
- $query = '
- SELECT
- in_interventi.id,
- in_interventi.updated_at
- FROM
- in_interventi
- WHERE
- deleted_at IS NULL AND (
- in_interventi.id IN (
- SELECT idintervento FROM in_interventi_tecnici
- WHERE in_interventi_tecnici.idintervento = in_interventi.id
- AND in_interventi_tecnici.orario_fine BETWEEN :period_start AND :period_end
- AND in_interventi_tecnici.idtecnico = :id_tecnico_q1
- )
- OR (
- in_interventi.id NOT IN (
- SELECT idintervento FROM in_interventi_tecnici
+ if(Auth::user()->is_admin){
+ $query = '
+ SELECT
+ in_interventi.id,
+ in_interventi.updated_at
+ FROM
+ in_interventi
+ WHERE
+ deleted_at IS NULL AND (in_interventi.id IN (
+ SELECT idintervento FROM in_interventi_tecnici WHERE in_interventi_tecnici.idintervento = in_interventi.id AND in_interventi_tecnici.orario_fine BETWEEN :period_start AND :period_end
)
- AND in_interventi.idstatointervento IN (SELECT idstatointervento FROM in_statiintervento WHERE is_completato = 0)
- )
- )';
- }
+ OR (
+ in_interventi.id NOT IN ( SELECT idintervento FROM in_interventi_tecnici
+ )
+ AND in_interventi.idstatointervento IN (SELECT idstatointervento FROM in_statiintervento WHERE is_completato = 0)
+ )
+ )';
+ }else{
+ $query = '
+ SELECT
+ in_interventi.id,
+ in_interventi.updated_at
+ FROM
+ in_interventi
+ WHERE
+ deleted_at IS NULL AND (
+ in_interventi.id IN (
+ SELECT idintervento FROM in_interventi_tecnici
+ WHERE in_interventi_tecnici.idintervento = in_interventi.id
+ AND in_interventi_tecnici.orario_fine BETWEEN :period_start AND :period_end
+ AND in_interventi_tecnici.idtecnico = :id_tecnico_q1
+ )
+ OR (
+ in_interventi.id NOT IN (
+ SELECT idintervento FROM in_interventi_tecnici
+ )
+ AND in_interventi.idstatointervento IN (SELECT idstatointervento FROM in_statiintervento WHERE is_completato = 0) AND in_interventi.id IN (
+ SELECT id_intervento FROM in_interventi_tecnici_assegnati WHERE in_interventi_tecnici_assegnati.id_tecnico = :id_tecnico_q2
+ )
+ )
+ )';
+ }
+
+ } else {
+ if(Auth::user()->is_admin){
+ $query = '
+ SELECT
+ in_interventi.id,
+ in_interventi.updated_at
+ FROM
+ in_interventi
+ WHERE
+ deleted_at IS NULL AND (
+ in_interventi.id IN (
+ SELECT idintervento FROM in_interventi_tecnici
+ WHERE in_interventi_tecnici.idintervento = in_interventi.id
+ AND in_interventi_tecnici.orario_fine BETWEEN :period_start AND :period_end
+ )
+ OR (
+ in_interventi.id NOT IN (
+ SELECT idintervento FROM in_interventi_tecnici
+ )
+ AND in_interventi.idstatointervento IN (SELECT idstatointervento FROM in_statiintervento WHERE is_completato = 0)
+ )
+ )';
+ }else{
+ $query = '
+ SELECT
+ in_interventi.id,
+ in_interventi.updated_at
+ FROM
+ in_interventi
+ WHERE
+ deleted_at IS NULL AND (
+ in_interventi.id IN (
+ SELECT idintervento FROM in_interventi_tecnici
+ WHERE in_interventi_tecnici.idintervento = in_interventi.id
+ AND in_interventi_tecnici.orario_fine BETWEEN :period_start AND :period_end
+ AND in_interventi_tecnici.idtecnico = :id_tecnico_q1
+ )
+ OR (
+ in_interventi.id NOT IN (
+ SELECT idintervento FROM in_interventi_tecnici
+ )
+ AND in_interventi.idstatointervento IN (SELECT idstatointervento FROM in_statiintervento WHERE is_completato = 0)
+ )
+ )';
+ }
+
+ }
// Filtro per data
// Gestione di tecnici assegnati o impianti modificati
@@ -161,18 +231,32 @@ class Interventi extends AppResource
}
if (setting('Visualizza solo promemoria assegnati') == 1) {
- $records = database()->fetchArray($query, [
- ':period_start' => $start,
- ':period_end' => $end,
- ':id_tecnico_q1' => $id_tecnico,
- ':id_tecnico_q2' => $id_tecnico,
- ]);
+ if(Auth::user()->is_admin){
+ $records = database()->fetchArray($query, [
+ ':period_start' => $start,
+ ':period_end' => $end,
+ ]);
+ } else {
+ $records = database()->fetchArray($query, [
+ ':period_start' => $start,
+ ':period_end' => $end,
+ ':id_tecnico_q1' => $id_tecnico,
+ ':id_tecnico_q2' => $id_tecnico,
+ ]);
+ }
} else {
- $records = database()->fetchArray($query, [
- ':period_start' => $start,
- ':period_end' => $end,
- ':id_tecnico_q1' => $id_tecnico,
- ]);
+ if(Auth::user()->is_admin){
+ $records = database()->fetchArray($query, [
+ ':period_start' => $start,
+ ':period_end' => $end,
+ ]);
+ } else {
+ $records = database()->fetchArray($query, [
+ ':period_start' => $start,
+ ':period_end' => $end,
+ ':id_tecnico_q1' => $id_tecnico,
+ ]);
+ }
}
return $this->mapModifiedRecords($records);
@@ -269,10 +353,12 @@ class Interventi extends AppResource
// Aggiornamento degli impianti collegati
$database->query('DELETE FROM my_impianti_interventi WHERE idintervento = '.prepare($record->id));
foreach ($data['impianti'] as $id_impianto) {
- $database->insert('my_impianti_interventi', [
- 'idimpianto' => $id_impianto,
- 'idintervento' => $record->id,
- ]);
+ if(!empty($id_impianto)){
+ $database->insert('my_impianti_interventi', [
+ 'idimpianto' => $id_impianto,
+ 'idintervento' => $record->id,
+ ]);
+ }
}
// Aggiornamento dei tecnici assegnati
@@ -283,6 +369,10 @@ class Interventi extends AppResource
], [
'id_tecnico' => $tecnici_assegnati,
]);
+
+ if(!empty($data['idrichiesta'])){
+ database()->query('UPDATE in_richieste SET idintervento = '.prepare($record->id).', updated_at=NOW() WHERE id = '.prepare($data['idrichiesta']));
+ }
}
protected function salvaFirma($firma_base64)
diff --git a/src/API/App/v1/Login.php b/src/API/App/v1/Login.php
old mode 100644
new mode 100755
index d9a7ea8ed..a91b2e44b
--- a/src/API/App/v1/Login.php
+++ b/src/API/App/v1/Login.php
@@ -35,18 +35,32 @@ class Login extends Resource implements CreateInterface
if (auth()->attempt($request['username'], $request['password'])) {
$user = $this->getUser();
$token = auth()->getToken();
-
- // Informazioni sull'utente, strettamente collegato ad una anagrafica di tipo Tecnico
- $utente = $database->fetchOne("SELECT
- `an_anagrafiche`.`idanagrafica` AS id_anagrafica,
- `an_anagrafiche`.`ragione_sociale`
- FROM `zz_users`
- INNER JOIN `an_anagrafiche` ON `an_anagrafiche`.`idanagrafica` = `zz_users`.`idanagrafica`
- INNER JOIN an_tipianagrafiche_anagrafiche ON an_tipianagrafiche_anagrafiche.idanagrafica = an_anagrafiche.idanagrafica
- INNER JOIN an_tipianagrafiche ON an_tipianagrafiche_anagrafiche.idtipoanagrafica = an_tipianagrafiche.idtipoanagrafica
- WHERE an_tipianagrafiche.descrizione = 'Tecnico' AND `an_anagrafiche`.`deleted_at` IS NULL AND `id` = :id", [
- ':id' => $user['id'],
- ]);
+
+ if(setting("Permetti l'accesso agli amministratori")){
+ $utente = $database->fetchOne("SELECT
+ `an_anagrafiche`.`idanagrafica` AS id_anagrafica,
+ `an_anagrafiche`.`ragione_sociale`,
+ zz_groups.nome AS gruppo
+ FROM `zz_users`
+ INNER JOIN `an_anagrafiche` ON `an_anagrafiche`.`idanagrafica` = `zz_users`.`idanagrafica`
+ INNER JOIN zz_groups ON zz_users.idgruppo=zz_groups.id
+ WHERE `an_anagrafiche`.`deleted_at` IS NULL AND `zz_users`.`id` = :id", [
+ ':id' => $user['id'],
+ ]);
+ }else{
+ $utente = $database->fetchOne("SELECT
+ `an_anagrafiche`.`idanagrafica` AS id_anagrafica,
+ `an_anagrafiche`.`ragione_sociale`,
+ zz_groups.nome AS gruppo
+ FROM `zz_users`
+ INNER JOIN `an_anagrafiche` ON `an_anagrafiche`.`idanagrafica` = `zz_users`.`idanagrafica`
+ INNER JOIN an_tipianagrafiche_anagrafiche ON an_tipianagrafiche_anagrafiche.idanagrafica = an_anagrafiche.idanagrafica
+ INNER JOIN an_tipianagrafiche ON an_tipianagrafiche_anagrafiche.idtipoanagrafica = an_tipianagrafiche.idtipoanagrafica
+ INNER JOIN zz_groups ON zz_users.idgruppo=zz_groups.id
+ WHERE an_tipianagrafiche.descrizione = 'Tecnico' AND `an_anagrafiche`.`deleted_at` IS NULL AND `id` = :id", [
+ ':id' => $user['id'],
+ ]);
+ }
if (!empty($utente)) {
// Informazioni da restituire tramite l'API
@@ -54,6 +68,7 @@ class Login extends Resource implements CreateInterface
'id_anagrafica' => (string) $utente['id_anagrafica'],
'ragione_sociale' => $utente['ragione_sociale'],
'token' => $token,
+ 'gruppo' => $utente['gruppo'],
'version' => Update::getVersion(),
];
} else {
diff --git a/src/API/Manager.php b/src/API/Manager.php
index 7f5fa48bc..0b0804c02 100755
--- a/src/API/Manager.php
+++ b/src/API/Manager.php
@@ -289,7 +289,10 @@ class Manager
// Operazioni della risorsa
$response = $object->{$method}($request);
- $database->commitTransaction();
+ try{
+ $database->commitTransaction();
+ } catch (PDOException $e) {
+ }
// Operazioni di completamento
$object->close($request, $response);
diff --git a/templates/preventivi/body.php b/templates/preventivi/body.php
index 9e47e6dea..605d2d6af 100755
--- a/templates/preventivi/body.php
+++ b/templates/preventivi/body.php
@@ -305,7 +305,7 @@ foreach ($righe as $key => $riga) {
$autofill->next();
$next = $righe->flatten()[$num];
- if ($has_gruppo && ($next->is_titolo || $next == null)) {
+ if ($has_gruppo && ($next->is_titolo || $next == null) && ($options['pricing'] || ($options['show-only-total']))) {
echo '
diff --git a/update/2_4_50.sql b/update/2_4_50.sql
index 929cec649..2c5d7179a 100644
--- a/update/2_4_50.sql
+++ b/update/2_4_50.sql
@@ -89,3 +89,9 @@ INSERT INTO `zz_views` (`id_module`, `name`, `query`, `order`, `search`, `slow`,
UPDATE `zz_prints` SET `predefined` = '0' WHERE `zz_prints`.`name` IN ('Stampa calendario settimanale', "Intervento & checklist", "Intervento & checklist (senza costi)", "Barcode bulk");
+UPDATE `zz_modules` SET `options` = 'SELECT |select| FROM `co_tipidocumento` LEFT JOIN zz_segments ON co_tipidocumento.id_segment = zz_segments.id WHERE 1=1 AND deleted_at IS NULL HAVING 2=2' WHERE `zz_modules`.`name` = 'Tipi documento';
+
+-- Impostazione per login amministratore da app
+INSERT INTO `zz_settings` (`nome`, `valore`, `tipo`, `editable`, `sezione`, `order`, `help`) VALUES ("Permetti l\'accesso agli amministratori", '1', 'boolean', 1, 'Applicazione', 4, '');
+
+UPDATE `co_pianodeiconti2` SET `dir` = 'entrata/uscita' WHERE `co_pianodeiconti2`.`descrizione` = 'Immobilizzazioni';
\ No newline at end of file
|