Merge branch 'master' into 2.4.2

This commit is contained in:
Thomas Zilio 2018-09-04 12:34:54 +02:00
commit 7ecbf85276
27 changed files with 373 additions and 123 deletions

View File

@ -15,7 +15,7 @@ github:
title: OpenSTAManager
subTitle: Il software gestionale open-source per l'assistenza tecnica e la fatturazione
fontAwesomeIcon: fa fa-cog
footerText: 'Progettato e sviluppato da <a href="http://devcode.it/">DevCode</a>.'
footerText: 'Progettato e sviluppato da DevCode.'
googleAnalyticsCode: UA-42808312-1
scripts:
@ -37,43 +37,49 @@ menu:
aggiornamento:
text: Aggiornamento
relativeUrl: aggiornamento.html
api:
text: API
relativeUrl: api.html
contribuire:
text: Contribuire
relativeUrl: contributing.html
structure:
name: Approfondimenti
name: Strutture
items:
struttura:
text: Struttura
relativeUrl: struttura.html
moduli:
text: Moduli
relativeUrl: moduli.html
upload:
text: Gestione degli upload
relativeUrl: upload.html
widget:
relativeUrl: structure/moduli.html
plugin:
text: Plugin
relativeUrl: widget.html
relativeUrl: structure/plugin.html
stampe:
text: Stampe
relativeUrl: stampe.html
relativeUrl: structure/stampe.html
widget:
text: Widget
relativeUrl: widget.html
custom:
relativeUrl: structure/widget.html
more:
name: Approfondimenti
items:
nucleo:
text: Nucleo
relativeUrl: more/nucleo.html
upload:
text: Upload
relativeUrl: more/upload.html
extra:
text: Extra
relativeUrl: more/extra.html
api:
text: API
relativeUrl: more/api.html
base:
name: Personalizzazione
items:
framework:
text: Framework
relativeUrl: framework.html
relativeUrl: base/framework.html
assets:
text: Assets
relativeUrl: assets.html
more:
relativeUrl: base/assets.html
links:
name: Link utili
items:
docs:

View File

@ -85,5 +85,5 @@ Per reimpostare la password di un account amministrativo è possibile procedere
- Se esiste un altro account amministrativo, seguire la procedura precedente per gli account comuni;
- Accedere al database ed eseguire la seguente query:
```sql
UPDATE `zz_utenti` SET password = MD5('nuova_password') WHERE username = 'admin';
UPDATE `zz_users` SET `password` = MD5('nuova_password') WHERE `username` = 'admin';
```

29
docs/more/Extra.md Normal file
View File

@ -0,0 +1,29 @@
---
currentMenu: extra
---
# Extra
<!-- TOC depthFrom:2 depthTo:6 orderedList:false updateOnSave:true withLinks:true -->
- [Campi personalizzati](#campi-personalizzati)
- [Messaggi personalizzati](#messaggi-personalizzati)
<!-- /TOC -->
## Campi personalizzati
A partire dalla versione 2.4 è possibile sfruttare dei campi personalizzati per aggiungere informazioni ai moduli principali in modo dinamico.
Questi campi sono gestiti a livello di database attarverso le tabelle `zz_fields` e `zz_field_record`, che si occupano riespettivamente della gestione generale dei campi e del salvataggio dei record personalizzati.
Le procedure automatiche di gestione di questi campi sono integrate nei file `actions.php`, `editor.php` e `add.php`.
E' eventualmente disponibile il modulo **Campi personalizzati**, da abilitare, per la gestione dinamica di queste informazioni.
## Messaggi personalizzati
A partire dalla versione 2.4.2 è stato reso possibile inserire dei messaggi, specifici per l'installazione in utilizzo, presenti in ogni pagina del gestionale.
E' possibile procedere alla personalizzazione di questi contenuti attraverso i seguenti file (da creare secondo necessità):
- `include/custom/extra/login.php`, dedicato ai messaggi da mostrare all'accesso
- `include/custom/extra/extra.php`, per i messaggi da mostrare una volta che l'utente si è autenticato

View File

@ -1,21 +1,17 @@
---
currentMenu: struttura
currentMenu: nucleo
---
# Struttura
<!-- TOC depthFrom:2 depthTo:6 orderedList:false updateOnSave:true withLinks:true -->
- [Caratteristiche](#caratteristiche)
- [open-source](#open-source)
- [Modulare e personalizzabile](#modulare-e-personalizzabile)
- [Multipiattaforma e user friendly](#multipiattaforma-e-user-friendly)
- [Struttura](#struttura)
- [Root](#root)
- [add.php](#addphp)
- [ajax_complete.php](#ajax_completephp)
- [ajax_dataload.php](#ajax_dataloadphp)
- [ajax_select.php](#ajax_selectphp)
- [ajax_complete.php](#ajaxcompletephp)
- [ajax_dataload.php](#ajaxdataloadphp)
- [ajax_select.php](#ajaxselectphp)
- [bug.php](#bugphp)
- [core.php](#corephp)
- [config.inc.php](#configincphp)
@ -42,34 +38,13 @@ currentMenu: struttura
- [Cartella modules](#cartella-modules)
- [Cartella templates](#cartella-templates)
- [Cartella update](#cartella-update)
- [create_updates.sql](#create_updatessql)
- [create_updates.sql](#createupdatessql)
- [VERSIONE.sql](#versionesql)
- [VERSIONE.php](#versionephp)
- [Cartella vendor](#cartella-vendor)
<!-- /TOC -->
## Caratteristiche
### open-source
La natura open-source (termine inglese che significa _sorgente aperta_) del progetto evidenzia lo spirito di collaborazione e condivisione che pervade l'attività di sviluppo del gestionale, di cui gli autori rendono pubblico il codice sorgente e ne favoriscono il libero studio, permettendo a programmatori indipendenti di apportarvi modifiche ed estensioni.
Particolarmente espressiva in questo senso risulta essere la documentazione ufficiale del progetto:
> Il progetto è un software open-source perché permette agli utilizzatori di studiarne il funzionamento ed adattarlo alle proprie esigenze; inoltre, in ambito commerciale, non obbliga l'utilizzatore ad essere legato allo stesso fornitore di assistenza.
La licenza in utilizzo è la GNU General Public License 3.0 (GPL 3.0).
### Modulare e personalizzabile
OpenSTAManager possiede una struttura fortemente modulare, che ne permette la rapida espandibilità e, nello specifico, la realizzazione di funzionalità _ad hoc_, personalizzate nel modo più completo secondo le richieste del cliente.
### Multipiattaforma e user friendly
Il progetto risulta compatibile con numerose piattaforme, necessitando esclusivamente un browser moderno da parte dei suoi utilizzatori per sfruttare appieno le sue potenzialità.
L'interfaccia di interazione con l'utente finale risulta inoltre estremamente semplificata e _user friendly_, oltre che _responsive_, presentando caratteristiche completamente compatibili con tutti i dispositivi mobili (in particolare, tablet e smartphone).
## Struttura
Scaricando la versione GIT del progetto dovreste trovare una struttura di base molto simile a quella seguente.

View File

@ -300,11 +300,13 @@ gulp.task('release', function () {
'files/**',
'logs/**',
'config.inc.php',
'*.lock',
'*.phar',
'**/*.lock',
'**/*.phar',
'**/*.log',
'**/*.zip',
'**/*.bak',
'**/*.jar',
'**/*.txt',
'**/~*',
]
});

View File

@ -99,6 +99,34 @@ if (!function_exists('str_contains')) {
}
}
if (!function_exists('str_to_lower')) {
/**
* Converts a string in the lower-case version.
*
* @param string $string
*
* @return bool
*/
function str_to_lower($string)
{
return S::create($string)->toLowerCase();
}
}
if (!function_exists('str_to_upper')) {
/**
* Converts a string in the upper-case version.
*
* @param string $string
*
* @return bool
*/
function str_to_upper($string)
{
return S::create($string)->toUpperCase();
}
}
if (!function_exists('random_string')) {
/**
* Generates a string of random characters.

View File

@ -123,8 +123,6 @@ return [
'names' => [
'Unità di misura',
'Unità misura',
'unità misura',
'unità di misura',
'Unit` di misura',
'um',
],
@ -132,18 +130,10 @@ return [
[
'field' => 'prezzo_acquisto',
'label' => 'Prezzo acquisto',
'names' => [
'Prezzo Acquisto',
'prezzo acquisto',
],
],
[
'field' => 'prezzo_vendita',
'label' => 'Prezzo vendita',
'names' => [
'Prezzo Vendita',
'prezzo vendita',
],
],
[
'field' => 'peso_lordo',
@ -158,7 +148,7 @@ return [
'label' => 'Volume (M3)',
'names' => [
'Volume (M3)',
'volume',
'Volume',
],
],
[
@ -168,7 +158,6 @@ return [
'Categoria',
'id_categoria',
'idcategoria',
'categoria',
],
],
[

View File

@ -0,0 +1,46 @@
<?php
include_once __DIR__.'/../../core.php';
switch (post('op')) {
case 'update':
$plugin = post('plugin_id') ?: null;
$module = $plugin ? null : post('module_id');
$dbo->update('zz_fields', [
'id_module' => $module,
'id_plugin' => $plugin,
'name' => post('name'),
'html_name' => post('html_name'),
'content' => post('content'),
'on_add' => post('on_add'),
'top' => post('top'),
], ['id' => $id_record]);
$_SESSION['infos'][] = tr('Salvataggio completato!');
break;
case 'add':
$plugin = post('plugin_id') ?: null;
$module = $plugin ? null : post('module_id');
$dbo->insert('zz_fields', [
'id_module' => $module,
'id_plugin' => $plugin,
'name' => post('name'),
'content' => post('content'),
'html_name' => secure_random_string(8),
]);
$id_record = $dbo->lastInsertedID();
$_SESSION['infos'][] = tr('Nuovo campo personalizzato creato!');
break;
case 'delete':
$dbo->delete('zz_fields', ['id' => $id_record]);
$dbo->delete('zz_field_record', ['id_field' => $id_record]);
break;
}

View File

@ -0,0 +1,37 @@
<?php
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-6">
{[ "type": "select", "label": "<?php echo tr('Modulo'); ?>", "name": "module_id", "values": "query=SELECT id, name as text FROM zz_modules WHERE enabled = 1" ]}
</div>
<div class="col-md-6">
{[ "type": "select", "label": "<?php echo tr('Plugin'); ?>", "name": "plugin_id", "values": "query=SELECT id, name as text FROM zz_plugins WHERE enabled = 1" ]}
</div>
</div>
<div class="row">
<div class="col-md-12">
{[ "type": "text", "label": "<?php echo tr('Nome'); ?>", "name": "name", "required": 1 ]}
</div>
</div>
<div class="row">
<div class="col-md-12">
{[ "type": "textarea", "label": "<?php echo tr('Contenuto'); ?>", "name": "content", "required": 1, "value": "$content$" ]}
</div>
</div>
<!-- PULSANTI -->
<div class="row">
<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,87 @@
<?php
include_once __DIR__.'/../../core.php';
?>
<form action="" method="post" id="edit-form">
<input type="hidden" name="op" value="update">
<input type="hidden" name="backto" value="record-edit">
<input type="hidden" name="id_record" value="<?php echo $id_record; ?>">
<div class="row">
<div class="col-md-6">
{[ "type": "select", "label": "<?php echo tr('Modulo'); ?>", "name": "module_id", "values": "query=SELECT id, name as text FROM zz_modules WHERE enabled = 1", "value": "$id_module$" ]}
</div>
<div class="col-md-6">
{[ "type": "select", "label": "<?php echo tr('Plugin'); ?>", "name": "plugin_id", "values": "query=SELECT id, name as text FROM zz_plugins WHERE enabled = 1", "value": "$id_plugin$" ]}
</div>
</div>
<div class="row">
<div class="col-md-6">
{[ "type": "text", "label": "<?php echo tr('Nome'); ?>", "name": "name", "required": 1, "value": "$name$" ]}
</div>
<div class="col-md-6">
{[ "type": "text", "label": "<?php echo tr('Nome HTML'); ?>", "name": "html_name", "required": 1, "value": "$html_name$" ]}
</div>
</div>
<div class="row">
<div class="col-md-6">
{[ "type": "checkbox", "label": "<?php echo tr('Mostra alla creazione record'); ?>", "name": "on_add","value": "$on_add$" ]}
</div>
<div class="col-md-6">
{[ "type": "checkbox", "label": "<?php echo tr('Mostra di sopra'); ?>", "name": "top", "value": "$top$" ]}
</div>
</div>
<div class="row">
<div class="col-md-12">
{[ "type": "textarea", "label": "<?php echo tr('Contenuto'); ?>", "name": "content", "required": 1, "value": "$content$" ]}
</div>
</div>
</form>
<!-- Istruzioni per il contenuto -->
<div class="box box-info">
<div class="box-header">
<h3 class="box-title"><?php echo tr('Istruzioni per il campo _FIELD_', [
'_FIELD_' => tr('Contenuto'),
]); ?></h3>
</div>
<div class="box-body">
<p><?php echo tr('Le seguenti sequenze di testo vengono sostituite nel seguente modo'); ?>:</p>
<ul>
<?php
$list = [
'name' => tr('Nome'),
'html_name' => tr('Nome HTML'),
];
foreach ($list as $key => $value) {
echo '
<li>'.tr('_TEXT_ con il valore del campo "_FIELD_"', [
'_TEXT_' => '<code>|'.$key.'|</code>',
'_FIELD_' => $value,
]).'</li>';
}
echo '
<li>'.tr('_TEXT_ con il valore impostato per il record', [
'_TEXT_' => '<code>|value|</code>',
]).'</li>';
?>
</ul>
</div>
</div>
<hr>
<a class="btn btn-danger ask" data-backto="record-list">
<i class="fa fa-trash"></i> <?php echo tr('Elimina'); ?>
</a>

View File

@ -0,0 +1,10 @@
<?php
include_once __DIR__.'/../../core.php';
if (isset($id_record)) {
$records = $dbo->fetchArray('SELECT * FROM zz_fields WHERE id='.prepare($id_record));
}
// TODO: prevedere un utilizzo pratico del campo options

View File

@ -88,27 +88,38 @@ echo '
// Variabili utilizzabili
$variables = include Modules::filepath($record['id_module'], 'variables.php');
if (sizeof($variables) > 0) {
echo '
<!-- Istruzioni per il contenuto -->
<div class="box box-info">
<div class="box-header">
<h3 class="box-title">'.tr('Istruzioni per i campi automatici').'</h3>
</div>
<div class="box-body">';
if (!empty($variables)) {
echo '
<div class="alert alert-info">
<p>'.tr("Puoi utilizzare le seguenti variabili nell'oggetto e nel corpo della mail").':</p>
<ul>';
<p>'.tr("Puoi utilizzare le seguenti sequenze di testo nell'oggetto e nel corpo della mail").':</p>
<ul>';
foreach ($variables as $variable => $value) {
echo '
<li>{'.$variable.'}</li>';
<li><code>{'.$variable.'}</code></li>';
}
echo '
</ul>
</div>';
</ul>';
} else {
echo '
<div class="alert alert-warning">
<i class="fa fa-warning"></i> '.tr('Non sono state definite variabili da utilizzare nel template').'.
</div>';
<p><i class="fa fa-warning"></i> '.tr('Non sono state definite variabili da utilizzare nel template').'.</p>';
}
echo '
</div>
</div>
<hr>';
?>
</div>

View File

@ -20,6 +20,9 @@ switch (post('op')) {
'headers' => $first_row,
]);
// Gestione automatica dei valori convertiti
$csv = Filter::parse($csv);
// Interpretazione dei dati
$data = [];
foreach ($csv as $row) {

View File

@ -65,7 +65,7 @@ if (empty($id_record)) {
// Individuazione delle corrispondenze
$selected = null;
foreach ($fields as $key => $value) {
if (in_array($rows[0][$column], $value['names'])) {
if (in_array(str_to_lower($rows[0][$column]), $value['names'])) {
$first_row = 1;
$selected = $key;
break;

View File

@ -115,7 +115,7 @@ for ($x = 0; $x < $n1; ++$x) {
for ($i = 0; $i < sizeof($rs); ++$i) {
echo " <tr><td>\n";
if ($rs[$i]['iddocumento'] != '') {
if (!empty($rs[$i]['iddocumento'])) {
$module = ($rs[$i]['dir'] == 'entrata') ? Modules::get('Fatture di vendita')['id'] : Modules::get('Fatture di acquisto')['id'];
echo "<a data-toggle='modal' data-title='Dettagli movimento...' data-target='#bs-popup' class='clickable' data-href='".$rootdir.'/modules/partitario/dettagli_movimento.php?id_movimento='.$rs[$i]['id'].'&id_conto='.$rs[$i]['idconto'].'&id_module='.$module."' >".$rs[$i]['descrizione']."</a>\n";
// echo " <a href='".$rootdir.'/editor.php?id_module='.$module.'&id_record='.$rs[$i]['iddocumento']."'>".$rs[$i]['descrizione']."</a>\n";

View File

@ -64,7 +64,6 @@ include_once __DIR__.'/../../core.php';
</div>
</div>
<!-- Campi extra -->
<div class="panel panel-primary">
<div class="panel-heading">
@ -73,43 +72,44 @@ include_once __DIR__.'/../../core.php';
<div class="panel-body">
<div class="row">
<?php
$array = preg_match('/(?<=FROM)\s([^\s]+)\s/', $record['options'], $table);
if (strpos($table[0], 'co_documenti') !== false) {
$righe = $dbo->fetchArray('SELECT COUNT(*) AS tot FROM '.$table[0].' WHERE id_segment = '.prepare($id_record));
$tot = $righe[0]['tot'];
}
?>
<div class="col-md-3">
{[ "type": "text", "label": "<?php echo tr('Maschera'); ?>", "name": "pattern", "class": "alphanumeric-mask", "value": "$pattern$", "maxlength": 25, "placeholder":"####/YY", "extra": "<?php echo ($tot > 0) ? 'readonly' : ''; ?>" ]}
</div>
</div>
<div class="row">
<div class="col-md-12">
<!-- Istruzioni per il contenuto -->
<div class="box box-info">
<div class="box-header">
<h3 class="box-title"><?php echo tr('Istruzioni per il campo _FIELD_', [
'_FIELD_' => tr('Maschera'),
]); ?></h3>
</div>
<div class="alert alert-info" style="margin:0;">
<h3 style="margin:0;"><?php echo tr('Istruzioni per il campo _FIELD_', [
'_FIELD_' => tr('Maschera'),
]); ?></h3>
<div class="box-body">
<p><?php echo tr('Le seguenti sequenze di testo vengono sostituite nel seguente modo'); ?>:</p>
<ul>
<?php
$list = [
'####' => tr('Numero progressivo del documento, con zeri non significativi per raggiungere il numero desiderato di caratteri'),
'YYYY' => tr('Anno corrente a 4 cifre'),
'yy' => tr('Anno corrente a 2 cifre'),
];
<p><font style='font-size:20px;'><b>####</b></font> <?php echo tr('Questi caratteri vengono sostituiti con il numero progressivo della fattura, vengono aggiunti zeri non significativi per raggiungere il numero desiderato di caratteri'); ?>.</p>
foreach ($list as $key => $value) {
echo '
<li>'.tr('_TEXT_: _FIELD_', [
'_TEXT_' => '<code>'.$key.'</code>',
'_FIELD_' => $value,
]).'</li>';
}
<p><font style='font-size:20px;'><b>YYYY</b></font> <?php echo tr("Questi caratteri vengono sosituiti con l'anno corrente a 4 cifre, è possibile specificare l'anno a 2 cifre con _YY_", [
'_YY_' => 'yy',
]); ?>.</p>
<p><?php echo tr("E' possibile aggiungere altri caratteri fissi, come lettere, trattini, eccetera, prima e/o dopo e/o tra le maschere _####_ e _YYYY_", [
'_####_' => '####',
'_YYYY_' => 'YYYY',
]); ?>.</p>
</p>
</div>
</div>
</div>
?>
</ul>
<p><?php echo tr("E' inoltre possibile aggiungere altri caratteri fissi (come lettere, trattini, eccetera) prima e/o dopo le sequenze di cui sopra"); ?>.</p>
</div>
</div>
</div>
</div>
@ -117,35 +117,42 @@ if (strpos($table[0], 'co_documenti') !== false) {
</form>
<?php
if ($tot > 0) {
echo "<div class='alert alert-danger' style='margin:0px;'>";
echo tr("Ci sono _TOT_ righe collegate al segmento per il modulo '_MODULO_'. Il comando elimina è stato disattivato, eliminare le righe per attivare il comando 'Elimina segmento'.", [
$array = preg_match('/(?<=FROM)\s([^\s]+)\s/', $record['options'], $table);
if (strpos($table[0], 'co_documenti') !== false) {
$righe = $dbo->fetchArray('SELECT COUNT(*) AS tot FROM '.$table[0].' WHERE id_segment = '.prepare($id_record));
$tot = $righe[0]['tot'];
}
if ($tot > 0) {
echo "<div class='alert alert-danger' style='margin:0px;'>";
echo tr("Ci sono _TOT_ righe collegate al segmento per il modulo '_MODULO_'. Il comando elimina è stato disattivato, eliminare le righe per attivare il comando 'Elimina segmento'.", [
'_TOT_' => $tot,
'_MODULO_' => $record['modulo'],
]);
echo '</div>';
} elseif ($record['predefined']) {
echo "<div class='alert alert-danger' style='margin:0px;'>";
echo '</div>';
} elseif ($records['predefined']) {
echo "<div class='alert alert-danger' style='margin:0px;'>";
echo tr("Questo è il segmento predefinito per il modulo '_MODULO_'. Il comando elimina è stato disattivato.", [
echo tr("Questo è il segmento predefinito per il modulo '_MODULO_'. Il comando elimina è stato disattivato.", [
'_MODULO_' => $record['modulo'],
]);
echo '</div>';
} elseif ($record['n_sezionali'] < 2) {
echo "<div class='alert alert-danger' style='margin:0px;'>";
echo '</div>';
} elseif ($record['n_sezionali'] < 2) {
echo "<div class='alert alert-danger' style='margin:0px;'>";
echo tr("Questo è l'unico segmento per il modulo '_MODULO_'. Il comando elimina è stato disattivato.", [
echo tr("Questo è l'unico segmento per il modulo '_MODULO_'. Il comando elimina è stato disattivato.", [
'_MODULO_' => $record['modulo'],
]);
echo '</div>';
} else {
echo '
echo '</div>';
} else {
echo '
<a class="btn btn-danger ask" data-backto="record-list">
<i class="fa fa-trash"></i> '.tr('Elimina').'
</a>';
}
}
?>

View File

@ -80,11 +80,20 @@ class Import
// Impostazione automatica dei nomi "ufficiali" dei campi
foreach ($fields as $key => $value) {
if (!isset($value['names'])) {
$fields[$key]['names'] = [
$names = [
$value['field'],
$value['label'],
];
} else {
$names = $value['names'];
}
// Impostazione dei nomi in minuscolo
foreach ($names as $k => $v) {
$names[$k] = str_to_lower($v);
}
$fields[$key]['names'] = $names;
}
return $fields;

View File

@ -50,11 +50,13 @@ include_once $docroot.'/templates/pdfgen_variables.php';
// LEFT OUTER JOIN mg_unitamisura ON mg_unitamisura.id=mg_articoli.idum
// mg_unitamisura.valore AS um
// LEFT OUTER JOIN mg_categorie ON (mg_categorie.id=mg_articoli.id_categoria AND mg_categorie.parent = 0) OR (mg_categorie.id=mg_articoli.id_sottocategoria AND mg_categorie.parent = 1)
$query = 'SELECT *, mg_articoli.id AS id_articolo, (SELECT nome FROM mg_categorie WHERE mg_categorie.parent = 0 AND mg_categorie.id = mg_articoli.id_categoria) AS categoria, (SELECT nome FROM mg_categorie WHERE mg_categorie.parent = 1 AND mg_categorie.id = mg_articoli.id_sottocategoria) AS subcategoria FROM mg_articoli WHERE 1=1 '.$add_where.' AND qta > 0 HAVING 2=2 '.$add_having.' ORDER BY codice ASC';
$period_end = $_SESSION['period_end'];
$query = 'SELECT *, mg_articoli.id AS id_articolo, (SELECT nome FROM mg_categorie WHERE mg_categorie.parent = 0 AND mg_categorie.id = mg_articoli.id_categoria) AS categoria, (SELECT nome FROM mg_categorie WHERE mg_categorie.parent = 1 AND mg_categorie.id = mg_articoli.id_sottocategoria) AS subcategoria, (SELECT SUM(qta) FROM mg_movimenti WHERE mg_movimenti.idarticolo=mg_articoli.id AND (mg_movimenti.idintervento IS NULL OR mg_movimenti.idautomezzo = 0) AND data <= '.prepare($period_end).' ) AS qta FROM mg_articoli WHERE 1=1 '.$add_where.' HAVING 2=2 '.$add_having.' ORDER BY codice ASC';
$rs = $dbo->fetchArray($query);
$totrows = sizeof($rs);
$body .= '<h3>INVENTARIO AL '.date('d/m/Y')."</h3>\n";
$body .= '<h3>INVENTARIO AL '.Translator::dateToLocale($period_end)."</h3>\n";
$body .= "<table cellspacing='0' style='table-layout:fixed;'>\n";
$body .= "<col width='100'><col width='230'><col width='70'><col width='70'><col width='70'><col width='90'>\n";

View File

@ -493,3 +493,12 @@ INSERT INTO `zz_prints` (`id`, `id_module`, `is_record`, `name`, `title`, `direc
(NULL, (SELECT id FROM zz_modules WHERE name='Fatture di vendita'), 1, 'Fattura di vendita (senza intestazione)', 'Fattura di vendita (senza intestazione)', 'fatture', 'iddocumento', '{"hide_header":true, "hide_footer":true}', 'fa fa-print', '', '', 0, 0, 1, 1);
UPDATE `zz_prints` SET `main` = '1' WHERE `name` = 'Fattura di vendita';
-- Innesto modulo per campi personalizzati
INSERT INTO `zz_modules` (`id`, `name`, `title`, `directory`, `options`, `options2`, `icon`, `version`, `compatibility`, `order`, `parent`, `default`, `enabled`) VALUES (NULL, 'Campi personalizzati', 'Campi personalizzati', 'custom_fields', 'SELECT |select| FROM `zz_fields` WHERE 1=1 HAVING 2=2', '', 'fa fa-list', '2.4.1', '2.4.1', '1', NULL, '1', '0');
UPDATE `zz_modules` `t1` INNER JOIN `zz_modules` `t2` ON (`t1`.`name` = 'Campi personalizzati' AND `t2`.`name` = 'Strumenti') SET `t1`.`parent` = `t2`.`id`;
INSERT INTO `zz_views` (`id`, `id_module`, `name`, `query`, `order`, `search`, `slow`, `format`, `enabled`, `summable`, `default`) VALUES
(NULL, (SELECT `id` FROM `zz_modules` WHERE `name` = 'Campi personalizzati'), 'id', 'id', 0, 0, 0, 0, 0, 0, 1),
(NULL, (SELECT `id` FROM `zz_modules` WHERE `name` = 'Campi personalizzati'), 'Modulo', '(SELECT name FROM zz_modules WHERE zz_modules.id = zz_fields.id_module)', 0, 1, 0, 0, 1, 0, 1),
(NULL, (SELECT `id` FROM `zz_modules` WHERE `name` = 'Campi personalizzati'), 'Plugin', '(SELECT name FROM zz_plugins WHERE zz_plugins.id = zz_fields.id_plugin)', 0, 1, 0, 0, 1, 0, 1),
(NULL, (SELECT `id` FROM `zz_modules` WHERE `name` = 'Campi personalizzati'), 'Nome', 'name', 0, 1, 0, 0, 1, 0, 1);