Merge branch 'master' into 2.4

This commit is contained in:
Thomas Zilio 2018-02-03 13:55:09 +01:00
commit 93e428d1fb
82 changed files with 2003 additions and 765 deletions

View File

@ -4,12 +4,14 @@
</a>
<p align="center">
Il gestionale open source per l'assistenza tecnica e la fatturazione.
Il software gestionale open source per l'assistenza tecnica e la fatturazione.
<br>
<br>
<a href="http://openstamanager.com">Sito web</a>
&middot;
<a href="https://devcode-it.github.io/openstamanager">Documentazione tecnica</a>
&middot;
<a href="http://openstamanager.com">Sito ufficiale</a>
<a href="http://openstamanager.com/forum">Forum</a>
</p>
</p>
@ -54,7 +56,7 @@ La documentazione ufficiale è disponibile all'indirizzo <https://devcode-it.git
L'installazione del gestionale richiede la presenza di un server web con abilitato il [DBMS MySQL](https://www.mysql.com) e il linguaggio di programmazione [PHP](http://php.net).
- PHP >= 5.4
- PHP >= 5.6
- MySQL >= 5.0
Per ulteriori informazioni sui pacchetti che forniscono questi elementi di default, visitare la sezione [Installazione](https://devcode-it.github.io/openstamanager/installazione.html) della documentazione.
@ -64,7 +66,7 @@ Per ulteriori informazioni sui pacchetti che forniscono questi elementi di defau
Per procedere all'installazione è necessario seguire i seguenti punti:
1. [Scaricare una release ufficiale del progetto](https://github.com/devcode-it/openstamanager/releases).
2. Creare una cartella (ad esempio `openstamanager`) nella root del sever web installato ed estrarvi il contenuto della release scaricata. Il percorso della cartella root del server varia in base al software in utilizzo:
2. Creare una cartella (ad esempio `openstamanager`) nella root del server web installato ed estrarvi il contenuto della release scaricata. Il percorso della cartella root del server varia in base al software in utilizzo:
- LAMP (`/var/www/html`)
- XAMPP (`C:/xampp/htdocs` per Windows, `/opt/lampp/htdocs/` per Linux, `/Applications/XAMPP/htdocs/` per MAC)
@ -88,7 +90,7 @@ Se siete inoltre interessati a supporto e assistenza professionali, li potete ri
### Github
Nel caso si stia utilizzando la versione direttamente ottenuta dalla repository di Github, è necessario eseguire i seguenti comandi da linea di comando per completare le dipendenze PHP (tramite [Composer](https://getcomposer.org)) e gli assets (tramite [Yarn](https://yarnpkg.com)) del progetto.
Nel caso si stia utilizzando la versione direttamente ottenuta dalla repository di Github, è necessario eseguire i seguenti comandi da linea di comando per completare le dipendenze PHP (tramite [Composer](https://getcomposer.org)) e gli assets (tramite [Yarn](https://yarnpkg.com)) del progetto.
```bash
php composer.phar install

View File

@ -21,7 +21,7 @@ session_write_close();
// Permesso di accesso all'API da ogni dispositivo
header('Access-Control-Allow-Origin: *');
// Attenzione: al momento l'API permette la lettura di tutte le tabelle rpesenti nel database (non limitate a quelle del progetto).
// Attenzione: al momento l'API permette la lettura di tutte le tabelle presenti nel database (non limitate a quelle del progetto)
try {
// Controlli sulla chiave di accesso
@ -30,21 +30,33 @@ try {
// Lettura delle informazioni
$request = API::getRequest();
// Gestione della richiesta
$method = $_SERVER['REQUEST_METHOD'];
switch ($method) {
// Richiesta PUT (modifica elementi)
case 'PUT':
$result = $api->update($request);
break;
// Richiesta POST (creazione elementi)
case 'POST':
$result = $api->create($request);
break;
// Richiesta GET (ottenimento elementi)
case 'GET':
// Risorsa specificata
if (!empty($request)) {
$result = $api->retrieve($request);
} else {
}
// Risorsa non specificata (lista delle risorse disponibili)
else {
$result = API::response(API::getResources()['retrieve']);
}
break;
// Richiesta DELETE (eliminazione elementi)
case 'DELETE':
$result = $api->delete($request);
break;
@ -55,4 +67,5 @@ try {
$result = API::error('serverError');
}
// Stampa dei risultati
echo $result;

View File

@ -30,7 +30,7 @@ a.disabled {
}
.btn-calendar>.btn {
color: inherit !important;
color: inherit;
background: transparent;
font-size: 20px;
margin-top: 2px;
@ -71,7 +71,7 @@ a.disabled {
}
.ui-menu {
position: fixed !important;
position: fixed;
}
.ui-autocomplete {
@ -136,14 +136,6 @@ a.disabled {
border-top: 0
}
@media ( max-width:768px) {
.box-center,
.box-center-large {
width: 90%;
margin-top: 20px
}
}
.li-widget a:hover {
text-decoration: none;
}
@ -279,25 +271,14 @@ span.form-control {
}
.colorpicker {
margin-top: 0px !important;
}
@media ( max-width: 992px) {
.table-bordered>thead>tr>th,
.table-bordered>tbody>tr>th,
.table-bordered>tfoot>tr>th,
.table-bordered>thead>tr>td,
.table-bordered>tbody>tr>td,
.table-bordered>tfoot>tr>td {
word-break: break-all;
}
margin-top: 0;
}
/* Aggiustamenti per i widget */
.widget li {
margin-left: 0 !important;
margin-left: 0;
list-style-type: none;
}
@ -324,10 +305,10 @@ span.form-control {
/* Tooltip dark */
.ui-tooltip {
background: #222 !important;
color: white !important;
border: 0px;
font-size: 11px !important;
background: #222;
color: white;
border: 0;
font-size: 11px;
}
.nav-tabs-custom>.nav-tabs.pull-right>li>a.back-btn {
@ -340,13 +321,6 @@ span.form-control {
color: #72AFD2;
}
@media ( max-width: 480px) {
#main_loading>div>i {
font-size: 160px;
margin-top: -80px;
}
}
.input-searching {
background: #FFBF91;
}
@ -425,26 +399,6 @@ span.form-control {
transform: skew(3deg) rotate(3deg);
}
@media screen and (max-width: 1024px) {
.signature-pad {
top: 0;
left: 0;
right: 0;
bottom: 0;
width: auto;
height: auto;
min-width: 250px;
min-height: 140px;
margin: 5%;
}
}
@media screen and (min-device-width: 768px) and (max-device-width: 1024px) {
.signature-pad {
margin: 10%;
}
}
#canvas {
width: 100%;
height: 100%;
@ -499,7 +453,7 @@ span.form-control {
.select2-search,
.select2-search__field {
width: 100%!important
width: 100%
}
.select2-results__option[aria-selected=true] {
@ -522,25 +476,6 @@ span.form-control {
border-radius: 0px;
}
@media screen and (max-width:767px) {
.main-header .logo {
display: none;
}
/*
.content-wrapper,
.right-side,
.left-side,
.main-sidebar {
padding-top: 50px;
}*/
}
@media screen and (max-width:1023px) {
.push {
position: static;
}
}
/* Interventi da pianificare in Dashboard */
@ -564,9 +499,71 @@ input.small-width {
}
.pac-container {
z-index: 1100 !important;
z-index: 1100;
}
.form-control#blob{
height: auto;
}
.form-control#blob {
height: auto;
}
@media (max-width: 480px) {
#main_loading>div>i {
font-size: 160px;
margin-top: -80px;
}
}
@media screen and (max-width: 768px) {
.box-center,
.box-center-large {
width: 90%;
margin-top: 20px
}
.main-header .logo {
display: none;
}
/*
.content-wrapper,
.right-side,
.left-side,
.main-sidebar {
padding-top: 50px;
}*/
}
@media screen and (min-width: 768px) and (max-width: 1024px) {
.signature-pad {
margin: 10%;
}
}
@media screen and (max-width: 992px) {
.table-bordered>thead>tr>th,
.table-bordered>tbody>tr>th,
.table-bordered>tfoot>tr>th,
.table-bordered>thead>tr>td,
.table-bordered>tbody>tr>td,
.table-bordered>tfoot>tr>td {
word-break: break-all;
}
}
@media screen and (max-width: 1024px) {
.push {
position: static;
}
.signature-pad {
top: 0;
left: 0;
right: 0;
bottom: 0;
width: auto;
height: auto;
min-width: 250px;
min-height: 140px;
margin: 5%;
}
}

View File

@ -2,6 +2,12 @@
include_once __DIR__.'/core.php';
if (!empty($id_record) && !empty($id_module)) {
redirect(ROOTDIR.'/editor.php?id_module='.$id_module.'&id_record='.$id_record);
} elseif (empty($id_module)) {
redirect(ROOTDIR.'/index.php');
}
if (file_exists($docroot.'/include/custom/top.php')) {
include $docroot.'/include/custom/top.php';
} else {
@ -22,10 +28,10 @@ include $docroot.'/actions.php';
/*
* Widget top
*/
//se non sono mobile nascondo i widget controller_top
if (!isMobile()){
echo Widgets::addModuleWidgets($id_module, 'controller_top');
if (!isMobile()) {
echo Widgets::addModuleWidgets($id_module, 'controller_top');
}
// Lettura eventuali plugins modulo da inserire come tab
@ -87,20 +93,19 @@ echo '
redirectOperation($id_module, $id_record);
/**
/*
* Widget laterali.
*/
// Controllo se ho widget per il lato destro dello schermo, altrimenti non creo la colonna di destra
//se sono mobile pesco anche i widget di controller_top
if (isMobile()){
$extra_where = " OR location = 'controller_top'";
}else{
$extra_where = "";
if (isMobile()) {
$extra_where = " OR location = 'controller_top'";
} else {
$extra_where = '';
}
$result_widgets = $dbo->fetchArray('SELECT `id`, `location`, `class` FROM `zz_widgets` WHERE `id_module`='.prepare($id_module)." AND (`location`='controller_right' ".$extra_where." ) AND `enabled`=1 ORDER BY `order` ASC");
$result_widgets = $dbo->fetchArray('SELECT `id`, `location`, `class` FROM `zz_widgets` WHERE `id_module`='.prepare($id_module)." AND (`location`='controller_right' ".$extra_where.' ) AND `enabled`=1 ORDER BY `order` ASC');
if (count($result_widgets) > 0) {
echo '
<div class="col-md-12">';

View File

@ -13,10 +13,10 @@ github:
repo: openstamanager
title: OpenSTAManager
subTitle: Il gestionale open source per l'assistenza tecnica e la fatturazione
subTitle: Il software gestionale open source per l'assistenza tecnica e la fatturazione
fontAwesomeIcon: fa fa-cog
footerText: 'Progettato e sviluppato da DevCode.'
##googleAnalyticsCode: GOOGLE-ANALYTICS-CODE
footerText: 'Progettato e sviluppato da <a href="http://devcode.it/">DevCode</a>.'
googleAnalyticsCode: UA-42808312-1
scripts:
after:
@ -26,24 +26,21 @@ scripts:
menu:
sections:
main:
name: Documentazione di base
name: Introduzione
items:
home:
text: Home page
text: Home
relativeUrl: index.html
installazione:
text: Installazione
relativeUrl: installazione.html
framework:
text: Framework
relativeUrl: framework.html
assets:
text: Assets
relativeUrl: assets.html
aggiornamento:
text: Aggiornamento
relativeUrl: aggiornamento.html
api:
text: API
relativeUrl: api.html
other:
structure:
name: Approfondimenti
items:
struttura:
@ -52,9 +49,36 @@ menu:
moduli:
text: Moduli
relativeUrl: moduli.html
upload:
text: Gestione degli upload
relativeUrl: upload.html
widget:
text: Plugin
relativeUrl: widget.html
stampe:
text: Stampe
relativeUrl: stampe.html
widget:
text: Widget
relativeUrl: widget.html
custom:
name: Personalizzazione
items:
framework:
text: Framework
relativeUrl: framework.html
assets:
text: Assets
relativeUrl: assets.html
more:
name: Link utili
items:
docs:
text: Documentazione completa
text: Documentazione
relativeUrl: docs/
osm:
text: Sito ufficiale
absoluteUrl: http://www.openstamanager.com/
text: Sito web
absoluteUrl: http://www.openstamanager.com
forum:
text: Forum
absoluteUrl: http://www.openstamanager.com/forum

View File

@ -13,6 +13,7 @@ Di seguito sono elencate le basi per connettersi al sistema e ottenere i dati a
<!-- TOC depthFrom:2 depthTo:6 orderedList:false updateOnSave:true withLinks:true -->
- [Requisiti aggiuntivi](#requisiti-aggiuntivi)
- [Standard di comunicazione](#standard-di-comunicazione)
- [Ottenere la chiave](#ottenere-la-chiave)
- [Formato dei componenti](#formato-dei-componenti)
@ -29,6 +30,18 @@ Di seguito sono elencate le basi per connettersi al sistema e ottenere i dati a
<!-- /TOC -->
## Requisiti aggiuntivi
Per rendere la gestione dell'API maggiormente mantenibile e unificata, il suo funzionamento è stato sottoposto al seguente requisito aggiuntivo:
- MySQL >= 5.6.5
Se queste requisito non viene soddisfatto, l'installazione del gestionale procederà correttamente, ma i tentativi di connessione con l'API saranno rifiutati con il codice di errore `503` e lo stato `Servizio non disponibile`.
Nel caso, a seguito dell'installazione di OpenSTAManager, venisse aggiornato il servizio MySQL per permettere il funzionamento dell'API, sarà necessaro causare l'esecuzione della procedura di aggiornamento del gestionale, che organizzarà correttamente il database per la compatibilità con l'API.
**Attenzione**: il solo aggiornamento del servizio MySQL senza il successivo aggiornamento del gestionale potrebbe causare malfunzionamenti di vario genere nell'utilizzo dell'API.
## Standard di comunicazione
Il funzionamento dell'API si basa fondamentalmente sull'utilizzo di una chiave di accesso, ospitata all'interno della tabella `zz_tokens` del database del progetto, univoca per ogni istanza dell'utente.

89
docs/Aggiornamento.md Normal file
View File

@ -0,0 +1,89 @@
---
currentMenu: aggiornamento
---
# Aggiornamento
**Attenzione**: Questa documentazione è esclusivamente relativa all'aggiornamento del software. Per maggiori informazioni sull'installazione consultare la documentazione relativa nella sezione [Installazione](Installazione.md).
Esistono due procedure ufficiale per effettuare l'aggiornamento di OpenSTAManager in modo corretto: una semplificata (_consigliata_) e una manuale.
In ogni caso, il corretto procedimento prevede di [scaricare una release ufficiale del progetto](https://github.com/devcode-it/openstamanager/releases) ed **effettuare un backup della versione corrente** (comprensivo di file e database).
<!-- TOC depthFrom:2 depthTo:6 orderedList:false updateOnSave:true withLinks:true -->
- [Aggiornamento semplificato](#aggiornamento-semplificato)
- [Aggiornamento manuale](#aggiornamento-manuale)
- [Migrazione dalla versione 1.x](#migrazione-dalla-versione-1x)
- [Recupero della password](#recupero-della-password)
- [Account comune](#account-comune)
- [Account amministrativo](#account-amministrativo)
<!-- /TOC -->
## Aggiornamento semplificato
La procedura di aggiornamento semplificato ha l'obiettivo di fornire un sistema di facile utilizzo per favorire l'aggiornamento, e migliorare in questo modo l'interazione con l'utente finale.
L'utilizzo di questa procedura è però sottoposto alla seguenti condizioni nelle impostazioni PHP:
- `upload_max_filesize` >= 16MB
- `post_max_size` >= 16MB
Di seguito la procedura:
1. Accedere con un account amministrativo
2. Entrare nel modulo **Aggiornamenti** (disponibile nel menu principale a sinistra, eventualmente sotto la dicitura **Strumenti**)
3. Selezionare il file _.zip_ della release attraverso l'apposita sezione "Carica un aggiornamento" e cliccare sul pulsante "Carica"
Dopo l'esecuzione di queste azioni, il gestionale effettuerà automaticamente il logout di tutti gli utenti connessi e renderà disponibile l'interfaccia di aggiornamento.
## Aggiornamento manuale
La procedura di aggiornamento manuale è resa disponibile per ovviare ai problemi relativi al caricamento del file _.zip_ (in alcuni casi il file non viene correttamente rilevato, non sono disponibili i permessi per caricare file oppure la dimensione del file eccede il limite di upload sul server).
Di seguito la procedura:
1. De-comprimere il contenuto del file _.zip_ in una cartella temporanea
2. Rinominare il file `VERSION` dell'installazione corrente in `VERSION.old` (rispettando minuscole e maiuscole) [facoltativo a partire dalla versione 2.3]
3. Copiare i file della nuova versione dalla cartella temporanea alla cartella del server, in modo che le cartelle principali (`files`, `modules`, `templates`, ...) vengano sovrascritte
Dopo l'esecuzione di queste azioni, il gestionale effettuerà automaticamente il logout di tutti gli utenti connessi e renderà disponibile l'interfaccia di aggiornamento.
## Migrazione dalla versione 1.x
E' possibile effettuare la migrazione da una qualsiasi versione 1.x alla nuova 2.0, seguendo una procedura un po diversa dalle precedenti:
1. Scaricare la versione 2.0 per la migrazione da SourceForge ([openstamanager-2.0-migrazione.zip](https://sourceforge.net/projects/openstamanager/files/openstamanager/openstamanager-2.x/))
2. Creare un backup completo della versione in uso
1. De-comprimere il contenuto del file _.zip_ in una cartella temporanea
4. Effettuare le seguenti operazioni dal backup della precedente versione alla cartella della versione 2.0:
- Copiare il file `VERSION`, rinominandolo in `VERSION.old`
- Copiare il file `config.inc.php`
- Copiare la cartella `files/`
- Copiare i contenuti della cartella `/modules/magazzino/articoli/images/` in `/files/articoli/`
- Copiare la cartella `templates/` (mantenendo però i file `pdfgen.php` e `pdfgen_variables.php` di della versione 2.0)
Dopo l'esecuzione di queste azioni, il gestionale renderà disponibile l'interfaccia di aggiornamento.
**Attenzione**: le stampe di _Interventi_, _Riepilogo interventi_, _Contratti_ e _Preventivi_ potrebbero non essere compatibili per via dellaggiornamento degli orari di lavoro, perciò è possibile riscrivere solo la parte di calcolo ore o partire dal template nuovo e apportare le dovute modifiche.
## Recupero della password
Non esiste una procedura semplificata per permettere il recupero della password degli account di amministrazione (di default, _admin_) o di quelli comuni.
Si ricorda che è comunque possibile **cambiare** la password in ogni momento, se è stato effettuato l'accesso, attraverso l'utilizzo del modulo **Utenti e permessi** (**Gestione permessi** per versioni precedenti alla 2.3) disponibile sotto la dicitura **Strumenti**.
Può però essere necessario **reimpostare** la password, in particolare se è stata dimenticata, per ripristinare l'accesso ad OpenSTAManager.
### Account comune
Per procedere alla reimpostazione della password di un account comune (non amministrativo) è necessario accedere con un account amministrativo e utilizzare il modulo **Utenti e permessi** (**Gestione permessi** per versioni precedenti alla 2.3), disponibile sotto la dicitura **Strumenti**.
In particolare, una volta entrati nella corretta categoria di accesso (_Agenti_, _Amministratori_, _Clienti_, ...) dell'account da modificare, è possibile utilizzare la procedura semplificata di cambio password attraverso l'_icona del lucchetto aperto_.
Nel caso non sia possibile accedere con un account amministrativo, contattare l'amministratore.
### Account amministrativo
Per reimpostare la password di un account amministrativo è possibile procedere in due modi:
- 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';
```

View File

@ -4,27 +4,23 @@ currentMenu: installazione
# Installazione
<!-- TOC depthFrom:2 depthTo:6 orderedList:false updateOnSave:true withLinks:true -->
- [Requisiti](#requisiti)
- [Installazione](#installazione)
- [Versioni](#versioni)
- [Github](#github)
- [Versioni](#versioni)
- [Github](#github)
- [Strumenti utili](#strumenti-utili)
- [Windows](#windows)
- [Linux](#linux)
- [MAC](#mac)
- [Windows](#windows)
- [Linux](#linux)
- [MAC](#mac)
- [Problemi comuni](#problemi-comuni)
- [Schermata bianca iniziale](#schermata-bianca-iniziale)
- [Blocco dell'installazione allo 0%](#blocco-dellinstallazione-allo-0%25)
<!-- /TOC -->
- [Schermata bianca](#schermata-bianca)
- [Blocco dell'installazione (0%)](#blocco-dellinstallazione-0)
## Requisiti
L'installazione del gestionale richiede la presenza di un server web con abilitato il [DBMS MySQL](https://www.mysql.com) e il linguaggio di programmazione [PHP](http://php.net).
- PHP >= 5.4
- PHP >= 5.6
- MySQL >= 5.0
Per ulteriori informazioni sui pacchetti che forniscono questi elementi di default, visitare la sezione [Installazione](https://devcode-it.github.io/openstamanager/installazione.html) della documentazione.
@ -34,7 +30,7 @@ Per ulteriori informazioni sui pacchetti che forniscono questi elementi di defau
Per procedere all'installazione è necessario seguire i seguenti punti:
1. [Scaricare una release ufficiale del progetto](https://github.com/devcode-it/openstamanager/releases).
2. Creare una cartella (ad esempio `openstamanager`) nella root del sever web installato ed estrarvi il contenuto della release scaricata. Il percorso della cartella root del server varia in base al software in utilizzo:
2. Creare una cartella (ad esempio `openstamanager`) nella root del server web installato ed estrarvi il contenuto della release scaricata. Il percorso della cartella root del server varia in base al software in utilizzo:
- LAMP (`/var/www/html`)
- XAMPP (`C:/xampp/htdocs` per Windows, `/opt/lampp/htdocs/` per Linux, `/Applications/XAMPP/htdocs/` per MAC)
@ -58,7 +54,7 @@ Se siete inoltre interessati a supporto e assistenza professionali, li potete ri
### Github
Nel caso si stia utilizzando la versione direttamente ottenuta dalla repository di Github, è necessario eseguire i seguenti comandi da linea di comando per completare le dipendenze PHP (tramite [Composer](https://getcomposer.org)) e gli assets (tramite [Yarn](https://yarnpkg.com)) del progetto.
Nel caso si stia utilizzando la versione direttamente ottenuta dalla repository di Github, è necessario eseguire i seguenti comandi da linea di comando per completare le dipendenze PHP (tramite [Composer](https://getcomposer.org)) e gli assets (tramite [Yarn](https://yarnpkg.com)) del progetto.
```bash
php composer.phar install
@ -115,18 +111,21 @@ Il gestionale è stato testato con successo su Mac OS X con [MAMP](http://www.ma
## Problemi comuni
### Schermata bianca iniziale
### Schermata bianca
**Attenzione**: a partire dalla versione 2.3 questa problema non è più presente.
**Attenzione**: a partire dalla versione 2.3 questo problema non è più presente.
Nel caso si verifichi il problema di schermata bianca iniziale è necessario controllare i valori delle variabili `$rootdir` e `$docroot` nelle prime righe di _core.php_. Una possibile soluzione, implementata dalla versione 2.3, potrebbe essere:
```php
$docroot = __DIR__;
$rootdir = substr($_SERVER['SCRIPT_NAME'], 0, strrpos($_SERVER['SCRIPT_NAME'], '/'));
$rootdir = substr($_SERVER['SCRIPT_NAME'], 0, strrpos($_SERVER['SCRIPT_NAME'], '/')).'/';
if (strrpos($rootdir, '/'.basename($docroot).'/') !== false) {
$rootdir = substr($rootdir, 0, strrpos($rootdir, '/'.basename($docroot).'/')).'/'.basename($docroot);
} else {
$rootdir = '/';
}
$rootdir = rtrim($rootdir, '/');
$rootdir = str_replace('%2F', '/', rawurlencode($rootdir));
```
@ -135,20 +134,29 @@ Si ricorda comunque che:
- `$docroot` deve corrispondere al percorso reale nel file system per raggiungere la cartella principale del gestionale.
- `$rootdir` deve corrispondere al percorso URL del browser per raggiungere il gestionale nel server web.
### Blocco dell'installazione allo 0%
### Blocco dell'installazione (0%)
**Attenzione**: a partire dalla versione 2.3 questa problema non è più presente.
**Attenzione**: a partire dalla versione 2.3 questo problema non è più presente.
Nel caso l'installazione iniziale del database si blocchi allo 0% è probabilmente necessario effettuare una modifica nel file di impostazione del DBMS (`my.ini` nel caso di MySQL).
Nel caso l'installazione iniziale del database si blocchi allo 0% è necessario effettuare la seguente modifica nelle righe 15, 16 e 17 del file `lib\dbo.class.php` (https://www.openstamanager.com/forum/viewtopic.php?f=4&t=88353#p93976):
```php
if(@mysql_select_db($db_name, $conn)) {
@mysql_query("SET sql_mode = ''");
return "ok";
} else
```
Eventualmente, se questo primo passaggio si rivelasse non funzionante, si può procedere alla modifica delle impostazioni del DBMS (file `my.ini` di MySQL).
```ini
#sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
sql-mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
```
La riga preceduta da `#` è quella originale, mentre quella seguente è l'opzione che permette il corretto funzionamento dell'installazione.
La riga iniziante da `#` è quella originale, mentre quella seguente è l'opzione che permette il corretto funzionamento dell'installazione.
Discussioni originale:
Discussioni originali:
- [\[RISOLTO\] Tabelle Mancanti](http://www.openstamanager.com/forum/viewtopic.php?f=2&t=86981)
- [MySQL running in Strict Mode and giving me problems. How to fix this?](http://stackoverflow.com/questions/21667601/mysql-running-in-strict-mode-and-giving-me-problems-how-to-fix-this)

View File

@ -26,13 +26,13 @@ Segue un'analisi della struttura fisica e logica del nucleo dei moduli supportat
- [actions.php](#actionsphp)
- [add.php e edit.php](#addphp-e-editphp)
- [init.php](#initphp)
- [controller_after.php e controller_before.php](#controller_afterphp-e-controller_beforephp)
- [controller_after.php e controller_before.php](#controllerafterphp-e-controllerbeforephp)
- [modutil.php](#modutilphp)
- [Database](#database)
- [zz_modules](#zz_modules)
- [zz_permissions e zz_group_module](#zz_permissions-e-zz_group_module)
- [zz_views e zz_group_view](#zz_views-e-zz_group_view)
- [zz_plugins e zz_widgets](#zz_plugins-e-zz_widgets)
- [zz_modules](#zzmodules)
- [zz_permissions e zz_group_module](#zzpermissions-e-zzgroupmodule)
- [zz_views e zz_group_view](#zzviews-e-zzgroupview)
- [zz_plugins e zz_widgets](#zzplugins-e-zzwidgets)
- [Consigli per lo sviluppo](#consigli-per-lo-sviluppo)
- [Progettazione](#progettazione)
- [Sviluppo](#sviluppo)
@ -40,7 +40,7 @@ Segue un'analisi della struttura fisica e logica del nucleo dei moduli supportat
- [Installazione](#installazione)
- [Archivio ZIP](#archivio-zip)
- [update/VERSIONE.sql](#updateversionesql)
- [update/unistall.php (INCLUDE)](#updateunistallphp-include)
- [update/unistall.php](#updateunistallphp)
- [MODULE](#module)
- [Moduli di base](#moduli-di-base)
@ -202,7 +202,7 @@ L'archivio scaricato deve contenere direttamente al proprio interno i contenuti
Il file `VERSIONE.sql` (dove VERSIONE sta per la versione del modulo con `_`[underscore] al posto di `.`[punto]) contiene le operazioni di installazione del modulo a livello del database, comprendenti la creazione delle tabelle di base del modulo e l'inserimento di ulteriori dati nelle altre tabelle.
#### update/unistall.php (INCLUDE)
#### update/unistall.php
Il file `unistall.php` contiene le operazioni di disinstallazione del modulo a livello del database, comprendenti l'eliminazione delle tabelle non più necessarie e dei dati inutilizzati.

View File

@ -8,3 +8,5 @@ currentMenu: plugin
<!-- /TOC -->
Pagina in costruzione.

View File

@ -4,11 +4,13 @@ currentMenu: stampe
# Stampe
Pagina in costruzione.
- [MPDF](#mpdf)
- [HTML2PDF](#html2pdf)
- [Struttura](#struttura)
- [pdfgen.php](#pdfgenphp)
- [pdfgen_variables.php (INCLUDE)](#pdfgenvariablesphp-include)
- [pdfgen_variables.php](#pdfgenvariablesphp)
- [Struttura interna](#struttura-interna)
@ -30,7 +32,7 @@ La cartella _templates_ contiene tutti i template per la creazione dei PDF, ragg
Il file `pdfgen.php` si occupa della formattazione dei contenuti dei template per la visualizzazione vera e propria del PDF, inizializzando l'oggetto relativo ed eseguendone l'output.
#### pdfgen_variables.php (INCLUDE)
#### pdfgen_variables.php
Il file `pdfgen_variables.php` si occupa della sostituzione delle variabili comuni a tutti i template, e viene richiamata dal file `pdfgen.MODULO.php` descritto di seguito.

View File

@ -1,8 +1,10 @@
---
currentMenu: file
currentMenu: upload
---
# File
# Gestione degli upload
Pagina in costruzione.
La cartella `files` viene utilizzata dal progetto per gestire in modo unificato contenuti di vario tipo per i moduli installati.
In generale, questa cartella è dedicata alla memorizzazione dei file di cui viene fatto l'upload attraverso la funzione fornita in automatico dal getionale, ma sono presenti delle specifiche personalizzazioni necessarie per l'adeguato funzionamento di alcuni moduli.

View File

@ -8,3 +8,5 @@ currentMenu: widget
<!-- /TOC -->
Pagina in costruzione.

View File

@ -262,6 +262,8 @@ gulp.task('release', function () {
'!./vendor/tecnickcom/tcpdf/fonts/*helvetica*',
'./vendor/mpdf/mpdf/tmp/*',
'./vendor/mpdf/mpdf/ttfonts/*',
'!./vendor/mpdf/mpdf/ttfonts/DejaVuinfo.txt',
'!./vendor/mpdf/mpdf/ttfonts/DejaVu*Condensed*',
'./vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/*',
]);

View File

@ -32,7 +32,6 @@ if (post('db_host') !== null) {
// Test della configurazione
if (post('test') !== null) {
ob_end_clean();
$state = 2;
if ($dbo->isConnected()) {
$requirements = [
@ -50,31 +49,42 @@ if (post('db_host') !== null) {
$results = $dbo->fetchArray('SHOW GRANTS FOR CURRENT_USER');
foreach ($results as $result) {
if (
str_contains($result, $find) &&
(
str_contains($result, ' ON `'.$db_name.'`.*') ||
str_contains($result, ' ON *.*')
)
) {
$pieces = explode(', ', explode(' ON ', str_replace('GRANT ', '', current($result)))[0]);
$privileges = current($result);
if (
str_contains($privileges, ' ON `'.$db_name.'`.*') ||
str_contains($privileges, ' ON *.*')
) {
$pieces = explode(', ', explode(' ON ', str_replace('GRANT ', '', $privileges))[0]);
// Permessi generici sul database
if (in_array('ALL', $pieces) || in_array('ALL PRIVILEGES', $pieces)) {
$requirements = [];
break;
}
// Permessi specifici sul database
foreach ($requirements as $key => $value) {
if (!in_array($value, $pieces)) {
$state = 1;
break 2;
} else {
if (in_array($value, $pieces)) {
unset($requirements[$key]);
}
}
}
}
} else {
// Permessi insufficienti
if (!empty($requirements)) {
$state = 1;
}
// Permessi completi
else {
$state = 2;
}
}
// Connessione fallita
else {
$state = 0;
}

View File

@ -207,15 +207,15 @@ $(document).ready(function () {
if (!isMobile.any()) {
// Salvo lo scroll per riportare qui l'utente al reload
$(window).on('scroll', function () {
if (localStorage != undefined) {
localStorage.setItem('scrollTop_' + globals.id_module + '_' + globals.id_record, $(document).scrollTop());
if (sessionStorage != undefined) {
sessionStorage.setItem('scrollTop_' + globals.id_module + '_' + globals.id_record, $(document).scrollTop());
}
});
// Riporto l'utente allo scroll precedente
if (localStorage['scrollTop_' + globals.id_module + '_' + globals.id_record] != undefined) {
if (sessionStorage['scrollTop_' + globals.id_module + '_' + globals.id_record] != undefined) {
setTimeout(function () {
scrollToAndFocus(localStorage['scrollTop_' + globals.id_module + '_' + globals.id_record]);
scrollToAndFocus(sessionStorage['scrollTop_' + globals.id_module + '_' + globals.id_record]);
}, 1);
}
}
@ -549,10 +549,10 @@ function start_datatables() {
retrieve: true,
stateSave: true,
stateSaveCallback: function (settings, data) {
localStorage.setItem('DataTables_' + id_module + '-' + id_plugin + '-' + id_parent, JSON.stringify(data));
sessionStorage.setItem('DataTables_' + id_module + '-' + id_plugin + '-' + id_parent, JSON.stringify(data));
},
stateLoadCallback: function (settings) {
return JSON.parse(localStorage.getItem('DataTables_' + id_module + '-' + id_plugin + '-' + id_parent));
return JSON.parse(sessionStorage.getItem('DataTables_' + id_module + '-' + id_plugin + '-' + id_parent));
},
columnDefs: [{
searchable: false,
@ -985,22 +985,29 @@ jQuery.fn.selectData = function () {
};
// Inputmask
function start_inputmask() {
function start_inputmask(element) {
if( element == undefined ){
element = '';
} else {
element = element + ' ';
}
var date = moment.localeData().longDateFormat('L').toLowerCase();
$(".date-mask").inputmask(date, {
$(element+".date-mask").inputmask(date, {
"placeholder": date
});
$('.email-mask').inputmask('Regex', {
$(element+'.email-mask').inputmask('Regex', {
regex: "^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+(?:\\.[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+)*@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$",
});
if (isMobile.any()) {
$('.inputmask-decimal, .date-mask, .timestamp-mask').each(function () {
$(element+'.inputmask-decimal, '+element+'.date-mask, '+element+'.timestamp-mask').each(function () {
$(this).attr('type', 'tel');
});
} else {
$('.inputmask-decimal').each(function () {
$(element+'.inputmask-decimal').each(function () {
var $this = $(this);
var min = $this.attr('min-value');

View File

@ -809,10 +809,12 @@ function sum($first, $second = null, $decimals = null)
$bcadd = function_exists('bcadd');
foreach ($array as $value) {
$value = round($value, $decimals);
if ($bcadd) {
$result = bcadd($result, $value, $decimals);
} else {
$result = round($result, $decimals) + round($value, $decimals);
$result += $value;
}
}
@ -888,7 +890,7 @@ function isMobile()
function getURLPath()
{
$path = $_SERVER['SCRIPT_FILENAME'];
$prefix = $_SERVER['DOCUMENT_ROOT'];
$prefix = rtrim($_SERVER['DOCUMENT_ROOT'], '/\\');
if (substr($path, 0, strlen($prefix)) == $prefix) {
$path = substr($path, strlen($prefix));

View File

@ -21,6 +21,7 @@ switch (post('op')) {
$idiva_vendita = post('idiva_vendita');
$gg_garanzia = post('gg_garanzia');
$servizio = post('servizio');
$componente_filename = post('componente_filename');
$volume = post('volume');
@ -42,6 +43,7 @@ switch (post('op')) {
' prezzo_acquisto='.prepare($prezzo_acquisto).','.
' idiva_vendita='.prepare($idiva_vendita).','.
' gg_garanzia='.prepare($gg_garanzia).','.
' servizio='.prepare($servizio).','.
' volume='.prepare($volume).','.
' peso_lordo='.prepare($peso_lordo).','.
' componente_filename='.prepare($componente_filename).','.

View File

@ -29,11 +29,11 @@ $_SESSION['superselect']['id_categoria'] = $records[0]['id_categoria'];
</div>
<div class="col-md-4">
{[ "type": "text", "label": "<?php echo tr('Codice'); ?>", "name": "codice", "required": 1, "value": "$codice$" ]}
<br>
{[ "type": "checkbox", "label": "<?php echo tr("Seleziona per rendere visibile l'articolo"); ?>", "name": "attivo", "value": "$attivo$", "help": "", "placeholder": "<?php echo tr('ATTIVO'); ?>" ]}
</div>
<div class="col-md-5">
@ -50,7 +50,7 @@ $_SESSION['superselect']['id_categoria'] = $records[0]['id_categoria'];
<div class="row">
<div class="col-md-2">
{[ "type": "number", "label": "<?php echo tr('Quantità'); ?>", "name": "qta", "required": 1, "value": "$qta$", "readonly": 1, "decimals": "qta|undefined" ]}
{[ "type": "number", "label": "<?php echo tr('Quantità'); ?>", "name": "qta", "required": 1, "value": "$qta$", "readonly": 1, "decimals": "qta", "min-value": "undefined" ]}
</div>
<div class="col-md-3">
{[ "type": "checkbox", "label": "<?php echo tr('Modifica manualmente quantità'); ?>", "name": "qta_manuale", "value": 0, "help": "<?php echo tr('Seleziona per modificare manualmente la quantità'); ?>", "placeholder": "<?php echo tr('Quantità manuale'); ?>" ]}
@ -68,35 +68,32 @@ $_SESSION['superselect']['id_categoria'] = $records[0]['id_categoria'];
<div class="col-md-2">
{[ "type": "select", "label": "<?php echo tr('Unità di misura'); ?>", "name": "um", "value": "$um$", "ajax-source": "misure", "icon-after": "add|<?php echo Modules::get('Unità di misura')['id']; ?>" ]}
</div>
<div class="col-md-2">
{[ "type": "number", "label": "<?php echo tr('Soglia minima quantità'); ?>", "name": "threshold_qta", "value": "$threshold_qta$", "decimals": "qta|undefined" ]}
{[ "type": "number", "label": "<?php echo tr('Soglia minima quantità'); ?>", "name": "threshold_qta", "value": "$threshold_qta$", "decimals": "qta", "min-value": "undefined" ]}
</div>
<?php
if (empty($records[0]['abilita_serial'])) {
$plugin = $dbo->fetchArray("SELECT id FROM zz_plugins WHERE name='Serial'");
echo '<script>$("#link-tab_'.$plugin[0]['id'].'").addClass("disabled");</script>';
}
?>
if (empty($records[0]['abilita_serial'])) {
$plugin = $dbo->fetchArray("SELECT id FROM zz_plugins WHERE name='Serial'");
echo '<script>$("#link-tab_'.$plugin[0]['id'].'").addClass("disabled");</script>';
}
?>
<div class="col-md-3">
{[ "type": "checkbox", "label": "<?php echo tr('Abilita serial number'); ?>", "name": "abilita_serial", "value": "$abilita_serial$", "help": "", "placeholder": "<?php echo tr('Abilita serial number in fase di aggiunta articolo in fattura o ddt'); ?>" ]}
</div>
</div>
<div class="row">
<div class="col-md-2">
{[ "type": "number", "label": "<?php echo tr('Prezzo di acquisto'); ?>", "name": "prezzo_acquisto", "value": "$prezzo_acquisto$", "icon-after": "&euro;" ]}
</div>
</div>
<div class="row">
<div class="col-md-2">
{[ "type": "number", "label": "<?php echo tr('Prezzo di vendita base'); ?>", "name": "prezzo_vendita", "value": "$prezzo_vendita$", "icon-after": "&euro;" ]}
</div>
@ -104,18 +101,20 @@ $_SESSION['superselect']['id_categoria'] = $records[0]['id_categoria'];
<div class="col-md-3">
{[ "type": "select", "label": "<?php echo tr('Iva di vendita'); ?>", "name": "idiva_vendita", "values": "query=SELECT * FROM co_iva ORDER BY descrizione ASC", "value": "$idiva_vendita$", "valore_predefinito": "Iva predefinita" ]}
</div>
<div class="col-md-2">
{[ "type": "number", "label": "<?php echo tr('Garanzia'); ?>", "name": "gg_garanzia", "decimals": 0, "value": "$gg_garanzia$", "icon-after": "GG" ]}
</div>
<div class="col-md-3">
{[ "type": "checkbox", "label": "<?php echo tr("Questo articolo è un servizio"); ?>", "name": "servizio", "value": "$servizio$", "help": "", "placeholder": "<?php echo tr('SERVIZIO'); ?>" ]}
</div>
</div>
<div class="row">
<div class="col-md-2">
{[ "type": "number", "label": "<?php echo tr('Peso lordo'); ?>", "name": "peso_lordo", "value": "$peso_lordo$", "icon-after": "KG" ]}
</div>
@ -298,13 +297,12 @@ $elementi = $dbo->fetchArray('SELECT `co_documenti`.`id`, `co_documenti`.`data`,
SELECT `dt_ddt`.`id`, `dt_ddt`.`data`, `dt_ddt`.`numero`, `dt_ddt`.`numero_esterno`, `dt_tipiddt`.`descrizione` AS tipo_documento, `dt_tipiddt`.`dir` FROM `dt_ddt` JOIN `dt_tipiddt` ON `dt_tipiddt`.`id` = `dt_ddt`.`idtipoddt` WHERE `dt_ddt`.`id` IN (SELECT `idddt` FROM `dt_righe_ddt` WHERE `idarticolo` = '.prepare($id_record).') UNION
SELECT `co_preventivi`.`id`, `co_preventivi`.`data_bozza`, `co_preventivi`.`numero`, 0 AS numero_esterno , "Preventivo" AS tipo_documento, 0 AS dir FROM `co_preventivi` WHERE `co_preventivi`.`id` IN (SELECT `idpreventivo` FROM `co_righe_preventivi` WHERE `idarticolo` = '.prepare($id_record).') ORDER BY `data`');
if (!empty($elementi)) {
echo '
<div class="alert alert-warning">
<p>'.tr('_NUM_ altr_I_ document_I_ collegat_I_', [
'_NUM_' => count($elementi),
'_I_' => (count($elementi)>1) ? tr('i') : tr('o')
'_I_' => (count($elementi) > 1) ? tr('i') : tr('o'),
]).':</p>
<ul>';
@ -314,17 +312,17 @@ if (!empty($elementi)) {
'_NUM_' => !empty($elemento['numero_esterno']) ? $elemento['numero_esterno'] : $elemento['numero'],
'_DATE_' => Translator::dateToLocale($elemento['data']),
]);
//se non è un preventivo è un ddt o una fattura
//se non è un ddt è una fattura.
if (in_array($elemento['tipo_documento'], ['Preventivo'])) {
$modulo ='Preventivi';
} else if (!in_array($elemento['tipo_documento'], ['Ddt di vendita', 'Ddt di acquisto'])) {
$modulo = ($elemento['dir'] == 'entrata') ? 'Fatture di vendita' : 'Fatture di acquisto';
} else {
$modulo = ($elemento['dir'] == 'entrata') ? 'Ddt di vendita' : 'Ddt di acquisto';
}
//se non è un preventivo è un ddt o una fattura
//se non è un ddt è una fattura.
if (in_array($elemento['tipo_documento'], ['Preventivo'])) {
$modulo = 'Preventivi';
} elseif (!in_array($elemento['tipo_documento'], ['Ddt di vendita', 'Ddt di acquisto'])) {
$modulo = ($elemento['dir'] == 'entrata') ? 'Fatture di vendita' : 'Fatture di acquisto';
} else {
$modulo = ($elemento['dir'] == 'entrata') ? 'Ddt di vendita' : 'Ddt di acquisto';
}
$id = $elemento['id'];
echo '
@ -341,4 +339,4 @@ if (!empty($elementi)) {
<a class="btn btn-danger ask" data-backto="record-list">
<i class="fa fa-trash"></i> <?php echo tr('Elimina'); ?>
</a>
</a>

View File

@ -12,6 +12,9 @@ function add_movimento_magazzino($idarticolo, $qta, $array = [], $descrizone = '
if (empty($qta)) {
return false;
}
//Info Articolo
$rs_art = $dbo->fetchArray("SELECT * FROM mg_articoli WHERE id='".$idarticolo."'");
// Ddt
if (!empty($array['idddt'])) {
@ -76,18 +79,21 @@ function add_movimento_magazzino($idarticolo, $qta, $array = [], $descrizone = '
$movimento = str_replace(['_NAME_', '_TYPE_', '_NUM_'], [$nome, $tipo, $numero], $movimento);
$new = ($qta > 0 ? '+' : '').$qta;
//Movimento il magazzino solo se l'articolo non è un servizio
if($rs_art[0]['servizio']==0){
// Movimentazione effettiva
if (empty($array['idintervento']) || empty($array['idautomezzo'])) {
$dbo->query('UPDATE mg_articoli SET qta = qta + '.$new.' WHERE id = '.prepare($idarticolo));
}
// Movimentazione effettiva
if (empty($array['idintervento']) || empty($array['idautomezzo'])) {
$dbo->query('UPDATE mg_articoli SET qta = qta + '.$new.' WHERE id = '.prepare($idarticolo));
// Registrazione della movimentazione
$dbo->insert('mg_movimenti', array_merge($array, [
'idarticolo' => $idarticolo,
'qta' => $qta,
'movimento' => $movimento,
]));
}
// Registrazione della movimentazione
$dbo->insert('mg_movimenti', array_merge($array, [
'idarticolo' => $idarticolo,
'qta' => $qta,
'movimento' => $movimento,
]));
return true;
}

View File

@ -138,6 +138,7 @@ switch (post('op')) {
// Aggiungo una riga al contratto
case 'addriga':
$idiva = post('idiva');
$idarticolo = post('idarticolo');
$descrizione = post('descrizione');
$qta = $post['qta'];
@ -159,14 +160,30 @@ switch (post('op')) {
$iva_indetraibile = $iva / 100 * $rs2[0]['indetraibile'];
$desc_iva = $rs2[0]['descrizione'];
$dbo->query('INSERT INTO co_righe2_contratti(idcontratto, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, um, qta, sconto, sconto_unitario, tipo_sconto, `order`) VALUES ('.prepare($id_record).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($subtot).', '.prepare($um).', '.prepare($qta).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe2_contratti AS t WHERE idcontratto='.prepare($id_record).'))');
$dbo->query('INSERT INTO co_righe2_contratti(idcontratto, idarticolo, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, um, qta, sconto, sconto_unitario, tipo_sconto, `order`) VALUES ('.prepare($id_record).', '.prepare($idarticolo).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($subtot).', '.prepare($um).', '.prepare($qta).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe2_contratti AS t WHERE idcontratto='.prepare($id_record).'))');
$_SESSION['infos'][] = tr('Articolo aggiunto!');
break;
case 'adddescrizione':
if (!empty($id_record)) {
$descrizione = post('descrizione');
$query = 'INSERT INTO co_righe2_contratti(idcontratto, descrizione, is_descrizione) VALUES('.prepare($id_record).', '.prepare($descrizione).', 1)';
if ($dbo->query($query)) {
$_SESSION['infos'][] = tr('Riga descrittiva aggiunta!');
}
}
break;
case 'editriga':
$idriga = post('idriga');
$rs = $dbo->fetchArray("SELECT * FROM co_righe2_contratti WHERE id='".$idriga."'");
$is_descrizione = $rs[0]['is_descrizione'];
$idarticolo = post('idarticolo');
$descrizione = post('descrizione');
$qta = $post['qta'];
@ -190,7 +207,11 @@ switch (post('op')) {
$desc_iva = $rs[0]['descrizione'];
// Modifica riga generica sul documento
$query = 'UPDATE co_righe2_contratti SET idiva='.prepare($idiva).', desc_iva='.prepare($desc_iva).', iva='.prepare($iva).', iva_indetraibile='.prepare($iva_indetraibile).', descrizione='.prepare($descrizione).', subtotale='.prepare($subtot).', sconto='.prepare($sconto).', sconto_unitario='.prepare($sconto_unitario).', tipo_sconto='.prepare($tipo_sconto).', um='.prepare($um).', qta='.prepare($qta).' WHERE id='.prepare($idriga);
if($is_descrizione==0){
$query = 'UPDATE co_righe2_contratti SET idarticolo='.prepare($idarticolo).', idiva='.prepare($idiva).', desc_iva='.prepare($desc_iva).', iva='.prepare($iva).', iva_indetraibile='.prepare($iva_indetraibile).', descrizione='.prepare($descrizione).', subtotale='.prepare($subtot).', sconto='.prepare($sconto).', sconto_unitario='.prepare($sconto_unitario).', tipo_sconto='.prepare($tipo_sconto).', um='.prepare($um).', qta='.prepare($qta).' WHERE id='.prepare($idriga);
}else{
$query = 'UPDATE co_righe2_contratti SET descrizione='.prepare($descrizione).' WHERE id='.prepare($idriga);
}
$dbo->query($query);
$_SESSION['infos'][] = tr('Riga modificata!');
@ -284,6 +305,10 @@ switch (get('op')) {
$dbo->query('INSERT INTO co_righe2_contratti(idcontratto, descrizione, subtotale, um, qta) VALUES('.prepare($new_idcontratto).', '.prepare($rs[$i]['descrizione']).', '.prepare($rs[$i]['subtotale']).', '.prepare($rs[$i]['um']).', '.prepare($rs[$i]['qta']).')');
}
// Replicazione degli impianti
$impianti = $dbo->fetchArray('SELECT idimpianto FROM my_impianti_contratti WHERE idcontratto='.prepare($id_record));
$dbo->sync('my_impianti_contratti', ['idcontratto' => $new_idcontratto], ['idimpianto' => array_column($impianti, 'idimpianto')]);
$_SESSION['infos'][] = tr('Contratto rinnovato!');
redirect($rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$new_idcontratto);

View File

@ -0,0 +1,41 @@
<?php
include_once __DIR__.'/../../core.php';
$module = Modules::get($id_module);
$record = $dbo->fetchArray('SELECT * FROM co_contratti WHERE id='.prepare($id_record));
$numero = $record[0]['numero'];
$idanagrafica = $record[0]['idanagrafica'];
/*
Form di inserimento riga documento
*/
echo '
<p>'.tr('Contratto numero _NUM_', [
'_NUM_' => $numero,
]).'</p>
<form action="'.$rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$id_record.'" method="post">
<input type="hidden" name="op" value="adddescrizione">
<input type="hidden" name="backto" value="record-edit">
<input type="hidden" name="dir" value="'.$dir.'">';
// Descrizione
echo '
<div class="row">
<div class="col-md-12">
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "required": 1 ]}
</div>
</div>';
echo '
<!-- PULSANTI -->
<div class="row">
<div class="col-md-12 text-right">
<button type="submit" class="btn btn-primary pull-right"><i class="fa fa-plus"></i> '.tr('Aggiungi').'</button>
</div>
</div>
</form>';

View File

@ -37,6 +37,7 @@ if (empty($idriga)) {
$rsr = $dbo->fetchArray('SELECT * FROM co_righe2_contratti WHERE idcontratto='.prepare($id_record).' AND id='.prepare($idriga));
$idarticolo = $rsr[0]['idarticolo'];
$descrizione = $rsr[0]['descrizione'];
$qta = $rsr[0]['qta'];
$um = $rsr[0]['um'];
@ -52,35 +53,43 @@ echo '
<input type="hidden" name="idriga" value="'.$idriga.'">
<input type="hidden" name="backto" value="record-edit">';
// Elenco articoli raggruppati per gruppi e sottogruppi
if($rsr[0]['is_descrizione']!=1){
echo '
<div class="col-md-12">
{[ "type": "select", "label": "'.tr('Articolo').'", "name": "idarticolo", "value": "'.$idarticolo.'", "ajax-source": "articoli" ]}
</div>';
}
// Descrizione
echo '
<div class="col-md-12">
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "value": '.json_encode($descrizione).', "required": 1 ]}
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "id": "descrizione_riga", "value": '.json_encode($descrizione).', "required": 1 ]}
</div>';
// Iva
echo '
if($rsr[0]['is_descrizione']!=1){
// Iva
echo '
<div class="col-md-4">
{[ "type": "select", "label": "'.tr('Iva').'", "name": "idiva", "required": 1, "values": "query=SELECT id, descrizione FROM co_iva ORDER BY descrizione ASC", "value": "'.$idiva.'" ]}
</div>';
// Quantità
echo '
// Quantità
echo '
<div class="col-md-4">
{[ "type": "number", "label": "'.tr('Q.tà').'", "name": "qta", "value": "'.$qta.'", "required": 1, "decimals": "qta" ]}
</div>';
// Unità di misura
echo '
// Unità di misura
echo '
<div class="col-md-4">
{[ "type": "select", "label": "'.tr('Unità di misura').'", "icon-after": "add|'.Modules::get('Unità di misura')['id'].'", "name": "um", "value": "'.$um.'", "ajax-source": "misure" ]}
</div>';
/*
if (!empty($idriga)) {
//Rivalsa INPS
if( get_var("Percentuale rivalsa INPS") != "" ){
/*
if (!empty($idriga)) {
//Rivalsa INPS
if( get_var("Percentuale rivalsa INPS") != "" ){
echo " <div class='col-md-3'>\n";
echo " <label>Rivalsa INPS:</label>\n";
echo " <select id='idrivalsainps' class='superselect' name=\"idrivalsainps\">\n";
@ -95,10 +104,10 @@ if( get_var("Percentuale rivalsa INPS") != "" ){
echo " </select>\n";
echo " </div>\n";
}
}
//Ritenuta d'acconto
if( get_var("Percentuale ritenuta d'acconto") != "" ){
//Ritenuta d'acconto
if( get_var("Percentuale ritenuta d'acconto") != "" ){
echo " <div class='col-md-3'>\n";
echo " <label>Ritenuta d'acconto:</label>\n";
echo " <select id='idritenutaacconto' class='superselect' name=\"idritenutaacconto\">\n";
@ -113,21 +122,39 @@ if( get_var("Percentuale ritenuta d'acconto") != "" ){
echo " </select>\n";
echo " </div>\n";
}
}
*/
}
}
*/
// Costo unitario
echo '
// Costo unitario
echo '
<div class="col-md-6">
{[ "type": "number", "label": "'.tr('Costo unitario').'", "name": "prezzo", "required": 1, "value": "'.$prezzo.'", "icon-after": "&euro;" ]}
</div>';
// Sconto unitario
echo '
// Sconto unitario
echo '
<div class="col-md-6">
{[ "type": "number", "label": "'.tr('Sconto unitario').'", "name": "sconto", "value": "'.$sconto.'", "icon-after": "choice|untprc|'.$tipo_sconto.'" ]}
</div>';
}
echo '
<script>
$(document).ready(function () {
$("#idarticolo").on("change", function(){
if($(this).val()){
session_set("superselect,idarticolo", $(this).val(), 0);
$data = $(this).selectData();
$("#prezzo").val($data.prezzo_vendita);
$("#descrizione_riga").val($data.descrizione);
$("#idiva").selectSet($data.idiva_vendita, $data.iva_vendita);
$("#um").selectSetNew($data.um, $data.um);
}
});
});
</script>';
echo '

View File

@ -42,10 +42,18 @@ $_SESSION['superselect']['idanagrafica'] = $records[0]['idanagrafica'];
</div>
<div class="col-md-4">
<?php
echo Modules::link('Anagrafiche', $records[0]['idanagrafica'], null, null, 'class="pull-right"');
?>
{[ "type": "select", "label": "<?php echo tr('Cliente'); ?>", "name": "idanagrafica", "id": "idanagrafica_c", "required": 1, "value": "$idanagrafica$", "ajax-source": "clienti" ]}
</div>
<div class="col-md-3">
<?php
if($records[0]['idagente']!=0)
echo Modules::link('Anagrafiche', $records[0]['idagente'], null, null, 'class="pull-right"');
?>
{[ "type": "select", "label": "<?php echo tr('Agente'); ?>", "name": "idagente", "values": "query=SELECT an_anagrafiche.idanagrafica AS id, ragione_sociale AS descrizione FROM an_anagrafiche INNER JOIN (an_tipianagrafiche_anagrafiche INNER JOIN an_tipianagrafiche ON an_tipianagrafiche_anagrafiche.idtipoanagrafica=an_tipianagrafiche.idtipoanagrafica) ON an_anagrafiche.idanagrafica=an_tipianagrafiche_anagrafiche.idanagrafica WHERE descrizione='Agente' AND deleted=0 ORDER BY ragione_sociale", "value": "$idagente$" ]}
</div>
@ -271,7 +279,8 @@ if (sizeof($rs) > 0) {
<?php
if ($records[0]['stato'] != 'Pagato') {
?>
<a class="btn btn-primary" data-href="<?php echo $rootdir ?>/modules/contratti/add_riga.php?id_module=<?php echo $id_module ?>&id_record=<?php echo $id_record ?>" data-toggle="modal" data-title="Aggiungi riga" data-target="#bs-popup"><i class="fa fa-plus"></i> <?php echo tr('Riga'); ?></a><br>
<a class="btn btn-primary" data-href="<?php echo $rootdir ?>/modules/contratti/add_riga.php?id_module=<?php echo $id_module ?>&id_record=<?php echo $id_record ?>" data-toggle="modal" data-title="Aggiungi riga" data-target="#bs-popup"><i class="fa fa-plus"></i> <?php echo tr('Riga'); ?></a>
<a class="btn btn-primary" data-href="<?php echo $rootdir ?>/modules/contratti/add_descrizione.php?id_module=<?php echo $id_module ?>&id_record=<?php echo $id_record ?>" data-toggle="modal" data-title="Aggiungi descrizione" data-target="#bs-popup"><i class="fa fa-plus"></i> <?php echo tr('Descrizione'); ?></a>
<?php
}
@ -406,4 +415,4 @@ if (!empty($fatture)) {
<a class="btn btn-danger ask" data-backto="record-list">
<i class="fa fa-trash"></i> <?php echo tr('Elimina'); ?>
</a>
</a>

View File

@ -104,6 +104,11 @@ if (!empty($rsi)) {
$sconto_ore = ($r['sconto'] != 0) ? '<br><span class="label label-danger">'.Translator::numberToLocale(-$r['sconto']).' &euro;</span>' : '';
$sconto_km = ($r['scontokm'] != 0) ? '<br><span class="label label-danger">'.Translator::numberToLocale(-$r['scontokm']).' &euro;</span>' : '';
// Aggiungo lo sconto globale nel totale ore
if( $int['sconto_globale'] > 0 ){
$sconto_ore .= ' <span class="label label-danger">'.Translator::numberToLocale(-$int['sconto_globale']).' &euro;</span>';
}
echo '
<tr>
<td>'.$r['ragione_sociale'].'</td>

View File

@ -11,12 +11,12 @@ $totale_da_evadere = 0.00;
/*
ARTICOLI
*/
$rs_art = $dbo->fetchArray('SELECT * FROM co_righe2_contratti WHERE idcontratto='.prepare($id_record).' ORDER BY `order`');
$rs_art = $dbo->fetchArray('SELECT *, IFNULL((SELECT codice FROM mg_articoli WHERE id=idarticolo), "") AS codice FROM co_righe2_contratti WHERE idcontratto='.prepare($id_record).' ORDER BY `order`');
$imponibile_art = 0.0;
$iva_art = 0.0;
echo '
<table class="table table-striped table-hover table-condensed">
<table class="table table-striped table-hover table-condensed table-bordered">
<thead>
<tr>
<th>'.tr('Descrizione').'</th>
@ -36,48 +36,72 @@ if (!empty($rs_art)) {
// descrizione
echo '
<tr data-id="'.$r['id'].'">
<td>
'.nl2br($r['descrizione']).'
<td>';
if (!empty($r['idarticolo'])) {
echo Modules::link('Articoli', $r['idarticolo'], $r['codice'].' - '.$r['descrizione']);
} else {
echo nl2br($r['descrizione']);
}
echo '
</td>';
// q.tà
echo '
<td class="text-center">
'.Translator::numberToLocale($r['qta']).'
<td class="text-center">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['qta']);
}
echo '
</td>';
// um
echo '
<td class="text-center">
'.$r['um'].'
<td class="text-center">';
if($r['is_descrizione']==0){
echo
$r['um'];
}
echo '
</td>';
// costo unitario
echo '
<td class="text-center">
'.Translator::numberToLocale($r['subtotale'] / $r['qta']).' &euro;
<td class="text-center">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['subtotale'] / $r['qta']).' &euro;';
}
echo'
</td>';
// iva
echo '
<td class="text-right">
'.Translator::numberToLocale($r['iva'])." &euro;<br>
<small class='help-block'>".$r['desc_iva'].'</small>
<td class="text-right">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['iva'])." &euro;<br>
<small class='help-block'>".$r['desc_iva'].'</small>';
}
echo '
</td>';
// Imponibile
echo '
<td class="text-right">
'.Translator::numberToLocale($r['subtotale']).' &euro;';
<td class="text-right">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['subtotale']).' &euro;';
if ($r['sconto_unitario'] > 0) {
echo '
<br><small class="label label-danger">- '.tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
if ($r['sconto_unitario'] > 0) {
echo '
<br><small class="label label-danger">- '.tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
}
}
echo '
</td>';

View File

@ -5,6 +5,7 @@ include_once __DIR__.'/../../core.php';
// Necessaria per la funzione add_movimento_magazzino
include_once $docroot.'/modules/articoli/modutil.php';
include_once $docroot.'/modules/fatture/modutil.php';
include_once $docroot.'/modules/ordini/modutil.php';
$module = Modules::get($id_module);
@ -199,6 +200,17 @@ switch (post('op')) {
}
break;
case 'adddescrizione':
if (!empty($id_record)) {
$descrizione = post('descrizione');
$query = 'INSERT INTO dt_righe_ddt(idddt, descrizione, is_descrizione) VALUES('.prepare($id_record).', '.prepare($descrizione).', 1)';
if ($dbo->query($query)) {
$_SESSION['infos'][] = tr('Riga descrittiva aggiunta!');
}
}
break;
// Creazione ddt da ordine
case 'ddt_da_ordine':
$totale_ordine = 0.00;
@ -223,7 +235,7 @@ switch (post('op')) {
foreach ($post['qta_da_evadere'] AS $idriga=>$value) {
// Processo solo le righe da evadere
if ($post['evadere'][$idriga] == 'on') {
$idarticolo = post('idarticolo')[$idriga];
$descrizione = post('descrizione')[$idriga];
@ -238,13 +250,19 @@ switch (post('op')) {
$idiva = post('idiva')[$idriga];
$iva = $post['iva'][$idriga] * $qta;
$qprc = 'SELECT tipo_sconto, sconto_unitario FROM or_righe_ordini WHERE id='.prepare($idriga);
$rsprc = $dbo->fetchArray($qprc);
$sconto_unitario = $rsprc[0]['sconto_unitario'];
$tipo_sconto = $rsprc[0]['tipo_sconto'];
// Calcolo l'iva indetraibile
$q = 'SELECT descrizione, indetraibile FROM co_iva WHERE id='.prepare($idiva);
$rs = $dbo->fetchArray($q);
$iva_indetraibile = $iva / 100 * $rs[0]['indetraibile'];
// Inserisco la riga in ddt
$dbo->query('INSERT INTO dt_righe_ddt(idddt, idordine, idarticolo, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, um, qta, abilita_serial, `order`) VALUES('.prepare($id_record).', '.prepare($idordine).', '.prepare($idarticolo).', '.prepare($idiva).', '.prepare($rs[0]['descrizione']).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($subtot).', '.prepare($sconto).', '.prepare($um).', '.prepare($qta).', '.prepare($abilita_serial).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM dt_righe_ddt AS t WHERE idddt='.prepare($id_record).'))');
$dbo->query('INSERT INTO dt_righe_ddt(idddt, idordine, idarticolo, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, abilita_serial, `order`) VALUES('.prepare($id_record).', '.prepare($idordine).', '.prepare($idarticolo).', '.prepare($idiva).', '.prepare($rs[0]['descrizione']).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($subtot).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).', '.prepare($um).', '.prepare($qta).', '.prepare($abilita_serial).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM dt_righe_ddt AS t WHERE idddt='.prepare($id_record).'))');
$riga = $dbo->lastInsertedID();
// Aggiornamento seriali dalla riga dell'ordine
@ -346,11 +364,12 @@ switch (post('op')) {
$subtot = $prezzo * $qta;
// Lettura idarticolo dalla riga ddt
$rs = $dbo->fetchArray('SELECT idddt, abilita_serial, idarticolo, idordine, qta FROM dt_righe_ddt WHERE id='.prepare($idriga));
$rs = $dbo->fetchArray('SELECT * FROM dt_righe_ddt WHERE id='.prepare($idriga));
$idarticolo = $rs[0]['idarticolo'];
$idordine = $rs[0]['idordine'];
$old_qta = $rs[0]['qta'];
$idddt = $rs[0]['idddt'];
$is_descrizione = $rs[0]['is_descrizione'];
// Controllo per gestire i serial
if (!empty($idarticolo)) {
@ -361,6 +380,11 @@ switch (post('op')) {
}
}
// Se c'è un collegamento ad un ordine, aggiorno la quantità evasa
if (!empty($idddt)) {
$dbo->query( 'UPDATE or_righe_ordini SET qta_evasa=qta_evasa-'.$old_qta.' + '.$qta.' WHERE descrizione='.prepare($rs[0]['descrizione']).' AND idarticolo='.prepare($rs[0]['idarticolo']).' AND idordine='.prepare($idordine).' AND idiva='.prepare($rs[0]['idiva']) );
}
// Calcolo iva
$query = 'SELECT * FROM co_iva WHERE id='.prepare($idiva);
$rs = $dbo->fetchArray($query);
@ -369,7 +393,11 @@ switch (post('op')) {
$desc_iva = $rs[0]['descrizione'];
// Modifica riga generica sul ddt
$query = 'UPDATE dt_righe_ddt SET idiva='.prepare($idiva).', desc_iva='.prepare($desc_iva).', iva='.prepare($iva).', iva_indetraibile='.prepare($iva_indetraibile).', descrizione='.prepare($descrizione).', subtotale='.prepare($subtot).', sconto='.prepare($sconto).', sconto_unitario='.prepare($sconto_unitario).', tipo_sconto='.prepare($tipo_sconto).', um='.prepare($um).', qta='.prepare($qta).' WHERE id='.prepare($idriga);
if($is_descrizione==0){
$query = 'UPDATE dt_righe_ddt SET idiva='.prepare($idiva).', desc_iva='.prepare($desc_iva).', iva='.prepare($iva).', iva_indetraibile='.prepare($iva_indetraibile).', descrizione='.prepare($descrizione).', subtotale='.prepare($subtot).', sconto='.prepare($sconto).', sconto_unitario='.prepare($sconto_unitario).', tipo_sconto='.prepare($tipo_sconto).', um='.prepare($um).', qta='.prepare($qta).' WHERE id='.prepare($idriga);
}else{
$query = 'UPDATE dt_righe_ddt SET descrizione='.prepare($descrizione).' WHERE id='.prepare($idriga);
}
if ($dbo->query($query)) {
if (!empty($idarticolo)) {
// Controlli aggiuntivi sulle quantità evase degli ordini
@ -467,6 +495,16 @@ switch (post('op')) {
break;
}
// Aggiornamento stato degli ordini presenti in questa fattura in base alle quantità totali evase
if( !empty($id_record) ){
$rs = $dbo->fetchArray( 'SELECT idordine FROM dt_righe_ddt WHERE idddt='.prepare($id_record) );
for( $i=0; $i<sizeof($rs); $i++ ){
$dbo->query( 'UPDATE or_ordini SET idstatoordine=(SELECT id FROM or_statiordine WHERE descrizione="'.get_stato_ordine($rs[$i]['idordine']).'")' );
}
}
// Aggiornamento sconto sulle righe
if (post('op') !== null && post('op') != 'update') {
aggiorna_sconto([
'parent' => 'dt_ddt',

View File

@ -0,0 +1,48 @@
<?php
include_once __DIR__.'/../../core.php';
$module = Modules::get($id_module);
if ($module['name'] == 'Ddt di vendita') {
$dir = 'entrata';
} else {
$dir = 'uscita';
}
// Info documento
$rs = $dbo->fetchArray('SELECT * FROM dt_ddt WHERE id='.prepare($id_record));
$numero = (!empty($rs[0]['numero_esterno'])) ? $rs[0]['numero_esterno'] : $rs[0]['numero'];
$idanagrafica = $rs[0]['idanagrafica'];
/*
Form di inserimento riga ddt
*/
echo '
<p>'.tr('Ddt numero _NUM_', [
'_NUM_' => $numero,
]).'</p>
<form action="'.$rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$id_record.'" method="post">
<input type="hidden" name="op" value="adddescrizione">
<input type="hidden" name="backto" value="record-edit">
<input type="hidden" name="dir" value="'.$dir.'">';
// Descrizione
echo '
<div class="row">
<div class="col-md-12">
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "required": 1 ]}
</div>
</div>';
echo '
<!-- PULSANTI -->
<div class="row">
<div class="col-md-12 text-right">
<button type="submit" class="btn btn-primary pull-right"><i class="fa fa-plus"></i> '.tr('Aggiungi').'</button>
</div>
</div>
</form>';

View File

@ -72,41 +72,45 @@ echo '
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "required": 1, "value": '.json_encode($descrizione).' ]}
</div>
</div>';
if($rsr[0]['is_descrizione']==0){
// Quantità
echo '
// Quantità
echo '
<div class="row">
<div class="col-md-6">
{[ "type": "number", "label": "'.tr('Q.tà').'", "name": "qta", "required": 1, "value": "'.$qta.'", "decimals": "qta" ]}
</div>';
// Unità di misura
// Unità di misura
echo '
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Unità di misura').'", "icon-after": "add|'.Modules::get('Unità di misura')['id'].'", "name": "um", "value": "'.$um.'", "ajax-source": "misure" ]}
</div>
</div>';
// Iva
echo '
// Iva
echo '
<div class="row">
<div class="col-md-4">
{[ "type": "select", "label": "'.tr('Iva').'", "name": "idiva", "values": "query=SELECT id, descrizione FROM co_iva ORDER BY descrizione ASC", "value": "'.$idiva.'" ]}
</div>';
// Costo unitario
echo '
// Costo unitario
echo '
<div class="col-md-4">
{[ "type": "number", "label": "'.tr('Costo unitario').'", "name": "prezzo", "required": 1, "value": "'.$subtot.'", "icon-after": "&euro;" ]}
</div>';
// Sconto unitario
echo '
// Sconto unitario
echo '
<div class="col-md-4">
{[ "type": "number", "label": "'.tr('Sconto unitario').'", "name": "sconto", "value": "'.$sconto.'", "icon-after": "choice|untprc|'.$tipo_sconto.'" ]}
</div>
</div>';
}
echo '
<!-- PULSANTI -->

View File

@ -145,6 +145,9 @@ if ($records[0]['stato'] != 'Evaso') {
<a class="btn btn-sm btn-primary" data-href="<?php echo $rootdir ?>/modules/ddt/add_riga.php?id_module=<?php echo $id_module ?>&id_record=<?php echo $id_record ?>&dir=<?php echo $dir ?>" data-toggle="modal" data-title="Aggiungi riga" data-target="#bs-popup">
<i class="fa fa-plus"></i> <?php echo tr('Riga generica'); ?>
</a>
<a class="btn btn-sm btn-primary" data-href="<?php echo $rootdir ?>/modules/ddt/add_descrizione.php?id_module=<?php echo $id_module ?>&id_record=<?php echo $id_record ?>&dir=<?php echo $dir ?>" data-toggle="modal" data-title="Aggiungi descrizione" data-target="#bs-popup">
<i class="fa fa-plus"></i> <?php echo tr('Descrizione'); ?>
</a>
<?php
}
@ -155,7 +158,7 @@ if ($records[0]['stato'] != 'Evaso') {
<!-- Stampe -->
<?php
if ($records[0]['stato'] != 'Evaso') {
if( !in_array( $records[0]['stato'], array( 'Bozza', 'Fatturato')) ) {
?>
<a class="btn btn-sm btn-info" data-href="<?php echo $rootdir ?>/modules/fatture/crea_documento.php?id_module=<?php echo $id_module ?>&id_record=<?php echo $id_record ?>&documento=fattura" data-toggle="modal" data-title="Crea fattura" data-target="#bs-popup">
<i class="fa fa-magic"></i> <?php echo tr('Crea fattura da ddt'); ?>...</i>

View File

@ -322,3 +322,27 @@ function add_articolo_inddt($idddt, $idarticolo, $descrizione, $idiva, $qta, $pr
return $idriga;
}
/**
* Restituisce lo stato del ddt in base alle righe.
*/
function get_stato_ddt($idddt)
{
global $dbo;
$rs = $dbo->fetchArray('SELECT SUM(qta) AS qta, SUM(qta_evasa) AS qta_evasa FROM dt_righe_ddt GROUP BY idddt HAVING idddt='.prepare($idddt));
if ($rs[0]['qta'] == 0) {
return 'Bozza';
} else {
if ($rs[0]['qta_evasa'] > 0) {
if ($rs[0]['qta'] > $rs[0]['qta_evasa']) {
return 'Parzialmente fatturato';
} elseif ($rs[0]['qta'] == $rs[0]['qta_evasa']) {
return 'Fatturato';
}
} else {
return 'Evaso';
}
}
}

View File

@ -85,49 +85,65 @@ if (!empty($rs)) {
echo '
<td class="text-center">';
if (empty($r['sconto_globale'])) {
echo '
<big>'.Translator::numberToLocale($r['qta'] - $r['qta_evasa']).'</big>
<br><small>('.tr('Q. iniziale').': '.Translator::numberToLocale($r['qta']).')</small>';
} else {
echo '1';
if($r['is_descrizione']==0){
if (empty($r['sconto_globale'])) {
echo '
<big>'.Translator::numberToLocale($r['qta'] - $r['qta_evasa']).'</big>
<br><small>('.tr('Q. iniziale').': '.Translator::numberToLocale($r['qta']).')</small>';
} else {
echo '1';
}
}
echo '
</td>';
// Unità di misura
echo '
<td class="text-center">
'.$r['um'].'
<td class="text-center">';
if($r['is_descrizione']==0){
echo
$r['um'];
}
echo '
</td>';
// Costo unitario
echo '
<td class="text-right">
'.Translator::numberToLocale($r['subtotale'] / $r['qta']).' &euro;';
<td class="text-right">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['subtotale'] / $r['qta']).' &euro;';
if ($r['sconto_unitario'] > 0) {
echo '
<br><small class="label label-danger">- '.tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
if ($r['sconto_unitario'] > 0) {
echo '
<br><small class="label label-danger">- '.tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
}
}
echo '
</td>';
// Iva
echo '
<td class="text-right">
'.Translator::numberToLocale($r['iva']).' &euro;
<br><small class="help-block">'.$r['desc_iva'].'</small>
<td class="text-right">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['iva']).' &euro;
<br><small class="help-block">'.$r['desc_iva'].'</small>';
}
echo '
</td>';
// Imponibile
echo '
<td class="text-right">
'.Translator::numberToLocale($r['subtotale'] - $r['sconto']).' &euro;
<td class="text-right">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['subtotale'] - $r['sconto']).' &euro;';
}
echo '
</td>';
// Possibilità di rimuovere una riga solo se il ddt non è evaso

View File

@ -5,6 +5,8 @@ include_once __DIR__.'/../../core.php';
// Necessaria per la funzione add_movimento_magazzino
include_once $docroot.'/modules/articoli/modutil.php';
include_once $docroot.'/modules/interventi/modutil.php';
include_once $docroot.'/modules/ddt/modutil.php';
include_once $docroot.'/modules/ordini/modutil.php';
$module = Modules::get($id_module);
@ -247,11 +249,11 @@ switch (post('op')) {
// TODO: sistemare la duplicazione delle righe generiche e degli articoli, ingorando interventi, ddt, ordini, preventivi
foreach ($righe as $riga) {
$dbo->query('INSERT INTO co_righe_documenti(iddocumento, idordine, idddt, idintervento, idarticolo, idpreventivo, idcontratto, idtecnico, idagente, idautomezzo, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, idritenutaacconto, ritenutaacconto, idrivalsainps, rivalsainps, um, qta, `order`) VALUES('.prepare($id_record).', 0, 0, 0, '.prepare($riga['idarticolo']).', '.prepare($riga['idpreventivo']).', '.prepare($riga['idcontratto']).', '.prepare($riga['idtecnico']).', '.prepare($riga['idagente']).', '.prepare($riga['idautomezzo']).', '.prepare($riga['idiva']).', '.prepare($riga['desc_iva']).', '.prepare($riga['iva']).', '.prepare($riga['iva_indetraibile']).', '.prepare($riga['descrizione']).', '.prepare($riga['subtotale']).', '.prepare($riga['sconto']).', '.prepare($riga['idritenutaacconto']).', '.prepare($riga['ritenutaacconto']).', '.prepare($riga['idrivalsainps']).', '.prepare($riga['rivalsainps']).', '.prepare($riga['um']).', '.prepare($riga['qta']).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))');
// Scarico/carico nuovamente l'articolo da magazzino
if (!empty($riga['idarticolo'])) {
add_articolo_infattura($id_record, $riga['idarticolo'], $riga['descrizione'], $riga['idiva'], $riga['qta'], $riga['subtotale']);
add_articolo_infattura($id_record, $riga['idarticolo'], $riga['descrizione'], $riga['idiva'], $riga['qta'], $riga['subtotale'], $riga['sconto'], $riga['sconto_unitario'], $riga['tipo_sconto'], $riga['idintervento'], $riga['idconto'], $riga['um']);
} else {
$dbo->query('INSERT INTO co_righe_documenti(iddocumento, idordine, idddt, idintervento, idarticolo, idpreventivo, idcontratto, idtecnico, idagente, idautomezzo, idconto, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, idritenutaacconto, ritenutaacconto, idrivalsainps, rivalsainps, um, qta, `order`) VALUES('.prepare($id_record).', 0, 0, 0, '.prepare($riga['idarticolo']).', '.prepare($riga['idpreventivo']).', '.prepare($riga['idcontratto']).', '.prepare($riga['idtecnico']).', '.prepare($riga['idagente']).', '.prepare($riga['idautomezzo']).', '.prepare($riga['idconto']).', '.prepare($riga['idiva']).', '.prepare($riga['desc_iva']).', '.prepare($riga['iva']).', '.prepare($riga['iva_indetraibile']).', '.prepare($riga['descrizione']).', '.prepare($riga['subtotale']).', '.prepare($riga['sconto']).', '.prepare($riga['sconto_unitario']).', '.prepare($riga['tipo_sconto']).', '.prepare($riga['idritenutaacconto']).', '.prepare($riga['ritenutaacconto']).', '.prepare($riga['idrivalsainps']).', '.prepare($riga['rivalsainps']).', '.prepare($riga['um']).', '.prepare($riga['qta']).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))');
}
}
@ -315,13 +317,11 @@ switch (post('op')) {
$ritenutaacconto = ($subtot - $sconto + $rivalsainps) / 100 * $rs[0]['percentuale'];
// Aggiunta diritto di chiamata (se presente) come riga a parte
$query = 'SELECT SUM(prezzo_dirittochiamata) AS diritto_chiamata FROM in_interventi_tecnici WHERE idintervento='.prepare($idintervento);
$rs = $dbo->fetchArray($query);
$diritto_chiamata = $rs[0]['diritto_chiamata'];
$diritto_chiamata = $costi_intervento['dirittochiamata_addebito'];
// Aggiunta riga intervento sul documento
$ore = get_ore_intervento($idintervento);
$query = 'INSERT INTO co_righe_documenti(iddocumento, idintervento, idconto, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, idrivalsainps, rivalsainps, idritenutaacconto, ritenutaacconto, `order`) VALUES('.prepare($id_record).', '.prepare($idintervento).', '.prepare($idconto).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($subtot - $diritto_chiamata).', '.prepare($sconto).', '.prepare($sconto).", 'UNT', 'ore', ".prepare($ore).', '.prepare(get_var('Percentuale rivalsa INPS')).', '.prepare($rivalsainps).', '.prepare(get_var("Percentuale ritenuta d'acconto")).', '.prepare($ritenutaacconto).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))';
$query = 'INSERT INTO co_righe_documenti(iddocumento, idintervento, idconto, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, idrivalsainps, rivalsainps, idritenutaacconto, ritenutaacconto, `order`) VALUES('.prepare($id_record).', '.prepare($idintervento).', '.prepare($idconto).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($subtot).', '.prepare($sconto).', '.prepare($sconto).", 'UNT', 'ore', ".prepare($ore).', '.prepare(get_var('Percentuale rivalsa INPS')).', '.prepare($rivalsainps).', '.prepare(get_var("Percentuale ritenuta d'acconto")).', '.prepare($ritenutaacconto).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))';
$dbo->query($query);
// Aggiunta diritto di chiamata se >0
@ -374,12 +374,12 @@ switch (post('op')) {
'.prepare($iva_indetraibile).',
"Diritto di chiamata",
'.prepare($diritto_chiamata).',
'.prepare($sconto).',
'.prepare($sconto).",
'UNT',
'-',
'1',
".prepare(get_var('Percentuale rivalsa INPS')).',
0,
0,
"UNT",
"-",
1,
'.prepare(get_var('Percentuale rivalsa INPS')).',
'.prepare($rivalsainps).',
'.prepare(get_var("Percentuale ritenuta d'acconto")).',
'.prepare($ritenutaacconto).',
@ -455,7 +455,7 @@ switch (post('op')) {
// Aggiunta sconto
if (!empty($costi_intervento['sconto_globale'])) {
$subtot = $costi_intervento['sconto_globale'];
$subtot = -$costi_intervento['sconto_globale'];
// Calcolo iva
$query = 'SELECT * FROM co_iva WHERE id='.prepare($idiva);
@ -475,7 +475,7 @@ switch (post('op')) {
$rs = $dbo->fetchArray($query);
$ritenutaacconto = ($subtot + $rivalsainps) / 100 * $rs[0]['percentuale'];
$query = 'INSERT INTO co_righe_documenti(iddocumento, idintervento, idconto, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, qta, idrivalsainps, rivalsainps, idritenutaacconto, ritenutaacconto, `order`) VALUES('.prepare($id_record).', NULL, '.prepare($idconto).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare('Sconto '.$descrizione).', '.prepare(-$subtot).', 1, '.prepare(get_var('Percentuale rivalsa INPS')).', '.prepare($rivalsainps).', '.prepare(get_var("Percentuale ritenuta d'acconto")).', '.prepare($ritenutaacconto).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))';
$query = 'INSERT INTO co_righe_documenti(iddocumento, idintervento, idconto, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, qta, idrivalsainps, rivalsainps, idritenutaacconto, ritenutaacconto, `order`) VALUES('.prepare($id_record).', NULL, '.prepare($idconto).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare('Sconto '.$descrizione).', '.prepare($subtot).', 1, '.prepare(get_var('Percentuale rivalsa INPS')).', '.prepare($rivalsainps).', '.prepare(get_var("Percentuale ritenuta d'acconto")).', '.prepare($ritenutaacconto).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))';
$dbo->query($query);
}
@ -746,6 +746,17 @@ switch (post('op')) {
}
break;
case 'adddescrizione':
if (!empty($id_record)) {
$descrizione = post('descrizione');
$query = 'INSERT INTO co_righe_documenti(iddocumento, descrizione, is_descrizione) VALUES('.prepare($id_record).', '.prepare($descrizione).', 1)';
if ($dbo->query($query)) {
$_SESSION['infos'][] = tr('Riga descrittiva aggiunta!');
}
}
break;
case 'editriga':
if (isset($post['idriga'])) {
// Selezione costi da intervento
@ -767,11 +778,14 @@ switch (post('op')) {
$subtot = $prezzo * $qta;
// Lettura idarticolo dalla riga documento
$rs = $dbo->fetchArray('SELECT iddocumento, idarticolo, qta, abilita_serial FROM co_righe_documenti WHERE id='.prepare($idriga));
$rs = $dbo->fetchArray('SELECT * FROM co_righe_documenti WHERE id='.prepare($idriga));
$idarticolo = $rs[0]['idarticolo'];
$idddt = $rs[0]['idddt'];
$idordine = $rs[0]['idordine'];
$old_qta = $rs[0]['qta'];
$iddocumento = $rs[0]['iddocumento'];
$abilita_serial = $rs[0]['abilita_serial'];
$is_descrizione = $rs[0]['is_descrizione'];
// Controllo per gestire i serial
if (!empty($idarticolo)) {
@ -782,6 +796,16 @@ switch (post('op')) {
}
}
// Se c'è un collegamento ad un ddt, aggiorno la quantità evasa
if (!empty($idddt)) {
$dbo->query('UPDATE dt_righe_ddt SET qta_evasa=qta_evasa-'.$old_qta.' + '.$qta.' WHERE descrizione='.prepare($rs[0]['descrizione']).' AND idarticolo='.prepare($rs[0]['idarticolo']).' AND idddt='.prepare($idddt).' AND idiva='.prepare($rs[0]['idiva']));
}
// Se c'è un collegamento ad un ordine, aggiorno la quantità evasa
if (!empty($idddt)) {
$dbo->query('UPDATE or_righe_ordini SET qta_evasa=qta_evasa-'.$old_qta.' + '.$qta.' WHERE descrizione='.prepare($rs[0]['descrizione']).' AND idarticolo='.prepare($rs[0]['idarticolo']).' AND idordine='.prepare($idordine).' AND idiva='.prepare($rs[0]['idiva']));
}
// Calcolo iva
$query = 'SELECT * FROM co_iva WHERE id='.prepare($idiva);
$rs = $dbo->fetchArray($query);
@ -799,8 +823,13 @@ switch (post('op')) {
$rs = $dbo->fetchArray($query);
$ritenutaacconto = (($prezzo * $qta) - $sconto + $rivalsainps) / 100 * $rs[0]['percentuale'];
// Modifica riga generica sul documento
$query = 'UPDATE co_righe_documenti SET idconto='.prepare($idconto).', idiva='.prepare($idiva).', desc_iva='.prepare($desc_iva).', iva='.prepare($iva).', iva_indetraibile='.prepare($iva_indetraibile).', descrizione='.prepare($descrizione).', subtotale='.prepare($subtot).', sconto='.prepare($sconto).', sconto_unitario='.prepare($sconto_unitario).', tipo_sconto='.prepare($tipo_sconto).', um='.prepare($um).', idritenutaacconto='.prepare(post('idritenutaacconto')).', ritenutaacconto='.prepare($ritenutaacconto).', idrivalsainps='.prepare(post('idrivalsainps')).', rivalsainps='.prepare($rivalsainps).', qta='.prepare($qta).' WHERE id='.prepare($idriga).' AND iddocumento='.prepare($iddocumento);
if ($is_descrizione == 0) {
// Modifica riga generica sul documento
$query = 'UPDATE co_righe_documenti SET idconto='.prepare($idconto).', idiva='.prepare($idiva).', desc_iva='.prepare($desc_iva).', iva='.prepare($iva).', iva_indetraibile='.prepare($iva_indetraibile).', descrizione='.prepare($descrizione).', subtotale='.prepare($subtot).', sconto='.prepare($sconto).', sconto_unitario='.prepare($sconto_unitario).', tipo_sconto='.prepare($tipo_sconto).', um='.prepare($um).', idritenutaacconto='.prepare(post('idritenutaacconto')).', ritenutaacconto='.prepare($ritenutaacconto).', idrivalsainps='.prepare(post('idrivalsainps')).', rivalsainps='.prepare($rivalsainps).', qta='.prepare($qta).' WHERE id='.prepare($idriga).' AND iddocumento='.prepare($iddocumento);
} else {
// Modifica riga descrizione sul documento
$query = 'UPDATE co_righe_documenti SET descrizione='.prepare($descrizione).' WHERE id='.prepare($idriga).' AND iddocumento='.prepare($iddocumento);
}
if ($dbo->query($query)) {
// Modifica per gestire i serial
if (!empty($idarticolo)) {
@ -874,7 +903,7 @@ switch (post('op')) {
$rs = $dbo->fetchArray($query);
$perc_iva = $rs[0]['percentuale'];
$desc_iva = $rs[0]['descrizione'];
$iva = $subtot / 100 * $perc_iva;
$iva = ($subtot - $sconto) / 100 * $perc_iva;
// Calcolo l'iva indetraibile
$q = 'SELECT indetraibile FROM co_iva WHERE id='.prepare($idiva);
@ -896,7 +925,7 @@ switch (post('op')) {
// Inserimento riga normale
elseif ($qta != 0) {
$query = 'INSERT INTO co_righe_documenti(iddocumento, idarticolo, descrizione, idddt, idiva, desc_iva, iva, iva_indetraibile, subtotale, sconto, um, qta, `order`) VALUES('.prepare($id_record).', '.prepare($idarticolo).', '.prepare($descrizione).', '.prepare($idddt).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($subtot).', '.prepare($sconto).', '.prepare($um).', '.prepare($qta).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))';
$query = 'INSERT INTO co_righe_documenti(iddocumento, idarticolo, descrizione, idddt, idiva, desc_iva, iva, iva_indetraibile, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, `order`) VALUES('.prepare($id_record).', '.prepare($idarticolo).', '.prepare($descrizione).', '.prepare($idddt).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($subtot).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).', '.prepare($um).', '.prepare($qta).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))';
$dbo->query($query);
}
@ -979,7 +1008,7 @@ switch (post('op')) {
// Inserimento riga normale
elseif ($qta != 0) {
$dbo->query('INSERT INTO co_righe_documenti(iddocumento, idarticolo, idordine, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, um, qta, `order`) VALUES('.prepare($id_record).', '.prepare($idarticolo).', '.prepare($idordine).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($subtot).', '.prepare($sconto).', '.prepare($um).', '.prepare($qta).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))');
$dbo->query('INSERT INTO co_righe_documenti(iddocumento, idarticolo, idordine, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, `order`) VALUES('.prepare($id_record).', '.prepare($idarticolo).', '.prepare($idordine).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($subtot).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).', '.prepare($um).', '.prepare($qta).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))');
$idriga = $dbo->lastInsertedID();
}
@ -1294,6 +1323,25 @@ switch (post('op')) {
break;
}
// Aggiornamento stato dei ddt presenti in questa fattura in base alle quantità totali evase
if (!empty($id_record)) {
$rs = $dbo->fetchArray('SELECT idddt FROM co_righe_documenti WHERE iddocumento='.prepare($id_record));
for ($i = 0; $i < sizeof($rs); ++$i) {
$dbo->query('UPDATE dt_ddt SET idstatoddt=(SELECT id FROM dt_statiddt WHERE descrizione="'.get_stato_ddt($rs[$i]['idddt']).'")');
}
}
// Aggiornamento stato degli ordini presenti in questa fattura in base alle quantità totali evase
if (!empty($id_record)) {
$rs = $dbo->fetchArray('SELECT idordine FROM co_righe_documenti WHERE iddocumento='.prepare($id_record));
for ($i = 0; $i < sizeof($rs); ++$i) {
$dbo->query('UPDATE or_ordini SET idstatoordine=(SELECT id FROM or_statiordine WHERE descrizione="'.get_stato_ordine($rs[$i]['idordine']).'")');
}
}
// Aggiornamento sconto sulle righe
if (post('op') !== null && post('op') != 'update') {
aggiorna_sconto([
'parent' => 'co_documenti',

View File

@ -0,0 +1,50 @@
<?php
include_once __DIR__.'/../../core.php';
$module = Modules::get($id_module);
if ($module['name'] == 'Fatture di vendita') {
$dir = 'entrata';
$conti = 'conti-vendite';
} else {
$dir = 'uscita';
$conti = 'conti-acquisti';
}
$record = $dbo->fetchArray('SELECT * FROM co_documenti WHERE id='.prepare($id_record));
$numero = ($record[0]['numero_esterno'] != '') ? $record[0]['numero_esterno'] : $record[0]['numero'];
$idconto = $record[0]['idconto'];
$idanagrafica = $record[0]['idanagrafica'];
/*
Form di inserimento riga documento
*/
echo '
<p>'.tr('Documento numero _NUM_', [
'_NUM_' => $numero,
]).'</p>
<form action="'.$rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$id_record.'" method="post">
<input type="hidden" name="op" value="adddescrizione">
<input type="hidden" name="backto" value="record-edit">
<input type="hidden" name="dir" value="'.$dir.'">';
// Descrizione
echo '
<div class="row">
<div class="col-md-12">
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "required": 1 ]}
</div>
</div>';
echo '
<!-- PULSANTI -->
<div class="row">
<div class="col-md-12 text-right">
<button type="submit" class="btn btn-primary pull-right"><i class="fa fa-plus"></i> '.tr('Aggiungi').'</button>
</div>
</div>
</form>';

View File

@ -41,7 +41,7 @@ foreach ($rs as $key => $value) {
echo '
<div class="row">
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Intervento').'", "name": "idintervento", "required": 1, "values": "json='.substr(str_replace('"', '\"', json_encode($rs)), 2, -2).'", "extra": "onchange=\"$data = $(this).selectData(); $(\'#descrizione\').val($data.descrizione); $(\'#prezzo\').val($data.prezzo);\"" ]}
{[ "type": "select", "label": "'.tr('Intervento').'", "name": "idintervento", "required": 1, "values": '.json_encode($rs).', "extra": "onchange=\"$data = $(this).selectData(); $(\'#descrizione\').val($data.descrizione); $(\'#prezzo\').val($data.prezzo);\"" ]}
</div>
</div>';

View File

@ -119,7 +119,7 @@ if (!empty($rs)) {
echo '
<tr>
<td>
<input type="hidden" name="abilita_serial['.$r['id'].']" value="'.$r['abilita_serial'].'" />
<input type="hidden" id="idarticolo_'.$i.'" name="idarticolo['.$r['id'].']" value="'.$r['idarticolo'].'" />
<input type="hidden" id="descrizione_'.$i.'" name="descrizione['.$r['id'].']" value="'.$r['descrizione'].'" />';
@ -144,7 +144,7 @@ if (!empty($rs)) {
// Q.tà da evadere
echo '
<td>
{[ "type": "number", "name": "qta_da_evadere['.$r['id'].']", "id": "qta_'.$i.'", "required": 1, "value": "'.$r['qta_rimanente'].'", "extra" : "onkeyup=\"ricalcola_subtotale_riga('.$i.');\"", "decimals": "qta|0" ]}
{[ "type": "number", "name": "qta_da_evadere['.$r['id'].']", "id": "qta_'.$i.'", "required": 1, "value": "'.$r['qta_rimanente'].'", "extra" : "onkeyup=\"ricalcola_subtotale_riga('.$i.');\"", "decimals": "qta", "min-value": "0" ]}
</td>';
// Subtotale

View File

@ -62,6 +62,9 @@ $_SESSION['superselect']['idanagrafica'] = $records[0]['idanagrafica'];
<div class="row">
<div class="col-md-3">
<?php
echo Modules::link('Anagrafiche', $records[0]['idanagrafica'], null, null, 'class="pull-right"');
if ($dir == 'entrata') {
?>
{[ "type": "select", "label": "<?php echo tr('Cliente'); ?>", "name": "idanagrafica", "required": 1, "ajax-source": "clienti", "value": "$idanagrafica$" ]}
@ -299,6 +302,11 @@ if ($records[0]['stato'] != 'Pagato' && $records[0]['stato'] != 'Emessa') {
<a class="btn btn-sm btn-primary" data-href="'.$rootdir.'/modules/fatture/add_riga.php?id_module='.$id_module.'&id_record='.$id_record.'" data-toggle="modal" data-title="Aggiungi riga" data-target="#bs-popup">
<i class="fa fa-plus"></i> Riga generica
</a>';
echo '
<a class="btn btn-sm btn-primary" data-href="'.$rootdir.'/modules/fatture/add_descrizione.php?id_module='.$id_module.'&id_record='.$id_record.'" data-toggle="modal" data-title="Aggiungi descrizione" data-target="#bs-popup">
<i class="fa fa-plus"></i> Descrizione
</a>';
}
?>
</div>

View File

@ -44,70 +44,73 @@ echo '
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "required": 1, "value": '.json_encode($rsr[0]['descrizione']).' ]}
</div>
</div>';
if($rsr[0]['is_descrizione']==0){
if (get_var('Percentuale rivalsa INPS') != '' || get_var("Percentuale ritenuta d'acconto") != '' || $dir == 'uscita') {
echo '
<div class="row">';
// Rivalsa INPS
if (get_var('Percentuale rivalsa INPS') != '' || $dir == 'uscita') {
echo '
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Rivalsa INPS').'", "name": "idrivalsainps", "value": "'.$rsr[0]['idrivalsainps'].'", "values": "query=SELECT * FROM co_rivalsainps", "required": '.intval($dir != 'uscita').' ]}
</div>';
}
// Ritenuta d'acconto
if (get_var("Percentuale ritenuta d'acconto") != '' || $dir == 'uscita') {
echo '
<div class="col-md-6">
{[ "type": "select", "label": "'.tr("Ritenuta d'acconto").'", "name": "idritenutaacconto", "value": "'.$rsr[0]['idritenutaacconto'].'", "values": "query=SELECT * FROM co_ritenutaacconto", "required": '.intval($dir != 'uscita').' ]}
</div>';
}
if (get_var('Percentuale rivalsa INPS') != '' || get_var("Percentuale ritenuta d'acconto") != '' || $dir == 'uscita') {
echo '
<div class="row">';
// Rivalsa INPS
if (get_var('Percentuale rivalsa INPS') != '' || $dir == 'uscita') {
echo '
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Rivalsa INPS').'", "name": "idrivalsainps", "value": "'.$rsr[0]['idrivalsainps'].'", "values": "query=SELECT * FROM co_rivalsainps", "required": '.intval($dir != 'uscita').' ]}
</div>';
}
// Ritenuta d'acconto
if (get_var("Percentuale ritenuta d'acconto") != '' || $dir == 'uscita') {
echo '
<div class="col-md-6">
{[ "type": "select", "label": "'.tr("Ritenuta d'acconto").'", "name": "idritenutaacconto", "value": "'.$rsr[0]['idritenutaacconto'].'", "values": "query=SELECT * FROM co_ritenutaacconto", "required": '.intval($dir != 'uscita').' ]}
</div>';
}
// Iva
echo '
<div class="row">
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Iva').'", "name": "idiva", "required": 1, "value": "'.$rsr[0]['idiva'].'", "values": "query=SELECT * FROM co_iva ORDER BY descrizione ASC" ]}
</div>';
echo '
</div>';
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Conto').'", "name": "idconto", "required": 1, "value": "'.$idconto.'", "ajax-source": "'.$conti.'" ]}
</div>
</div>';
// Quantità
echo '
<div class="row">
<div class="col-md-3">
{[ "type": "number", "label": "'.tr('Q.tà').'", "name": "qta", "required": 1, "value": "'.$rsr[0]['qta'].'", "decimals": "qta" ]}
</div>';
// Unità di misura
echo '
<div class="col-md-3">
{[ "type": "select", "label": "'.tr('Unità di misura').'", "icon-after": "add|'.Modules::get('Unità di misura')['id'].'", "name": "um", "ajax-source": "misure", "value": "'.$rsr[0]['um'].'" ]}
</div>';
// Costo unitario
echo '
<div class="col-md-3">
{[ "type": "number", "label": "'.tr('Costo unitario').'", "name": "prezzo", "required": 1, "value": "'.($rsr[0]['subtotale'] / $rsr[0]['qta']).'", "icon-after": "&euro;" ]}
</div>';
// Sconto unitario
echo '
<div class="col-md-3">
{[ "type": "number", "label": "'.tr('Sconto unitario').'", "name": "sconto", "value": "'.$sconto.'", "icon-after": "choice|untprc|'.$tipo_sconto.'" ]}
</div>
</div>';
}
// Iva
echo '
<div class="row">
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Iva').'", "name": "idiva", "required": 1, "value": "'.$rsr[0]['idiva'].'", "values": "query=SELECT * FROM co_iva ORDER BY descrizione ASC" ]}
</div>';
echo '
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Conto').'", "name": "idconto", "required": 1, "value": "'.$idconto.'", "ajax-source": "'.$conti.'" ]}
</div>
</div>';
// Quantità
echo '
<div class="row">
<div class="col-md-3">
{[ "type": "number", "label": "'.tr('Q.tà').'", "name": "qta", "required": 1, "value": "'.$rsr[0]['qta'].'", "decimals": "qta" ]}
</div>';
// Unità di misura
echo '
<div class="col-md-3">
{[ "type": "select", "label": "'.tr('Unità di misura').'", "icon-after": "add|'.Modules::get('Unità di misura')['id'].'", "name": "um", "ajax-source": "misure", "value": "'.$rsr[0]['um'].'" ]}
</div>';
// Costo unitario
echo '
<div class="col-md-3">
{[ "type": "number", "label": "'.tr('Costo unitario').'", "name": "prezzo", "required": 1, "value": "'.($rsr[0]['subtotale'] / $rsr[0]['qta']).'", "icon-after": "&euro;" ]}
</div>';
// Sconto unitario
echo '
<div class="col-md-3">
{[ "type": "number", "label": "'.tr('Sconto unitario').'", "name": "sconto", "value": "'.$sconto.'", "icon-after": "choice|untprc|'.$tipo_sconto.'" ]}
</div>
</div>';
echo '
<!-- PULSANTI -->

View File

@ -9,15 +9,17 @@ $rs = $dbo->fetchArray("SELECT *, IFNULL((SELECT codice FROM mg_articoli WHERE i
echo '
<table class="table table-striped table-hover table-condensed table-bordered">
<tr>
<th>'.tr('Descrizione').'</th>
<th width="120">'.tr('Q.').'</th>
<th width="80">'.tr('U.m.').'</th>
<th width="120">'.tr('Costo unitario').'</th>
<th width="120">'.tr('Iva').'</th>
<th width="120">'.tr('Imponibile').'</th>
<th width="60"></th>
</tr>
<thead>
<tr>
<th>'.tr('Descrizione').'</th>
<th width="120">'.tr('Q.').'</th>
<th width="80">'.tr('U.m.').'</th>
<th width="120">'.tr('Costo unitario').'</th>
<th width="120">'.tr('Iva').'</th>
<th width="120">'.tr('Imponibile').'</th>
<th width="60"></th>
</tr>
</thead>
<tbody class="sortable">';
if (!empty($rs)) {
@ -151,43 +153,69 @@ if (!empty($rs)) {
</td>';
echo '
<td class="text-right">
'.Translator::numberToLocale($r['qta']).'
<td class="text-right">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['qta']);
}
echo '
</td>';
// Unità di misura
echo '
<td class="text-center">
'.$r['um'].'
<td class="text-center">';
if($r['is_descrizione']==0){
echo
$r['um'];
}
echo '
</td>';
// Costo unitario
echo '
<td class="text-right">
'.Translator::numberToLocale($r['subtotale'] / $r['qta']).' &euro;';
<td class="text-right">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['subtotale'] / $r['qta']).' &euro;';
if ($r['sconto_unitario'] > 0) {
echo '
<br><small class="label label-danger">- '.tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
if ($r['sconto_unitario'] > 0) {
echo '
<br><small class="label label-danger">- '.tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
}
}
echo '
</td>';
// Iva
echo '
<td class="text-right">
'.Translator::numberToLocale($r['iva']).' &euro;
<br><small class="help-block">'.$r['desc_iva'].'</small>
<td class="text-right">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['iva']).' &euro;
<br><small class="help-block">'.$r['desc_iva'].'</small>';
}
echo '
</td>';
// Imponibile
echo '
<td class="text-right">
'.Translator::numberToLocale($r['subtotale'] - $r['sconto']).' &euro;
<td class="text-right">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['subtotale'] - $r['sconto']).' &euro;';
}
echo '
</td>';
// Possibilità di rimuovere una riga solo se la fattura non è pagata

View File

@ -120,10 +120,10 @@ switch (post('op')) {
}
// Totali
$prezzo_ore_consuntivo = $prezzo_ore_unitario * $ore + $prezzo_dirittochiamata;
$prezzo_ore_consuntivo = $prezzo_ore_unitario * $ore;
$prezzo_km_consuntivo = $prezzo_km_unitario * $km;
$prezzo_ore_consuntivo_tecnico = $prezzo_ore_unitario_tecnico * $ore + $prezzo_dirittochiamata_tecnico;
$prezzo_ore_consuntivo_tecnico = $prezzo_ore_unitario_tecnico * $ore;
$prezzo_km_consuntivo_tecnico = $prezzo_km_unitario_tecnico * $km;
// Sconti
@ -216,11 +216,17 @@ switch (post('op')) {
}
*/
$formato = get_var('Formato codice intervento');
$template = str_replace('#', '%', $formato);
// Condizioni aggiuntive: WHERE concat("", codice * 1) = codice AND LENGTH(codice) = '.strlen($formato).'
$rs = $dbo->fetchArray('SELECT codice FROM in_interventi ORDER BY id DESC LIMIT 1');
$rs = $dbo->fetchArray('SELECT codice FROM in_interventi WHERE codice=(SELECT MAX(CAST(codice AS SIGNED)) FROM in_interventi) AND codice LIKE '.prepare($template).' ORDER BY codice DESC LIMIT 0,1');
$codice = get_next_code($rs[0]['codice'], 1, $formato);
if (empty($codice)) {
$rs = $dbo->fetchArray('SELECT codice FROM in_interventi WHERE codice LIKE '.prepare($template).' ORDER BY codice DESC LIMIT 0,1');
$codice = get_next_code($rs[0]['codice'], 1, $formato);
}
// Informazioni di base
$idpreventivo = post('idpreventivo');
$idcontratto = post('idcontratto');

View File

@ -27,6 +27,13 @@ if (Auth::admin() || $_SESSION['gruppo'] != 'Tecnici') {
<td class="text-right">'.Translator::numberToLocale($costi['manodopera_scontato']).' &euro;</td>
</tr>
<tr>
<th>'.tr('Totale diritto di chiamata', [], ['upper' => true]).'</th>
<td class="text-right">'.Translator::numberToLocale($costi['dirittochiamata_costo']).' &euro;</td>
<td class="text-right">'.Translator::numberToLocale($costi['dirittochiamata_addebito']).' &euro;</td>
<td class="text-right">'.Translator::numberToLocale($costi['dirittochiamata_scontato']).' &euro;</td>
</tr>
<tr>
<th>'.tr('Totale viaggio', [], ['upper' => true]).'</th>
<td class="text-right">'.Translator::numberToLocale($costi['viaggio_costo']).' &euro;</td>
@ -54,16 +61,16 @@ if (Auth::admin() || $_SESSION['gruppo'] != 'Tecnici') {
<td class="text-right">-</td>
<td class="text-right">'.Translator::numberToLocale(-$costi['sconto_globale']).' &euro;</td>
</tr>
<tr class='.$hide.' >
<th>'.tr('Imponibile', [], ['upper' => true]).'</th>
<td class="text-right">'.Translator::numberToLocale($costi['totale_costo']).' &euro;</td>
<td class="text-right">'.Translator::numberToLocale($costi['totale_addebito']).' &euro;</td>
<td class="text-right">'.Translator::numberToLocale($costi['totale']).' &euro;</td>
</tr>
<tr class='.$hide.' >
<th>'.tr('IVA (_DESC_)', [ _DESC_ => $rs_iva[0]['descrizione']], ['upper' => true]).'</th>
<td class="text-right">'.Translator::numberToLocale(($costi['totale_costo']/100*$rs_iva[0]['percentuale'])).' &euro;</td>

View File

@ -45,7 +45,7 @@ if (empty($records[0]['firma_file'])) {
<!-- RIGA 1 -->
<div class="row">
<div class="col-md-3">
<?php
<?php
echo Modules::link('Anagrafiche', $records[0]['idanagrafica'], null, null, 'class="pull-right"');
?>
{[ "type": "select", "label": "<?php echo tr('Cliente'); ?>", "name": "idanagrafica", "required": 1, "values": "query=SELECT an_anagrafiche.idanagrafica AS id, ragione_sociale AS descrizione FROM an_anagrafiche INNER JOIN (an_tipianagrafiche_anagrafiche INNER JOIN an_tipianagrafiche ON an_tipianagrafiche_anagrafiche.idtipoanagrafica=an_tipianagrafiche.idtipoanagrafica) ON an_anagrafiche.idanagrafica=an_tipianagrafiche_anagrafiche.idanagrafica WHERE descrizione='Cliente' AND deleted=0 ORDER BY ragione_sociale", "value": "$idanagrafica$", "ajax-source": "clienti" ]}
@ -56,6 +56,9 @@ if (empty($records[0]['firma_file'])) {
</div>
<div class="col-md-3">
<?php
echo Modules::link('Anagrafiche', $records[0]['idclientefinale'], null, null, 'class="pull-right"');
?>
{[ "type": "select", "label": "<?php echo tr('Per conto di'); ?>", "name": "idclientefinale", "value": "$idclientefinale$", "ajax-source": "clienti" ]}
</div>
@ -335,4 +338,4 @@ if (!empty($fatture)) {
<a class="btn btn-danger ask" data-backto="record-list">
<i class="fa fa-trash"></i> <?php echo tr('Elimina') ?>
</a>
</a>

View File

@ -173,6 +173,16 @@ function get_costi_intervento($id_intervento)
ROUND(prezzo_ore_consuntivo, '.$decimals.') - ROUND(sconto, '.$decimals.')
), 0) AS manodopera_scontato,
COALESCE(SUM(
ROUND(prezzo_dirittochiamata_tecnico, '.$decimals.')
), 0) AS dirittochiamata_costo,
COALESCE(SUM(
ROUND(prezzo_dirittochiamata, '.$decimals.')
), 0) AS dirittochiamata_addebito,
COALESCE(SUM(
ROUND(prezzo_dirittochiamata, '.$decimals.')
), 0) AS dirittochiamata_scontato,
COALESCE(SUM(
ROUND(prezzo_km_consuntivo_tecnico, '.$decimals.')
), 0) AS viaggio_costo,
@ -215,6 +225,7 @@ function get_costi_intervento($id_intervento)
$result['totale_costo'] = sum([
$result['manodopera_costo'],
$result['dirittochiamata_costo'],
$result['viaggio_costo'],
$result['ricambi_costo'],
$result['altro_costo'],
@ -222,6 +233,7 @@ function get_costi_intervento($id_intervento)
$result['totale_addebito'] = sum([
$result['manodopera_addebito'],
$result['dirittochiamata_addebito'],
$result['viaggio_addebito'],
$result['ricambi_addebito'],
$result['altro_addebito'],
@ -229,6 +241,7 @@ function get_costi_intervento($id_intervento)
$result['totale_scontato'] = sum([
$result['manodopera_scontato'],
$result['dirittochiamata_scontato'],
$result['viaggio_scontato'],
$result['ricambi_scontato'],
$result['altro_scontato'],

View File

@ -11,5 +11,5 @@ function genera_form_componente($contenuto)
$fields[$key] = '<div class="col-md-4">'.$value.'</div>';
}
echo $title.PHP_EOL.implode(PHP_EOL, $fields).PHP_EOL.'<script src="'.ROOTDIR.'/lib/init.js"></script>';
echo $title.PHP_EOL.implode(PHP_EOL, $fields).PHP_EOL.'<script>start_inputmask( "#info_componente" );</script>';
}

View File

@ -189,6 +189,17 @@ switch (post('op')) {
}
}
break;
case 'adddescrizione':
if (!empty($id_record)) {
$descrizione = post('descrizione');
$query = 'INSERT INTO or_righe_ordini(idordine, descrizione, is_descrizione) VALUES('.prepare($id_record).', '.prepare($descrizione).', 1)';
if ($dbo->query($query)) {
$_SESSION['infos'][] = tr('Riga descrittiva aggiunta!');
}
}
break;
// Scollegamento articolo da ordine
case 'unlink_articolo':
@ -253,11 +264,12 @@ switch (post('op')) {
$sconto = $sconto * $qta;
// Lettura idarticolo dalla riga documento
$rs = $dbo->fetchArray('SELECT idordine, idarticolo, qta, abilita_serial FROM or_righe_ordini WHERE id='.prepare($idriga));
$rs = $dbo->fetchArray('SELECT idordine, idarticolo, qta, abilita_serial, is_descrizione FROM or_righe_ordini WHERE id='.prepare($idriga));
$idarticolo = $rs[0]['idarticolo'];
$old_qta = $rs[0]['qta'];
$idordine = $rs[0]['idordine'];
$abilita_serial = $rs[0]['abilita_serial'];
$is_descrizione = $rs[0]['is_descrizione'];
// Controllo per gestire i serial
if (!empty($idarticolo)) {
@ -275,8 +287,12 @@ switch (post('op')) {
$iva_indetraibile = $iva / 100 * $rs[0]['indetraibile'];
$desc_iva = $rs[0]['descrizione'];
// Modifica riga generica sul documento
$query = 'UPDATE or_righe_ordini SET idiva='.prepare($idiva).', desc_iva='.prepare($rs[0]['descrizione']).', iva='.prepare($iva).', iva_indetraibile='.prepare($iva_indetraibile).', descrizione='.prepare($descrizione).', subtotale='.prepare($subtot).', sconto='.prepare($sconto).', sconto_unitario='.prepare($sconto_unitario).', tipo_sconto='.prepare($tipo_sconto).', um='.prepare($um).', qta='.prepare($qta).' WHERE id='.prepare($idriga);
if($is_descrizione==0){
// Modifica riga generica sul documento
$query = 'UPDATE or_righe_ordini SET idiva='.prepare($idiva).', desc_iva='.prepare($rs[0]['descrizione']).', iva='.prepare($iva).', iva_indetraibile='.prepare($iva_indetraibile).', descrizione='.prepare($descrizione).', subtotale='.prepare($subtot).', sconto='.prepare($sconto).', sconto_unitario='.prepare($sconto_unitario).', tipo_sconto='.prepare($tipo_sconto).', um='.prepare($um).', qta='.prepare($qta).' WHERE id='.prepare($idriga);
}else{
$query = 'UPDATE or_righe_ordini SET descrizione='.prepare($descrizione).' WHERE id='.prepare($idriga);
}
if ($dbo->query($query)) {
$_SESSION['infos'][] = tr('Riga modificata!');

View File

@ -0,0 +1,41 @@
<?php
include_once __DIR__.'/../../core.php';
$module = Modules::get($id_module);
$record = $dbo->fetchArray('SELECT * FROM or_ordini WHERE id='.prepare($id_record));
$numero = $record[0]['numero'];
$idanagrafica = $record[0]['idanagrafica'];
/*
Form di inserimento riga documento
*/
echo '
<p>'.tr('Ordine numero _NUM_', [
'_NUM_' => $numero,
]).'</p>
<form action="'.$rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$id_record.'" method="post">
<input type="hidden" name="op" value="adddescrizione">
<input type="hidden" name="backto" value="record-edit">
<input type="hidden" name="dir" value="'.$dir.'">';
// Descrizione
echo '
<div class="row">
<div class="col-md-12">
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "required": 1 ]}
</div>
</div>';
echo '
<!-- PULSANTI -->
<div class="row">
<div class="col-md-12 text-right">
<button type="submit" class="btn btn-primary pull-right"><i class="fa fa-plus"></i> '.tr('Aggiungi').'</button>
</div>
</div>
</form>';

View File

@ -79,39 +79,41 @@ echo '
</div>
</div>';
// Iva
echo '
if($rsr[0]['is_descrizione']!=1){
// Iva
echo '
<div class="row">
<div class="col-md-4">
{[ "type": "select", "label": "'.tr('Iva').'", "name": "idiva", "required": 1, "value": "'.$idiva.'", "values": "query=SELECT * FROM co_iva ORDER BY descrizione ASC" ]}
</div>';
// Quantità
echo '
// Quantità
echo '
<div class="col-md-4">
{[ "type": "number", "label": "'.tr('Q.tà').'", "name": "qta", "required": 1, "value": "'.$qta.'", "decimals": "qta" ]}
</div>';
// Unità di misura
echo '
// Unità di misura
echo '
<div class="col-md-4">
{[ "type": "select", "label": "'.tr('Unità di misura').'", "icon-after": "add|'.Modules::get('Unità di misura')['id'].'", "name": "um", "ajax-source": "misure", "value": "'.$um.'" ]}
</div>
</div>';
// Costo unitario
echo '
// Costo unitario
echo '
<div class="row">
<div class="col-md-6">
{[ "type": "number", "label": "'.tr('Costo unitario').'", "name": "prezzo", "required": 1, "icon-after": "&euro;", "value": "'.$prezzo.'" ]}
</div>';
// Sconto unitario
echo '
// Sconto unitario
echo '
<div class="col-md-6">
{[ "type": "number", "label": "'.tr('Sconto unitario').'", "name": "sconto", "value": "'.$sconto.'", "icon-after": "choice|untprc|'.$tipo_sconto.'" ]}
</div>
</div>';
}
echo '

View File

@ -42,9 +42,12 @@ if ($module['name'] == 'Ordini cliente') {
<div class="row">
<div class="col-md-3">
<?php
<?php
echo Modules::link('Anagrafiche', $records[0]['idanagrafica'], null, null, 'class="pull-right"');
if ($dir == 'entrata') {
?>
?>
{[ "type": "select", "label": "<?php echo tr('Cliente'); ?>", "name": "idanagrafica", "required": 1, "values": "query=SELECT an_anagrafiche.idanagrafica AS id, ragione_sociale AS descrizione FROM an_anagrafiche INNER JOIN (an_tipianagrafiche_anagrafiche INNER JOIN an_tipianagrafiche ON an_tipianagrafiche_anagrafiche.idtipoanagrafica=an_tipianagrafiche.idtipoanagrafica) ON an_anagrafiche.idanagrafica=an_tipianagrafiche_anagrafiche.idanagrafica WHERE descrizione='Cliente' AND deleted=0 ORDER BY ragione_sociale", "value": "$idanagrafica$", "ajax-source": "clienti" ]}
<?php
} else {
@ -93,6 +96,7 @@ if ($module['name'] == 'Ordini cliente') {
?>
<a class="btn btn-sm btn-primary" data-href="<?php echo $rootdir ?>/modules/ordini/add_articolo.php?id_module=<?php echo $id_module ?>&id_record=<?php echo $id_record ?>" data-toggle="modal" data-title="Aggiungi articolo" data-target="#bs-popup"><i class="fa fa-plus"></i> Articolo</a>
<a class="btn btn-sm btn-primary" data-href="<?php echo $rootdir ?>/modules/ordini/add_riga.php?id_module=<?php echo $id_module ?>&id_record=<?php echo $id_record ?>" data-toggle="modal" data-title="Aggiungi riga" data-target="#bs-popup"><i class="fa fa-plus"></i> Riga generica</a>
<a class="btn btn-sm btn-primary" data-href="<?php echo $rootdir ?>/modules/ordini/add_descrizione.php?id_module=<?php echo $id_module ?>&id_record=<?php echo $id_record ?>" data-toggle="modal" data-title="Aggiungi descrizione" data-target="#bs-popup"><i class="fa fa-plus"></i> Descrizione</a>
<?php
} ?>
</div>

View File

@ -2,6 +2,9 @@
include_once __DIR__.'/../../core.php';
// Aggiornamento stato di questo ordine
$dbo->query( 'UPDATE or_ordini SET idstatoordine=(SELECT id FROM or_statiordine WHERE descrizione="'.get_stato_ordine($id_record).'")' );
if (isset($id_record)) {
$records = $dbo->fetchArray('SELECT *, or_ordini.note, or_ordini.idpagamento, or_ordini.id AS idordine, or_statiordine.descrizione AS `stato`, or_tipiordine.descrizione AS `descrizione_tipodoc` FROM ((or_ordini LEFT OUTER JOIN or_statiordine ON or_ordini.idstatoordine=or_statiordine.id) INNER JOIN an_anagrafiche ON or_ordini.idanagrafica=an_anagrafiche.idanagrafica) INNER JOIN or_tipiordine ON or_ordini.idtipoordine=or_tipiordine.id WHERE or_ordini.id='.prepare($id_record));
}

View File

@ -75,49 +75,65 @@ if (!empty($rs)) {
echo '
<td class="text-center">';
if (empty($r['sconto_globale'])) {
echo '
<big>'.Translator::numberToLocale($r['qta'] - $r['qta_evasa']).'</big>
<br><small>('.tr('Q. iniziale').': '.Translator::numberToLocale($r['qta']).')</small>';
} else {
echo '1';
if($r['is_descrizione']==0){
if (empty($r['sconto_globale'])) {
echo '
<big>'.Translator::numberToLocale($r['qta'] - $r['qta_evasa']).'</big>
<br><small>('.tr('Q. iniziale').': '.Translator::numberToLocale($r['qta']).')</small>';
} else {
echo '1';
}
}
echo '
</td>';
// Unità di misura
echo '
<td class="text-center">
'.$r['um'].'
<td class="text-center">';
if($r['is_descrizione']==0){
echo
$r['um'];
}
echo '
</td>';
// Costo unitario
echo '
<td class="text-right">
'.Translator::numberToLocale($r['subtotale'] / $r['qta']).' &euro;';
<td class="text-right">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['subtotale'] / $r['qta']).' &euro;';
if ($r['sconto_unitario'] > 0) {
echo '
<br><small class="label label-danger">- '.tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
if ($r['sconto_unitario'] > 0) {
echo '
<br><small class="label label-danger">- '.tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
}
}
echo '
</td>';
// Iva
echo '
<td class="text-right">
'.Translator::numberToLocale($r['iva']).' &euro;
<br><small class="help-block">'.$r['desc_iva'].'</small>
<td class="text-right">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['iva']).' &euro;
<br><small class="help-block">'.$r['desc_iva'].'</small>';
}
echo '
</td>';
// Imponibile
echo '
<td class="text-right">
'.Translator::numberToLocale($r['subtotale'] - $r['sconto']).' &euro;
<td class="text-right">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['subtotale'] - $r['sconto']).' &euro;';
}
echo '
</td>';
// Possibilità di rimuovere una riga solo se l'ordine non è evaso

View File

@ -68,13 +68,14 @@ foreach ($results as $result) {
<div class="col-xs-12 col-md-6">
{[ "type": "select", "label": "'.tr('Scadenza').'", "name": "scadenza[]", "values": "list=\"1\":\"'.tr('Data fatturazione').'\",\"2\":\"'.tr('Data fatturazione fine mese').'\",\"3\":\"'.tr('Data fatturazione giorno fisso').'\",\"4\":\"'.tr('Data fatturazione fine mese (giorno fisso)').'\"", "value": "';
if ($select['giorno'] == 0) {
if ($result['giorno'] == 0) {
$select = 1;
} elseif ($select['giorno'] == -1) {
} elseif ($result['giorno'] == -1) {
$select = 2;
} elseif ($select['giorno'] < -1) {
} elseif ($result['giorno'] < -1) {
$select = 4;
} elseif ($select['giorno'] > 0) {
} elseif ($result['giorno'] > 0) {
$select = 3;
}
echo $select;

View File

@ -233,10 +233,25 @@ switch (post('op')) {
$_SESSION['infos'][] = tr('Articolo aggiunto!');
break;
case 'adddescrizione':
if (!empty($id_record)) {
$descrizione = post('descrizione');
$query = 'INSERT INTO co_righe_preventivi(idpreventivo, descrizione, is_descrizione) VALUES('.prepare($id_record).', '.prepare($descrizione).', 1)';
if ($dbo->query($query)) {
$_SESSION['infos'][] = tr('Riga descrittiva aggiunta!');
}
}
break;
case 'editriga':
$idriga = post('idriga');
$descrizione = post('descrizione');
//Info riga Preventivo
$rs = $dbo->fetchArray('SELECT * FROM co_righe_preventivi WHERE id='.prepare($idriga));
$is_descrizione = $rs[0]['is_descrizione'];
$qta = $post['qta'];
$prezzo = $post['prezzo'];
@ -257,8 +272,12 @@ switch (post('op')) {
$iva_indetraibile = $iva / 100 * $rs2[0]['indetraibile'];
$desc_iva = $rs2[0]['descrizione'];
// Modifica riga generica sul documento
$query = 'UPDATE co_righe_preventivi SET idiva='.prepare($idiva).', desc_iva='.prepare($desc_iva).', iva='.prepare($iva).', iva_indetraibile='.prepare($iva_indetraibile).', descrizione='.prepare($descrizione).', subtotale='.prepare($subtot).', sconto='.prepare($sconto).', sconto_unitario='.prepare($sconto_unitario).', tipo_sconto='.prepare($tipo_sconto).', um='.prepare($um).', qta='.prepare($qta).' WHERE id='.prepare($idriga);
if($is_descrizione==0){
// Modifica riga generica sul documento
$query = 'UPDATE co_righe_preventivi SET idiva='.prepare($idiva).', desc_iva='.prepare($desc_iva).', iva='.prepare($iva).', iva_indetraibile='.prepare($iva_indetraibile).', descrizione='.prepare($descrizione).', subtotale='.prepare($subtot).', sconto='.prepare($sconto).', sconto_unitario='.prepare($sconto_unitario).', tipo_sconto='.prepare($tipo_sconto).', um='.prepare($um).', qta='.prepare($qta).' WHERE id='.prepare($idriga);
}else{
$query = 'UPDATE co_righe_preventivi SET descrizione='.prepare($descrizione).' WHERE id='.prepare($idriga);
}
$dbo->query($query);
$_SESSION['infos'][] = 'Riga modificata!';

View File

@ -0,0 +1,41 @@
<?php
include_once __DIR__.'/../../core.php';
$module = Modules::get($id_module);
$record = $dbo->fetchArray('SELECT * FROM co_preventivi WHERE id='.prepare($id_record));
$numero = $record[0]['numero'];
$idanagrafica = $record[0]['idanagrafica'];
/*
Form di inserimento riga documento
*/
echo '
<p>'.tr('Preventivo numero _NUM_', [
'_NUM_' => $numero,
]).'</p>
<form action="'.$rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$id_record.'" method="post">
<input type="hidden" name="op" value="adddescrizione">
<input type="hidden" name="backto" value="record-edit">
<input type="hidden" name="dir" value="'.$dir.'">';
// Descrizione
echo '
<div class="row">
<div class="col-md-12">
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "required": 1 ]}
</div>
</div>';
echo '
<!-- PULSANTI -->
<div class="row">
<div class="col-md-12 text-right">
<button type="submit" class="btn btn-primary pull-right"><i class="fa fa-plus"></i> '.tr('Aggiungi').'</button>
</div>
</div>
</form>';

View File

@ -31,10 +31,17 @@ $_SESSION['superselect']['idanagrafica'] = $records[0]['idanagrafica'];
</div>
<div class="col-md-4">
<?php
echo Modules::link('Anagrafiche', $records[0]['idanagrafica'], null, null, 'class="pull-right"');
?>
{[ "type": "select", "label": "<?php echo tr('Cliente'); ?>", "name": "idanagrafica", "required": 1, "values": "query=SELECT an_anagrafiche.idanagrafica AS id, ragione_sociale AS descrizione FROM an_anagrafiche INNER JOIN (an_tipianagrafiche_anagrafiche INNER JOIN an_tipianagrafiche ON an_tipianagrafiche_anagrafiche.idtipoanagrafica=an_tipianagrafiche.idtipoanagrafica) ON an_anagrafiche.idanagrafica=an_tipianagrafiche_anagrafiche.idanagrafica WHERE descrizione='Cliente' AND deleted=0 ORDER BY ragione_sociale", "value": "$idanagrafica$", "ajax-source": "clienti" ]}
</div>
<div class="col-md-3">
<?php
if($records[0]['idagente']!=0)
echo Modules::link('Anagrafiche', $records[0]['idagente'], null, null, 'class="pull-right"');
?>
{[ "type": "select", "label": "<?php echo tr('Agente'); ?>", "name": "idagente", "values": "query=SELECT an_anagrafiche.idanagrafica AS id, ragione_sociale AS descrizione FROM an_anagrafiche INNER JOIN (an_tipianagrafiche_anagrafiche INNER JOIN an_tipianagrafiche ON an_tipianagrafiche_anagrafiche.idtipoanagrafica=an_tipianagrafiche.idtipoanagrafica) ON an_anagrafiche.idanagrafica=an_tipianagrafiche_anagrafiche.idanagrafica WHERE descrizione='Agente' AND deleted=0 ORDER BY ragione_sociale", "value": "$idagente$" ]}
</div>
@ -133,10 +140,12 @@ $_SESSION['superselect']['idanagrafica'] = $records[0]['idanagrafica'];
<div class="panel-body">
<?php if ($records[0]['stato'] != 'Pagato') {
?>
<div class="pull-left">
<a class="btn btn-primary" data-href="<?php echo $rootdir ?>/modules/preventivi/edit_riga.php?id_module=<?php echo $id_module ?>&id_record=<?php echo $id_record ?>" data-toggle="modal" data-title="Aggiungi riga" data-target="#bs-popup"><i class="fa fa-plus"></i> Riga</a><br>
</div>
?>
<a class="btn btn-primary" data-href="<?php echo $rootdir ?>/modules/preventivi/edit_riga.php?id_module=<?php echo $id_module ?>&id_record=<?php echo $id_record ?>" data-toggle="modal" data-title="Aggiungi riga" data-target="#bs-popup"><i class="fa fa-plus"></i> Riga</a>
<a class="btn btn-primary" data-href="<?php echo $rootdir ?>/modules/preventivi/add_descrizione.php?id_module=<?php echo $id_module ?>&id_record=<?php echo $id_record ?>" data-toggle="modal" data-title="Aggiungi descrizione" data-target="#bs-popup"><i class="fa fa-plus"></i> Descrizione</a>
<?php
} ?>
@ -200,4 +209,4 @@ if (!empty($fatture)) {
<a class="btn btn-danger ask" data-backto="record-list">
<i class="fa fa-trash"></i> <?php echo tr('Elimina'); ?>
</a>
</a>

View File

@ -61,55 +61,77 @@ echo '
<input type="hidden" name="idriga" value="'.$idriga.'">
<input type="hidden" name="backto" value="record-edit">';
// Elenco articoli raggruppati per gruppi e sottogruppi
echo '
if($rsr[0]['is_descrizione']!=1){
// Elenco articoli raggruppati per gruppi e sottogruppi
echo '
<div class="row">
<div class="col-md-12">
{[ "type": "select", "label": "'.tr('Articolo').'", "name": "idarticolo", "value": "'.$idarticolo.'", "ajax-source": "articoli", "extra": "onchange=\"session_set(\'superselect,idarticolo\', $(this).val(), 0); $data = $(this).selectData(); $(\'#prezzo\').val($data.prezzo_vendita); $(\'#desc\').val($data.descrizione); $(\'#um\').selectSetNew($data.um, $data.um); $(\'#idiva\').selectSet($data.iva_vendita, $data.iva_vendita);\"" ]}
{[ "type": "select", "label": "'.tr('Articolo').'", "name": "idarticolo", "value": "'.$idarticolo.'", "ajax-source": "articoli" ]}
</div>
</div>';
}
// Descrizione
echo '
<div class="row">
<div class="col-md-12">
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "id": "desc", "value": '.json_encode($descrizione).', "required": 1 ]}
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "id": "descrizione_riga", "value": '.json_encode($descrizione).', "required": 1 ]}
</div>
</div>';
// Quantità
echo '
if($rsr[0]['is_descrizione']!=1){
// Quantità
echo '
<div class="row">
<div class="col-md-4">
{[ "type": "number", "label": "'.tr('Q.tà').'", "name": "qta", "value": "'.$qta.'", "required": 1, "decimals": "qta" ]}
</div>';
// Unità di misura
echo '
// Unità di misura
echo '
<div class="col-md-4">
{[ "type": "select", "label": "'.tr('Unità di misura').'", "icon-after": "add|'.Modules::get('Unità di misura')['id'].'", "name": "um", "value": "'.$um.'", "ajax-source": "misure" ]}
</div>';
// Iva
echo '
// Iva
echo '
<div class="col-md-4">
{[ "type": "select", "label": "'.tr('Iva').'", "name": "idiva", "required": 1, "value": "'.$idiva.'", "values": "query=SELECT * FROM co_iva ORDER BY descrizione ASC" ]}
</div>
</div>';
// Costo unitario
echo '
// Costo unitario
echo '
<div class="row">
<div class="col-md-6">
{[ "type": "number", "label": "'.tr('Costo unitario').'", "name": "prezzo", "required": 1, "value": "'.$subtot.'", "icon-after": "&euro;" ]}
</div>';
// Sconto unitario
echo '
// Sconto unitario
echo '
<div class="col-md-6">
{[ "type": "number", "label": "'.tr('Sconto unitario').'", "name": "sconto", "value": "'.$sconto.'", "icon-after": "choice|untprc|'.$tipo_sconto.'" ]}
</div>
</div>';
}
echo '
<script>
$(document).ready(function () {
$("#idarticolo").on("change", function(){
if($(this).val()){
session_set("superselect,idarticolo", $(this).val(), 0);
$data = $(this).selectData();
$("#prezzo").val($data.prezzo_vendita);
$("#descrizione_riga").val($data.descrizione);
$("#idiva").selectSet($data.idiva_vendita, $data.iva_vendita);
$("#um").selectSetNew($data.um, $data.um);
}
});
});
</script>';
echo '

View File

@ -106,6 +106,11 @@ if (!empty($rsi)) {
$sconto_ore = ($r['sconto'] != 0) ? '<br><span class="label label-danger">'.Translator::numberToLocale(-$r['sconto']).' &euro;</span>' : '';
$sconto_km = ($r['scontokm'] != 0) ? '<br><span class="label label-danger">'.Translator::numberToLocale(-$r['scontokm']).' &euro;</span>' : '';
// Aggiungo lo sconto globale nel totale ore
if( $int['sconto_globale'] > 0 ){
$sconto_ore .= ' <span class="label label-danger">'.Translator::numberToLocale(-$int['sconto_globale']).' &euro;</span>';
}
echo '
<tr>
<td>'.$r['ragione_sociale'].'</td>

View File

@ -38,27 +38,38 @@ if (!empty($rs)) {
// q.tà
echo '
<td class="text-center">
'.Translator::numberToLocale($r['qta'] - $r['qta_evasa']).'
<td class="text-center">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['qta'] - $r['qta_evasa']);
}
echo '
</td>';
// um
echo '
<td class="text-center">
'.$r['um'].'
<td class="text-center">';
if($r['is_descrizione']==0){
echo
$r['um'];
}
echo '
</td>';
// costo unitario
echo '
<td class="text-right">
'.Translator::numberToLocale($r['subtotale'] / $r['qta']).' &euro;';
<td class="text-right">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['subtotale'] / $r['qta']).' &euro;';
if ($r['sconto_unitario'] > 0) {
echo '
<br><small class="label label-danger">- '.tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
if ($r['sconto_unitario'] > 0) {
echo '
<br><small class="label label-danger">- '.tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
}
}
echo '
@ -66,15 +77,23 @@ if (!empty($rs)) {
// iva
echo '
<td class="text-right">
'.Translator::numberToLocale($r['iva']).' &euro;
<br><small class="help-block">'.$r['desc_iva'].'</small>
<td class="text-right">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['iva']).' &euro;
<br><small class="help-block">'.$r['desc_iva'].'</small>';
}
echo'
</td>';
// Imponibile
echo '
<td class="text-right">
'.Translator::numberToLocale($r['subtotale'] - $r['sconto']).' &euro;
<td class="text-right">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['subtotale'] - $r['sconto']).' &euro;';
}
echo'
</td>';
// Possibilità di rimuovere una riga solo se il preventivo non è stato pagato

View File

@ -40,8 +40,8 @@ switch (filter('op')) {
$rs = true;
foreach ((array) $post['query'] as $c => $k) {
// Fix per la protezone contro XSS
$post['query'][$c] = htmlspecialchars_decode($post['query'][$c], ENT_QUOTES);
// Fix per la protezone contro XSS, che interpreta la sequenza "<testo" come un tag HTML
$post['query'][$c] = $_POST['query'][$c];
if (check_query($post['query'][$c])) {
$array = [
@ -88,8 +88,8 @@ switch (filter('op')) {
$rs = true;
foreach ((array) $post['query'] as $c => $k) {
// Fix per la protezone contro XSS
$post['query'][$c] = htmlspecialchars_decode($post['query'][$c], ENT_QUOTES);
// Fix per la protezone contro XSS, che interpreta la sequenza "<testo" come un tag HTML
$post['query'][$c] = $_POST['query'][$c];
if (check_query($post['query'][$c])) {
$array = [

View File

@ -376,7 +376,7 @@ class Auth extends \Util\Singleton
{
$database = Database::getConnection();
if (!$database->isInstalled() || !$database->fetchNum("SHOW TABLES LIKE 'zz_logs'")) {
if (!$database->isInstalled() || !$database->fetchNum("SHOW TABLES LIKE 'zz_logs'") || Update::isUpdateAvailable()) {
return false;
}

View File

@ -88,6 +88,7 @@ class HTMLBuilder
*/
public static function replace($html)
{
// Gestione dei manager generici
preg_match_all('/'.preg_quote(self::$open['manager']).'(.+?)'.preg_quote(self::$close['manager']).'/is', $html, $managers);
foreach ($managers[0] as $value) {
@ -99,6 +100,7 @@ class HTMLBuilder
$html = str_replace($value, !empty($result) ? $result : $value, $html);
}
// Gestione del formato di input HTML semplificato
preg_match_all('/'.preg_quote(self::$open['handler']).'(.+?)'.preg_quote(self::$close['handler']).'/is', $html, $handlers);
foreach ($handlers[0] as $value) {
@ -155,10 +157,10 @@ class HTMLBuilder
{
$string = '{'.substr($string, strlen(self::$open[$type]), -strlen(self::$close[$type])).'}';
// Fix per contenuti con newline integrate
// Fix per contenuti con newline integrati
$string = str_replace(["\n", "\r"], ['\\n', '\\r'], $string);
$json = (array) json_decode($string, true, 2);
$json = (array) json_decode($string, true);
return $json;
}
@ -212,7 +214,7 @@ class HTMLBuilder
// Attributi normali
foreach ($json as $key => $value) {
$values[trim($key)] = trim($value);
$values[trim($key)] = is_string($value) ? trim($value) : $value;
}
// Valori particolari

View File

@ -3,33 +3,50 @@
namespace HTMLBuilder\Handler;
/**
* Gestione dell'input di tipo "checkbox".
*
* @since 2.3
*/
class ChoicesHandler implements HandlerInterface
{
public function handle(&$values, &$extras)
{
// Delega della gestione al metodo specifico per il tipo di input richiesto
$result = $this->{$values['type']}($values, $extras);
return $result;
}
/**
* Gestione dell'input di tipo "checkbox".
* Esempio: {[ "type": "checkbox", "label": "Checkbox di test", "placeholder": "Test", "name": "checkbox", "value": "1" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function checkbox(&$values, &$extras)
{
unset($values['class'][0]);
// Restrizione dei valori permessi
$values['value'] = (empty($values['value']) || $values['value'] == 'off') ? false : true;
// Gestione della proprietà "checked"
if (!empty($values['value']) && !in_array('checked', $extras)) {
$extras[] = 'checked';
}
// Gestione della proprietà "readonly"
if (in_array('readonly', $extras)) {
$extras[] = 'disabled';
}
$values['placeholder'] = (isset($values['placeholder'])) ? $values['placeholder'] : $values['label'];
// Gestione dei placeholder
$values['placeholder'] = isset($values['placeholder']) ? $values['placeholder'] : $values['label'];
// Generazione del codice HTML
$result .= '
<div class="input-group">
<span class="input-group-addon">

View File

@ -3,6 +3,8 @@
namespace HTMLBuilder\Handler;
/**
* Gestione dell'input di tipo "timestamp", "date" e "time".
*
* @since 2.3
*/
class DateHandler implements HandlerInterface
@ -10,26 +12,34 @@ class DateHandler implements HandlerInterface
public function handle(&$values, &$extras)
{
// Impostazione alla data corrente se il contenuto corrisponde a "now"
if ($values['value'] == '-now-') {
$values['value'] = date(\Translator::getFormatter()->getStandardFormats()['timestamp']);
}
if ($values['max-date'] == '-now-') {
$values['max-date'] = date(\Translator::getFormatter()->getStandardFormats()['timestamp']);
}
if ($values['min-date'] == '-now-') {
$values['min-date'] = date(\Translator::getFormatter()->getStandardFormats()['timestamp']);
$detect = [
'value',
'max-date',
'min-date',
];
foreach ($detect as $attr) {
if ($values[$attr] == '-now-') {
$values[$attr] = date(\Translator::getFormatter()->getStandardFormats()['timestamp']);
}
}
// Restrizione dei valori permessi
// Timestamp
if ($values['type'] == 'timestamp' && \Translator::getFormatter()->isStandardTimestamp($values['value'])) {
$values['value'] = \Translator::timestampToLocale($values['value']);
} elseif ($values['type'] == 'date' && \Translator::getFormatter()->isStandardDate($values['value'])) {
}
// Data
elseif ($values['type'] == 'date' && \Translator::getFormatter()->isStandardDate($values['value'])) {
$values['value'] = \Translator::dateToLocale($values['value']);
} elseif ($values['type'] == 'time' && \Translator::getFormatter()->isStandardTime($values['value'])) {
}
// Orario
elseif ($values['type'] == 'time' && \Translator::getFormatter()->isStandardTime($values['value'])) {
$values['value'] = \Translator::timeToLocale($values['value']);
}
// Controllo sulla correttezza sintattica del valore impostato
if (!(
($values['type'] == 'timestamp' && \Translator::getFormatter()->isFormattedTimestamp($values['value'])) ||
($values['type'] == 'date' && \Translator::getFormatter()->isFormattedDate($values['value'])) ||
@ -38,10 +48,12 @@ class DateHandler implements HandlerInterface
$values['value'] = '';
}
// Delega della gestione al metodo specifico per il tipo di input richiesto
$result = $this->{$values['type']}($values, $extras);
$values['type'] = 'text';
// Generazione del codice HTML di default
if (empty($result)) {
$result = '
<input |attr|>';
@ -50,6 +62,15 @@ class DateHandler implements HandlerInterface
return $result;
}
/**
* Gestione dell'input di tipo "timestamp".
* Esempio: {[ "type": "timestamp", "label": "Timestamp di test", "name": "timestamp", "value": "2018-01-01 12:00:30" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function timestamp(&$values, &$extras)
{
$values['class'][] = 'text-center';
@ -57,6 +78,15 @@ class DateHandler implements HandlerInterface
$values['class'][] = 'timestamp-mask';
}
/**
* Gestione dell'input di tipo "date".
* Esempio: {[ "type": "date", "label": "Data di test", "name": "date", "value": "2018-01-01" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function date(&$values, &$extras)
{
$values['class'][] = 'text-center';
@ -64,6 +94,15 @@ class DateHandler implements HandlerInterface
$values['class'][] = 'date-mask';
}
/**
* Gestione dell'input di tipo "time".
* Esempio: {[ "type": "time", "label": "Orario di test", "name": "time", "value": "12:00:30" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function time(&$values, &$extras)
{
$values['class'][] = 'text-center';

View File

@ -3,37 +3,98 @@
namespace HTMLBuilder\Handler;
/**
* Gestione dell'input di tipo "text", "file", "password", "email", "number", "textarea" e "hidden".
*
* @since 2.3
*/
class DefaultHandler implements HandlerInterface
{
public function handle(&$values, &$extras)
{
// Delega della gestione al metodo specifico per il tipo di input richiesto
if (in_array($values['type'], get_class_methods($this))) {
$result = $this->{$values['type']}($values, $extras);
} else {
}
// Caso non previsto
else {
$result = $this->custom($values, $extras);
}
return $result;
}
/**
* Gestione dell'input di tipo non altrimenti previsto.
* Esempio: {[ "type": "undefined", "label": "Custom di test", "placeholder": "Test", "name": "custom", "value": "custom" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function custom(&$values, &$extras)
{
// Generazione del codice HTML
return '
<span |attr|>|value|</span>';
}
/**
* Gestione dell'input di tipo "text".
* Esempio: {[ "type": "text", "label": "Text di test", "placeholder": "Test", "name": "text" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function text(&$values, &$extras)
{
// Generazione del codice HTML
return '
<input |attr|>';
}
/**
* Gestione dell'input di tipo "file".
* Esempio: {[ "type": "file", "label": "File di test", "placeholder": "Test", "name": "file" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function file(&$values, &$extras)
{
// Delega al metodo "text", per la generazione del codice HTML
return $this->text($values, $extras);
}
/**
* Gestione dell'input di tipo "password".
* Esempio: {[ "type": "password", "label": "Password di test", "placeholder": "Test", "name": "password" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function password(&$values, &$extras)
{
// Delega al metodo "text", per la generazione del codice HTML
return $this->text($values, $extras);
}
/**
* Gestione dell'input di tipo "hidden".
* Esempio: {[ "type": "hidden", "label": "Hidden di test", "placeholder": "Test", "name": "hidden" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function hidden(&$values, &$extras)
{
$original = $values;
@ -44,54 +105,81 @@ class DefaultHandler implements HandlerInterface
$values['name'] = $original['name'];
$values['class'] = [];
// Delega al metodo "text", per la generazione del codice HTML
return $this->text($values, $extras);
}
/**
* Gestione dell'input di tipo "email".
* Esempio: {[ "type": "email", "label": "Email di test", "placeholder": "Test", "name": "email" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function email(&$values, &$extras)
{
$values['class'][] = 'email-mask';
$values['type'] = 'text';
// Delega al metodo "text", per la generazione del codice HTML
return $this->text($values, $extras);
}
/**
* Gestione dell'input di tipo "number".
* Esempio: {[ "type": "number", "label": "Number di test", "placeholder": "Test", "name": "number" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function number(&$values, &$extras)
{
$values['class'][] = 'inputmask-decimal';
$values['value'] = !empty($values['value']) ? $values['value'] : 0;
// Gestione della precisione (numero specifico, oppure "qta" per il valore previsto nell'impostazione "Cifre decimali per quantità").
$decimals = null;
if (isset($values['decimals'])) {
if (is_numeric($values['decimals'])) {
$decimals = $values['decimals'];
} elseif (starts_with($values['decimals'], 'qta')) {
$parts = explode('|', $values['decimals']);
$values['min-value'] = isset($parts[1]) ? $parts[1] : 1;
// Se non è previsto un valore minimo, lo imposta a 1
$values['min-value'] = isset($values['min-value']) ? $values['min-value'] : 0;
$decimals = \Settings::get('Cifre decimali per quantità');
$values['decimals'] = $decimals;
}
}
// Controllo sulla correttezza sintattica del valore impostato
$values['value'] = (\Translator::getFormatter()->isStandardNumber($values['value'])) ? \Translator::numberToLocale($values['value'], $decimals) : $values['value'];
$values['type'] = 'text';
// Delega al metodo "text", per la generazione del codice HTML
return $this->text($values, $extras);
}
protected function custom(&$values, &$extras)
{
return '
<span |attr|>|value|</span>';
}
/**
* Gestione dell'input di tipo "textarea".
* Esempio: {[ "type": "textarea", "label": "Textarea di test", "placeholder": "Test", "name": "textarea" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function textarea(&$values, &$extras)
{
$values['class'][] = 'autosize';
// Generazione del codice HTML
return '
<textarea |attr|>|value|</textarea>';
}

View File

@ -3,10 +3,19 @@
namespace HTMLBuilder\Handler;
/**
* Intefaccia utilizzata per interagire con la classe HTMLBuilder.
*
* @since 2.3
*/
interface HandlerInterface
{
/**
* Gestore pubblico, liberamente implementabile per la creazione del codice HTML.
*
* @param array $values
* @param array $extras
*
* @return string
*/
public function handle(&$values, &$extras);
}

View File

@ -3,33 +3,49 @@
namespace HTMLBuilder\Handler;
/**
* Gestione dell'input di tipo "image".
*
* @since 2.3
*/
class MediaHandler implements HandlerInterface
{
public function handle(&$values, &$extras)
{
// Delega della gestione al metodo specifico per il tipo di input richiesto
$result = $this->{$values['type']}($values, $extras);
return $result;
}
/**
* @since 2.3
* Gestione dell'input di tipo "image".
* Esempio: {[ "type": "image", "label": "Immagine di test", "name": "image", "class": "img-thumbnail", "value": "image_path" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
public function handle(&$values, &$extras)
public function image(&$values, &$extras)
{
unset($values['class'][0]);
// Form upload
// Valore non imposato
if (empty($values['value'])) {
$values['type'] = 'file';
// Generazione del codice HTML
return '
<input |attr|>';
} else {
// Visualizzazione dell'immagine e della relativa spunta per la cancellazione
}
// Valore presente
// Visualizzazione dell'immagine e della relativa spunta per la cancellazione
else {
$values['class'][] = 'img-thumbnail';
$values['class'][] = 'img-responsive';
// Generazione del codice HTML
return '
<img src="|value|" |attr|><br>
<label>

View File

@ -3,16 +3,21 @@
namespace HTMLBuilder\Handler;
/**
* Gestione dell'input di tipo "select".
*
* @since 2.3
*/
class SelectHandler implements HandlerInterface
{
public function handle(&$values, &$extras)
{
$values['class'][] = (!empty($values['ajax-source'])) ? 'superselectajax' : 'superselect';
// Individuazione della classe per la corretta gestione JavaScript
$values['class'][] = !empty($values['ajax-source']) ? 'superselectajax' : 'superselect';
$values['data-source'] = (!empty($values['ajax-source'])) ? $values['ajax-source'] : '';
// Individuazione della richiesta AJAX (se presente)
$values['data-source'] = !empty($values['ajax-source']) ? $values['ajax-source'] : '';
// Individuazione e gestione dei valori tramite array
$values['value'] = explode(',', $values['value']);
if (count($values['value']) === 1 && strlen($values['value'][0]) === 0) {
$values['value'] = [];
@ -25,16 +30,19 @@ class SelectHandler implements HandlerInterface
$values['value'] = (array) $values['value'];
// Inizializzazione del codice HTML
$result = '
<select |attr|>';
// Delega della generazione del codice HTML in base alle caratteristiche del formato
// Gestione delle richieste AJAX (se il campo "ajax-source" è impostato)
if (!empty($values['ajax-source'])) {
if (!empty($values['value']) || is_numeric($values['value'])) {
$result .= $this->select2($values['ajax-source'], $values['value']);
}
}
// Generazione <select> da query
// Gestione del select da query specifica (se il campo "values" è impostato a "query=SQL")
elseif (preg_match_all('/^query=(.+?)$/', $values['values'], $matches)) {
$result .= '
<option></option>';
@ -42,21 +50,23 @@ class SelectHandler implements HandlerInterface
$result .= $this->selectQuery($matches[1][0], $values['value']);
}
// Generazione <select> da JSON
// esempio creazione select con opzioni: Maschio, Femmina, Unisex
// {[ "type": "select", "label": "Sesso", "name": "sesso", "values": "list=\"\": \"\", \"M\": \"Maschio\", \"F\": \"Femmina\", \"U\": \"Unisex\"", "value": "$sesso$" ]}
// Gestione del select dal formato JSON parziale (valori singoli)
elseif (preg_match_all('/^list=(.+?)$/', $values['values'], $matches)) {
$result .= '
<option></option>';
$result .= $this->selectList(json_decode('{'.$matches[1][0].'}', true), $values);
} elseif (preg_match_all('/^json=(.+?)$/', $values['values'], $matches)) {
}
// Gestione del select dal formato JSON completo, convertito in array
elseif (is_array($values['values'])) {
$result .= '
<option></option>';
$result .= $this->selectJSON(json_decode('[{'.$matches[1][0].'}]', true), $values['value']);
$result .= $this->selectArray($values['values'], $values['value']);
}
// Impostazione del placeholder
$values['placeholder'] = !empty($values['placeholder']) ? $values['placeholder'] : '- '.tr("Seleziona un'opzione").' -';
$values['data-placeholder'] = $values['placeholder'];
@ -65,11 +75,13 @@ class SelectHandler implements HandlerInterface
$result .= '
</select>';
// Gestione delle proprietà "disabled" e "readonly"
if (in_array('disabled', $extras) || in_array('readonly', $extras)) {
$result .= '
<script>$("#'.$values['id'].'").prop("disabled", true);</script>';
}
// Ulteriore gestione della proprietà "readonly" (per rendere il select utilizzabile dopo il submit)
if (in_array('readonly', $extras) && empty($values['ajax-source'])) {
$result .= '
<select class="hide" name="'.prepareToField($values['name']).'"'.((in_array('multiple', $extras)) ? ' multiple' : '').'>';
@ -86,9 +98,18 @@ class SelectHandler implements HandlerInterface
return $result;
}
/**
* Gestione dell'input di tipo "select" con richieste AJAX (nome della richiesta indicato tramite attributo "ajax-source").
* Esempio: {[ "type": "select", "label": "Select di test", "name": "test", "ajax-source": "test" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function select2($op, $elements)
{
// Richiamo alla pagina ajax_select.php per aggiungere il valore iniziale al select
// Richiamo del file dedicato alle richieste AJAX per ottenere il valore iniziale del select
ob_start();
$dbo = \Database::getConnection();
include DOCROOT.'/ajax_select.php';
@ -127,7 +148,16 @@ class SelectHandler implements HandlerInterface
return $result;
}
protected function selectJSON($array, $values)
/**
* Gestione dell'input di tipo "select" basato su un array associativo.
* Esempio: {[ "type": "select", "name": "tipo", "values": [{"id":"M","text":"Maschio"},{"id":"F","text":"Femmina"},{"id":"U","text":"Unisex"}], "value": "U", "placeholder": "Non specificato" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function selectArray($array, $values)
{
$prev = '';
foreach ($array as $element) {
@ -150,7 +180,9 @@ class SelectHandler implements HandlerInterface
$attributes[] = 'style="background:'.$element['_bgcolor_'].'; color:'.color_inverse($element['_bgcolor_']).';"';
}
$exclude = ['optgroup'];
$exclude = [
'optgroup',
];
// Leggo ulteriori campi oltre a id e descrizione per inserirli nell'option nella forma "data-nomecampo1", "data-nomecampo2", ecc
foreach ($element as $key => $value) {
if (!in_array($key, $exclude)) {
@ -165,6 +197,15 @@ class SelectHandler implements HandlerInterface
return $result;
}
/**
* Gestione dell'input di tipo "select" basato su una query specifica.
* Esempio: {[ "type": "select", "label": "Select di test", "name": "select", "values": "query=SELECT id, name as text FROM table" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function selectQuery($query, $values)
{
$result = '';
@ -173,27 +214,30 @@ class SelectHandler implements HandlerInterface
$array = $database->fetchArray($query);
return $this->selectJSON($array, $values);
return $this->selectArray($array, $values);
}
/**
* Gestione dell'input di tipo "select" basato su una lista parzialmente JSON.
* Esempio: {[ "type": "select", "label": "Sesso", "name": "sesso", "values": "list=\"\": \"Non specificato\", \"M\": \"Maschio\", \"F\": \"Femmina\", \"U\": \"Unisex\"", "value": "M" ]}.
*
* @param array $values
* @param array $extras
*
* @return string
*/
protected function selectList($datas, &$values)
{
$result = '';
$array = [];
foreach ($datas as $key => $value) {
if (!empty($key)) {
$attributes = [];
if (in_array($key, $values['value'])) {
$attributes[] = 'selected';
}
$result .= '
<option value="'.prepareToField($key).'" '.implode(' ', $attributes).'>'.$value.'</option>';
$array[] = ['id' => $key, 'text' => $value];
} elseif (empty($values['placeholder'])) {
$values['placeholder'] = $value;
}
}
return $result;
return $this->selectArray($array, $values['value']);
}
}

View File

@ -135,7 +135,7 @@ class HTMLWrapper implements WrapperInterface
$value = (empty($pieces[2]) || !in_array($pieces[2], array_column($choices, 'id'))) ? 'UNT' : $pieces[2];
if ($type == 'untprc') {
$result = '{[ "type": "select", "name": "tipo_'.prepareToField($values['name']).'", "value": "'.prepareToField($value).'", "values": "json='.substr(str_replace('"', '\"', json_encode($choices)), 2, -2).'", "class": "no-search" ]}';
$result = '{[ "type": "select", "name": "tipo_'.prepareToField($values['name']).'", "value": "'.prepareToField($value).'", "values": '.json_encode($choices).', "class": "no-search" ]}';
$result = \HTMLBuilder\HTMLBuilder::replace($result);
}

View File

@ -316,7 +316,15 @@ class Modules
$query .= ' LEFT JOIN `zz_modules` AS `t'.$i.'` ON `t'.$i.'`.`parent` = `t'.($i - 1).'`.`id`';
}
$query .= ' WHERE `t0`.`parent` IS NULL ORDER BY `t0`.`order` ASC';
$query .= ' WHERE `t0`.`parent` IS NULL ORDER BY ';
for ($i = 0; $i < $depth; ++$i) {
$query .= '`t'.$i.'`.`order` ASC';
if ($i != $depth - 1) {
$query .= ', ';
}
}
$modules = $database->fetchArray($query);

View File

@ -323,7 +323,7 @@ class Prints
// Instanziamento dell'oggetto mPDF
$mpdf = new \Mpdf\Mpdf([
'mode' => 'c',
'mode' => 'utf-8',
'format' => $settings['format'],
'orientation' => $settings['orientation'],
'font-size' => $settings['font-size'],

View File

@ -20,35 +20,12 @@ class Update
$database_ready = $database->isConnected() && $database->fetchNum("SHOW TABLES LIKE 'updates'");
// Individuazione di tutti gli aggiornamenti fisicamente presenti
$results = [];
// Aggiornamenti del gestionale
$core = (array) glob(DOCROOT.'/update/*.{php,sql}', GLOB_BRACE);
foreach ($core as $value) {
$infos = pathinfo($value);
$value = str_replace('_', '.', $infos['filename']);
if (self::isVersion($value)) {
$results[] = $value;
}
}
$core = self::getCoreUpdates();
// Aggiornamenti dei moduli
$modules = (array) glob(DOCROOT.'/modules/*/update/*.{php,sql}', GLOB_BRACE);
foreach ($modules as $value) {
$infos = pathinfo($value);
$modules = self::getModulesUpdates();
$module = end(explode('/', dirname($infos['dirname'])));
$value = str_replace('_', '.', $infos['filename']);
if (self::isVersion($value)) {
$results[] = $module.'_'.$value;
}
}
$results = array_unique($results);
asort($results);
$results = array_merge($core, $modules);
// Individuazione di tutti gli aggiornamenti inseriti
$updates = ($database_ready) ? $database->fetchArray('SELECT * FROM `updates`') : [];
@ -89,6 +66,62 @@ class Update
}
}
/**
* Restituisce l'elenco degli aggiornamento del gestionale presenti nella cartella <b>update<b>.
*
* @return array
*/
protected static function getCoreUpdates()
{
$results = [];
// Aggiornamenti del gestionale
$core = (array) glob(DOCROOT.'/update/*.{php,sql}', GLOB_BRACE);
foreach ($core as $value) {
$infos = pathinfo($value);
$value = str_replace('_', '.', $infos['filename']);
if (self::isVersion($value)) {
$results[] = $value;
}
}
$results = array_unique($results);
asort($results);
return $results;
}
/**
* Restituisce l'elenco degli aggiornamento dei moduli, presenti nella cartella <b>update<b> dei singoli moduli.
*
* @return array
*/
protected static function getModulesUpdates()
{
$results = [];
// Aggiornamenti dei moduli
$modules = (array) glob(DOCROOT.'/modules/*/update/*.{php,sql}', GLOB_BRACE);
foreach ($modules as $value) {
$infos = pathinfo($value);
$temp = explode('/', dirname($infos['dirname']));
$module = end($temp);
$value = str_replace('_', '.', $infos['filename']);
if (self::isVersion($value)) {
$results[] = $module.'_'.$value;
}
}
$results = array_unique($results);
asort($results);
return $results;
}
/**
* Restituisce l'elenco degli aggiornamento incompleti o non ancora effettuati.
*
@ -205,7 +238,14 @@ class Update
$result = self::getFile('VERSION');
if (empty($result)) {
$result = self::getDatabaseVersion();
$database = Database::getConnection();
if ($database->isInstalled()) {
$result = self::getDatabaseVersion();
} else {
$updatelist = self::getCoreUpdates();
$result = end($updatelist);
}
}
return $result;

View File

@ -106,34 +106,44 @@ foreach ($righe as $r) {
</td>';
echo "
<td class='text-center'>
".(empty($r['qta']) ? '' : Translator::numberToLocale($r['qta'])).' '.$r['um'].'
<td class='text-center'>";
if($r['is_descrizione']==0){
echo
(empty($r['qta']) ? '' : Translator::numberToLocale($r['qta'])).' '.$r['um'];
}
echo '
</td>';
if ($options['pricing']) {
// Prezzo unitario
echo "
<td class='text-right'>
".(empty($r['qta']) || empty($r['subtotale']) ? '' : Translator::numberToLocale($r['subtotale'] / $r['qta'])).' &euro;
<td class='text-right'>";
if($r['is_descrizione']==0){
echo
(empty($r['qta']) || empty($r['subtotale']) ? '' : Translator::numberToLocale($r['subtotale'] / $r['qta'])).' &euro;';
}
echo '
</td>';
// Imponibile
echo "
<td class='text-right'>
".(empty($r['subtotale']) ? '' : Translator::numberToLocale($r['subtotale'])).' &euro;';
<td class='text-right'>";
if($r['is_descrizione']==0){
echo
(empty($r['subtotale']) ? '' : Translator::numberToLocale($r['subtotale'])).' &euro;';
if ($r['sconto'] > 0) {
echo '
<br><small class="help-block">- '.tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
if ($r['sconto'] > 0) {
echo '
<br><small class="help-block">- '.tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
if ($count <= 1) {
$count += 0.4;
if ($count <= 1) {
$count += 0.4;
}
}
}
echo '
</td>';
} else {

View File

@ -68,40 +68,55 @@ foreach ($rs_gen as $r) {
echo '
</td>';
echo "
<td class='text-center'>
".Translator::numberToLocale($r['qta']).' '.$r['um'].'
echo '
<td class="text-center">';
if ($r['is_descrizione'] == 0) {
echo
Translator::numberToLocale($r['qta']).' '.$r['um'];
}
echo '
</td>';
if ($options['pricing']) {
// Prezzo unitario
echo "
<td class='text-right'>
".Translator::numberToLocale($r['subtotale'] / $r['qta']).' &euro;
<td class='text-right'>";
if (empty($r['is_descrizione'])) {
echo '
'.Translator::numberToLocale($r['subtotale'] / $r['qta']).' &euro;';
}
echo '
</td>';
// Imponibile
echo "
<td class='text-right'>
".Translator::numberToLocale($r['subtotale']).' &euro;';
<td class='text-right'>";
if ($r['is_descrizione'] == 0) {
echo
Translator::numberToLocale($r['subtotale']).' &euro;';
if ($r['sconto'] > 0) {
if ($count <= 1) {
$count += 0.4;
if ($r['sconto'] > 0) {
if ($count <= 1) {
$count += 0.4;
}
echo '
<br><small class="help-block">- '.tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
}
echo '
<br><small class="help-block">- '.tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
}
echo '
</td>';
// Iva
echo "
<td class='text-center'>
".Translator::numberToLocale($r['perc_iva']).'
<td class='text-center'>";
if ($r['is_descrizione'] == 0) {
echo
Translator::numberToLocale($r['perc_iva']);
}
echo '
</td>';
}
echo '

View File

@ -104,25 +104,32 @@ foreach ($righe as $r) {
echo '
</td>';
echo "
<td class='text-center'>
".Translator::numberToLocale($r['qta']).' '.$r['um'].'
echo '
<td class="text-center">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['qta']).' '.$r['um'];
}
echo '
</td>';
// Prezzo unitario
echo "
<td class='text-right'>
".(empty($r['qta']) || empty($r['subtotale']) ? '' : Translator::numberToLocale($r['subtotale'] / $r['qta'])).' &euro;';
<td class='text-right'>";
if($r['is_descrizione']==0){
echo
(empty($r['qta']) || empty($r['subtotale']) ? '' : Translator::numberToLocale($r['subtotale'] / $r['qta'])).' &euro;';
if ($r['sconto'] > 0) {
echo "
<br><small class='text-muted'>- ".tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
if ($r['sconto'] > 0) {
echo "
<br><small class='text-muted'>- ".tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
if ($count <= 1) {
$count += 0.4;
if ($count <= 1) {
$count += 0.4;
}
}
}
@ -131,28 +138,34 @@ foreach ($righe as $r) {
// Imponibile
echo "
<td class='text-right'>
".(empty($r['subtotale']) ? '' : Translator::numberToLocale($r['subtotale'])).' &euro;';
<td class='text-right'>";
if($r['is_descrizione']==0){
echo
(empty($r['subtotale']) ? '' : Translator::numberToLocale($r['subtotale'] - $r['sconto'])).' &euro;';
if ($r['sconto'] > 0) {
echo "
<br><small class='text-muted'>".tr('sconto di _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto']),
'_TYPE_' => '&euro;',
]).'</small>';
if ($r['sconto'] > 0) {
echo "
<br><small class='text-muted'>- ".tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto']),
'_TYPE_' => '&euro;',
]).'</small>';
if ($count <= 1) {
$count += 0.4;
if ($count <= 1) {
$count += 0.4;
}
}
}
echo '
</td>';
// Iva
echo '
<td class="text-center">
'.Translator::numberToLocale($r['perc_iva']).'
<td class="text-center">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['perc_iva']);
}
echo '
</td>
</tr>';

View File

@ -269,7 +269,36 @@ if ($records[0]['ritenutaacconto'] != 0) {
echo '
<td class="cell-padded text-center" colspan="'.$second_colspan.'">
<td class="cell-padded text-center" colspan="'.$second_colspan.'">
'.Translator::numberToLocale($totale - $records[0]['ritenutaacconto']).' &euro;
</td>
</tr>';
}
if (empty($records[0]['ritenutaacconto']) && empty($records[0]['rivalsainps']) && abs($records[0]['bollo']) > 0) {
$first_colspan = 3;
$second_colspan = 2;
if (empty($sconto)) {
$first_colspan = 1;
}
echo '
<tr>
<th class="text-center small" colspan="'.$first_colspan.'">
'.tr('Marca da bollo', [], ['upper' => true]).'
</th>
<th class="text-center small" colspan="'.$second_colspan.'">
'.tr('Netto a pagare', [], ['upper' => true]).'
</th>
</tr>
<tr>
<td class="cell-padded text-center" colspan="'.$first_colspan.'">
'.Translator::numberToLocale($records[0]['bollo']).' &euro;
</td>
<td class="cell-padded text-center" colspan="'.$second_colspan.'">
'.Translator::numberToLocale($totale - $records[0]['ritenutaacconto']).' &euro;
</td>
</tr>';

View File

@ -71,6 +71,14 @@ echo '
</td>
</tr>';
// Tipo intervento
echo '
<tr>
<td colspan="4">
<b>'.tr('Tipo intervento').':</b> '.$records[0]['tipointervento'].'
</td>
</tr>';
// Richiesta
echo '
<tr>
@ -275,19 +283,19 @@ echo '
</th>
</tr>
<tr>
<th class="text-center" style="font-size:8pt;width:30%">
<th class="text-center" style="font-size:8pt;">
<b>'.tr('Tecnico').'</b>
</th>
<th class="text-center" style="font-size:8pt;width:15%">
<th class="text-center" style="font-size:8pt;width:14%">
<b>'.tr('Data').'</b>
</th>
<th class="text-center" style="font-size:8pt;width:10%">
<th class="text-center" style="font-size:8pt;width:7%">
<b>'.tr('Dalle').'</b>
</th>
<th class="text-center" style="font-size:8pt;width:10%">
<th class="text-center" style="font-size:8pt;width:7%">
<b>'.tr('Alle').'</b>
</th>
@ -345,56 +353,65 @@ foreach ($rst as $i => $r) {
</tr>';
}
echo '
<tr>';
// Ore lavorate
$ore = get_ore_intervento($idintervento);
echo '
<tr>
<td class="text-center">
<small>'.tr('Ore lavorate').':</small><br/><b>'.Translator::numberToLocale($ore).'</b>
</td>';
// Costo totale manodopera
if ($options['pricing']) {
$ore = get_ore_intervento($id_record);
$costo_orario = $records[0]['tot_ore_consuntivo'] - $records[0]['tot_dirittochiamata'];
if ($ore > 0) {
$costo_orario /= $ore;
}
echo '
<td class="text-center">
'.tr('Ore lavorate').':<br/><b>'.Translator::numberToLocale($ore).'</b>
</td>';
// Costo orario
echo '
<td class="text-center">
'.tr('Costo orario').':<br/><b>'.Translator::numberToLocale($costo_orario).'</b>';
if ($records[0]['tot_dirittochiamata'] != 0) {
echo '
<small> + '.Translator::numberToLocale($records[0]['tot_dirittochiamata']).' d.c.</small>';
}
echo '
</td>';
// Costo totale manodopera
echo '
<td colspan="2" class="text-center">
'.tr('Manodopera').':<br/><b>'.Translator::numberToLocale($costi_intervento['manodopera_scontato']).'</b>
<td colspan="3" class="text-center">
<small>'.tr('Totale manodopera').':</small><br/><b>'.Translator::numberToLocale($costi_intervento['manodopera_addebito']).' &euro;</b>
</td>';
} else {
echo '
<td colspan="4"></td>';
<td colspan="3" class="text-center">-</td>';
}
// Timbro e firma
$firma = !empty($records[0]['firma_file']) ? '<img src="'.$docroot.'/files/interventi/'.$records[0]['firma_file'].'" style="width:70mm;">' : '';
echo '
<td class="text-center" style="font-size:8pt;height:30mm;vertical-align:bottom">
<td rowspan="2" class="text-center" style="font-size:8pt;height:30mm;vertical-align:bottom">
'.$firma.'<br>
<i>('.tr('Timbro e firma leggibile').'.)</i>
</td>
</tr>';
// Totale km
echo '
<tr>
<td class="text-center">
<small>'.tr('Km percorsi').':</small><br/><b>'.Translator::numberToLocale($records[0]['tot_km']).'</b>
</td>';
// Costo trasferta
if ($options['pricing']) {
echo '
<td class="text-center">
<small>'.tr('Costi di trasferta').':</small><br/><b>'.Translator::numberToLocale($records[0]['tot_km_consuntivo']).' &euro;</b>
</td>';
} else {
echo '
<td class="text-center">-</td>';
}
// Diritto di chiamata
if ($options['pricing']) {
echo '
<td class="text-center" colspan="2">
<small>'.tr('Diritto di chiamata').':</small><br/><b>'.Translator::numberToLocale($records[0]['tot_dirittochiamata']).' &euro;</b>
</td>';
} else {
echo '
<td class="text-center" colspan="2">-</td>
';
}
// TOTALE COSTI FINALI
if ($options['pricing']) {
// Totale imponibile
@ -405,34 +422,38 @@ if ($options['pricing']) {
</td>
<th class="text-center">
<b>'.Translator::numberToLocale($costi_intervento['totale_scontato']).' &euro;</b>
<b>'.Translator::numberToLocale($costi_intervento['totale_addebito']).' &euro;</b>
</th>
</tr>';
// Eventuale sconto incondizionato
if (!empty($costi_intervento['sconto_globale'])) {
$sconto_addebito = $costi_intervento['totale_addebito'] - $costi_intervento['totale_scontato'];
$totale_sconto = $costi_intervento['sconto_globale'] + $sconto_addebito;
// Eventuale sconto totale
if (!empty($totale_sconto)) {
echo '
<tr>
<td colspan="4" class="text-right">
<b>'.tr('Sconto incondizionato', [], ['upper' => true]).':</b>
</td>
<tr>
<td colspan="4" class="text-right">
<b>'.tr('Sconto', [], ['upper' => true]).':</b>
</td>
<th class="text-center">
<b>-'.Translator::numberToLocale($costi_intervento['sconto_globale']).' &euro;</b>
</th>
</tr>';
<th class="text-center">
<b>-'.Translator::numberToLocale($totale_sconto).' &euro;</b>
</th>
</tr>';
// Imponibile scontato
echo '
<tr>
<td colspan="4" class="text-right">
<b>'.tr('Imponibile scontato', [], ['upper' => true]).':</b>
</td>
<tr>
<td colspan="4" class="text-right">
<b>'.tr('Imponibile scontato', [], ['upper' => true]).':</b>
</td>
<th class="text-center">
<b>'.Translator::numberToLocale($costi_intervento['totale']).' &euro;</b>
</th>
</tr>';
<th class="text-center">
<b>'.Translator::numberToLocale($costi_intervento['totale']).' &euro;</b>
</th>
</tr>';
}
// Leggo iva da applicare

View File

@ -7,7 +7,7 @@ include_once $docroot.'/modules/interventi/modutil.php';
$module_name = 'Interventi';
// carica intervento
$query = 'SELECT in_interventi.*, (SELECT numero FROM co_contratti WHERE id=(SELECT idcontratto FROM co_righe_contratti WHERE idintervento=in_interventi.id)) AS numero_contratto, (SELECT numero FROM co_preventivi WHERE id=(SELECT idpreventivo FROM co_preventivi_interventi WHERE idintervento=in_interventi.id ORDER BY idpreventivo DESC LIMIT 0,1)) AS numero_preventivo, (SELECT SUM(prezzo_dirittochiamata) FROM in_interventi_tecnici GROUP BY idintervento HAVING idintervento=in_interventi.id) AS `tot_dirittochiamata`, (SELECT SUM(km) FROM in_interventi_tecnici GROUP BY idintervento HAVING idintervento=in_interventi.id) AS `tot_km`, (SELECT SUM(ore*prezzo_ore_unitario) FROM in_interventi_tecnici GROUP BY idintervento HAVING idintervento=in_interventi.id) AS `tot_ore_consuntivo`, (SELECT SUM(prezzo_km_consuntivo) FROM in_interventi_tecnici GROUP BY idintervento HAVING idintervento=in_interventi.id) AS `tot_km_consuntivo`, in_interventi.descrizione AS `descrizione_intervento`, richiesta FROM in_interventi INNER JOIN in_tipiintervento ON in_interventi.idtipointervento=in_tipiintervento.idtipointervento WHERE id='.prepare($id_record).' '.Modules::getAdditionalsQuery('Interventi');
$query = 'SELECT in_interventi.*, (SELECT numero FROM co_contratti WHERE id=(SELECT idcontratto FROM co_righe_contratti WHERE idintervento=in_interventi.id)) AS numero_contratto, (SELECT numero FROM co_preventivi WHERE id=(SELECT idpreventivo FROM co_preventivi_interventi WHERE idintervento=in_interventi.id ORDER BY idpreventivo DESC LIMIT 0,1)) AS numero_preventivo, (SELECT SUM(prezzo_dirittochiamata) FROM in_interventi_tecnici GROUP BY idintervento HAVING idintervento=in_interventi.id) AS `tot_dirittochiamata`, (SELECT SUM(km) FROM in_interventi_tecnici GROUP BY idintervento HAVING idintervento=in_interventi.id) AS `tot_km`, (SELECT SUM(ore*prezzo_ore_unitario) FROM in_interventi_tecnici GROUP BY idintervento HAVING idintervento=in_interventi.id) AS `tot_ore_consuntivo`, (SELECT SUM(prezzo_km_consuntivo) FROM in_interventi_tecnici GROUP BY idintervento HAVING idintervento=in_interventi.id) AS `tot_km_consuntivo`, in_interventi.descrizione AS `descrizione_intervento`, richiesta, (SELECT descrizione FROM in_tipiintervento WHERE idtipointervento=in_interventi.idtipointervento) AS tipointervento FROM in_interventi INNER JOIN in_tipiintervento ON in_interventi.idtipointervento=in_tipiintervento.idtipointervento WHERE id='.prepare($idintervento).' '.Modules::getAdditionalsQuery('Interventi');
$records = $dbo->fetchArray($query);
$costi_intervento = get_costi_intervento($id_record);

View File

@ -58,48 +58,56 @@ foreach ($righe as $r) {
</td>';
echo "
<td class='text-center'>
".(empty($r['qta']) ? '' : Translator::numberToLocale($r['qta'])).' '.$r['um'].'
<td class='text-center'>";
if($r['is_descrizione']==0){
echo
(empty($r['qta']) ? '' : Translator::numberToLocale($r['qta'])).' '.$r['um'];
}
echo '
</td>';
if ($options['pricing']) {
// Prezzo unitario
echo "
<td class='text-right'>
".(empty($r['qta']) || empty($r['subtotale']) ? '' : Translator::numberToLocale($r['subtotale'] / $r['qta'])).' &euro;';
<td class='text-right'>";
if($r['is_descrizione']==0){
echo
(empty($r['qta']) || empty($r['subtotale']) ? '' : Translator::numberToLocale($r['subtotale'] / $r['qta'])).' &euro;';
if ($r['sconto'] > 0) {
echo "
<br><small class='text-muted'>- ".tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
if ($r['sconto'] > 0) {
echo "
<br><small class='text-muted'>- ".tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
if ($count <= 1) {
$count += 0.4;
if ($count <= 1) {
$count += 0.4;
}
}
}
echo '
</td>';
// Imponibile
echo "
<td class='text-right'>
".(empty($r['subtotale']) ? '' : Translator::numberToLocale($r['subtotale'])).' &euro;';
<td class='text-right'>";
if($r['is_descrizione']==0){
echo
(empty($r['subtotale']) ? '' : Translator::numberToLocale($r['subtotale'])).' &euro;';
if ($r['sconto'] > 0) {
echo "
<br><small class='text-muted'>- ".tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto']),
'_TYPE_' => '&euro;',
]).'</small>';
if ($r['sconto'] > 0) {
echo "
<br><small class='text-muted'>- ".tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto']),
'_TYPE_' => '&euro;',
]).'</small>';
if ($count <= 1) {
$count += 0.4;
if ($count <= 1) {
$count += 0.4;
}
}
}
echo '
</td>';
} else {
@ -110,8 +118,12 @@ foreach ($righe as $r) {
// Iva
echo '
<td class="text-center">
'.Translator::numberToLocale($r['perc_iva']).'
<td class="text-center">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['perc_iva']);
}
echo '
</td>
</tr>';

View File

@ -107,48 +107,56 @@ foreach ($righe as $r) {
</td>';
echo "
<td class='text-center'>
".(empty($r['qta']) ? '' : Translator::numberToLocale($r['qta'])).' '.$r['um'].'
<td class='text-center'>";
if($r['is_descrizione']==0){
echo
(empty($r['qta']) ? '' : Translator::numberToLocale($r['qta'])).' '.$r['um'];
}
echo '
</td>';
if ($options['pricing']) {
// Prezzo unitario
echo "
<td class='text-right'>
".(empty($r['qta']) || empty($r['subtotale']) ? '' : Translator::numberToLocale($r['subtotale'] / $r['qta'])).' &euro;';
<td class='text-right'>";
if($r['is_descrizione']==0){
echo
(empty($r['qta']) || empty($r['subtotale']) ? '' : Translator::numberToLocale($r['subtotale'] / $r['qta'])).' &euro;';
if ($r['sconto'] > 0) {
echo "
<br><small class='text-muted'>- ".tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
if ($r['sconto'] > 0) {
echo "
<br><small class='text-muted'>- ".tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto_unitario']),
'_TYPE_' => ($r['tipo_sconto'] == 'PRC' ? '%' : '&euro;'),
]).'</small>';
if ($count <= 1) {
$count += 0.4;
if ($count <= 1) {
$count += 0.4;
}
}
}
echo '
</td>';
// Imponibile
echo "
<td class='text-right'>
".(empty($r['subtotale']) ? '' : Translator::numberToLocale($r['subtotale'])).' &euro;';
<td class='text-right'>";
if($r['is_descrizione']==0){
echo
(empty($r['subtotale']) ? '' : Translator::numberToLocale($r['subtotale'])).' &euro;';
if ($r['sconto'] > 0) {
echo "
<br><small class='text-muted'>- ".tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto']),
'_TYPE_' => '&euro;',
]).'</small>';
if ($r['sconto'] > 0) {
echo "
<br><small class='text-muted'>- ".tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($r['sconto']),
'_TYPE_' => '&euro;',
]).'</small>';
if ($count <= 1) {
$count += 0.4;
if ($count <= 1) {
$count += 0.4;
}
}
}
echo '
</td>';
} else {
@ -159,8 +167,12 @@ foreach ($righe as $r) {
// Iva
echo '
<td class="text-center">
'.Translator::numberToLocale($r['perc_iva']).'
<td class="text-center">';
if($r['is_descrizione']==0){
echo
Translator::numberToLocale($r['perc_iva']);
}
echo '
</td>
</tr>';

17
test.php Normal file
View File

@ -0,0 +1,17 @@
<?php
require 'core.php';
$user = \App::getUser();
print_r(Models\Module::getHierarchy()->toArray());
exit();
print_r($user->modules()->get()->toArray());
print_r($user->toArray());
$modules = Models\Module::all();
foreach ($modules as $module) {
print_r($module->title.': '.$module->permission.'<br>');
//print_r($module->views.'<br><br>');
}
exit();

View File

@ -375,13 +375,13 @@ CREATE TABLE IF NOT EXISTS `zz_semaphores` (
) ENGINE=InnoDB;
-- Aggiornamento zz_modules
INSERT INTO `zz_modules` (`id`, `name`, `directory`, `options`, `options2`, `icon`, `version`, `compatibility`, `order`, `level`, `parent`, `default`, `enabled`) VALUES (NULL, 'Strumenti', '', '', '', 'fa fa-cog', '2.3', '2.3', '1', '0', '', '1', '1');
INSERT INTO `zz_modules` (`id`, `name`, `directory`, `options`, `options2`, `icon`, `version`, `compatibility`, `order`, `level`, `parent`, `default`, `enabled`) VALUES (NULL, 'Strumenti', '', '', '', 'fa fa-cog', '2.3', '2.3', '1', '0', 0, '1', '1');
ALTER TABLE `zz_modules` DROP `level`;
UPDATE `zz_modules` SET `options` = 'menu' WHERE `options` = '';
INSERT INTO `zz_modules` (`id`, `name`, `directory`, `options`, `options2`, `icon`, `version`, `compatibility`, `order`, `parent`, `default`, `enabled`) VALUES (NULL, 'Viste', 'viste', 'SELECT |select| FROM `zz_modules` WHERE 1=1 HAVING 2=2 ORDER BY `name`, `title` ASC', '', 'fa fa-eye', '2.3', '2.3', '1', 1, '1', '1');
INSERT INTO `zz_modules` (`id`, `name`, `directory`, `options`, `options2`, `icon`, `version`, `compatibility`, `order`, `parent`, `default`, `enabled`) VALUES (NULL, 'Viste', 'viste', 'SELECT |select| FROM `zz_modules` WHERE 1=1 HAVING 2=2 ORDER BY `name`, `title` ASC', '', 'fa fa-eye', '2.3', '2.3', '1', 1, '1', '0');
INSERT INTO `zz_modules` (`id`, `name`, `directory`, `options`, `options2`, `icon`, `version`, `compatibility`, `order`, `parent`, `default`, `enabled`) VALUES (NULL, 'Utenti e permessi', 'utenti', 'SELECT |select| FROM `zz_groups` WHERE 1=1 HAVING 2=2 ORDER BY `id`, `nome` ASC', '', 'fa fa-lock', '2.3', '2.3', '1', 1, '1', '1');
@ -658,9 +658,12 @@ ALTER TABLE `zz_widgets` ADD FOREIGN KEY (`id_module`) REFERENCES `zz_modules`(`
ALTER TABLE `zz_group_module` ADD FOREIGN KEY (`idmodule`) REFERENCES `zz_modules`(`id`) ON DELETE CASCADE, ADD FOREIGN KEY (`idgruppo`) REFERENCES `zz_groups`(`id`) ON DELETE CASCADE;
-- Aggiunta di chiavi esterne in zz_permissions
DELETE FROM `zz_permissions` WHERE `idmodule` NOT IN (SELECT `id` FROM `zz_modules`);
ALTER TABLE `zz_permissions` ADD FOREIGN KEY (`idmodule`) REFERENCES `zz_modules`(`id`) ON DELETE CASCADE, ADD FOREIGN KEY (`idgruppo`) REFERENCES `zz_groups`(`id`) ON DELETE CASCADE;
-- Aggiunta di chiavi esterne in zz_plugins
DELETE FROM `zz_plugins` WHERE `idmodule_to` NOT IN (SELECT `id` FROM `zz_modules`);
DELETE FROM `zz_plugins` WHERE `idmodule_from` NOT IN (SELECT `id` FROM `zz_modules`);
ALTER TABLE `zz_plugins` ADD FOREIGN KEY (`idmodule_from`) REFERENCES `zz_modules`(`id`) ON DELETE CASCADE, ADD FOREIGN KEY (`idmodule_to`) REFERENCES `zz_modules`(`id`) ON DELETE CASCADE;
-- Aggiunta di chiavi esterne in zz_users
@ -669,6 +672,7 @@ ALTER TABLE `zz_users` CHANGE `idutente` `id` int(11) NOT NULL AUTO_INCREMENT, A
-- Aggiunta di chiavi esterne in zz_logs
ALTER TABLE `zz_logs` DROP `password`, CHANGE `idutente` `id_utente` int(11), CHANGE `timestamp` `timestamp` datetime;
UPDATE `zz_logs` SET `id_utente` = NULL WHERE `id_utente` = 0;
DELETE FROM `zz_logs` WHERE `id_utente` IS NOT NULL AND `id_utente` NOT IN (SELECT `id` FROM `zz_users`);
ALTER TABLE `zz_logs` ADD FOREIGN KEY (`id_utente`) REFERENCES `zz_users`(`id`) ON DELETE CASCADE;
-- Aggiunta di chiavi esterne in zz_semaphores
@ -697,7 +701,13 @@ ALTER TABLE `my_impianto_componenti` ADD FOREIGN KEY (`idsostituto`) REFERENCES
-- Adeguamento dei contenuti di zz_files
ALTER TABLE `zz_files` CHANGE `externalid` `id_record` int(11) NOT NULL, ADD `id_module` int(11) NOT NULL AFTER `filename`, ADD `original` varchar(255) NOT NULL AFTER `filename`;
UPDATE `zz_files` SET `id_module` = (SELECT `id` FROM `zz_modules` WHERE `zz_modules`.`directory` = `zz_files`.`module`);
-- Adeguamento delle fatture (zz_files)
UPDATE `zz_files` SET `id_module` = (SELECT `id` FROM `zz_modules` WHERE `zz_modules`.`name` = 'Fatture di vendita') WHERE `module`= 'fatture' AND `id_record` IN (SELECT `id` FROM `co_documenti` WHERE `idtipodocumento` IN (SELECT `id` FROM `co_tipidocumento` WHERE `dir` = 'entrata'));
UPDATE `zz_files` SET `id_module` = (SELECT `id` FROM `zz_modules` WHERE `zz_modules`.`name` = 'Fatture di acquisto') WHERE `module`= 'fatture' AND `id_record` IN (SELECT `id` FROM `co_documenti` WHERE `idtipodocumento` IN (SELECT `id` FROM `co_tipidocumento` WHERE `dir` = 'uscita'));
-- Adeguamento generico di zz_files
UPDATE `zz_files` SET `id_module` = (SELECT `id` FROM `zz_modules` WHERE `zz_modules`.`directory` = `zz_files`.`module`) WHERE `id_module` IS NULL;
ALTER TABLE `zz_files` DROP `module`;
-- Fix del widget 'Tutte le anagrafiche'
@ -714,7 +724,7 @@ UPDATE `zz_group_module` SET `default` = 1;
UPDATE `zz_widgets` SET `more_link` = REPLACE(TRIM(`more_link`), 'templates/pdfgen.php', 'pdfgen.php');
-- Nuova struttura per i plugins
ALTER TABLE `zz_plugins` ADD `title` varchar(255) NOT NULL AFTER `name`, CHANGE `idmodule_from` `idmodule_from` int(11), CHANGE `idmodule_to` `idmodule_to` int(11),
ALTER TABLE `zz_plugins` ADD `title` varchar(255) NOT NULL AFTER `name`,
ADD `directory` varchar(50) NOT NULL AFTER `script`, ADD `options` text AFTER `script`, ADD `options2` text AFTER `script`, ADD `version` varchar(15) NOT NULL AFTER `script`, ADD `compatibility` varchar(1000) NOT NULL AFTER `script`, ADD `order` int(11) NOT NULL AFTER `script`, ADD `default` boolean NOT NULL DEFAULT 0 AFTER `script`, ADD `enabled` boolean NOT NULL DEFAULT 1 AFTER `script`;
UPDATE `zz_plugins` SET `name` = 'Serial' WHERE `name` = 'Lotti';
@ -973,10 +983,27 @@ ALTER TABLE `in_interventi` ADD `deleted` TINYINT NOT NULL DEFAULT '0' AFTER `da
UPDATE `mg_listini` SET `prc_guadagno` = - `prc_guadagno`;
-- Aggiunta pagamento di default "Bonifico bancario"
INSERT INTO `co_pagamenti` (`id`, `descrizione`, `giorno`, `num_giorni`, `prc`, `created_at`, `idconto_vendite`, `idconto_acquisti`) VALUES (NULL, 'Bonifico bancario', '0', '10', '100', CURRENT_TIMESTAMP, NULL, NULL);
INSERT INTO `co_pagamenti` (`id`, `descrizione`, `giorno`, `num_giorni`, `prc`, `idconto_vendite`, `idconto_acquisti`) VALUES (NULL, 'Bonifico bancario', '0', '10', '100', NULL, NULL);
-- Per Dashboard e Articoli i widgets vanno in alto
UPDATE `zz_widgets` SET `location` = 'controller_top' WHERE `zz_widgets`.`id_module` = (SELECT id FROM zz_modules WHERE name = 'Dashboard' ) OR `zz_widgets`.`id_module` = (SELECT id FROM zz_modules WHERE name = 'Articoli' );
-- Disabilito widgets 'Ordini di servizio da impostare' e 'Rate contrattuali'
UPDATE `zz_widgets` SET `enabled` = '0' WHERE `zz_widgets`.`name` = 'Ordini di servizio da impostare' OR `zz_widgets`.`name` = 'Rate contrattuali';
UPDATE `zz_widgets` SET `enabled` = '0' WHERE `zz_widgets`.`name` = 'Ordini di servizio da impostare' OR `zz_widgets`.`name` = 'Rate contrattuali';
-- Aggiunta articolo su contratti
ALTER TABLE `co_righe2_contratti` ADD `idarticolo` INT NOT NULL AFTER `idcontratto`;
-- Campo per identificare le righe descrittive documenti/ddt/preventivi/contratti/ordini
ALTER TABLE `co_righe_documenti` ADD `is_descrizione` TINYINT(1) NOT NULL AFTER `idcontratto`;
ALTER TABLE `dt_righe_ddt` ADD `is_descrizione` TINYINT(1) NOT NULL AFTER `idarticolo`;
ALTER TABLE `co_righe_preventivi` ADD `is_descrizione` TINYINT(1) NOT NULL AFTER `idarticolo`;
ALTER TABLE `co_righe2_contratti` ADD `is_descrizione` TINYINT(1) NOT NULL AFTER `idarticolo`;
ALTER TABLE `or_righe_ordini` ADD `is_descrizione` TINYINT(1) NOT NULL AFTER `idarticolo`;
-- Aggiunta flag "servizio" su articolo
ALTER TABLE `mg_articoli` ADD `servizio` TINYINT(1) NOT NULL AFTER `id_sottocategoria`;
-- Aggiunto lo stato ddt "Parzialmente fatturato" e cambiato lo stato "Pagato" in "Fatturato"
UPDATE `dt_statiddt` SET `descrizione` = 'Fatturato' WHERE `dt_statiddt`.`descrizione` = 'Pagato';
INSERT INTO `dt_statiddt` (`id`, `descrizione`, `icona`) VALUES (NULL, 'Parzialmente fatturato', 'fa fa-clock-o text-warning');

5
update/2_3_1.sql Normal file
View File

@ -0,0 +1,5 @@
-- Rimosso il referente dalla lista sedi, per non mostrare sedi duplicate nella lista sedi
UPDATE `zz_plugins` SET `options` = ' { "main_query": [ { "type": "table", "fields": "Nome, Indirizzo, Città, CAP, Provincia", "query": "SELECT an_sedi.id, an_sedi.nomesede AS Nome, an_sedi.indirizzo AS Indirizzo, an_sedi.citta AS Città, an_sedi.cap AS CAP, an_sedi.provincia AS Provincia FROM an_sedi WHERE 1=1 AND an_sedi.idanagrafica=|idanagrafica| HAVING 2=2 ORDER BY an_sedi.id DESC"} ]}', `created_at` = NULL WHERE `zz_plugins`.`name` = 'Sedi';
-- Aggiunta possibilità di collegare allegati anche ai plugins
ALTER TABLE `zz_files` ADD `id_plugin` int(11) AFTER `id_module`;

View File

@ -92,7 +92,7 @@ $tables = [
foreach ($tables as $table) {
if ($database->fetchNum('SHOW TABLES WHERE `Tables_in_'.$database->getDatabaseName().'` = '.prepare($table))) {
$query = 'SHOW COLUMNS FROM '.$table.' FROM '.$database->getDatabaseName()." WHERE Field='|field|'";
$query = 'SHOW COLUMNS FROM `'.$table.'` IN `'.$database->getDatabaseName()."` WHERE Field='|field|'";
$created_at = $database->fetchArray(str_replace('|field|', 'created_at', $query));
if (empty($created_at)) {