Merge branch 'master' into tasks

This commit is contained in:
Thomas Zilio 2020-08-12 14:54:47 +02:00
commit bbbae482c1
14 changed files with 98 additions and 37 deletions

View File

@ -25,6 +25,7 @@
ServerSignature Off
<IfModule mod_headers.c>
Header set X-Robots-Tag: "noindex,nofollow"
Header set X-Content-Type-Options nosniff
</IfModule>
<IfModule mod_rewrite.c>

View File

@ -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.17 (2020-08-12)](#2417-2020-08-12)
- [2.4.16 (2020-07-28)](#2416-2020-07-28)
- [2.4.15 (2020-05-01)](#2415-2020-05-01)
- [2.4.14 (2020-04-23)](#2414-2020-04-23)
@ -26,6 +27,38 @@ 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.17 (2020-08-12)
### Aggiunto (Added)
- Versione API per l'interazione con l'applicazione ufficiale (v3)
- Modal intermedio per la duplicazione **Articoli**
- Aggiunto controllo aggiuntivo sui checksum dei file (#705)
- Sistema per l'assegnazione di specifici Tecnici ad **Attività senza sessioni di lavoro** (**Promemoria di attività**), con nuove impostazioni per la gestione della **Dashboard**
- Funzioni JavaScript di utility per la gestione degli input
- Introduzione del *Totale reddito* per i *Movimenti* della **Prima Nota** e del **Piano dei conti**, con relativa revisione della generazione dei *Movimenti*
- Introduzione della sostituzione automatica per i caratteri speciali in Fattura Elettronica
- Aggiunta la *Data prevista evasione* sulle righe degli **Ordini**
- Aggiunto nome del firmatario nella stampa del **Rapportino attività**
- Aggiunta procedura per il salvataggio dinamico delle modifiche dei documenti alla creazione/modifica delle righe (#636)
### Modificato (Changed)
- Miglioramento dello stile delle checkbox
- Sistema di gestione dei parametri per la generazione AJAX delle opzioni select (*select-options*)
- Tabelle *responsive* per le righe di tutti i documenti
- Modifica del modulo **MyImpianti** in **Impianti**
- Miglioramento della struttura JavaScript della **Dashboard**
- Aggiornamento del modal di aggiunta **Attività**
- Separazione della gestione del *Bollo* e delle *Scadenze* dal codice delle *Fatture*
- Aggiornamento della struttura dedicata all'importazione dei file CSV
- Rimozione dello stato intervento "Chiamata" se inutilizzato
### Fixed
- Fix della duplicazione di Fattura, che in alcuni casi non rimuoveva lo stato FE originale
- Fix della procedura di duplicazione di gruppo per le **Attività**
- Risoluzione bug nella modifica manuale della **Prima Note** risalente a versioni <= 2.4.11 (#864)
- Fix dell'ordinamento per i conti primari del **Piano dei conti**, con correzione dei totali di riepilogo relativi
- Correzione sui tooltip bloccati sui pulsanti disabilitati
## 2.4.16 (2020-07-28)
### Aggiunto (Added)
@ -49,7 +82,6 @@ Il formato utilizzato è basato sulle linee guida di [Keep a Changelog](http://k
- Aggiunti totali delle tabelle ristretti alla selezione
- Aggiunta articoli in sequenza tramite barcode
### Modificato (Changed)
- Allineamento Fattura Elettronica a versione schema XML 1.2.1
- Aggiornamento foglio di stile FE Asso Invoice
@ -59,7 +91,6 @@ Il formato utilizzato è basato sulle linee guida di [Keep a Changelog](http://k
- Compattazione grafica righe documenti
- Ottimizzazione caricamento lista fatture
### Fixed
- Fix pulsante compilazione automatica campi in fase di import Fattura Elettronica passiva
- Fix statistiche per anagrafiche eliminate

View File

@ -182,10 +182,9 @@ class Movimenti
// Inversione contabile per i documenti di acquisto
if ($is_acquisto) {
foreach ($movimenti as $movimento) {
$temp = $movimento['avere'];
$movimento['avere'] = $movimento['dare'];
$movimento['dare'] = $temp;
foreach ($movimenti as $key => $movimento) {
$movimenti[$key]['avere'] = $movimento['dare'];
$movimenti[$key]['dare'] = $movimento['avere'];
}
}

View File

@ -219,6 +219,7 @@ if (!$is_completato) {
}
echo '
<script src="'.$rootdir.'/assets/src/js/functions/functions.js"></script>
<script>$(document).ready(init)</script>
<script type="text/javascript">
@ -235,7 +236,7 @@ async function modificaSessione(button) {
$(button).tooltipster("close");
// Apertura modal
openModal("'.tr('Modifica riga').'", "'.$module->fileurl('manage_sessione.php').'?id_module=" + globals.id_module + "&id_record=" + globals.id_record + "&id_sessione=" + id);
openModal("'.tr('Modifica sessione').'", "'.$module->fileurl('manage_sessione.php').'?id_module=" + globals.id_module + "&id_record=" + globals.id_record + "&id_sessione=" + id);
}
}

View File

@ -36,12 +36,13 @@ switch (post('op')) {
$idpianodeiconti = post('idpianodeiconti');
$numero = post('numero');
$descrizione = post('descrizione');
$dir = post('dir');
$lvl = post('lvl');
if ($lvl == 2) {
$duplicate_query = 'SELECT numero FROM co_pianodeiconti2 WHERE numero='.prepare($numero).' AND NOT id='.prepare($idconto).' AND idpianodeiconti1='.prepare($idpianodeiconti);
$update_query = 'UPDATE co_pianodeiconti2 SET numero='.prepare($numero).', descrizione='.prepare($descrizione).' WHERE id='.prepare($idconto);
$update_query = 'UPDATE co_pianodeiconti2 SET numero='.prepare($numero).', descrizione='.prepare($descrizione).', dir='.prepare($dir).' WHERE id='.prepare($idconto);
} else {
$duplicate_query = 'SELECT idpianodeiconti2, numero FROM co_pianodeiconti3 WHERE numero='.prepare($numero).' AND NOT id='.prepare($idconto).' AND idpianodeiconti2='.prepare($idpianodeiconti);

View File

@ -9,9 +9,9 @@ $query = 'SELECT *, idpianodeiconti2 AS idpianodeiconti FROM co_pianodeiconti3 W
$conto = $dbo->fetchOne($query);
echo '
<p>'.tr('Seleziona il periodo temporale per cui aggiornare il totale reddito del Conto "_DESC_" secondo la percentuale deducibile _PERC_%', [
<p>'.tr('Seleziona il periodo temporale per il quale desideri aggiornare la percentuale di deducibilità del conto "_DESC_". La nuova percentuale è: _PERC_%', [
'_DESC_' => $conto['descrizione'],
'_PERC_' => numberFormat($conto['percentuale_deducibile']),
'_PERC_' => numberFormat($conto['percentuale_deducibile'], 0),
]).'.</p>
<form action="" method="post">
<input type="hidden" name="op" value="aggiorna_reddito">

View File

@ -4,7 +4,7 @@ include_once __DIR__.'/../../../core.php';
switch ($resource) {
case 'conti':
$query = 'SELECT co_pianodeiconti2.* FROM co_pianodeiconti2 LEFT JOIN co_pianodeiconti3 ON co_pianodeiconti3.idpianodeiconti2=co_pianodeiconti2.id |where| GROUP BY co_pianodeiconti2.id';
$query = 'SELECT co_pianodeiconti2.* FROM co_pianodeiconti2 LEFT JOIN co_pianodeiconti3 ON co_pianodeiconti3.idpianodeiconti2=co_pianodeiconti2.id |where| GROUP BY co_pianodeiconti2.id ORDER BY co_pianodeiconti2.numero ASC, co_pianodeiconti3.numero ASC';
if ($search != '') {
$wh = 'WHERE (co_pianodeiconti3.descrizione LIKE '.prepare('%'.$search.'%')." OR CONCAT( co_pianodeiconti2.numero, '.', co_pianodeiconti3.numero ) LIKE ".prepare('%'.$search.'%').')';
@ -54,7 +54,7 @@ switch ($resource) {
break;
case 'conti-vendite':
$query = "SELECT co_pianodeiconti3.id, CONCAT( co_pianodeiconti2.numero, '.', co_pianodeiconti3.numero, ' ', co_pianodeiconti3.descrizione ) AS descrizione FROM co_pianodeiconti3 INNER JOIN (co_pianodeiconti2 INNER JOIN co_pianodeiconti1 ON co_pianodeiconti2.idpianodeiconti1=co_pianodeiconti1.id) ON co_pianodeiconti3.idpianodeiconti2=co_pianodeiconti2.id |where| ORDER BY co_pianodeiconti3.numero ASC";
$query = "SELECT co_pianodeiconti3.id, CONCAT( co_pianodeiconti2.numero, '.', co_pianodeiconti3.numero, ' ', co_pianodeiconti3.descrizione ) AS descrizione FROM co_pianodeiconti3 INNER JOIN (co_pianodeiconti2 INNER JOIN co_pianodeiconti1 ON co_pianodeiconti2.idpianodeiconti1=co_pianodeiconti1.id) ON co_pianodeiconti3.idpianodeiconti2=co_pianodeiconti2.id |where| ORDER BY co_pianodeiconti2.numero ASC, co_pianodeiconti3.numero ASC";
foreach ($elements as $element) {
$filter[] = 'co_pianodeiconti3.id='.prepare($element);
@ -70,7 +70,7 @@ switch ($resource) {
break;
case 'conti-acquisti':
$query = "SELECT co_pianodeiconti3.id, CONCAT( co_pianodeiconti2.numero, '.', co_pianodeiconti3.numero, ' ', co_pianodeiconti3.descrizione ) AS descrizione FROM co_pianodeiconti3 INNER JOIN (co_pianodeiconti2 INNER JOIN co_pianodeiconti1 ON co_pianodeiconti2.idpianodeiconti1=co_pianodeiconti1.id) ON co_pianodeiconti3.idpianodeiconti2=co_pianodeiconti2.id |where| ORDER BY co_pianodeiconti3.numero ASC";
$query = "SELECT co_pianodeiconti3.id, CONCAT( co_pianodeiconti2.numero, '.', co_pianodeiconti3.numero, ' ', co_pianodeiconti3.descrizione ) AS descrizione FROM co_pianodeiconti3 INNER JOIN (co_pianodeiconti2 INNER JOIN co_pianodeiconti1 ON co_pianodeiconti2.idpianodeiconti1=co_pianodeiconti1.id) ON co_pianodeiconti3.idpianodeiconti2=co_pianodeiconti2.id |where| ORDER BY co_pianodeiconti2.numero ASC, co_pianodeiconti3.numero ASC";
foreach ($elements as $element) {
$filter[] = 'co_pianodeiconti3.id='.prepare($element);

View File

@ -21,7 +21,7 @@ echo '
</div>';
// Livello 1
$query1 = 'SELECT * FROM `co_pianodeiconti1` ORDER BY id ASC';
$query1 = 'SELECT * FROM `co_pianodeiconti1` ORDER BY id DESC';
$primo_livello = $dbo->fetchArray($query1);
foreach ($primo_livello as $conto_primo) {
$totale_attivita = [];
@ -99,7 +99,7 @@ foreach ($primo_livello as $conto_primo) {
$totale_conto = $conto_terzo['totale'];
$totale_reddito = $conto_terzo['totale_reddito'];
if ($conto_primo['descrizione'] == 'Patrimoniale') {
if ($conto_primo['descrizione'] != 'Patrimoniale') {
$totale_conto = -$totale_conto;
$totale_reddito = -$totale_reddito;
}
@ -147,10 +147,12 @@ foreach ($primo_livello as $conto_primo) {
}
// Pulsante per aggiornare il totale reddito del conto di livello 3
if ($conto_secondo['dir'] == 'uscita') {
echo '
<button type="button" class="btn btn-info btn-xs" onclick="aggiornaReddito('.$conto_terzo['id'].')">
<i class="fa fa-refresh"></i>
</button>';
}
// Pulsante per modificare il nome del conto di livello 3
echo '
@ -172,7 +174,7 @@ foreach ($primo_livello as $conto_primo) {
// Span con info del conto
echo '
<span class="clickable" id="movimenti-'.$conto_terzo['id'].'">
&nbsp;'.$conto_secondo['numero'].'.'.$conto_terzo['numero'].' '.$conto_terzo['descrizione'].'
&nbsp;'.$conto_secondo['numero'].'.'.$conto_terzo['numero'].' '.$conto_terzo['descrizione'].($conto_terzo['percentuale_deducibile'] < 100 ? ' <span class="text-muted">('.tr('deducibile al _PERC_%', ['_PERC_' => Translator::numberToLocale($conto_terzo['percentuale_deducibile'], 0)]).')</span>' : '').'
</span>
<div id="conto_'.$conto_terzo['id'].'" style="display:none;"></div>
</td>
@ -408,6 +410,6 @@ echo '
}
function aggiornaReddito(id_conto){
openModal("'.tr('Aggiorna totale reddito').'", "'.$structure->fileurl('aggiorna_reddito.php').'?id=" + id_conto)
openModal("'.tr('Ricalcola importo deducibile').'", "'.$structure->fileurl('aggiorna_reddito.php').'?id=" + id_conto)
}
</script>';

View File

@ -9,7 +9,7 @@ $lvl = get('lvl');
if ($lvl == 2) {
$query = 'SELECT *, idpianodeiconti1 AS idpianodeiconti FROM co_pianodeiconti2 WHERE id='.prepare($idconto);
} else {
$query = 'SELECT *, idpianodeiconti2 AS idpianodeiconti FROM co_pianodeiconti3 WHERE id='.prepare($idconto);
$query = 'SELECT *, idpianodeiconti2 AS idpianodeiconti, (SELECT dir FROM co_pianodeiconti2 WHERE co_pianodeiconti2.id=co_pianodeiconti3.idpianodeiconti2) AS dir FROM co_pianodeiconti3 WHERE id='.prepare($idconto);
}
$info = $dbo->fetchOne($query);
@ -23,17 +23,21 @@ $info = $dbo->fetchOne($query);
<input type="hidden" name="idconto" value="<?php echo $info['id']; ?>">
<div class="row">
<div class="col-md-6">
<div class="col-md-4">
{[ "type": "text", "label": "<?php echo tr('Numero'); ?>", "name": "numero", "required": 1, "class": "text-center", "value": "<?php echo $info['numero']; ?>", "extra": "maxlength=\"6\"" ]}
</div>
<div class="col-md-6">
{[ "type": "number", "label": "<?php echo tr('Percentuale deducibile'); ?>", "name": "percentuale_deducibile", "value": "<?php echo $info['percentuale_deducibile']; ?>", "disabled": <?php echo intval($lvl == 2); ?>, "icon-after": "<i class=\"fa fa-percent\"></i>", "max-value": "100", "min-value": "0" ]}
<div class="col-md-8">
{[ "type": "text", "label": "<?php echo tr('Descrizione'); ?>", "name": "descrizione", "required": 1, "value": <?php echo json_encode($info['descrizione']); ?> ]}
</div>
</div>
<div class="row">
<div class="col-md-12">
{[ "type": "text", "label": "<?php echo tr('Descrizione'); ?>", "name": "descrizione", "required": 1, "value": <?php echo json_encode($info['descrizione']); ?> ]}
<div class="col-md-4 <?php echo intval($lvl != 3 || $info['dir'] != 'uscita') ? 'hidden' : ''; ?>">
{[ "type": "number", "decimals": 0, "label": "<?php echo tr('Percentuale deducibile'); ?>", "name": "percentuale_deducibile", "value": "<?php echo $info['percentuale_deducibile']; ?>", "icon-after": "<i class=\"fa fa-percent\"></i>", "max-value": "100", "min-value": "0" ]}
</div>
<div class="col-md-4 <?php echo intval($lvl != 2) ? 'hidden' : ''; ?>">
{[ "type": "select", "label": "<?php echo tr('Utilizza come'); ?>", "name": "dir", "value": "<?php echo $info['dir']; ?>", "values": "list=\"entrata\":\"Ricavo\", \"uscita\":\"Costo\", \"\": \"Non usare\"" ]}
</div>
</div>
<br>

View File

@ -200,7 +200,7 @@ function importAll(btn) {
type: "info",
});
buttonRestore(button, restore);
buttonRestore(btn, restore);
$("#main_loading").fadeOut();
});

View File

@ -4,10 +4,22 @@ namespace API;
class Resource
{
/**
* @param $request
*
* @return bool se true, la richiesta di apertura di considera fallita e viene restituito 404
*/
public function open($request)
{
return false;
}
/**
* @param $request
* @param $response
*
* @retrun void
*/
public function close($request, $response)
{
}

View File

@ -16,6 +16,8 @@ class CKEditorHandler implements HandlerInterface
<textarea |attr|>|value|</textarea>
<script src="'.ROOTDIR.'/assets/dist/js/ckeditor/ckeditor.js"></script>
<script>
CKEDITOR.addCss(".cke_editable img { max-width: 100% !important; height: auto !important; }");
CKEDITOR.replace("'.prepareToField($values['id']).'", {
toolbar: globals.ckeditorToolbar,
language: globals.locale,

View File

@ -329,10 +329,18 @@ if ($options['pricing']) {
// Timbro e firma
$firma = !empty($documento['firma_file']) ? '<img src="'.DOCROOT.'/files/interventi/'.$documento['firma_file'].'" style="width:70mm;">' : '';
echo '
<td rowspan="2" class="text-center" style="font-size:8pt;height:30mm;vertical-align:bottom">
'.$firma.'<br>
<i>('.tr('Timbro e firma leggibile').'.)</i>
'.$firma.'<br>';
if (empty($documento['firma_file'])) {
echo ' <i>('.tr('Timbro e firma leggibile').'.)</i>';
} else {
echo ' <i>'.$documento['firma_nome'].'</i>';
}
echo '
</td>
</tr>';

View File

@ -145,7 +145,7 @@ INSERT INTO `zz_api_resources` (`id`, `version`, `type`, `resource`, `class`, `e
-- Impostazioni relative all'applicazione
INSERT INTO `zz_settings` (`id`, `nome`, `valore`, `tipo`, `editable`, `sezione`, `order`, `help`) VALUES
(NULL, 'Google Maps API key', '', 'string', '1', 'Applicazione', 1, ''),
(NULL, 'Google Maps API key per Tecnici', '', 'string', '1', 'Applicazione', 1, ''),
(NULL, 'Mostra prezzi', '1', 'boolean', '1', 'Applicazione', 2, ''),
(NULL, 'Sincronizza solo i Clienti per cui il Tecnico ha lavorato in passato', '1', 'boolean', '1', 'Applicazione', 3, ''),
(NULL, 'Mesi per lo storico delle Attività', '6', 'integer', '1', 'Applicazione', 3, '');