1
0
mirror of https://github.com/devcode-it/openstamanager.git synced 2025-06-05 22:09:38 +02:00

feat: migliorie gestione allegati

This commit is contained in:
MatteoPistorello
2025-05-14 12:45:31 +02:00
parent 7c40d32d08
commit 2101ad178c
15 changed files with 362 additions and 108 deletions

View File

@@ -123,7 +123,7 @@ if (filter('op') == 'aggiungi-allegato' || filter('op') == 'rimuovi-allegato') {
if (filter('op') == 'aggiungi-allegato' && !empty($_FILES) && !empty($_FILES['file']['name'])) {
$upload = Uploads::upload($_FILES['file'], [
'name' => filter('nome_allegato'),
'category' => filter('categoria'),
'id_category' => filter('id_category') ?: null,
'id_module' => $id_module,
'id_plugin' => $id_plugin,
'id_record' => $id_record,
@@ -223,12 +223,12 @@ elseif (filter('op') == 'modifica-allegato') {
if (sizeof($id_allegati) == 1) {
$upload = Upload::find($id_allegati[0]);
$upload->name = post('nome_allegato');
$upload->category = post('categoria_allegato');
$upload->id_category = post('categoria_allegato') ?: null;
$upload->save();
} else {
foreach ($id_allegati as $id_allegato) {
$upload = Upload::find($id_allegato);
$upload->category = post('categoria_allegato');
$upload->id_category = post('categoria_allegato') ?: null;
$upload->save();
}
}

View File

@@ -21,6 +21,7 @@
include_once __DIR__.'/core.php';
use Models\Hook;
use Modules\CategorieFiles\Categoria;
switch (filter('op')) {
// Imposta un valore ad un array di $_SESSION
@@ -68,7 +69,8 @@ switch (filter('op')) {
break;
case 'list_attachments':
echo '{( "name": "filelist_and_upload", "id_module": "'.$id_module.'", "id_record": "'.$id_record.'", "id_plugin": "'.$id_plugin.'" )}';
$category = get('id_category') ? Categoria::find(get('id_category'))->name : null;
echo '{( "name": "filelist_and_upload", "id_module": "'.$id_module.'", "id_record": "'.$id_record.'", "id_plugin": "'.$id_plugin.'", "category": "'.$category.'" )}';
break;

View File

@@ -48,6 +48,7 @@ function initGestioneAllegati(gestione) {
id_module: gestione.data('id_module'),
id_plugin: gestione.data('id_plugin'),
id_record: gestione.data('id_record'),
id_category: gestione.data('id_category')
}).toString();
let dragdrop = new Dropzone(dropzone_id, {
@@ -96,40 +97,6 @@ function modificaCategoriaAllegati(gestione, pulsanteModifica) {
inputNome.removeClass("hidden");
}
/**
* Funzione per salvare le modifiche effettuate su una categoria di allegati.
* @param gestione
* @param pulsanteSalva
*/
function salvaCategoriaAllegati(gestione, pulsanteSalva) {
const categoria = $(pulsanteSalva).parent().parent();
const nome = categoria.find(".box-title");
const inputNome = categoria.find(".category-name");
mostraCaricamentoAllegati(gestione);
$.ajax({
url: globals.rootdir + "/actions.php",
cache: false,
type: "POST",
data: {
op: "modifica-categoria-allegato",
id_module: gestione.data('id_module'),
id_plugin: gestione.data('id_plugin'),
id_record: gestione.data('id_record'),
category: nome.text(),
name: inputNome.val(),
},
success: function (data) {
ricaricaAllegati(gestione);
},
error: function (gestione) {
ricaricaAllegati(gestione);
}
});
}
/**
* Funzione per caricare un nuovo allegato.
* @param gestione
@@ -176,6 +143,7 @@ function ricaricaAllegati(gestione) {
id_module: gestione.data('id_module'),
id_plugin: gestione.data('id_plugin'),
id_record: gestione.data('id_record'),
id_category: gestione.data('id_category')
}).toString();
$(id).load(globals.rootdir + "/ajax.php?" + params, function () {
@@ -295,34 +263,3 @@ function rimuoviAllegato(button) {
});
}).catch(swal.noop);
}
function impostaCategorieAllegatiDisponibili(gestione, categorie) {
// Disabilitazione per rimozione input in aggiunta
return;
const id = "#" + gestione.attr('id');
const input = $("#modifica-allegato #categoria_allegato")[0];
autocomplete({
minLength: 0,
input: input,
emptyMsg: globals.translations.noResults,
fetch: function (text, update) {
text = text.toLowerCase();
const suggestions = categorie.filter(n => n.toLowerCase().startsWith(text));
// Trasformazione risultati in formato leggibile
const results = suggestions.map(function (result) {
return {
label: result,
value: result
}
});
update(results);
},
onSelect: function (item) {
input.value = item.label;
},
});
}

View File

@@ -115,6 +115,7 @@
"Modules\\Partitario\\": ["modules/partitario/custom/src/", "modules/partitario/src/"],
"Modules\\StatoEmail\\": ["modules/stato_email/custom/src/", "modules/stato_email/src/"],
"Modules\\FileAdapters\\": ["modules/adattatori_archiviazione/custom/src/", "modules/adattatori_archiviazione/src/"],
"Modules\\CategorieFiles\\": ["modules/categorie_files/custom/src/", "modules/categorie_files/src/"],
"Plugins\\AssicurazioneCrediti\\": ["plugins/assicurazione_crediti/custom/src/", "plugins/assicurazione_crediti/src/"],
"Plugins\\ExportFE\\": ["plugins/exportFE/custom/src/", "plugins/exportFE/src/"],
"Plugins\\ImportFE\\": ["plugins/importFE/custom/src/", "plugins/importFE/src/"],

View File

@@ -18,6 +18,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use Models\Module;
use Models\Upload;
$id_allegati = (array) json_decode(filter('id_allegati'));
@@ -37,13 +38,13 @@ if (sizeof($id_allegati) == 1) {
{[ "type": "text", "label": "'.tr('Nome').'", "name": "nome_allegato", "value": "'.$allegato->name.'" ]}
</div>
<div class="col-md-6">
{[ "type": "text", "label": "'.tr('Categoria').'", "name": "categoria_allegato", "value": "'.$allegato->category.'", "disabled": "'.intval(in_array($allegato->category, ['Fattura Elettronica'])).'" ]}
{[ "type": "select", "label": "'.tr('Categoria').'", "name": "categoria_allegato", "ajax-source": "categorie-files", "value": "'.$allegato->id_category.'", "disabled": "'.intval(in_array($allegato->categoria->name, ['Fattura Elettronica'])).'", "icon-after": "add|'.Module::where('name', 'Categorie file')->first()->id.'" ]}
</div>';
} else {
$allegato = Upload::find($id_allegati[0]);
echo '
<div class="col-md-6">
{[ "type": "text", "label": "'.tr('Categoria').'", "name": "categoria_allegato", "value": "" ]}
{[ "type": "select", "label": "'.tr('Categoria').'", "name": "categoria_allegato", "ajax-source": "categorie-files", "value": "", "icon-after": "add|'.Module::where('name', 'Categorie file')->first()->id.'" ]}
</div>';
}
echo '

View File

@@ -0,0 +1,72 @@
<?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 Modules\CategorieFiles\Categoria;
switch (post('op')) {
case 'update':
$name = post('name');
$categoria_new = Categoria::where('name', '=', $name)->where('deleted_at', '=', null)->where('id','!=', $id_record)->first();
if (!empty($categoria_new)) {
flash()->error(tr('Categoria _NAME_ già esistente!', [
'_NAME_' => $name,
]));
} else {
$categoria->name = $name;
$categoria->save();
flash()->info(tr('Informazioni salvate correttamente!'));
}
break;
case 'add':
$name = post('name');
$categoria_new = Categoria::where('name', '=', $name)->where('deleted_at', '=', null)->first();
if (!empty($categoria_new)) {
flash()->error(tr('Categoria _NAME_ già esistente!', [
'_NAME_' => $name,
]));
} else {
$categoria = Categoria::build();
$categoria->name = $name;
$id_record = $dbo->lastInsertedID();
$categoria->save();
if (isAjaxRequest()) {
echo json_encode(['id' => $id_record, 'text' => $name]);
}
flash()->info(tr('Nuova categoria file aggiunta!'));
}
break;
case 'delete':
$dbo->query('UPDATE `zz_files_categories` SET `deleted_at` = NOW() WHERE `id` = '.prepare($id_record));
flash()->info(tr('Categoria eliminata!'));
break;
}

View File

@@ -0,0 +1,39 @@
<?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';
?><form action="" method="post" id="add-form">
<input type="hidden" name="op" value="add">
<input type="hidden" name="backto" value="record-edit">
<div class="row">
<div class="col-md-12">
{[ "type": "text", "label": "<?php echo tr('Descrizione'); ?>", "name": "name", "required": 1, "value": "", "extra": "" ]}
</div>
</div>
<!-- PULSANTI -->
<div class="modal-footer">
<div class="col-md-12 text-right">
<button type="submit" class="btn btn-primary"><i class="fa fa-plus"></i> <?php echo tr('Aggiungi'); ?></button>
</div>
</div>
</form>

View File

@@ -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';
switch ($resource) {
case 'categorie-files':
$query = 'SELECT `zz_files_categories`.`id`, `zz_files_categories`.`name` as descrizione FROM `zz_files_categories` ORDER BY `name` ASC';
foreach ($elements as $element) {
$filter[] = '`zz_files_categories`.`id`='.prepare($element);
}
if (empty($filter)) {
$where[] = '`deleted_at` IS NULL';
}
if (!empty($search)) {
$search_fields[] = '`zz_files_categories`.`name` LIKE '.prepare('%'.$search.'%');
}
break;
}

View File

@@ -0,0 +1,46 @@
<?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';
?><form action="" method="post" id="edit-form">
<input type="hidden" name="backto" value="record-edit">
<input type="hidden" name="op" value="update">
<div class="card card-primary">
<div class="card-header">
<h3 class="card-title"><?php echo tr('Dati'); ?></h3>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
{[ "type": "text", "label": "<?php echo tr('Descrizione'); ?>", "name": "name", "required": 1, "value": "$name$" ]}
</div>
</div>
</div>
</div>
</form>
<?php
echo '
<a class="btn btn-danger ask" data-backto="record-list">
<i class="fa fa-trash"></i> '.tr('Elimina').'
</a>';

View File

@@ -0,0 +1,36 @@
<?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 Modules\CategorieFiles\Categoria;
if (!empty($id_record)) {
$categoria = Categoria::find($id_record);
$record = $dbo->fetchOne('SELECT *,
(SELECT COUNT(`id`) FROM `zz_files` WHERE `id_category` = '.prepare($id_record).') AS doc_associati
FROM
`zz_files_categories`
WHERE
`zz_files_categories`.`id`='.prepare($id_record).'
GROUP BY
`zz_files_categories`.`id`');
}

View File

@@ -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/>.
*/
namespace Modules\CategorieFiles;
use Common\SimpleModelTrait;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Traits\RecordTrait;
class Categoria extends Model
{
use SimpleModelTrait;
use SoftDeletes;
use RecordTrait;
protected $table = 'zz_files_categories';
public static function build()
{
$model = new static();
$model->save();
return $model;
}
public function getModuleAttribute()
{
return 'Categorie file';
}
}

View File

@@ -21,6 +21,7 @@
namespace HTMLBuilder\Manager;
use Models\Upload;
use Modules\CategorieFiles\Categoria;
use Util\FileSystem;
/**
@@ -45,8 +46,10 @@ class FileManager implements ManagerInterface
$options['id_plugin'] = !empty($options['id_plugin']) ? $options['id_plugin'] : null;
$id_categoria = $options['category'] ? Categoria::where('name', $options['category'])->first()->id : null;
// ID del form
$attachment_id = 'attachments_'.$options['id_module'].'_'.$options['id_plugin'];
$attachment_id = 'attachments_'.$options['id_module'].'_'.$options['id_plugin'].($id_categoria ? '_'.$id_categoria : '');
if (ini_get('upload_max_filesize') < ini_get('post_max_size')) {
$upload_max_filesize = ini_get('upload_max_filesize');
@@ -62,7 +65,7 @@ class FileManager implements ManagerInterface
// Codice HTML
$result = '
<div class="gestione-allegati" id="'.$attachment_id.'" data-id_module="'.$options['id_module'].'" data-id_plugin="'.$options['id_plugin'].'" data-id_record="'.$options['id_record'].'" data-max_filesize="'.$upload_max_filesize.'">';
<div class="gestione-allegati" id="'.$attachment_id.'" data-id_module="'.$options['id_module'].'" data-id_plugin="'.$options['id_plugin'].'" data-id_record="'.$options['id_record'].'" data-max_filesize="'.$upload_max_filesize.'" data-id_category="'.$id_categoria.'">';
if (!empty($options['showcard'])) {
$result .= '
@@ -75,20 +78,28 @@ class FileManager implements ManagerInterface
$count = 0;
$where = '`id_module` '.(!empty($options['id_module']) && empty($options['id_plugin']) ? '= '.prepare($options['id_module']) : 'IS NULL').' AND `id_plugin` '.(!empty($options['id_plugin']) ? '= '.prepare($options['id_plugin']) : 'IS NULL').'';
$where = '`id_module` '.(!empty($options['id_module']) && empty($options['id_plugin']) ? '= '.prepare($options['id_module']) : 'IS NULL').' AND `id_plugin` '.(!empty($options['id_plugin']) ? '= '.prepare($options['id_plugin']) : 'IS NULL');
// Limitare alle categorie specificate
if (!empty($id_categoria)) {
$where .= ' AND `id_category` = '.prepare($id_categoria);
}
// Categorie
$categories = $dbo->fetchArray('SELECT DISTINCT(BINARY `category`) AS `category` FROM `zz_files` WHERE '.$where.' ORDER BY `category`');
$categories = $dbo->fetchArray('SELECT DISTINCT(BINARY `id_category`) AS `id_category` FROM `zz_files` LEFT JOIN `zz_files_categories` ON `zz_files`.`id_category` = `zz_files_categories`.`id` WHERE '.$where.' ORDER BY `zz_files_categories`.`name`');
$categories = array_column($categories, 'id_category');
foreach ($categories as $category) {
$category = $category['category'];
$categoria = $category ? Categoria::find($category)->name : 'Generale';
$rs = $dbo->fetchArray('SELECT * FROM `zz_files` WHERE BINARY `category`'.(!empty($category) ? '= '.prepare($category) : 'IS NULL').' AND `id_record` = '.prepare($options['id_record']).' AND '.$where);
$rs = $dbo->fetchArray('SELECT `zz_files`.* FROM `zz_files` WHERE BINARY `id_category`'.(!empty($category) ? '= '.prepare($category) : 'IS NULL').' AND `id_record` = '.prepare($options['id_record']).' AND '.$where);
if (!empty($rs)) {
$result .= '
<div class="card card-info">
<div class="card-header with-border">
<h3 class="card-title">'.(!empty($category) ? $category : tr('Generale')).'</h3>
<h3 class="card-title">'.tr('_CATEGORY_', [
'_CATEGORY_' => $categoria
]).' <span class="badge">'.count($rs).'</span></h3>
<div class="card-tools pull-right">
<button type="button" class="btn btn-tool" data-card-widget="collapse">
@@ -102,8 +113,8 @@ class FileManager implements ManagerInterface
<tr>
<th scope="col" width="5%" class="text-center"></th>
<th scope="col" >'.tr('Nome').'</th>
<th scope="col" width="15%" >'.tr('Data').'</th>
<th scope="col" width="10%" class="text-center">#</th>
<th scope="col" class="text-center" width="18%" >'.tr('Data').'</th>
<th scope="col" width="18%" class="text-right"></th>
</tr>
</thead>
<tbody class="files">';
@@ -136,9 +147,9 @@ class FileManager implements ManagerInterface
<small> ('.$file->extension.')'.((!empty($file->size)) ? ' ('.FileSystem::formatBytes($file->size).')' : '').' '.(((setting('Logo stampe') == $file->filename) || (setting('Filigrana stampe') == $file->filename)) ? '<span class="tip" title="'.tr('Logo caricato correttamente').'." >✔️</span>' : '').'</small>'.'
</td>
<td>'.timestampFormat($file['created_at']).'</td>
<td class="text-center">'.timestampFormat($file['created_at']).'</td>
<td class="text-center">
<td class="text-right">
<button type="button" class="btn btn-xs btn-primary" onclick="scaricaAllegato(this)">
<i class="fa fa-download"></i>
</button>';
@@ -233,8 +244,6 @@ class FileManager implements ManagerInterface
</div>';
}
$source = array_clean(array_column($categories, 'category'));
$result .= '
<script>$(document).ready(init)</script>
@@ -243,26 +252,6 @@ $(document).ready(function() {
const container = $("#'.$attachment_id.'");
initGestioneAllegati(container);
impostaCategorieAllegatiDisponibili(container, '.json_encode($source).');
});
// Modifica categoria
$("#'.$attachment_id.' .category-edit").click(function() {
const container = $(this).closest(".gestione-allegati");
modificaCategoriaAllegati(container, this);
});
$("#'.$attachment_id.' .category-save").click(function() {
const container = $(this).closest(".gestione-allegati");
salvaCategoriaAllegati(container, this);
});
$("#'.$attachment_id.' .category-cancel").click(function() {
const container = $(this).closest(".gestione-allegati");
ricaricaAllegati(gestione);
});
// Upload

View File

@@ -22,6 +22,7 @@ namespace Models;
use Common\SimpleModelTrait;
use Illuminate\Database\Eloquent\Model;
use Modules\CategorieFiles\Categoria;
use Modules\FileAdapters\FileAdapter;
use Modules\FileAdapters\OSMFilesystem;
use Intervention\Image\ImageManager;
@@ -89,12 +90,16 @@ class Upload extends Model
$name = $data['name'] ?? ($source['name'] ?? $source);
}
if ($category) {
$id_category = Categoria::where('name', '=', $category)->first()->id;
}
$original_name = $source['name'] ?? $name;
$category = $data['category'] ?? $category;
$id_category = $data['id_category'] ?? $id_category;
// Nome e categoria dell'allegato
$model->name = !empty($name) ? $name : $original_name;
$model->category = $category;
$model->id_category = $id_category;
// Nome di origine dell'allegato
$original_name = !empty($data['original_name']) ? $data['original_name'] : $original_name; // Campo "original_name" variato in modo dinamico
@@ -424,4 +429,9 @@ class Upload extends Model
$img->scale(100, null);
$img->save(slashes($directory.'/'.$info['filename'].'_thumb100.'.$info['extension']));
}
public function categoria()
{
return $this->belongsTo(Categoria::class, 'id_category');
}
}

View File

@@ -137,4 +137,14 @@ foreach ($conti_speciali_livello3 as $conto_livello3) {
echo "Creato conto di terzo livello speciale: ".$conto_livello3." (numero: ".$nuovo_numero.")\n";
}
}
}
}
// Creazione record categorie allegati
$categories = $dbo->fetchArray('SELECT DISTINCT(BINARY `category`) AS `category` FROM `zz_files` ORDER BY `category`');
$categories = array_clean(array_column($categories, 'category'));
foreach ($categories as $categoria) {
$dbo->insert('zz_files_categories', ['name' => $categoria]);
$id = $dbo->lastInsertedId();
$dbo->query('UPDATE `zz_files` SET `id_category` = '.$id.' WHERE `category` = '.prepare($categoria));
}
$dbo->query('ALTER TABLE `zz_files` DROP `category`');

View File

@@ -449,4 +449,27 @@ WHERE
HAVING
2=2
ORDER BY
`co_contratti`.`data_bozza` DESC" WHERE `name` = 'Contratti';
`co_contratti`.`data_bozza` DESC" WHERE `name` = 'Contratti';
-- Nuovo modulo "Categorie file"
INSERT INTO `zz_modules` (`name`, `directory`, `options`, `options2`, `icon`, `version`, `compatibility`, `order`, `parent`, `default`, `enabled`, `use_notes`, `use_checklists`) VALUES ('Categorie file', 'categorie_files', 'SELECT |select| FROM `zz_files_categories` WHERE 1=1 AND `deleted_at` IS NULL HAVING 2=2', '', 'fa fa-circle-o', '2.8', '2.8', '8', (SELECT `id` FROM `zz_modules` AS `t` WHERE `name` = 'Tabelle'), '1', '1', '1', '1');
SELECT @id_module := `id` FROM `zz_modules` WHERE `name` = 'Categorie file';
INSERT INTO `zz_modules_lang` (`id_lang`, `id_record`, `title`, `meta_title`) VALUES
('1', @id_module, 'Categorie file', 'Categorie file'),
('2', @id_module, 'Categorie file', 'Categorie file');
SELECT @id_module := `id` FROM `zz_modules` WHERE `name` = 'Categorie file';
INSERT INTO `zz_views` (`id_module`, `name`, `query`, `order`, `search`, `slow`, `format`, `html_format`, `search_inside`, `order_by`, `visible`, `summable`, `avg`, `default`) VALUES
(@id_module, 'Descrizione', 'zz_files_categories.name', '2', '1', '0', '0', '0', NULL, NULL, '1', '0', '0', '1'),
(@id_module, 'id', '`zz_files_categories`.`id`', '1', '0', '0', '0', '0', NULL, NULL, '0', '0', '0', '1');
SELECT @id_module := `id` FROM `zz_modules` WHERE `name` = 'Categorie file';
INSERT INTO `zz_views_lang` (`id_lang`, `id_record`, `title`) VALUES
('1', (SELECT `id` FROM `zz_views` WHERE `name` = 'Descrizione' AND `id_module` = @id_module), 'Descrizione'),
('2', (SELECT `id` FROM `zz_views` WHERE `name` = 'Descrizione' AND `id_module` = @id_module), 'Description'),
('1', (SELECT `id` FROM `zz_views` WHERE `name` = 'id' AND `id_module` = @id_module), 'id'),
('2', (SELECT `id` FROM `zz_views` WHERE `name` = 'id' AND `id_module` = @id_module), 'id');
CREATE TABLE `zz_files_categories` (`id` INT NOT NULL AUTO_INCREMENT , `name` VARCHAR(255) NOT NULL , `deleted_at` TIMESTAMP NULL , PRIMARY KEY (`id`));
ALTER TABLE `zz_files` ADD `id_category` INT NULL AFTER `category`;