This commit is contained in:
MatteoPistorello 2022-12-07 16:21:41 +01:00
commit c4b720a7bc
16 changed files with 306 additions and 66 deletions

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.38 (2022-12-07)](#2438-2022-12-07)
- [2.4.37 (2022-11-02)](#2437-2022-11-04)
- [2.4.36 (2022-09-16)](#2436-2022-09-16)
- [2.4.35 (2022-08-12)](#2435-2022-08-12)
@ -49,6 +50,61 @@ Il formato utilizzato è basato sulle linee guida di [Keep a Changelog](http://k
- [2.1 (2015-04-02)](#21-2015-04-02)
## 2.4.38 (2022-12-07)
### Aggiunto (Added)
- Aggiunto tempDir per mpdf
- Aggiunto controllo cartella files/temp
- Aggiunto invio delle mail con procedura in cron
- Aggiunta psalm per migliorare lo sviluppo
- Aggiunta strumenti di debug
- Aggiunto modulo Listini clienti
- Aggiunta gestione prezzo minimo e visulizzazione listini in fase di aggiunta riga
- Aggiunti modelli di prima nota per pagamento di salari e stipendi
- Aggiunta eliminazione massiva destinatari lista newsletter
- Aggiunta campi provvigione su righe promemoria
- Aggiunta fatturazione rate contratto con azione di gruppo da widget in dashboard
- Aggiunto avviso gruppo o username già in uso in fase di creazione/modifica
- Aggiunto colore per livello di permesso impostato
- Aggiunta gestione permessi segmenti e numerazione documenti
- Aggiunto controllo file di servizio
- Aggiunta email tecnici assegnati nel template Notifica intervento
- Aggiunta azione di gruppo invio mail da Attività
- Aggiunte opzioni per connessione al Database
- Aggiunto controllo plugin duplicati per i moduli
- Aggiunto controllo per Anagrafiche con codici REA non validi
### Modificato(Changed)
- Miglioria gestione prezzi
- Ottimizzate query viste per aumentare la velocità di caricamento dei moduli principali
- Miglioria ricerca di corrispondenza tra anagrafiche in fase di impostazione dei permessi
- Sostituita funzione deprecata formatLocalized con isoFormat
- Rimozione codice non raggiungibile
### Fixed
- Corretta la selezione dei colori
- Corretta la visualizzazione delle colonne datatables
- Corretta variabile referenti in template DDT
- Corretta creazione del file manifest.json
- Corretta l'importazione delle fatture con importi negativi
- Corretta eliminazione di articoli da azioni di gruppo
- Corretta visualizzazione utente collegato ad anagrafica
- Corretto login tramite API
- Corretta query vista Piani di scondo/maggiorazione
- Corretta validazione username
- Corretta importazione csv Anagrafiche con PHP8.0
- Corretto messaggio di contenuto modificato all'uscita dalla pagina di impostazione dei permessi
- Corretta descrizione periodi in pianificazione fatturazione contratti
- Corretti avvisi settore merceologico e provenienza già presenti
- Corretti id pulsanti in rowlist
- Corretta icona bandiera select2
- Corretta verifica prezzo minimo di vendita
- Corretta notifica inserimento fattura
- Corretto redirect da fatturazione rate contratto a Fatture di vendita
- Corretta visualizzazione rate da fatturare
- Corretta visualizzazione query viste
- Corretto calcolo prezzo di vendita da cambio coefficiente da azione di gruppo
- Corretta query elenco di scadenze scadute per cliente in nuova fattura di vendita
- Corretta logica riapertura fattura pagata
- Corretta valorizzazione codice REA in fase di importazione fattura elettronica
- Corretta creazione fattura da azioni di gruppo in Attività se valorizzato 'Per conto di'
## 2.4.37 (2022-11-04)
### Aggiunto (Added)
- Aggiunto modulo Mappa per geolocalizzare le attività

View File

@ -23,6 +23,10 @@ $db_username = '|username|';
$db_password = '|password|';
$db_name = '|database|';
//$port = '|port|';
$db_options = [
//'sort_buffer_size' => '4M',
];
// Percorso della cartella di backup
$backup_dir = __DIR__.'/backup/';

View File

@ -182,29 +182,93 @@ if ($database->isInstalled()){
$db = [
'mysql_version' => [
'type' => 'mysql',
'type' => 'version',
'description' => '5.7.x - 8.0.x',
'minimum' => '5.7.0',
'maximum' => '8.0.99',
],
'sort_buffer_size' => [
'type' => 'value',
'description' => '>4M',
],
];
/*foreach (App::getConfig()['db_options'] as $n => $v){
switch ($n){
case 'sort_buffer_size':
$db[$n] = [
'type' => 'value',
'description' => '>4M',
];
break;
}
}*/
}
foreach ($db as $name => $values) {
$description = $values['description'];
$description = tr('Valore consigliato: _VALUE_ (Valore attuale: _MYSQL_VERSION_)', [
'_VALUE_' => $description,
'_MYSQL_VERSION_' => $database->getMySQLVersion(),
]);
$status = ((version_compare($database->getMySQLVersion(), $values['minimum'], ">=") && version_compare($database->getMySQLVersion(), $values['maximum'], "<=")) ? 1 : 0);
$description = $values['description'];
if ($values['type'] == 'version') {
$type = tr('Versione');
$description = tr('Valore consigliato: _VALUE_ (Valore attuale: _MYSQL_VERSION_)', [
'_VALUE_' => $description,
'_MYSQL_VERSION_' => $database->getMySQLVersion(),
]);
$status = ((version_compare($database->getMySQLVersion(), $values['minimum'], ">=") && version_compare($database->getMySQLVersion(), $values['maximum'], "<=")) ? 1 : 0);
} else{
$type = tr('Impostazione');
//Vedo se riesco a recuperare l'impostazione dalle variabili di sessione o globali di mysql
$rs_session_variabile = $dbo->fetchArray('SHOW SESSION VARIABLES LIKE '.prepare($name));
$rs_global_variabile = $dbo->fetchArray('SHOW GLOBAL VARIABLES LIKE '.prepare($name));
if (!empty($rs_session_variabile[0]['Value']))
$inc = \Util\FileSystem::formatBytes($rs_session_variabile[0]['Value']);
else if (!empty($rs_global_variabile[0]['Value']))
$inc = \Util\FileSystem::formatBytes($rs_global_variabile[0]['Value']);
else
$inc = str_replace(['k', 'M'], ['000', '000000'], App::getConfig()['db_options'][$name]);
$real = str_replace(['k', 'M'], ['000', '000000'], $description);
if (string_starts_with($real, '>')) {
$status = $inc >= substr($real, 1);
} elseif (string_starts_with($real, '<')) {
$status = $inc <= substr($real, 1);
} else {
$status = ($real == $inc);
}
if (is_bool($description)) {
$description = !empty($description) ? 'On' : 'Off';
} else {
$description = str_replace(['>', '<'], '', $description);
}
$description = tr('Valore consigliato: _VALUE_ (Valore attuale: _INC_)', [
'_VALUE_' => $description,
'_INC_' => $inc,
]);
}
$mysql[] = [
'name' => $name,
'description' => $description,
'status' => $status,
'type' => tr('Versione'),
'type' => $type,
];
}
@ -232,7 +296,7 @@ foreach ($dirs_to_check as $name => $description) {
// File di servizio
$files_to_check = [
'manifest.json' => tr('Necessario per aggiunta a schermata home da terminale'),
'manifest.json' => tr('Necessario per l\'aggiunta a schermata home da terminale'),
'database_5_7.json' => tr('Necessario per il controllo integrità con database MySQL 5.7.x'),
'database.json' => tr('Necessario per il controllo integrità con database MySQL 8.0.x'),
'checksum.json' => tr('Necessario per il controllo integrità dei files del gestionale'),

View File

@ -21,6 +21,8 @@ include_once __DIR__.'/../../core.php';
use Models\Cache;
use Modules\Aggiornamenti\Controlli\ColonneDuplicateViste;
use Modules\Aggiornamenti\Controlli\ReaValidi;
use Modules\Aggiornamenti\Controlli\PluginDuplicati;
use Modules\Aggiornamenti\Controlli\Controllo;
use Modules\Aggiornamenti\Controlli\DatiFattureElettroniche;
use Modules\Aggiornamenti\Controlli\PianoConti;
@ -57,6 +59,8 @@ switch (filter('op')) {
PianoConti::class,
DatiFattureElettroniche::class,
ColonneDuplicateViste::class,
PluginDuplicati::class,
ReaValidi::class,
];
$results = [];

View File

@ -84,7 +84,7 @@ class PianoConti extends Controllo
if (!empty($descrizione)) {
$this->addResult([
'id' => $anagrafica['id'],
'nome' => $anagrafica['ragione_sociale'],
'nome' => \Modules::link('Anagrafiche', $anagrafica['id'], $anagrafica['ragione_sociale']),
'descrizione' => $descrizione,
]);
}

View File

@ -0,0 +1,58 @@
<?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/>.
*/
namespace Modules\Aggiornamenti\Controlli;
use Models\Module;
class PluginDuplicati extends Controllo
{
public function getName()
{
return tr('Plugin duplicati per i Moduli');
}
public function getType($record)
{
return 'warning';
}
public function check()
{
$duplicati = database()->fetchArray('SELECT `idmodule_to`, `name` FROM `zz_plugins` GROUP BY `idmodule_to`, `name` HAVING COUNT(`name`) > 1');
foreach ($duplicati as $plugin) {
$modulo = Module::pool($plugin['idmodule_to']);
$this->addResult([
'id' => $plugin['name'],
'nome' => $modulo->title.': '.$plugin['name'],
'descrizione' => tr('Il plugin _NAME_ del modulo _MODULE_ esiste più volte', [
'_NAME_' => $plugin['name'],
'_MODULE_' => $modulo->title,
]),
]);
}
}
public function execute($record, $params = [])
{
return false;
}
}

View File

@ -0,0 +1,83 @@
<?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/>.
*/
namespace Modules\Aggiornamenti\Controlli;
use Modules\Anagrafiche\Anagrafica;
class ReaValidi extends Controllo
{
public function getName()
{
return tr('Anagrafiche con codici REA non validi');
}
public function getType($record)
{
return 'warning';
}
public function getOptions($record)
{
return [];
}
public function check()
{
$database = database();
/**
* Verifico se i rea inseriti per le anagrafiche hanno una struttura valida.
*/
$anagrafiche_interessate = $database->fetchArray('SELECT
an_anagrafiche.idanagrafica AS id,
an_anagrafiche.codicerea,
an_anagrafiche.ragione_sociale,
GROUP_CONCAT(an_tipianagrafiche.descrizione) AS tipi_anagrafica
FROM an_anagrafiche
INNER JOIN an_tipianagrafiche_anagrafiche ON an_tipianagrafiche_anagrafiche.idanagrafica = an_anagrafiche.idanagrafica
INNER JOIN an_tipianagrafiche ON an_tipianagrafiche.idtipoanagrafica = an_tipianagrafiche_anagrafiche.idtipoanagrafica
WHERE
codicerea NOT REGEXP "^..-......$" AND codicerea != ""
AND
deleted_at IS NULL
GROUP BY an_anagrafiche.idanagrafica');
foreach ($anagrafiche_interessate as $anagrafica) {
/*$tipi = explode(',', $anagrafica['tipi_anagrafica']);
$cliente = in_array('Cliente', $tipi) && empty($anagrafica['idconto_cliente']);
$fornitore = in_array('Fornitore', $tipi) && empty($anagrafica['idconto_fornitore']);*/
$this->addResult([
'id' => $anagrafica['id'],
'nome' => \Modules::link('Anagrafiche', $anagrafica['id'], $anagrafica['ragione_sociale']),
'descrizione' => tr('Il codice REA "_REA_" non è valido', [
'_REA_' => $anagrafica['codicerea'],
]),
]);
}
}
public function execute($record, $params = [])
{
return false;
}
}

View File

@ -97,7 +97,14 @@ switch (post('op')) {
// Lettura righe selezionate
foreach ($interventi as $intervento) {
$id_anagrafica = $intervento['idanagrafica'];
if (!empty($intervento['idclientefinale'])){
$id_anagrafica = $intervento['idclientefinale'];
}
else {
$id_anagrafica = $intervento['idanagrafica'];
}
$id_documento = $id_documento_cliente[$id_anagrafica];
$anagrafica = Anagrafica::find($id_anagrafica);

View File

@ -85,7 +85,7 @@ echo '
</div>';
//gestione replace
$descrizione = get_var('Descrizione fattura pianificata');
$descrizione = setting('Descrizione fattura pianificata');
$modules = MODULES::get('Contratti')['id'];
$variables = include Modules::filepath($modules, 'variables.php');
foreach ($variables as $variable => $value) {

View File

@ -36,7 +36,7 @@ class Interventi extends AppResource
$today = new Carbon();
$mesi_precedenti = intval(setting('Mesi per lo storico delle Attività'));
$start = $today->copy()->subMonths($mesi_precedenti);
$end = $today->copy()->addMonth(1);
$end = $today->copy()->addMonth();
return [
'today' => $today,

View File

@ -38,7 +38,7 @@ class RigheInterventi extends AppResource
// Periodo per selezionare interventi
$today = new Carbon();
$start = $today->copy()->subMonths(2);
$end = $today->copy()->addMonth(1);
$end = $today->copy()->addMonth();
// Informazioni sull'utente
$user = Auth::user();
@ -72,7 +72,7 @@ class RigheInterventi extends AppResource
// Periodo per selezionare interventi
$today = new Carbon();
$start = $today->copy()->subMonths(2);
$end = $today->copy()->addMonth(1);
$end = $today->copy()->addMonth();
// Informazioni sull'utente
$user = Auth::user();

View File

@ -34,7 +34,7 @@ class SessioniInterventi extends AppResource
$mesi_precedenti = intval(setting('Mesi per lo storico delle Attività'));
$today = new Carbon();
$start = $today->copy()->subMonths($mesi_precedenti);
$end = $today->copy()->addMonth(1);
$end = $today->copy()->addMonth();
// Informazioni sull'utente
$user = Auth::user();
@ -73,7 +73,7 @@ class SessioniInterventi extends AppResource
$mesi_precedenti = intval(setting('Mesi per lo storico delle Attività'));
$today = new Carbon();
$start = $today->copy()->subMonths($mesi_precedenti);
$end = $today->copy()->addMonth(1);
$end = $today->copy()->addMonth();
// Informazioni sull'utente
$user = Auth::user();

View File

@ -80,9 +80,11 @@ class Database extends Util\Singleton
'database' => $database_name,
'username' => $username,
'password' => $password,
'charset' => 'utf8',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_general_ci',
'prefix' => '',
'port' => $port,
'options' => App::getConfig()['db_options'],
]);
$this->is_connected = !empty($this->getPDO());

View File

@ -116,8 +116,9 @@ class Zip
*/
public static function check($path)
{
$errno = zip_open($path);
zip_close($errno);
$zip = new ZipArchive;
$errno = $zip->open($path);
$errno = $zip->close();
if (!is_resource($errno)) {
// using constant name as a string to make this function PHP4 compatible

View File

@ -28,11 +28,11 @@ $anno_precedente_end = (new Carbon($date_end))->subYears(1)->format('Y-m-d');
$periodo = $dbo->fetchOne('SELECT valore FROM zz_settings WHERE nome="Liquidazione iva"');
if ($periodo['valore'] == 'Mensile') {
$periodo_precedente_start = (new Carbon($date_start))->subMonth(1)->format('Y-m-d');
$periodo_precedente_end = (new Carbon($date_end))->subMonth(1)->format('Y-m-d');
$periodo_precedente_start = (new Carbon($date_start))->subMonth()->format('Y-m-d');
$periodo_precedente_end = (new Carbon($date_end))->subMonth()->format('Y-m-d');
} else {
$periodo_precedente_start = (new Carbon($date_start))->subMonth(3)->format('Y-m-d');
$periodo_precedente_end = (new Carbon($date_end))->subMonth(3)->format('Y-m-d');
$periodo_precedente_start = (new Carbon($date_start))->subMonths(3)->format('Y-m-d');
$periodo_precedente_end = (new Carbon($date_end))->subMonths(3)->format('Y-m-d');
}
$maggiorazione = 0;

View File

@ -441,48 +441,9 @@ LEFT JOIN `co_ritenuta_contributi` ON `co_documenti`.`id_ritenuta_contributi` =
LEFT JOIN `co_pagamenti` ON `co_documenti`.`idpagamento` = `co_pagamenti`.`id`
LEFT JOIN (SELECT co_banche.id, CONCAT(`nome`, ' - ', `iban`) AS descrizione FROM `co_banche`) AS banche ON `banche`.`id` = `co_documenti`.`id_banca_azienda`
LEFT JOIN (SELECT iddocumento, CONCAT(co_pianodeiconti3.descrizione) AS descrizione FROM co_righe_documenti INNER JOIN co_pianodeiconti3 ON co_pianodeiconti3.id = co_righe_documenti.idconto) AS conti ON conti.iddocumento = co_documenti.id
LEFT JOIN(
SELECT `iddocumento`,
SUM(`subtotale` - `sconto`) AS `totale_imponibile`,
SUM(`iva`) AS `iva`
FROM
`co_righe_documenti`
GROUP BY
`iddocumento`
) AS righe
ON
`co_documenti`.`id` = `righe`.`iddocumento`
LEFT JOIN(
SELECT COUNT(`d`.`id`) AS `conteggio`,
IF(
`d`.`numero_esterno` = '',
`d`.`numero`,
`d`.`numero_esterno`
) AS `numero_documento`,
`d`.`idanagrafica` AS `anagrafica`,
`id_segment`
FROM
`co_documenti` AS `d`
LEFT JOIN `co_tipidocumento` AS `d_tipo`
ON
`d`.`idtipodocumento` = `d_tipo`.`id`
WHERE
1 = 1 AND `d_tipo`.`dir` = 'uscita' AND(
'|period_start|' <= `d`.`data` AND '|period_end|' >= `d`.`data` OR '|period_start|' <= `d`.`data_competenza` AND '|period_end|' >= `d`.`data_competenza`
)
GROUP BY
`id_segment`,
`numero_documento`,
`d`.`idanagrafica`
) AS `d`
ON
(
`d`.`numero_documento` = IF(
`co_documenti`.`numero_esterno` = '',
`co_documenti`.`numero`,
`co_documenti`.`numero_esterno`
) AND `d`.`anagrafica` = `co_documenti`.`idanagrafica` AND `d`.`id_segment` = `co_documenti`.`id_segment`
)
LEFT JOIN (SELECT `iddocumento`, SUM(`subtotale` - `sconto`) AS `totale_imponibile`, SUM(`iva`) AS `iva` FROM `co_righe_documenti` GROUP BY `iddocumento`) AS righe ON `co_documenti`.`id` = `righe`.`iddocumento`
LEFT JOIN (SELECT COUNT(`d`.`id`) AS `conteggio`, IF(`d`.`numero_esterno` = '', `d`.`numero`, `d`.`numero_esterno`) AS `numero_documento`, `d`.`idanagrafica` AS `anagrafica`, `id_segment` FROM `co_documenti` AS `d`
LEFT JOIN `co_tipidocumento` AS `d_tipo` ON `d`.`idtipodocumento` = `d_tipo`.`id` WHERE 1=1 AND `d_tipo`.`dir` = 'uscita' AND('|period_start|' <= `d`.`data` AND '|period_end|' >= `d`.`data` OR '|period_start|' <= `d`.`data_competenza` AND '|period_end|' >= `d`.`data_competenza`) GROUP BY `id_segment`, `numero_documento`, `d`.`idanagrafica`) AS `d` ON (`d`.`numero_documento` = IF(`co_documenti`.`numero_esterno` = '',`co_documenti`.`numero`,`co_documenti`.`numero_esterno`) AND `d`.`anagrafica` = `co_documenti`.`idanagrafica` AND `d`.`id_segment` = `co_documenti`.`id_segment`)
WHERE
1=1
AND