Merge branch 'master' into 2.3.1

This commit is contained in:
Thomas Zilio 2017-11-11 10:23:02 +01:00
commit b7950b0b6b
44 changed files with 565 additions and 212 deletions

1
.gitignore vendored
View File

@ -82,3 +82,4 @@ files/my_impianti/*
!files/my_impianti/componente.ini
config.inc.php
REVISION
.php_cs.cache

View File

@ -38,18 +38,18 @@ php_value post_max_size 20M
SetEnv HTTP_MOD_REWRITE On
# Deny access to protected folders
RewriteRule ^backup/?$ - [F,L]
RewriteRule ^docs/?$ - [F,L]
RewriteRule ^include/?$ - [F,L]
RewriteRule ^locale/?$ - [F,L]
RewriteRule ^logs/?$ - [F,L]
RewriteRule ^update/?$ - [F,L]
RewriteRule ^backup/ - [F,L]
RewriteRule ^docs/ - [F,L]
RewriteRule ^include/ - [F,L]
RewriteRule ^locale/ - [F,L]
RewriteRule ^logs/ - [F,L]
RewriteRule ^update/ - [F,L]
# Deny access to svn, git, node_modules and vendor folders
RewriteRule ^.git/?$ - [F,L]
RewriteRule ^.svn/?$ - [F,L]
RewriteRule ^node_modules/?$ - [F,L]
RewriteRule ^vendor/?$ - [F,L]
RewriteRule ^.git/ - [F,L]
RewriteRule ^.svn/ - [F,L]
RewriteRule ^node_modules/ - [F,L]
RewriteRule ^vendor/ - [F,L]
# Prevent hacks
# proc/self/environ? no way!

View File

@ -15,6 +15,12 @@
<br>
[![GitHub release](https://img.shields.io/github/release/devcode-it/openstamanager/all.svg)](https://github.com/devcode-it/openstamanager/releases)
[![Downloads](https://img.shields.io/github/downloads/devcode-it/openstamanager/total.svg)](https://github.com/devcode-it/openstamanager/releases)
[![SourceForge](https://img.shields.io/sourceforge/dt/openstamanager.svg?label=SourceForge)](https://sourceforge.net/projects/openstamanager/)
[![license](https://img.shields.io/github/license/devcode-it/openstamanager.svg)](https://github.com/devcode-it/openstamanager/blob/master/LICENSE)
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](http://sourceforge.net/donate/index.php?group_id=236538)
Il gestionale OpenSTAManager è un software open-source e web based, sviluppato dall'azienda informatica DevCode di Este per gestire ed archiviare il servizio di assistenza tecnica e la relativa fatturazione.
Il nome del progetto deriva dalla parziale traduzione in inglese degli elementi principali che lo compongono: la natura open source e il suo obiettivo quale Gestore del Servizio Tecnico di Assistenza.
@ -36,7 +42,7 @@ La documentazione ufficiale è disponibile all'indirizzo <https://devcode-it.git
- [Installazione](#installazione)
- [Versioni](#versioni)
- [Github](#github)
- [Perché software open source](#perché-software-open-source)
- [Perché software open source](#perch%C3%A9-software-open-source)
- [Community](#community)
- [Contribuire](#contribuire)
- [Sviluppatori](#sviluppatori)
@ -131,7 +137,7 @@ Maggiori informazioni sulla configurazione e sul plugin sono disponibili nel sit
- **Fabio Lovato**, il fondatore ([loviuz](https://github.com/loviuz))
- **Fabio Piovan** ([fpsoftware](https://github.com/fpsoftware))
- **Luca Salvà** ([lucasalva87](https://github.com/lucasalva87))
- **Matteo Baccarin**
- **Matteo Baccarin** ([Bacca1997](https://github.com/Bacca1997))
- **Thomas Zilio** ([Dasc3er](https://github.com/Dasc3er))
## Licenza

View File

@ -216,7 +216,7 @@ if (filter('op') == 'link_file' || filter('op') == 'unlink_file') {
download($upload_dir.'/'.$rs[0]['filename'], $rs[0]['original']);
}
if (Modules::getPermission($permesso) == 'rw') {
if (Modules::getPermission($permesso) == 'r' || Modules::getPermission($permesso) == 'rw') {
if (!empty($info['script'])) {
// Inclusione di eventuale plugin personalizzato
if (file_exists($docroot.'/modules/'.$info['module_dir'].'/plugins/custom/'.$info['script'])) {
@ -242,28 +242,30 @@ if (Modules::getPermission($permesso) == 'rw') {
include $docroot.$directory.'/init.php';
}
// Esecuzione delle operazioni di gruppo
$id_records = post('id_records');
$id_records = is_array($id_records) ? $id_records : explode(';', $id_records);
$id_records = array_filter($id_records, function ($var) {return !empty($var); });
$id_records = array_unique($id_records);
if(Modules::getPermission($permesso) == 'rw'){
// Esecuzione delle operazioni di gruppo
$id_records = post('id_records');
$id_records = is_array($id_records) ? $id_records : explode(';', $id_records);
$id_records = array_filter($id_records, function ($var) {return !empty($var); });
$id_records = array_unique($id_records);
$bulk = null;
if (file_exists($docroot.$directory.'/custom/bulk.php')) {
$bulk = include $docroot.$directory.'/custom/bulk.php';
} elseif (file_exists($docroot.$directory.'/bulk.php')) {
$bulk = include $docroot.$directory.'/bulk.php';
}
$bulk = (array) $bulk;
$bulk = null;
if (file_exists($docroot.$directory.'/custom/bulk.php')) {
$bulk = include $docroot.$directory.'/custom/bulk.php';
} elseif (file_exists($docroot.$directory.'/bulk.php')) {
$bulk = include $docroot.$directory.'/bulk.php';
}
$bulk = (array) $bulk;
if (in_array(post('op'), array_keys($bulk))) {
redirect(ROOTDIR.'/controller.php?id_module='.$id_module, 'js');
} else {
// Esecuzione delle operazioni del modulo
if (file_exists($docroot.$directory.'/custom/actions.php')) {
include $docroot.$directory.'/custom/actions.php';
} elseif (file_exists($docroot.$directory.'/actions.php')) {
include $docroot.$directory.'/actions.php';
if (in_array(post('op'), array_keys($bulk))) {
redirect(ROOTDIR.'/controller.php?id_module='.$id_module, 'js');
} else {
// Esecuzione delle operazioni del modulo
if (file_exists($docroot.$directory.'/custom/actions.php')) {
include $docroot.$directory.'/custom/actions.php';
} elseif (file_exists($docroot.$directory.'/actions.php')) {
include $docroot.$directory.'/actions.php';
}
}
}
}

View File

@ -23,6 +23,7 @@
"type": "project",
"require": {
"php": ">=5.4",
"aluguest/ical-easy-reader": "^1.5",
"danielstjules/stringy": "^3.1",
"ezyang/htmlpurifier": "^4.8",
"filp/whoops": "^2.1",

View File

@ -27,7 +27,7 @@ echo Widgets::addModuleWidgets($id_module, 'controller_top');
// Lettura eventuali plugins modulo da inserire come tab
echo '
<div class="nav-tabs-custom">
<ul class="nav nav-tabs pull-right" role="tablist">
<ul class="nav nav-tabs pull-right" id="tabs" role="tablist">
<li class="pull-left active header">';
// Verifico se ho impostato un nome modulo personalizzato

View File

@ -14,10 +14,13 @@ if (file_exists(__DIR__.'/config.inc.php')) {
// Individuazione dei percorsi di base
$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));
// Aggiunta delle variabili globali

View File

@ -54,7 +54,7 @@ if (empty($records)) {
*/
echo '
<div class="nav-tabs-custom">
<ul class="nav nav-tabs pull-right" role="tablist">
<ul class="nav nav-tabs pull-right" id="tabs" role="tablist">
<li class="pull-left active header">';
// Verifico se ho impostato un nome modulo personalizzato
@ -63,17 +63,18 @@ if (empty($records)) {
echo '
<a data-toggle="tab" href="#tab_0">
<i class="'.$module['icon'].'"></i> '.$name;
// Pulsante "Aggiungi" solo se il modulo è di tipo "table" e se esiste il template per la popup
if (file_exists($docroot.'/modules/'.$module_dir.'/add.php') && $module['permessi'] == 'rw') {
echo '
// Pulsante "Aggiungi" solo se il modulo è di tipo "table" e se esiste il template per la popup
if (file_exists($docroot.'/modules/'.$module_dir.'/add.php') && $module['permessi'] == 'rw') {
echo '
<button type="button" class="btn btn-primary" data-toggle="modal" data-title="'.tr('Aggiungi').'..." data-target="#bs-popup" data-href="add.php?id_module='.$id_module.'"><i class="fa fa-plus"></i></button>';
}
}
echo '
</a>
<a class="back-btn" href="controller.php?id_module='.$id_module.'"><i class="fa fa-chevron-left"></i> '.tr("Torna all'elenco").'</a>
</li>';
$plugins = $dbo->fetchArray('SELECT id, title FROM zz_plugins WHERE idmodule_to='.prepare($id_module)." AND position='tab' AND enabled = 1");
foreach ($plugins as $plugin) {
echo '
<li>
@ -148,7 +149,6 @@ if ($module['permessi'] == 'r') {
$('a.btn-info, button.btn-info, input[type=button].btn-info', 'section.content').show();
});
<?php
} ?>
var content_was_modified = false;
@ -173,7 +173,7 @@ if ($module['permessi'] == 'r') {
};
<?php
if ($advanced_sessions) {
?>
?>
function getActiveUsers(){
$.getJSON('<?php echo ROOTDIR; ?>/call.php', {
@ -196,8 +196,7 @@ if ($advanced_sessions) {
setInterval(getActiveUsers, <?php echo get_var('Timeout notifica di presenza (minuti)') * 1000; ?>);
<?php
}
}
?>
</script>
<?php

View File

@ -229,6 +229,7 @@ gulp.task('i18n', function () {
gulp.task('php-debugbar', function () {
gulp.src([
'./vendor/maximebf/debugbar/src/DebugBar/Resources/**/*',
'!./vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/**/*',
])
.pipe(gulpIf('*.css', minifyCSS(), gulpIf('*.js', minifyJS())))
.pipe(gulp.dest(config.production + '/php-debugbar'));
@ -247,6 +248,7 @@ gulp.task('release', function () {
'./vendor/mpdf/mpdf/iccprofiles/*',
'./vendor/mpdf/mpdf/qrcode/*',
'./vendor/mpdf/mpdf/ttfonts/*',
'./vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/*',
]);
var output = fs.createWriteStream('./release.zip');

View File

@ -193,12 +193,12 @@ $(document).ready(function () {
}
// Tabs
$('#tabs').tabs();
$('.nav-tabs').tabs();
// Entra nel tab indicato al caricamento della pagina
var hash = window.location.hash ? window.location.hash : getUrlVars().hash;
if (hash && hash != '#tab_0') {
$('ul.nav a[href="' + hash + '"]').tab('show');
$('ul.nav-tabs a[href="' + hash + '"]').tab('show');
}
// Nel caso la navigazione sia da mobile, disabilito il ritorno al punto precedente

View File

@ -82,7 +82,12 @@ switch (post('op')) {
}
// Aggiorno le tipologie di anagrafica
$dbo->sync('an_tipianagrafiche_anagrafiche', ['idanagrafica' => $id_record], ['idtipoanagrafica' => (array) $post['idtipoanagrafica']]);
$post['idtipoanagrafica'] = (array) $post['idtipoanagrafica'];
if (str_contains($records[0]['idtipianagrafica'], $id_azienda)) {
$post['idtipoanagrafica'][] = $id_azienda;
}
$dbo->sync('an_tipianagrafiche_anagrafiche', ['idanagrafica' => $id_record], ['idtipoanagrafica' => $post['idtipoanagrafica']]);
// Verifico se esiste già l'associazione dell'anagrafica a conti del partitario
$rs = $dbo->fetchArray('SELECT idconto_cliente, idconto_fornitore FROM an_anagrafiche WHERE idanagrafica='.prepare($id_record));
@ -209,7 +214,7 @@ switch (post('op')) {
case 'delete':
// Se l'anagrafica non è l'azienda principale, la disattivo
if (str_contains($records[0]['idtipianagrafica'], $id_azienda) === false) {
if (!str_contains($records[0]['idtipianagrafica'], $id_azienda)) {
$dbo->query('UPDATE an_anagrafiche SET deleted = 1 WHERE idanagrafica = '.prepare($id_record).Modules::getAdditionalsQuery($id_module));
$_SESSION['infos'][] = tr('Anagrafica eliminata!');

View File

@ -13,15 +13,14 @@ if (!empty($google)) {
}
if (!$cliente) {
$plugins = $dbo->fetchArray("SELECT id FROM zz_plugins WHERE name='Impianti del cliente' OR name='Ddt del cliente'");
$ignore = $dbo->fetchArray("SELECT id FROM zz_plugins WHERE name='Impianti del cliente' OR name='Ddt del cliente'");
foreach ($plugins as $plugin) {
foreach ($ignore as $plugin) {
echo '
<script>
$("#link-tab_'.$plugin['id'].'").addClass("disabled");
</script>';
}
}
?>
@ -312,9 +311,13 @@ if ($fornitore) {
<div class="row">
<div class="col-md-3">
{[ "type": "select", "multiple": "1", "label": "<?php echo tr('Tipo di anagrafica'); ?>", "name": "idtipoanagrafica[]", "values": "query=SELECT idtipoanagrafica AS id, descrizione FROM an_tipianagrafiche WHERE idtipoanagrafica NOT IN (SELECT DISTINCT(x.idtipoanagrafica) FROM an_tipianagrafiche_anagrafiche x INNER JOIN an_tipianagrafiche t ON x.idtipoanagrafica = t.idtipoanagrafica INNER JOIN an_anagrafiche ON an_anagrafiche.idanagrafica = x.idanagrafica WHERE t.descrizione = 'Azienda' AND deleted = 0) OR idtipoanagrafica IN (SELECT DISTINCT(z.idtipoanagrafica) FROM an_tipianagrafiche_anagrafiche z WHERE idanagrafica = <?php echo $records[0]['idanagrafica']; ?>) ORDER BY descrizione", "value": "$idtipianagrafica$"<?php if (str_contains($records[0]['idtipianagrafica'], $id_azienda)) {
echo ', "readonly": 1';
} ?> ]}
{[ "type": "select", "multiple": "1", "label": "<?php echo tr('Tipo di anagrafica'); ?>", "name": "idtipoanagrafica[]", "values": "query=SELECT idtipoanagrafica AS id, descrizione FROM an_tipianagrafiche WHERE idtipoanagrafica NOT IN (SELECT DISTINCT(x.idtipoanagrafica) FROM an_tipianagrafiche_anagrafiche x INNER JOIN an_tipianagrafiche t ON x.idtipoanagrafica = t.idtipoanagrafica INNER JOIN an_anagrafiche ON an_anagrafiche.idanagrafica = x.idanagrafica WHERE t.descrizione = 'Azienda' AND deleted = 0) ORDER BY descrizione", "value": "$idtipianagrafica$" ]}
<?php
if (str_contains($records[0]['idtipianagrafica'], $id_azienda)) {
echo '
<p>'.tr('Questa anagrafica appartiene alla tipologia "Azienda"').'.</p>';
}
?>
</div>
<?php
if (in_array('Tecnico', explode(',', $records[0]['tipianagrafica']))) {
@ -408,15 +411,15 @@ if (!str_contains($records[0]['idtipianagrafica'], $id_azienda)) {
<script>
$(document).ready( function(){
$('.colorpicker').colorpicker().on('changeColor', function(){
$('#colore').parent().find('.square').css('background', $('#colore').val());
$(".colorpicker").colorpicker().on("changeColor", function(){
$("#colore").parent().find(".square").css("background", $("#colore").val());
});
$('#colore').parent().find('.square').css('background', $('#colore').val());
$("#colore").parent().find(".square").css("background", $("#colore").val());
$("#geocomplete input").geocomplete({
map: $('#map').length ? "#map" : false,
location: $('#gaddress').val() ? $('#gaddress').val() : [$('#lat').val(), $('#lng').val()],
map: $("#map").length ? "#map" : false,
location: $("#gaddress").val() ? $("#gaddress").val() : [$("#lat").val(), $("#lng").val()],
details: ".details",
detailsAttribute: "data-geo"
}).bind("geocode:result", function (event, result) {

View File

@ -213,7 +213,7 @@ echo '
echo '
<tr>
<td>'.$rsl[$i]['nome'].'</td>
<td>'.Translator::numberToLocale($rsart[0]['prezzo_vendita'] + $rsart[0]['prezzo_vendita'] / 100 * $rsl[$i]['prc_guadagno']).' &euro;</td>
<td>'.Translator::numberToLocale($rsart[0]['prezzo_vendita'] - $rsart[0]['prezzo_vendita'] / 100 * $rsl[$i]['prc_guadagno']).' &euro;</td>
</tr>';
}

View File

@ -35,7 +35,7 @@ if (empty($idriga)) {
$op = 'editriga';
$button = tr('Modifica');
$rsr = $dbo->fetchArray('SELECT * FROM co_righe2_contratti WHERE idcontratto='.prepare($idcontratto).' AND id='.prepare($idriga));
$rsr = $dbo->fetchArray('SELECT * FROM co_righe2_contratti WHERE idcontratto='.prepare($id_record).' AND id='.prepare($idriga));
$descrizione = $rsr[0]['descrizione'];
$qta = $rsr[0]['qta'];
@ -47,7 +47,7 @@ if (empty($idriga)) {
}
echo '
<form action="'.$rootdir.'/editor.php?id_module='.Modules::get('Contratti')['id'].'&id_record='.$idcontratto.'" method="post">
<form action="'.$rootdir.'/editor.php?id_module='.Modules::get('Contratti')['id'].'&id_record='.$id_record.'" method="post">
<input type="hidden" name="op" value="'.$op.'">
<input type="hidden" name="idriga" value="'.$idriga.'">
<input type="hidden" name="backto" value="record-edit">';
@ -55,7 +55,7 @@ echo '
// Descrizione
echo '
<div class="col-md-12">
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "value": "'.$descrizione.'", "required": 1 ]}
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "value": '.json_encode($descrizione).', "required": 1 ]}
</div>';
// Iva

View File

@ -94,7 +94,7 @@ if (!empty($rsi)) {
<th width="120">'.tr('Costo orario').'</th>
<th width="120">'.tr('Costo km').'</th>
<th width="120">'.tr('Diritto ch.').'</th>
<th width="120">'.tr('Prezzo orario').'</th>
<th width="120">'.tr('Costo addebitato').'</th>
<th width="120">'.tr('Prezzo km').'</th>
<th width="120">'.tr('Diritto ch.').'</th>
</tr>';
@ -293,12 +293,12 @@ if (!empty($contratto_tot_ore)) {
<table class="table text-left">
<tr>
<td>'.tr('Ore residue').':</td>
<td class="text-right">'.Translator::numberToLocale(floatval($contratto_tot_ore) - floatval($totale_ore_impiegate)).'</td>
<td class="text-right">'.Translator::numberToLocale(floatval($contratto_tot_ore) - floatval($totale_ore)).'</td>
</tr>
<tr>
<td>'.tr('Ore erogate').':</td>
<td class="text-right">'.Translator::numberToLocale($totale_ore_impiegate).'</td>
<td class="text-right">'.Translator::numberToLocale($totale_ore).'</td>
</tr>
<tr>

View File

@ -96,7 +96,7 @@ if (!empty($rs_art)) {
<div class="btn-group">';
echo "
<a class='btn btn-xs btn-warning' onclick=\"launch_modal('Modifica riga', '".$rootdir.'/modules/contratti/add_riga.php?idcontratto='.$id_record.'&idriga='.$r['id']."', 1 );\"><i class='fa fa-edit'></i></a>
<a class='btn btn-xs btn-warning' onclick=\"launch_modal('Modifica riga', '".$rootdir.'/modules/contratti/add_riga.php?id_record='.$id_record.'&idriga='.$r['id']."', 1 );\"><i class='fa fa-edit'></i></a>
<a href='javascript:;' class='btn btn-xs btn-danger' title='Rimuovi questa riga' onclick=\"if( confirm('Rimuovere questa riga dal contratto?') ){ $('#delete-form-".$r['id']."').submit(); }\"><i class='fa fa-trash'></i></a>";
echo '
</div>

View File

@ -69,7 +69,7 @@ if (!empty($idriga)) {
echo '
<div class="row">
<div class="col-md-12">
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "required": 1, "value": "'.$descrizione.'" ]}
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "required": 1, "value": '.json_encode($descrizione).' ]}
</div>
</div>';

View File

@ -197,13 +197,13 @@ switch (post('op')) {
}
// Se delle righe sono state create da un ordine, devo riportare la quantità evasa nella tabella degli ordini al valore di prima, riaggiungendo la quantità che sto togliendo
$rs = $dbo->fetchArray('SELECT qta, descrizione, idarticolo, idordine, idiva FROM co_righe_documenti WHERE iddocumento='.prepare($iddocumento));
$rs = $dbo->fetchArray('SELECT qta, descrizione, idarticolo, idordine, idiva FROM co_righe_documenti WHERE iddocumento='.prepare($id_record));
foreach ($rs as $r) {
$dbo->query('UPDATE or_righe_ordini SET qta_evasa=qta_evasa-'.$r['qta'].' WHERE descrizione='.prepare($r['descrizione']).' AND idarticolo='.prepare($r['idarticolo']).' AND idordine='.prepare($r['idordine']).' AND idiva='.prepare($r['idiva']));
}
// Se delle righe sono state create da un ddt, devo riportare la quantità evasa nella tabella dei ddt al valore di prima, riaggiungendo la quantità che sto togliendo
$rs = $dbo->fetchArray('SELECT qta, descrizione, idarticolo, idddt, idiva FROM co_righe_documenti WHERE iddocumento='.prepare($iddocumento));
$rs = $dbo->fetchArray('SELECT qta, descrizione, idarticolo, idddt, idiva FROM co_righe_documenti WHERE iddocumento='.prepare($id_record));
foreach ($rs as $r) {
$dbo->query('UPDATE dt_righe_ddt SET qta_evasa=qta_evasa-'.$r['qta'].' WHERE descrizione='.prepare($r['descrizione']).' AND idarticolo='.prepare($r['idarticolo']).' AND idddt='.prepare($r['idddt']).' AND idiva='.prepare($r['idiva']));
}
@ -246,8 +246,7 @@ switch (post('op')) {
$id_record = $dbo->lastInsertedID();
// TODO: sistemare la duplicazione delle righe generiche e degli articoli, ingorando interventi, ddt, ordini, preventivi
/*
foreach ($righe as $riga) {
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
@ -255,7 +254,6 @@ switch (post('op')) {
add_articolo_infattura($id_record, $riga['idarticolo'], $riga['descrizione'], $riga['idiva'], $riga['qta'], $riga['subtotale']);
}
}
*/
// Ricalcolo inps, ritenuta e bollo (se la fattura non è stata pagata)
if ($dir == 'entrata') {
@ -315,10 +313,80 @@ switch (post('op')) {
$query = 'SELECT * FROM co_ritenutaacconto WHERE id='.prepare(get_var("Percentuale ritenuta d'acconto"));
$rs = $dbo->fetchArray($query);
$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'];
// Aggiunta riga intervento sul documento
$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', '-', 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).'))';
$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).'))';
$dbo->query($query);
if( $diritto_chiamata > 0 ){
// Calcolo iva
$query = 'SELECT * FROM co_iva WHERE id='.prepare($idiva);
$rs = $dbo->fetchArray($query);
$iva = $diritto_chiamata / 100 * $rs[0]['percentuale'];
$iva_indetraibile = $iva / 100 * $rs[0]['indetraibile'];
$desc_iva = $rs[0]['descrizione'];
// Calcolo rivalsa inps
$query = 'SELECT * FROM co_rivalsainps WHERE id='.prepare(get_var('Percentuale rivalsa INPS'));
$rs = $dbo->fetchArray($query);
$rivalsainps = $diritto_chiamata / 100 * $rs[0]['percentuale'];
// Calcolo ritenuta d'acconto
$query = 'SELECT * FROM co_ritenutaacconto WHERE id='.prepare(get_var("Percentuale ritenuta d'acconto"));
$rs = $dbo->fetchArray($query);
$ritenutaacconto = $diritto_chiamata / 100 * $rs[0]['percentuale'];
$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).',
"Diritto di chiamata",
'.prepare($diritto_chiamata).',
'.prepare($sconto).',
'.prepare($sconto).",
'UNT',
'-',
".prepare($rs[0]['diritto_chiamata']).",
".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);
}
// Collego in fattura eventuali articoli collegati all'intervento
$rs2 = $dbo->fetchArray('SELECT mg_articoli_interventi.*, idarticolo FROM mg_articoli_interventi INNER JOIN mg_articoli ON mg_articoli_interventi.idarticolo=mg_articoli.id WHERE idintervento='.prepare($idintervento).' AND ( idintervento NOT IN(SELECT idintervento FROM co_righe_preventivi WHERE idpreventivo IN(SELECT idpreventivo FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).')) AND idintervento NOT IN(SELECT idintervento FROM co_righe_contratti WHERE idcontratto IN(SELECT idcontratto FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).')) )');
@ -760,7 +828,6 @@ switch (post('op')) {
$idanagrafica = $post['idanagrafica'];
$idarticolo = $post['idarticolo'];
$idpagamento = $post['idpagamento'];
$idconto = $post['idconto'];
$idddt = $post['idddt'];
$numero = get_new_numerofattura($data);
@ -770,7 +837,13 @@ switch (post('op')) {
$numero_esterno = '';
}
$tipo_documento = ($dir == 'entrata') ? 'Fattura differita di vendita' : 'Fattura differita di acquisto';
if( $dir == 'entrata' ){
$tipo_documento = 'Fattura differita di vendita';
$idconto = get_var('Conto predefinito fatture di vendita');
} else {
$tipo_documento = 'Fattura differita di acquisto';
$idconto = get_var('Conto predefinito fatture di acquisto');
}
// Creazione nuova fattura
$dbo->query('INSERT INTO co_documenti(numero, numero_esterno, data, idanagrafica, idtipodocumento, idstatodocumento, idpagamento, idconto) VALUES('.prepare($numero).', '.prepare($numero_esterno).', '.prepare($data).', '.prepare($idanagrafica).', (SELECT id FROM co_tipidocumento WHERE descrizione='.prepare($tipo_documento)."), (SELECT id FROM co_statidocumento WHERE descrizione='Bozza'), ".prepare($idpagamento).', '.prepare($idconto).')');

View File

@ -34,7 +34,7 @@ echo '
echo '
<div class="row">
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Preventivo').'", "name": "idpreventivo", "required": 1, "values": "query=SELECT id, CONCAT(\'Preventivo numero \', numero, \' - \', nome) AS descrizione, (SELECT SUM(subtotale) FROM co_righe_preventivi WHERE idpreventivo=co_preventivi.id GROUP BY idpreventivo) - (SELECT SUM(sconto) FROM co_righe_preventivi WHERE idpreventivo=co_preventivi.id GROUP BY idpreventivo) AS subtot FROM co_preventivi WHERE idanagrafica='.prepare($idanagrafica).' AND id NOT IN (SELECT idpreventivo FROM co_righe_documenti WHERE NOT idpreventivo=NULL) AND idstato IN( SELECT id FROM co_statipreventivi WHERE descrizione=\'Accettato\' OR descrizione=\'In lavorazione\' OR descrizione=\'In attesa di conferma\')", "extra": "onchange=\"$data = $(this).selectData(); $(\'#descrizione\').val($data.text); $(\'#prezzo\').val($data.subtot);\"" ]}
{[ "type": "select", "label": "'.tr('Preventivo').'", "name": "idpreventivo", "required": 1, "values": "query=SELECT id, nome AS descrizione, (SELECT SUM(subtotale) FROM co_righe_preventivi WHERE idpreventivo=co_preventivi.id GROUP BY idpreventivo) - (SELECT SUM(sconto) FROM co_righe_preventivi WHERE idpreventivo=co_preventivi.id GROUP BY idpreventivo) AS subtot FROM co_preventivi WHERE idanagrafica='.prepare($idanagrafica).' AND id NOT IN (SELECT idpreventivo FROM co_righe_documenti WHERE NOT idpreventivo=NULL) AND idstato IN( SELECT id FROM co_statipreventivi WHERE descrizione=\'Accettato\' OR descrizione=\'In lavorazione\' OR descrizione=\'In attesa di conferma\')", "extra": "onchange=\"$data = $(this).selectData(); $(\'#descrizione\').val($data.text); $(\'#prezzo\').val($data.subtot);\"" ]}
</div>
<div class="col-md-6">

View File

@ -47,7 +47,7 @@ if (get_var('Percentuale rivalsa INPS') != '' || get_var("Percentuale ritenuta d
if (get_var('Percentuale rivalsa INPS') != '' || $dir == 'uscita') {
echo '
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Rivalsa INPS').'", "name": "idrivalsainps", "required": 1, "value": "'.get_var('Percentuale rivalsa INPS').'", "values": "query=SELECT * FROM co_rivalsainps" ]}
{[ "type": "select", "label": "'.tr('Rivalsa INPS').'", "name": "idrivalsainps", "value": "'.get_var('Percentuale rivalsa INPS').'", "values": "query=SELECT * FROM co_rivalsainps", "required": '.intval($dir != 'uscita').' ]}
</div>';
}
@ -55,7 +55,7 @@ if (get_var('Percentuale rivalsa INPS') != '' || get_var("Percentuale ritenuta d
if (get_var("Percentuale ritenuta d'acconto") != '' || $dir == 'uscita') {
echo '
<div class="col-md-6">
{[ "type": "select", "label": "'.tr("Ritenuta d'acconto").'", "name": "idritenutaacconto", "required": 1, "value": "'.get_var("Percentuale ritenuta d'acconto").'", "values": "query=SELECT * FROM co_ritenutaacconto" ]}
{[ "type": "select", "label": "'.tr("Ritenuta d'acconto").'", "name": "idritenutaacconto", "value": "'.get_var("Percentuale ritenuta d'acconto").'", "values": "query=SELECT * FROM co_ritenutaacconto", "required": '.intval($dir != 'uscita').' ]}
</div>';
}

View File

@ -34,16 +34,19 @@ $_SESSION['superselect']['idanagrafica'] = $records[0]['idanagrafica'];
<div class="clearfix"></div>
<div class="row">
<?php
if ($dir == 'uscita') {
echo '
<?php
if ($dir == 'uscita') {
echo '
<div class="col-md-3">
{[ "type": "span", "label": "'.tr('Numero fattura').'", "name": "numero","class": "text-center", "value": "$numero$" ]}
</div>';
$label = tr('Numero secondario');
} else {
$label = tr('Numero fattura');
}
?>
<div class="col-md-3">
{[ "type": "span", "label": "'.tr('Numero fattura').'", "name": "numero","class": "text-center", "value": "$numero$" ]}
</div>';
}
?>
<div class="col-md-3">
{[ "type": "text", "label": "<?php echo tr('Numero secondario'); ?>", "name": "numero_esterno", "class": "text-center", "value": "$numero_esterno$" ]}
{[ "type": "text", "label": "<?php echo $label; ?>", "name": "numero_esterno", "class": "text-center", "value": "$numero_esterno$" ]}
</div>
<div class="col-md-3">
@ -91,7 +94,7 @@ if ($dir == 'uscita') {
<p><strong>'.tr('Scadenze').'</strong></p>';
foreach ($scadenze as $scadenza) {
echo '
<p>'.Translator::dateToLocale($scadenza['scadenza']).' - '.Translator::numberToLocale($scadenza['da_pagare']).'&euro;</p>';
<p>'.Translator::dateToLocale($scadenza['scadenza']).': '.Translator::numberToLocale($scadenza['da_pagare']).'&euro;</p>';
}
echo '
</div>';

View File

@ -41,7 +41,7 @@ echo '
echo '
<div class="row">
<div class="col-md-12">
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "required": 1, "value": "'.$rsr[0]['descrizione'].'" ]}
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "required": 1, "value": '.json_encode($rsr[0]['descrizione']).' ]}
</div>
</div>';
@ -53,7 +53,7 @@ if (get_var('Percentuale rivalsa INPS') != '' || get_var("Percentuale ritenuta d
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" ]}
{[ "type": "select", "label": "'.tr('Rivalsa INPS').'", "name": "idrivalsainps", "value": "'.$rsr[0]['idrivalsainps'].'", "values": "query=SELECT * FROM co_rivalsainps", "required": '.intval($dir != 'uscita').' ]}
</div>';
}
@ -61,7 +61,7 @@ if (get_var('Percentuale rivalsa INPS') != '' || get_var("Percentuale ritenuta d
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" ]}
{[ "type": "select", "label": "'.tr("Ritenuta d'acconto").'", "name": "idritenutaacconto", "value": "'.$rsr[0]['idritenutaacconto'].'", "values": "query=SELECT * FROM co_ritenutaacconto", "required": '.intval($dir != 'uscita').' ]}
</div>';
}

View File

@ -91,14 +91,14 @@ if (!empty($rs)) {
// Aggiunta riferimento a ordine
if (!empty($r['idordine'])) {
$data = $dbo->fetchArray("SELECT IF(numero_esterno != '', numero_esterno, numero) AS numero, data FROM or_ordini.id=".prepare($r['idordine']));
$data = $dbo->fetchArray("SELECT IF(numero_esterno != '', numero_esterno, numero) AS numero, data FROM or_ordini WHERE id=".prepare($r['idordine']));
$ref_modulo = ($dir == 'entrata') ? 'Ordini cliente' : 'Ordini fornitore';
$ref_id = $r['idordine'];
$documento = tr('Ordine');
} elseif (!empty($r['idddt'])) {
$data = $dbo->fetchArray("SELECT IF(numero_esterno != '', numero_esterno, numero) AS numero, data FROM dt_ddt WHERE dt_ddt.id=".prepare($r['idddt']));
$data = $dbo->fetchArray("SELECT IF(numero_esterno != '', numero_esterno, numero) AS numero, data FROM dt_ddt WHERE id=".prepare($r['idddt']));
$ref_modulo = ($dir == 'entrata') ? 'Ddt di vendita' : 'Ddt di acquisto';
$ref_id = $r['idddt'];

View File

@ -31,8 +31,8 @@ switch (post('op')) {
}
/*
Collegamento intervento a contratto (se impostato).
Oltre al collegamento al contratto, l'intervento è collegato ad una riga di pianificazione, perciò è importante considerarla se è impostata
Collegamento intervento a contratto (se impostato).
Oltre al collegamento al contratto, l'intervento è collegato ad una riga di pianificazione, perciò è importante considerarla se è impostata
*/
$array = [
'idintervento' => $id_record,
@ -217,7 +217,8 @@ switch (post('op')) {
*/
$formato = get_var('Formato codice intervento');
$rs = $dbo->fetchArray('SELECT codice FROM in_interventi WHERE concat("", codice * 1) = codice AND LENGTH(codice) = '.strlen($formato).' ORDER BY CAST(codice AS SIGNED) DESC LIMIT 1');
// 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');
$codice = get_next_code($rs[0]['codice'], 1, $formato);
// Informazioni di base

View File

@ -87,7 +87,7 @@ echo '
echo '
<div class="row">
<div class="col-md-12">
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "required": 1, "value": "'.$descrizione.'" ]}
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "id": "descrizione_articolo", "required": 1, "value": '.json_encode($descrizione).' ]}
</div>
</div>
<br>';
@ -162,8 +162,9 @@ echo '
session_set("superselect,idarticolo", $(this).val(), 0);
$data = $(this).selectData();
$("#prezzo").val($data.prezzo_vendita);
$("#descrizione").val($data.descrizione);
$("#prezzo_vendita").val($data.prezzo_vendita);
$("#descrizione_articolo").val($data.descrizione);
$("#um").selectSetNew($data.um, $data.um);
}else{
$("#prezzi_articolo button").addClass("disabled");

View File

@ -54,7 +54,7 @@ echo '
echo '
<div class="row">
<div class="col-md-12">
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "id": "descrizione_riga", "name": "descrizione", "required": 1, "value": "'.$descrizione.'" ]}
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "id": "descrizione_riga", "name": "descrizione", "required": 1, "value": '.json_encode($descrizione).' ]}
</div>
</div>
<br>';

View File

@ -0,0 +1,47 @@
<?php
switch ($resource) {
case 'sync':
$dbo->query("UPDATE in_interventi_tecnici SET summary=(SELECT ragione_sociale FROM an_anagrafiche INNER JOIN in_interventi ON an_anagrafiche.idanagrafica=in_interventi.idanagrafica WHERE in_interventi.id=in_interventi_tecnici.idintervento) WHERE summary=''");
$dbo->query("UPDATE in_interventi_tecnici SET uid=id WHERE uid=''");
if ($idtecnico != '0') {
$query = 'SELECT in_interventi_tecnici.id AS idriga, in_interventi_tecnici.idintervento, (SELECT ragione_sociale FROM an_anagrafiche WHERE idanagrafica=in_interventi.idanagrafica) AS cliente, richiesta, orario_inizio, orario_fine, (SELECT ragione_sociale FROM an_anagrafiche WHERE idanagrafica=idtecnico) AS nome_tecnico, summary FROM in_interventi_tecnici INNER JOIN in_interventi ON in_interventi_tecnici.idintervento=in_interventi.id WHERE CAST(orario_inizio AS DATE) BETWEEN CURDATE()-INTERVAL 7 DAY AND CURDATE()+INTERVAL 3 MONTH AND in_interventi_tecnici.idtecnico="'.$idtecnico.'" AND deleted=0';
} else {
$query = 'SELECT in_interventi_tecnici.id AS idriga, in_interventi_tecnici.idintervento, (SELECT ragione_sociale FROM an_anagrafiche WHERE idanagrafica=in_interventi.idanagrafica) AS cliente, richiesta, orario_inizio, orario_fine, (SELECT ragione_sociale FROM an_anagrafiche WHERE idanagrafica=idtecnico) AS nome_tecnico, summary FROM in_interventi_tecnici INNER JOIN in_interventi ON in_interventi_tecnici.idintervento=in_interventi.id WHERE CAST(orario_inizio AS DATE) BETWEEN CURDATE()-INTERVAL 7 DAY AND CURDATE()+INTERVAL 3 MONTH AND deleted=0';
}
$rs = $dbo->fetchArray($query);
$results = [];
$results['custom'] = '';
$results['custom'] .= "BEGIN:VCALENDAR\n";
$results['custom'] .= "VERSION:2.0\n";
$results['custom'] .= "PRODID:-// OpenSTAManager\n";
for ($i = 0; $i < sizeof($rs); ++$i) {
$richiesta = str_replace("\r\n", "\n", $rs[$i]['richiesta']);
$richiesta = str_replace("\r", "\n", $richiesta);
$richiesta = str_replace("\n", '\\n', $richiesta);
$oggetto = str_replace("\r\n", "\n", $rs[$i]['oggetto']);
$results['custom'] .= "BEGIN:VEVENT\n";
$results['custom'] .= 'UID:'.$rs[$i]['idriga']."\n";
$results['custom'] .= 'DTSTAMP:'.date('Ymd').'T'.date('His')."\n";
$results['custom'] .= 'ORGANIZER;CN='.$azienda.':MAILTO:'.$email."\n";
$results['custom'] .= 'DTSTART:'.date('Ymd', strtotime($rs[$i]['orario_inizio'])).'T'.date('His', strtotime($rs[$i]['orario_inizio']))."\n";
$results['custom'] .= 'DTEND:'.date('Ymd', strtotime($rs[$i]['orario_fine'])).'T'.date('His', strtotime($rs[$i]['orario_fine']))."\n";
$results['custom'] .= 'SUMMARY:'.html_entity_decode($rs[$i]['summary'])."\n";
$results['custom'] .= 'DESCRIPTION:'.html_entity_decode($richiesta, ENT_QUOTES, 'UTF-8')."\n";
$results['custom'] .= "END:VEVENT\n";
}
$results['custom'] .= "END:VCALENDAR\n";
break;
}
return [
'sync',
];

View File

@ -0,0 +1,148 @@
<?php
switch ($resource) {
case 'update_anagrafica':
$idtecnico = $user['idanagrafica'];
$response = file_get_contents('php:// input');
// file_put_contents('calendario.txt', $response);
// $events = iCalDecoder( $response );
$ical = new iCalEasyReader();
$events = $ical->load($response);
// file_put_contents('calendario.txt', print_r($events, 1));
for ($j = 0; $j < sizeof($events['VEVENT']); ++$j) {
$description = $events['VEVENT'][$j]['DESCRIPTION'];
// file_put_contents('cal.txt', $description, FILE_APPEND);
// idriga di in_interventi_tecnici
if (strstr($events['VEVENT'][$j]['UID'], '-')) {
$idriga = 'NEW';
} else {
$idriga = $events['VEVENT'][$j]['UID'];
}
// Data-ora inizio
$dataora = explode('T', $events['VEVENT'][$j]['DTSTART']);
$data = $dataora[0];
$ora = $dataora[1];
$Y = substr($data, 0, 4);
$m = substr($data, 4, 2);
$d = substr($data, 6, 2);
$H = substr($ora, 0, 2);
$i = substr($ora, 2, 2);
$orario_inizio = "$Y-$m-$d $H:$i:00";
// Data-ora fine
$dataora = explode('T', $events['VEVENT'][$j]['DTEND']);
$data = $dataora[0];
$ora = $dataora[1];
$Y = substr($data, 0, 4);
$m = substr($data, 4, 2);
$d = substr($data, 6, 2);
$H = substr($ora, 0, 2);
$i = substr($ora, 2, 2);
$orario_fine = "$Y-$m-$d $H:$i:00";
// Descrizione
$richiesta = $events['VEVENT'][$j]['DESCRIPTION'];
$richiesta = str_replace('\\r\\n', "\n", $richiesta);
$richiesta = str_replace('\\n', "\n", $richiesta);
$oggetto = trim($events['VEVENT'][$j]['SUMMARY']);
$richiesta = str_replace('\\r\\n', "\n", $richiesta);
$richiesta = str_replace('\\n', "\n", $richiesta);
// Nuova attività
if ($idriga == 'NEW') {
// Data-ora inizio
$dataora = explode('T', $events['VEVENT'][$j]['DTSTART']['value']);
$data = $dataora[0];
$ora = $dataora[1];
$Y = substr($data, 0, 4);
$m = substr($data, 4, 2);
$d = substr($data, 6, 2);
$H = substr($ora, 0, 2);
$i = substr($ora, 2, 2);
$orario_inizio = "$Y-$m-$d $H:$i:00";
// Data-ora fine
$dataora = explode('T', $events['VEVENT'][$j]['DTEND']['value']);
$data = $dataora[0];
$ora = $dataora[1];
$Y = substr($data, 0, 4);
$m = substr($data, 4, 2);
$d = substr($data, 6, 2);
$H = substr($ora, 0, 2);
$i = substr($ora, 2, 2);
$orario_fine = "$Y-$m-$d $H:$i:00";
$rs_copie = $dbo->fetchArray("SELECT * FROM in_interventi_tecnici WHERE uid='".$events['VEVENT'][$j]['UID']."'");
if (sizeof($rs_copie) > 0) {
$query = 'UPDATE in_interventi_tecnici SET orario_inizio="'.$orario_inizio.'", orario_fine="'.$orario_fine.'", summary="'.prepare($oggetto).'" WHERE uid="'.$events['VEVENT'][$j]['UID'].'" AND idtecnico="'.$idtecnico.'"';
$dbo->query($query);
$query = 'UPDATE in_interventi SET richiesta="'.prepare($richiesta).'", oggetto="'.prepare($oggetto)."\" WHERE idintervento=(SELECT idintervento FROM in_interventi_tecnici WHERE idintervento='".$rs_copie[0]['idintervento']."' AND idtecnico=\"".$idtecnico.'" LIMIT 0,1)';
$dbo->query($query);
$idriga = $rs_copie[0]['id'];
} else {
$idintervento = get_new_idintervento();
$query = 'INSERT INTO in_interventi( idintervento, idanagrafica, data_richiesta, richiesta, idtipointervento, idstatointervento, oggetto ) VALUES( "'.$idintervento."\", (SELECT valore FROM zz_impostazioni WHERE nome='Azienda predefinita'), NOW(), \"".prepare($richiesta).'", 0, "CALL", "'.prepare($oggetto).'" )';
$dbo->query($query);
$query = 'INSERT INTO in_interventi_tecnici( idintervento, idtecnico, orario_inizio, orario_fine, summary, uid ) VALUES( "'.$idintervento.'", "'.$idtecnico.'", "'.$orario_inizio.'", "'.$orario_fine.'", "'.$oggetto.'", "'.$events['VEVENT'][$j]['UID'].'" )';
$dbo->query($query);
$idriga = $dbo->last_inserted_id();
}
}
// Modifica attività esistente
else {
$query = 'UPDATE in_interventi_tecnici SET orario_inizio="'.$orario_inizio.'", orario_fine="'.$orario_fine.'", summary="'.prepare($oggetto).'" WHERE id="'.$idriga.'" AND idtecnico="'.$idtecnico.'"';
$dbo->query($query);
$query = 'UPDATE in_interventi SET richiesta="'.prepare($richiesta).'", oggetto="'.prepare($oggetto).'" WHERE idintervento=(SELECT idintervento FROM in_interventi_tecnici WHERE id="'.$idriga.'" AND idtecnico="'.$idtecnico.'" LIMIT 0,1)';
$dbo->query($query);
}
array_push($allsession, $idriga);
}
// Eliminazione attività
/*
$rs_sessioni = $dbo->fetchArray("SELECT * FROM in_interventi_tecnici");
for($i=0;$i<sizeof($rs_sessioni);$i++){
if(!in_array($rs_sessioni[$i]['id'], $allsession)){
$idintervento = $rs_sessioni[$i]['idintervento'];
$dbo->query("DELETE FROM in_interventi_tecnici WHERE id='".$rs_sessioni[$i]['id']."'");
$rs_per_intervento = $dbo->fetchArray("SELECT * FROM in_interventi_tecnici WHERE idintervento='".$idintervento."'");
if(sizeof($rs_per_intervento)==0){
$dbo->query("UPDATE in_interventi SET deleted=1 WHERE idintervento='".$idintervento."'");
}
}
}
*/
break;
}
return [
'syncs',
];

View File

@ -75,7 +75,7 @@ if (!empty($idriga)) {
echo '
<div class="row">
<div class="col-md-12">
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "required": 1, "value": "'.$descrizione.'" ]}
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "required": 1, "value": '.json_encode($descrizione).' ]}
</div>
</div>';

View File

@ -13,8 +13,6 @@ echo '
<tr>
<th>'.tr('Descrizione riga').'</th>
<th width="100">'.tr('Imponibile').'</th>
<th width="100">'.tr('Q.').'</th>
<th width="100">'.tr('Um').'</th>
</tr>';
$totale_imponibile = 0;
@ -26,17 +24,9 @@ for ($i = 0; $i < sizeof($rs); ++$i) {
<span>'.$rs[$i]['desc_riga'].'</span>
</td>
<td>
<td class="text-right">
<span>'.Translator::numberToLocale($rs[$i]['imponibile']).' &euro; </span>
</td>
<td
<span>'.Translator::numberToLocale($rs[$i]['qta']).'</span>
</td>
<td>
<span>'.$rs[$i]['um'].'</span>
</td>
</tr>';
$totale_imponibile += $rs[$i]['imponibile'];
@ -45,10 +35,8 @@ for ($i = 0; $i < sizeof($rs); ++$i) {
echo '
<tr>
<th>'.tr('Totali').': </th>
<th width="100"><span>'.Translator::numberToLocale($totale_imponibile).' &euro;</span></th>
<th width="100"><span>'.Translator::numberToLocale($totale_qta).'</span></th>
<th width="100"></th>
<th class="text-right">'.tr('Totali').': </th>
<th width="100" class="text-right"><span>'.Translator::numberToLocale($totale_imponibile).' &euro;</span></th>
</tr>
</table>

View File

@ -73,7 +73,7 @@ echo '
echo '
<div class="row">
<div class="col-md-12">
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "id": "desc", "value": "'.$descrizione.'", "required": 1 ]}
{[ "type": "textarea", "label": "'.tr('Descrizione').'", "name": "descrizione", "id": "desc", "value": '.json_encode($descrizione).', "required": 1 ]}
</div>
</div>';
@ -97,33 +97,6 @@ echo '
</div>
</div>';
/*
if (get_var('Percentuale rivalsa INPS') != '' || get_var("Percentuale ritenuta d'acconto") != '') {
echo '
<div class="row">';
// Rivalsa INPS
if (get_var('Percentuale rivalsa INPS') != '') {
echo '
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Rivalsa INPS').'", "name": "idrivalsainps", "required": 1, "value": "'.get_var('Percentuale rivalsa INPS').'", "values": "query=SELECT * FROM co_rivalsainps" ]}
</div>';
}
// Ritenuta d'acconto
if (get_var("Percentuale ritenuta d'acconto") != '') {
echo '
<div class="col-md-6">
{[ "type": "select", "label": "'.tr("Ritenuta d'acconto").'", "name": "idritenutaacconto", "required": 1, "value": "'.get_var("Percentuale ritenuta d'acconto").'", "values": "query=SELECT * FROM co_ritenutaacconto" ]}
</div>';
}
echo '
</div>';
}
*/
// Costo unitario
echo '
<div class="row">

View File

@ -12,9 +12,12 @@ switch (post('op')) {
// Verifico se il totale sommato è uguale al totale da pagare
foreach ($post['scadenza'] as $idscadenza => $da_pagare) {
$totale_utente += $da_pagare;
$totale_utente += floatval($da_pagare);
}
// Fix per problemi di comparazione tra float
$totale_utente = (string) $totale_utente;
if ($totale_utente == $totale_da_pagare) {
foreach ($post['scadenza'] as $idscadenza => $da_pagare) {
$dbo->query('UPDATE co_scadenziario SET da_pagare='.prepare($da_pagare).', pagato='.prepare(post('pagato')[$idscadenza]).', scadenza='.prepare(post('data')[$idscadenza]).' WHERE id='.prepare($idscadenza));

View File

@ -3,6 +3,11 @@
include_once __DIR__.'/../../core.php';
echo '
<div class="alert alert-warning">
<i class="fa fa-warning"></i> <b>'.tr('Attenzione', [], ['upper']).':</b> '.tr('le suddette stampe contabili non sono da considerarsi valide ai fini fiscali').'.
</div>
<div class="row">
<div class="col-xs-12 col-md-4">
<div class="panel panel-primary">
@ -24,14 +29,14 @@ echo '
<div class="col-xs-12 col-md-4">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">'.tr('Spesometro dal _START_ al _END_', [
<h3 class="panel-title">'.tr('Comunicazione dati fatture (ex-spesometro) dal _START_ al _END_', [
'_START_' => Translator::dateToLocale($_SESSION['period_start']),
'_END_' => Translator::dateToLocale($_SESSION['period_end']),
]).'</h3>
</div>
<div class="panel-body">
'.Prints::getLink('Spesometro', $id_record, 'btn-primary', '<br>'.tr('Stampa').'<br>'.tr('spesometro'), '|default| fa-2x', 'dir=uscita').'
'.Prints::getLink('Spesometro', $id_record, 'btn-primary', '<br>'.tr('Stampa').'<br>'.tr('dati fatture'), '|default| fa-2x', 'dir=uscita').'
</div>
</div>
</div>

View File

@ -38,7 +38,7 @@ $d1 = new DateTime($start);
$d2 = new DateTime($end);
$count = $d1->diff($d2)->m + ($d1->diff($d2)->y * 12) + 1;
$fatturato = $dbo->fetchArray("SELECT SUM(subtotale - sconto) AS totale, YEAR(co_documenti.data) AS year, MONTH(co_documenti.data) AS month FROM co_documenti INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id INNER JOIN co_righe_documenti ON co_righe_documenti.iddocumento=co_documenti.id WHERE co_tipidocumento.dir='uscita' AND co_tipidocumento.descrizione!='Bozza' AND co_documenti.data BETWEEN ".prepare($start).' AND '.prepare($end).' GROUP BY YEAR(co_documenti.data), MONTH(co_documenti.data) ORDER BY YEAR(co_documenti.data) ASC, MONTH(co_documenti.data) ASC');
$fatturato = $dbo->fetchArray("SELECT SUM(subtotale - sconto) AS totale, YEAR(co_documenti.data) AS year, MONTH(co_documenti.data) AS month FROM co_documenti INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id INNER JOIN co_righe_documenti ON co_righe_documenti.iddocumento=co_documenti.id WHERE co_tipidocumento.dir='entrata' AND co_tipidocumento.descrizione!='Bozza' AND co_documenti.data BETWEEN ".prepare($start).' AND '.prepare($end).' GROUP BY YEAR(co_documenti.data), MONTH(co_documenti.data) ORDER BY YEAR(co_documenti.data) ASC, MONTH(co_documenti.data) ASC');
$entrate = $dbo->fetchArray("SELECT SUM(subtotale - sconto) AS totale, YEAR(co_documenti.data) AS year, MONTH(co_documenti.data) AS month FROM co_documenti INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id INNER JOIN co_righe_documenti ON co_righe_documenti.iddocumento=co_documenti.id INNER JOIN co_movimenti ON co_movimenti.iddocumento=co_documenti.id AND primanota=1 WHERE co_tipidocumento.dir='entrata' AND co_documenti.data BETWEEN ".prepare($start).' AND '.prepare($end).' GROUP BY YEAR(co_documenti.data), MONTH(co_documenti.data) ORDER BY YEAR(co_documenti.data) ASC, MONTH(co_documenti.data) ASC');

60
modules/utenti/sync.php Normal file
View File

@ -0,0 +1,60 @@
<?php
include __DIR__.'/../../core.php';
?>
<div class="text-center">
<h4>Per generare il link per visualizzare il calendario su applicazioni esterne, inserisci username e password qui sotto, poi copia il link nella tua applicazione:</h4>
</div>
<br>
<div class="row fields">
<div class="col-md-offset-3 col-md-3">
<div class="form-group">
<label>Username:</label>
<input type="text" class="form-control" id="username">
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label>Password:</label>
<input type="password" class="form-control" id="password">
</div>
</div>
</div>
<div class="row fields">
<div class="col-md-offset-3 col-md-6">
<div class="form-group">
<label>LINK:</label>
<input type="text" class="form-control text-center" id="link" value="">
</div>
</div>
</div>
<div class="row fields">
<div class="col-md-offset-3 col-md-6">
Per <b>Android</b>, scarica <a href="https://play.google.com/store/apps/details?id=org.kc.and.ical&hl=it" target="_blank"><b>iCalSync2</b></a>.<br><br>
Per <b>Apple</b>, puoi configurare un nuovo calendario dall'app standard del calendario, specificando l'URL sopra.<br><br>
Per <b>PC</b>, per altri client di posta, considerare le relative funzionalit&agrave; o eventuali plugin.
</div>
</div>
<script>
$('.fields input').on('keyup change', function(){
$('#link').val( "<?php echo $rootdir ?>/modules/osmsync/sync_interventi.php?username="+$('#username').val()+"&password="+$('#password').val() );
});
$('#link').on('click', function(){
$(this).select();
});
$('.fields input').trigger('change');
</script>

View File

@ -30,7 +30,7 @@
},
"main": "gulpfile.js",
"dependencies": {
"admin-lte": "^2.3.11",
"admin-lte": "~2.3.11",
"autosize": "^3.0.21",
"bootstrap": "^3.3.7",
"bootstrap-colorpicker": "^2.5.1",
@ -47,7 +47,7 @@
"font-awesome": "^4.7.0",
"fullcalendar": "^3.4.0",
"geocomplete": "^1.7.0",
"inputmask": "^3.3.6",
"inputmask": "3.3.9",
"jquery": "^3.2.1",
"jquery-form": "^4.2.1",
"jquery-ui-touch-punch": "^0.2.3",
@ -58,7 +58,7 @@
"select2-bootstrap-theme": "^0.1.0-beta.10",
"signature_pad": "^2.1.1",
"smartwizard": "^4.2.2",
"sweetalert2": "^6.6.5",
"sweetalert2": "^6.11.4",
"tooltipster": "^4.2.5"
},
"devDependencies": {

View File

@ -59,6 +59,13 @@ class API extends \Util\Singleton
{
$user = Auth::user();
// Controllo sulla compatibilità dell'API
if (!self::isCompatible()) {
return self::response([
'status' => self::$status['incompatible']['code'],
]);
}
$table = '';
$select = '*';
$where = [];
@ -183,6 +190,13 @@ class API extends \Util\Singleton
{
$user = Auth::user();
// Controllo sulla compatibilità dell'API
if (!self::isCompatible()) {
return self::response([
'status' => self::$status['incompatible']['code'],
]);
}
$resources = self::getResources()[$kind];
$resource = $request['resource'];
@ -280,33 +294,32 @@ class API extends \Util\Singleton
*/
public static function response($array)
{
// Controllo sulla compatibilità dell'API
if (!self::isCompatible()) {
$array = [
'status' => self::$status['incompatible']['code'],
];
if (empty($array['custom'])) {
// Agiunta dello status di default
if (empty($array['status'])) {
$array['status'] = self::$status['ok']['code'];
}
// Aggiunta del messaggio in base allo status
if (empty($array['message'])) {
$codes = array_column(self::$status, 'code');
$messages = array_column(self::$status, 'message');
$array['message'] = $messages[array_search($array['status'], $codes)];
}
$flags = JSON_FORCE_OBJECT;
// Beautify forzato dei risultati
if (get('beautify') !== null) {
$flags |= JSON_PRETTY_PRINT;
}
$result = json_encode($array, $flags);
} else {
$result = $array['custom'];
}
// Agiunta dello status di default
if (empty($array['status'])) {
$array['status'] = self::$status['ok']['code'];
}
// Aggiunta del messaggio in base allo status
if (empty($array['message'])) {
$codes = array_column(self::$status, 'code');
$messages = array_column(self::$status, 'message');
$array['message'] = $messages[array_search($array['status'], $codes)];
}
$flags = JSON_FORCE_OBJECT;
// Beautify forzato dei risultati
if (get('beautify') !== null) {
$flags |= JSON_PRETTY_PRINT;
}
return json_encode($array, $flags);
return $result;
}
/**

View File

@ -90,7 +90,7 @@ class Auth extends \Util\Singleton
$database = Database::getConnection();
$log = [];
$log['username'] = $username;
$log['username'] = (string) $username;
$log['ip'] = get_client_ip();
$log['stato'] = self::$status['failed']['code'];

View File

@ -94,14 +94,18 @@ class HTMLBuilder
$json = self::decode($value, 'manager');
$class = self::getManager($json['name']);
$html = str_replace($value, !empty($class) ? $class->manage($json) : '', $html);
$result = !empty($class) ? $class->manage($json) : '';
$html = str_replace($value, !empty($result) ? $result : $value, $html);
}
preg_match_all('/'.preg_quote(self::$open['handler']).'(.+?)'.preg_quote(self::$close['handler']).'/is', $html, $handlers);
foreach ($handlers[0] as $value) {
$json = self::decode($value, 'handler');
$html = str_replace($value, self::generate($json), $html);
$result = self::generate($json);
$html = str_replace($value, !empty($result) ? $result : $value, $html);
}
return $html;
@ -396,15 +400,3 @@ class HTMLBuilder
}
}
}
/**
* Predispone un testo per l'inserimento all'interno di un attributo HTML.
*
* @param string $string
*
* @return string
*/
function prepareToField($string)
{
return str_replace('"', '&quot;', $string);
}

View File

@ -62,7 +62,7 @@ class DefaultHandler implements HandlerInterface
$values['value'] = !empty($values['value']) ? $values['value'] : 0;
$decimals = true;
$decimals = null;
if (isset($values['decimals'])) {
if (is_numeric($values['decimals'])) {
$decimals = $values['decimals'];

View File

@ -144,17 +144,30 @@ class Formatter
*/
public function parseNumber($value)
{
if (!ctype_digit(str_replace(array_values($this->getNumberSeparators()), '', $value))) {
if ($value[0] == '+' || $value[0] == '-') {
$sign = $value[0];
$value = substr($value, 1);
}
// Controllo sull'effettiva natura del numero
$number = str_replace(array_values($this->getNumberSeparators()), '', $value);
$pieces = explode($this->getNumberSeparators()['decimals'], $value);
$integer = str_replace(array_values($this->getNumberSeparators()), '', $pieces[0]);
if (!ctype_digit($number) || (strlen($integer) != strlen((int) $integer))) {
return false;
}
$value = $sign.$value;
if (is_object($this->numberFormatter)) {
$result = $this->numberFormatter->parse($value);
} else {
$result = $this->customNumber($value, $this->getNumberSeparators(), $this->getStandardFormats()['number']);
}
$result = is_numeric($result) ? floatval($result) : $result;
$result = is_numeric($result) ? floatval($result) : false;
return $result;
}
@ -170,7 +183,7 @@ class Formatter
{
$result = $this->formatNumber($value);
return !empty($result);
return !is_bool($result);
}
/**
@ -184,7 +197,7 @@ class Formatter
{
$result = $this->parseNumber($value);
return !empty($result);
return !is_bool($result);
}
/**
@ -335,7 +348,7 @@ class Formatter
{
$result = $this->formatTimestamp($value);
return !empty($result);
return !is_bool($result);
}
/**
@ -349,7 +362,7 @@ class Formatter
{
$result = $this->parseTimestamp($value);
return !empty($result);
return !is_bool($result);
}
/**
@ -419,7 +432,7 @@ class Formatter
{
$result = $this->formatDate($value);
return !empty($result);
return !is_bool($result);
}
/**
@ -433,7 +446,7 @@ class Formatter
{
$result = $this->parseDate($value);
return !empty($result);
return !is_bool($result);
}
/**
@ -503,7 +516,7 @@ class Formatter
{
$result = $this->formatTime($value);
return !empty($result);
return !is_bool($result);
}
/**
@ -517,7 +530,7 @@ class Formatter
{
$result = $this->parseTime($value);
return !empty($result);
return !is_bool($result);
}
/**

View File

@ -66,15 +66,15 @@ if ('entrata' == $dir) {
$body .= "
<table cellspacing='0' style='table-layout:fixed;'>
<col width='40'><col width='100'><col width='100'><col width='362'><col width='160'><col width='90'><col width='90'>
<col width='90'><col width='90'><col width='450'><col width='120'><col width='120'><col width='90'><col width='90'>
<thead>
<tr>
<th bgcolor='#dddddd' class='full_cell1 cell-padded'> Documento</th>
<th bgcolor='#dddddd' class='full_cell1 cell-padded'>Data</th>
<th bgcolor='#dddddd' class='full_cell1 cell-padded'>Causale<br>Ragione sociale</th>
<th bgcolor='#dddddd' class='full_cell1 cell-padded'>Aliquota</th>
<th bgcolor='#dddddd' class='full_cell1 cell-padded'>Imponibile</th>
<th bgcolor='#dddddd' class='full_cell1 cell-padded'>Imposta</th>
<th bgcolor='#dddddd' class='full_cell1 cell-padded'> doc.</th>
<th bgcolor='#dddddd' class='full_cell cell-padded'>Data</th>
<th bgcolor='#dddddd' class='full_cell cell-padded'>Causale<br>Ragione sociale</th>
<th bgcolor='#dddddd' class='full_cell cell-padded'>Aliquota</th>
<th bgcolor='#dddddd' class='full_cell cell-padded'>Imponibile</th>
<th bgcolor='#dddddd' class='full_cell cell-padded'>Imposta</th>
</tr>
</thead>
";

View File

@ -14,8 +14,8 @@ echo "
<table class='table table-bordered'>
<thead>
<tr>
<th class='text-center' style='width:10%'>".tr('P.Iva', [], ['upper' => true])."</th>
<th class='text-center' style='width:15%'>".tr('Ragione sociale', [], ['upper' => true])."</th>
<th class='text-center' style='width:10%'>".tr('Ragione sociale', [], ['upper' => true])."</th>
<th class='text-center' style='width:15%'>".tr('P.Iva', [], ['upper' => true])."</th>
<th class='text-center' style='width:25%'>".tr('Documento', [], ['upper' => true])."</th>
<th class='text-center' style='width:20%'>".tr('Aliquota', [], ['upper' => true])."</th>
<th class='text-center' style='width:10%'>".tr('Imponibile', [], ['upper' => true])."</th>

View File

@ -964,3 +964,14 @@ UPDATE `zz_modules` SET `title` = `name` WHERE `title` = '';
-- Nuova struttura per i plugin Ddt del cliente e Impianti del cliente in Anagrafiche
UPDATE `zz_plugins` SET `script` = '', `options` = ' { "main_query": [ { "type": "table", "fields": "Numero, Data, Descrizione, Qtà", "query": "SELECT dt_ddt.id, (SELECT `id` FROM `zz_modules` WHERE `name` = \'Ddt di vendita\') AS _link_module_, dt_ddt.id AS _link_record_, IF(dt_ddt.numero_esterno = \'\', dt_ddt.numero, dt_ddt.numero_esterno) AS Numero, DATE_FORMAT(dt_ddt.data, ''%d/%m/%Y'') AS Data, dt_righe_ddt.descrizione AS `Descrizione`, CONCAT(REPLACE(REPLACE(REPLACE(FORMAT(dt_righe_ddt.qta, 2), \',\', \'#\'), \'.\', \',\'), \'#\', \'.\'), \' \', dt_righe_ddt.um) AS `Qtà` FROM dt_ddt JOIN dt_righe_ddt ON dt_ddt.id=dt_righe_ddt.idddt WHERE dt_ddt.idanagrafica=|idanagrafica| HAVING 2=2 ORDER BY dt_ddt.id DESC"} ]}', `directory` = '', `version` = '2.3', `compatibility` = '2.*' WHERE `name` = 'Ddt del cliente';
UPDATE `zz_plugins` SET `script` = '', `options` = ' { "main_query": [ { "type": "table", "fields": "Matricola, Nome, Data, Descrizione", "query": "SELECT id, (SELECT `id` FROM `zz_modules` WHERE `name` = \'MyImpianti\') AS _link_module_, id AS _link_record_, matricola AS Matricola, nome AS Nome, DATE_FORMAT(data, ''%d/%m/%Y'') AS Data, descrizione AS Descrizione FROM my_impianti WHERE idanagrafica=|idanagrafica| HAVING 2=2 ORDER BY id DESC"} ]}', `directory` = '', `version` = '2.3', `compatibility` = '2.*' WHERE `name` = 'Impianti del cliente';
-- Aggiunta del supporto alla sincronizzazione interventi
ALTER TABLE `in_interventi_tecnici` ADD `uid` VARCHAR(255) NOT NULL AFTER `prezzo_dirittochiamata_tecnico`, ADD `summary` VARCHAR(255) NOT NULL AFTER `uid`;
ALTER TABLE `in_interventi` ADD `deleted` TINYINT NOT NULL DEFAULT '0' AFTER `data_invio`;
-- Fix nella conversione dei listini precedenti
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);