From 12cd1a199117639063b1a2a107760a07e3959a1b Mon Sep 17 00:00:00 2001
From: Dasc3er <dasc3er@users.noreply.github.com>
Date: Fri, 16 Oct 2020 21:35:19 +0200
Subject: [PATCH] Miglioramento del modulo Impostazioni

Introduzione di una struttura dinamica per il modulo Impostazioni, con ricerca locale specializzata su Sezioni e su singole impostazioni.
---
 assets/src/js/base/custom.js     |   2 +-
 modules/impostazioni/actions.php |  40 +++++++++
 modules/impostazioni/edit.php    | 140 ++++++++++++++++++++++++++-----
 modules/impostazioni/init.php    |   4 -
 modules/impostazioni/sezione.php |  39 +++++++++
 src/Settings.php                 |   2 +-
 update/2_4_18.sql                |   3 +
 7 files changed, 202 insertions(+), 28 deletions(-)
 create mode 100644 modules/impostazioni/sezione.php

diff --git a/assets/src/js/base/custom.js b/assets/src/js/base/custom.js
index b1d4af3c7..f50e29026 100644
--- a/assets/src/js/base/custom.js
+++ b/assets/src/js/base/custom.js
@@ -40,7 +40,7 @@ $(document).ready(function () {
         "newestOnTop": false,
         "progressBar": true,
         "positionClass": "toast-top-right",
-        "preventDuplicates": true,
+        //"preventDuplicates": true,
         "onclick": null,
         "showDuration": "300",
         "hideDuration": "1000",
diff --git a/modules/impostazioni/actions.php b/modules/impostazioni/actions.php
index 09198b68d..27d484dc7 100755
--- a/modules/impostazioni/actions.php
+++ b/modules/impostazioni/actions.php
@@ -17,9 +17,49 @@
  * along with this program. If not, see <https://www.gnu.org/licenses/>.
  */
 
+use Models\Setting;
+
 include_once __DIR__.'/../../core.php';
 
 switch (filter('op')) {
+    case 'salva':
+        $id = filter('id');
+        $valore = filter('valore');
+
+        $impostazione = Setting::find($id);
+        if (!$impostazione->editable) {
+            echo json_encode([
+                'result' => true,
+            ]);
+
+            return;
+        }
+
+        $result = Settings::setValue($impostazione->id, $valore);
+        echo json_encode([
+            'result' => $result,
+        ]);
+
+        if ($result) {
+            flash()->info('Impostazione modificata con successo!');
+        } else {
+            flash()->error('Errore durante il salvataggio!');
+        }
+
+        break;
+
+    case 'ricerca':
+        $search = filter('search');
+        $sezioni = Setting::select('sezione')
+            ->where('sezione', 'like', '%'.$search.'%')
+            ->orWhere('nome', 'like', '%'.$search.'%')
+            ->groupBy(['sezione'])
+            ->get()->pluck('sezione');
+
+        echo json_encode($sezioni);
+
+        break;
+
     case 'update':
         $is_all_valid = true;
 
diff --git a/modules/impostazioni/edit.php b/modules/impostazioni/edit.php
index e1ddc3808..fb5034f05 100755
--- a/modules/impostazioni/edit.php
+++ b/modules/impostazioni/edit.php
@@ -17,36 +17,132 @@
  * along with this program. If not, see <https://www.gnu.org/licenses/>.
  */
 
+use Models\Setting;
+
 include_once __DIR__.'/../../core.php';
 
+$gruppi = Setting::selectRaw('sezione AS nome, COUNT(id) AS numero')
+    ->groupBy(['sezione'])
+    ->orderBy('sezione')
+    ->get();
+
 echo '
-<form action="" method="post" id="edit-form">
-	<input type="hidden" name="backto" value="record-edit">
-	<input type="hidden" name="op" value="update">
+<div class="row">
+    <div class="col-md-6 col-md-offset-3">
+        <div class="input-group">
+            <input type="text" class="form-control" placeholder="'.tr('Ricerca rapida').'" id="ricerca_impostazioni"/>
+            <div class="input-group-btn">
+                <button class="btn btn-primary" type="button">
+                    <span class="fa fa-search"></span>
+                </button>
+            </div>
+        </div>
+    </div>
 
-	<!-- DATI -->
-	<div class="panel panel-primary">
-		<div class="panel-heading">
-            <h3 class="panel-title">'.tr('Impostazioni _SEZIONE_', [
-                '_SEZIONE_' => $record['sezione'],
-            ]).'</h3>
-		</div>
+    <div class="col-md-3">
+        <button class="btn btn-warning hidden" type="button" id="riprova_salvataggi" onclick="riprovaSalvataggio()">
+            <span class="fa fa-save"></span> '.tr('Riprova salvataggi falliti').'
+        </button>
+    </div>
+</div>
 
-		<div class="panel-body">';
+<br><hr>';
 
-foreach ($records as $record) {
+foreach ($gruppi as $key => $gruppo) {
     echo '
-            <div class="col-md-6">
-                '.Settings::input($record['id']).'
-            </div>';
+<!-- Impostazioni della singola sezione -->
+<div class="box box-primary collapsed-box" title="'.$gruppo['nome'].'">
+    <div class="box-header clickable" id="impostazioni-'.$key.'">
+        <div class="box-title">'.tr('Impostazioni _SEZIONE_', [
+            '_SEZIONE_' => $gruppo['nome'],
+        ]).'</div>
+        <div class="box-tools pull-right">
+            <div class="badge">'.$gruppo['numero'].'</div>
+        </div>
+    </div>
+
+    <div class="box-body""></div>
+</div>';
 }
 
 echo '
-			<div class="clearfix"></div><hr>
-            <div class="pull-right">
-				<button type="submit" class="btn btn-success"><i class="fa fa-check"></i> '.tr('Salva modifiche').'</button>
-			</div>
-		</div>
-	</div>
+<script>
+globals.impostazioni = {
+    errors: {},
+};
 
-</form>';
+$("[id^=impostazioni]").click(function() {
+    caricaSezione(this);
+});
+
+$("#ricerca_impostazioni").change(function (){
+    let ricerca = $(this).val();
+    $(".box").removeClass("hidden");
+
+    if (ricerca) {
+        $.get("'.$structure->fileurl('actions.php').'?id_module='.$id_module.'&op=ricerca&search=" + ricerca, function(data) {
+            $(".box").addClass("hidden");
+
+            let sezioni = JSON.parse(data);
+            for(const sezione of sezioni){
+                $(`.box[title="` + sezione + `"]`).removeClass("hidden");
+            }
+        });
+    }
+})
+
+function caricaSezione(header) {
+    let box = $(header).closest(".box");
+    box.toggleClass("collapsed-box");
+
+    // Controllo sul caricamento giĆ  effettuato
+    let container = box.find(".box-body");
+    if (container.html()){
+        return ;
+    }
+
+    // Caricamento della sezione di impostazioni
+    let sezione = box.attr("title");
+    localLoading(container, true);
+    return $.get("'.$structure->fileurl('sezione.php').'?id_module='.$id_module.'&sezione=" + sezione, function(data) {
+        container.html(data);
+        localLoading(container, false);
+    });
+}
+
+function salvaImpostazione(id, valore){
+    $.ajax({
+        url: globals.rootdir + "/actions.php",
+        cache: false,
+        type: "GET",
+        dataType: "JSON",
+        data: {
+            op: "salva",
+            id_module: globals.id_module,
+            id: id,
+            valore: valore,
+        },
+        success: function(data) {
+            renderMessages();
+
+            if(!data.result) {
+                globals.impostazioni.errors[id] = valore;
+                $("#riprova_salvataggi").removeClass("hidden");
+            }
+        },
+        error: function(data) {
+            swal("'.tr('Errore').'", "'.tr('Errore durante il salvataggio dei dati').'", "error");
+        }
+    });
+}
+
+function riprovaSalvataggio() {
+    const impostazioni = JSON.parse(JSON.stringify(globals.impostazioni.errors));;
+    globals.impostazioni.errors = {};
+
+    $("#riprova_salvataggi").addClass("hidden");
+    for ([id, valore] of Object.entries(impostazioni)) {
+        salvaImpostazione(id, valore);
+    }
+}
+</script>';
diff --git a/modules/impostazioni/init.php b/modules/impostazioni/init.php
index ae6c8e6a6..705e57273 100755
--- a/modules/impostazioni/init.php
+++ b/modules/impostazioni/init.php
@@ -18,7 +18,3 @@
  */
 
 include_once __DIR__.'/../../core.php';
-
-if (isset($id_record)) {
-    $records = $dbo->fetchArray('SELECT * FROM `zz_settings` WHERE `sezione` = (SELECT sezione FROM `zz_settings` WHERE `id` = '.prepare($id_record).') ORDER BY `order`');
-}
diff --git a/modules/impostazioni/sezione.php b/modules/impostazioni/sezione.php
new file mode 100644
index 000000000..5cd268875
--- /dev/null
+++ b/modules/impostazioni/sezione.php
@@ -0,0 +1,39 @@
+<?php
+/*
+ * OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
+ * Copyright (C) DevCode s.n.c.
+ *
+ * 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 Models\Setting;
+
+include_once __DIR__.'/../../core.php';
+
+$sezione = filter('sezione');
+$impostazioni = Setting::where('sezione', $sezione)
+    ->get();
+
+foreach ($impostazioni as $impostazione) {
+    echo '
+    <div class="col-md-6">
+        '.Settings::input($impostazione['id']).'
+    </div>
+
+    <script>
+    input("setting['.$impostazione->id.']").change(function (){
+        salvaImpostazione('.$impostazione->id.', input(this).get());
+    });
+    </script>';
+}
diff --git a/src/Settings.php b/src/Settings.php
index bd135a65a..f00b8a473 100755
--- a/src/Settings.php
+++ b/src/Settings.php
@@ -142,7 +142,7 @@ class Settings
             return true;
         }
 
-        return  false;
+        return false;
     }
 
     /**
diff --git a/update/2_4_18.sql b/update/2_4_18.sql
index c777f8745..03f7ed750 100644
--- a/update/2_4_18.sql
+++ b/update/2_4_18.sql
@@ -317,3 +317,6 @@ INSERT INTO `zz_settings` (`id`, `nome`, `valore`, `tipo`, `editable`, `sezione`
 UPDATE `dt_ddt` SET `idcausalet` = (SELECT `id` FROM `dt_causalet` WHERE `predefined` = 1 LIMIT 1) WHERE EXISTS(SELECT `id` FROM `dt_causalet` WHERE `predefined` = 1) AND (idcausalet = 0 OR idcausalet IS NULL);
 UPDATE `dt_ddt` SET `idcausalet` = (SELECT `id` FROM `dt_causalet` WHERE `descrizione` = 'Vendita' LIMIT 1) WHERE EXISTS(SELECT `id` FROM `dt_causalet` WHERE `descrizione` = 'Vendita') AND (idcausalet = 0 OR idcausalet IS NULL);
 UPDATE `dt_ddt` SET `idcausalet` = (SELECT `id` FROM `dt_causalet`) WHERE EXISTS(SELECT `id` FROM `dt_causalet`) AND (idcausalet = 0 OR idcausalet IS NULL);
+
+-- Aggiornamento del modulo Impostazioni
+UPDATE `zz_modules` SET `options` = 'custom' WHERE `name` = 'Impostazioni';