1
0
mirror of https://github.com/devcode-it/openstamanager.git synced 2025-02-16 19:40:44 +01:00
This commit is contained in:
Beppe 2023-05-11 14:26:37 +02:00
commit 4f11a7659c
86 changed files with 2379 additions and 298 deletions

View File

@ -4,6 +4,7 @@ Tutti i maggiori cambiamenti di questo progetto saranno documentati in questo fi
Il formato utilizzato è basato sulle linee guida di [Keep a Changelog](http://keepachangelog.com/), e il progetto segue il [Semantic Versioning](http://semver.org/) per definire le versioni delle release.
- [2.4.44 (2023-04-21)](#2444-2023-04-21)
- [2.4.43 (2023-03-31)](#2443-2023-03-31)
- [2.4.42 (2023-03-10)](#2442-2023-03-10)
- [2.4.41 (2023-02-27)](#2441-2023-02-27)
@ -55,6 +56,34 @@ Il formato utilizzato è basato sulle linee guida di [Keep a Changelog](http://k
- [2.1 (2015-04-02)](#21-2015-04-02)
## 2.4.44 (2023-04-21)
### Aggiunto (Added)
- Aggiunto il cambio di stato dei preventivi da azioni di gruppo
- Aggiunto il cambio di stato dei contratti da azioni di gruppo
- Aggiunta visualizzazione deducibilità conto nel conto economico
- Aggiunta colonna Prima nota in vista Fatture di vendita
- Aggiunto il filtro Tutti sui promemoria in Dashboard
- Aggiunto automatismo per fatture TD21 e TD27
### Modificato (Changed)
- Rimosso moment-timezone per fullcalendar
- Ottimizzata la ricerca nel piano dei conti
- Miglioria plugin listino fornitore: unificato prezzo e dettaglio
- Ottimizzata l'apertura di fatture con molte righe
- Allineamento dello sconto con segno negativo nei documenti
### Fixed
- Corretta maggiorazione IVA per liquidazione trimestrale
- Corretta la stampa liquidazione IVA
- Corretto doppio avviso in modifica righe
- Corretta la selezione dei segmenti nelle query delle viste
- Corretta impostazione IVA da anagrafica nei documenti
- Corretti i riferimenti automatici in fase di importazione di Fatture elettroniche
- Corretto il controllo dei totali delle fatture
- Corretta l'impostazione del prezzo di acquisto nei documenti di acquisto
- Corretta la modifica degli allegati
- Corretta la visualizzazione del colore delle relazioni
- Corretta l'impostazione dei decimali per quantità in Articoli e Attività
- Corretto il calcolo dello sconto totale delle righe
## 2.4.43 (2023-03-31)
### Aggiunto (Added)
- Aggiunto invio automatico di solleciti
@ -67,6 +96,7 @@ Il formato utilizzato è basato sulle linee guida di [Keep a Changelog](http://k
- Aggiunte azioni di gruppo per modifica categoria ed esportazione in ZIP degli allegati
- Aggiunto il campo Descrizione in aggiunta Attività
- Aggiunta opzione per immagini in stampa preventivi e ordini
- Aggiunta azione di gruppo per firma interventi
### Modificato (Changed)
- Miglioria logiche per stampe
@ -79,6 +109,7 @@ Il formato utilizzato è basato sulle linee guida di [Keep a Changelog](http://k
- Modificato l'ordinamento dello scalare in piano dei conti
- Disattivati i processi in cron per installazioni in localhost con possibilità di forzatura
### Fixed
- Corretta la sede di partenza articoli in Attività
- Corretta l'esportazione dello scadenzario Ri.Ba.
@ -95,6 +126,7 @@ Il formato utilizzato è basato sulle linee guida di [Keep a Changelog](http://k
- Corretto il calcolo dell'IVA su rivalsa INPS
- Corretta la gestione degli eventi ricorrenti su Dashboard
- Correzione per inserimento sottocategorie con lo stesso nome delle categorie
- Corretto link a preventivi da Dashboard non funzionante
## 2.4.42 (2023-03-10)
### Aggiunto (Added)
- Aggiunta la gestione della provvigione in fase di aggiunta riga

View File

@ -223,11 +223,10 @@ elseif (filter('op') == 'download-zip-allegati') {
// Modifica dati di un allegato
elseif (filter('op') == 'modifica-allegato') {
$id_allegato = filter('id_allegato');
$id_allegati = explode(';',filter('id_allegati'));
if ($id_allegato) {
$upload = Upload::find($id_allegato);
if (sizeof($id_allegati) == 1) {
$upload = Upload::find($id_allegati[0]);
$upload->name = post('nome_allegato');
$upload->category = post('categoria_allegato');
$upload->save();

View File

@ -1109,7 +1109,7 @@ div.tip {
.local-loader>div {
position: absolute;
top: 100px;
top: 0px;
z-index: 2;
opacity: 0.5;
width: 100%

View File

@ -194,7 +194,7 @@ function ricaricaAllegati(gestione) {
* @param id
* @param ids
*/
function modificaAllegato(button, id, ids) {
function modificaAllegato(button, ids) {
const gestione = $(button).closest(".gestione-allegati");
let params = new URLSearchParams({
@ -203,7 +203,6 @@ function modificaAllegato(button, id, ids) {
id_plugin: gestione.data('id_plugin'),
id_record: gestione.data('id_record'),
id_allegati: ids,
id_allegato: id,
}).toString();
openModal(globals.translations.allegati.modifica, globals.rootdir + "/actions.php?" + params);

View File

@ -344,16 +344,16 @@ function csrf() {
function pdfjs() {
const web = gulp.src([
config.nodeDirectory + '/pdf.js/web/**/*',
'!' + config.nodeDirectory + '/pdf.js/web/cmaps/*',
'!' + config.nodeDirectory + '/pdf.js/web/*.map',
'!' + config.nodeDirectory + '/pdf.js/web/*.pdf',
config.nodeDirectory + '/pdf.js/demo/vue/public/pdfjs-prebuilt/web/**/*',
'!' + config.nodeDirectory + '/pdf.js/demo/vue/public/pdfjs-prebuilt/web/cmaps/*',
'!' + config.nodeDirectory + '/pdf.js/demo/vue/public/pdfjs-prebuilt/web/*.map',
'!' + config.nodeDirectory + '/pdf.js/demo/vue/public/pdfjs-prebuilt/web/*.pdf',
])
.pipe(gulp.dest(config.production + '/pdfjs/web'));
const build = gulp.src([
config.nodeDirectory + '/pdf.js/build/*',
'!' + config.nodeDirectory + '/pdf.js/build/*.map',
config.nodeDirectory + '/pdf.js/demo/vue/public/pdfjs-prebuilt/build/*',
'!' + config.nodeDirectory + '/pdf.js/demo/vue/public/pdfjs-prebuilt/build/*.map',
])
.pipe(gulp.dest(config.production + '/pdfjs/build'));

View File

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

View File

@ -129,7 +129,7 @@ if (!empty($options['create_document'])) {
</div>
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Tipo').'", "name": "id_tipo_intervento", "required": 1, "values": "query=SELECT idtipointervento AS id, descrizione FROM in_tipiintervento" ]}
{[ "type": "select", "label": "'.tr('Tipo').'", "name": "id_tipo_intervento", "required": 1, "ajax-source": "tipiintervento" ]}
</div>';
}

View File

@ -17,6 +17,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
$articolo = $database->selectOne('mg_articoli', '*', ['id' => $result['idarticolo']]);
$width = $options['dir'] == 'uscita' && $articolo['fattore_um_secondaria'] ? 3 : 4;
// Descrizione
echo App::internalLoad('descrizione.php', $result, $options);
@ -26,21 +29,49 @@ echo App::internalLoad('conti.php', $result, $options);
// Iva
echo '
<div class="row">
<div class="col-md-4 '.(!empty($options['nascondi_prezzi']) ? 'hidden' : '').'">
<div class="col-md-'.$width.' '.(!empty($options['nascondi_prezzi']) ? 'hidden' : '').'">
{[ "type": "select", "label": "'.tr('Iva').'", "name": "idiva", "required": 1, "value": "'.$result['idiva'].'", "ajax-source": "iva", "select-options": '.json_encode($options['select-options']['iva']).' ]}
</div>';
// Quantità
echo '
<div class="col-md-4">
<div class="col-md-'.$width.'">
{[ "type": "number", "label": "'.tr('Q.tà').'", "name": "qta", "required": 1, "value": "'.abs((float) $result['qta']).'", "decimals": "qta"'.(isset($result['max_qta']) ? ', "icon-after": "<span class=\"tip\" title=\"'.tr("L'elemento è collegato a un documento: la quantità massima ammessa è relativa allo stato di evasione dell'elemento nel documento di origine (quantità dell'elemento / quantità massima ammessa)").'\">/ '.numberFormat(abs((float) $result['max_qta']), 'qta').' <i class=\"fa fa-question-circle-o\"></i></span>"' : '').', "min-value": "'.abs((float) $result['qta_evasa']).'" ]}
</div>';
// Unità di misura
echo '
<div class="col-md-4">
<div class="col-md-'.$width.'">
{[ "type": "select", "label": "'.tr('Unità di misura').'", "icon-after": "add|'.Modules::get('Unità di misura')['id'].'", "name": "um", "value": "'.$result['um'].'", "ajax-source": "misure" ]}
</div>';
// Unità di misura
if ($options['dir'] == 'uscita' && $articolo['fattore_um_secondaria']) {
echo '
<div class="col-md-3">
{[ "type": "number", "label": "'.tr('Q.tà secondaria').'", "name": "fattore_um_secondaria", "value": "'.abs((float)$articolo['fattore_um_secondaria'] * $result['qta']).'", "icon-after": "'.$articolo['um_secondaria'].'" ]}
</div>
<script>
input("fattore_um_secondaria").on("change", function() {
let articolo = input("idarticolo").getData();
let qta = input(this).get() / articolo.fattore_um_secondaria;
if (input("qta").get() != qta) {
input("qta").set(qta);
}
});
input("qta").on("change", function() {
let articolo = input("idarticolo").getData();
let fattore_um_secondaria = input(this).get() * articolo.fattore_um_secondaria;
if (input("fattore_um_secondaria").get() != fattore_um_secondaria) {
input("fattore_um_secondaria").set(fattore_um_secondaria);
}
});
</script>';
}
echo '
</div>';
$is_nota = $options['is_nota'] ?: 0;

View File

@ -19,20 +19,18 @@
use Models\Upload;
$id_allegati = json_decode(filter('id_allegati'));
$id_allegato = json_decode(filter('id_allegato'));
$id_allegati = (array)json_decode(filter('id_allegati'));
// Form di inserimento riga documento
echo '
<form action="" method="post" id="modifica-allegato">
<input type="hidden" name="id_allegati" value="'.implode(';',$id_allegati).'">
<input type="hidden" name="id_allegato" value="'.$id_allegato.'">
<input type="hidden" name="backto" value="record-edit">
<input type="hidden" name="op" value="modifica-allegato">
<div class="row">';
if ($id_allegato) {
$allegato = Upload::find($id_allegato);
if (sizeof($id_allegati) == 1) {
$allegato = Upload::find($id_allegati[0]);
echo '
<div class="col-md-6">
{[ "type": "text", "label": "'.tr('Nome').'", "name": "nome_allegato", "value": "'.$allegato->name.'" ]}

View File

@ -666,7 +666,7 @@ if ($free_space < ($space_limit * (1024 ** 3))) {
<p>'.tr('Lo spazio a disposizione del gestionale è in esaurimento: sono al momento disponibili _TOT_', [
'_TOT_' => FileSystem::formatBytes($free_space),
]).'.</p>
<p>'.tr('Questo può risultare un serio problema per la continuità di funzionamento del software, poichè le operazioni più espansive riguardanti lo spazio di archiviazione possono provocare malfunzionamento imprevedibili').'. '.tr('Operazioni di backup, caricamento di allegati o anche il semplice utilizzo del gestionale possono rendere i dati inaffidabili, provocando pertanto una perdita irreversibile delle informazioni salvate').'.</p>
<p>'.tr("Contatta gli amministratori di sistema oppure l'assistenza tecnica per risolvere al più presto il problema").'.</p>
<p>'.tr('Questo può risultare un serio problema per la continuità di funzionamento del software, poiché le operazioni più espansive che richiedono spazio di archiviazione possono causare malfunzionamenti imprevisti').'. '.tr('Ad esempio, le attività di backup, caricamento di allegati o anche l\'utilizzo normale del gestionale potrebbero rendere i dati inaffidabili, provocando pertanto una perdita delle informazioni salvate').'.</p>
<p>'.tr("Contatta gli amministratori di sistema per risolvere al più presto il problema").'.</p>
</div>';
}

View File

@ -127,7 +127,7 @@ switch ($resource) {
break;
case 'vettori':
$query = "SELECT an_anagrafiche.idanagrafica AS id, CONCAT(ragione_sociale, IF(citta IS NULL OR citta = '', '', CONCAT(' (', citta, ')')), IF(deleted_at IS NULL, '', ' (".tr('eliminata').")'),' - ', an_anagrafiche.codice) AS descrizione, idtipointervento_default AS idtipointervento 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| ORDER BY ragione_sociale";
$query = "SELECT an_anagrafiche.idanagrafica AS id, CONCAT(ragione_sociale, IF(citta IS NULL OR citta = '', '', CONCAT(' (', citta, ')')), IF(an_anagrafiche.deleted_at IS NULL, '', ' (".tr('eliminata').")'),' - ', an_anagrafiche.codice) AS descrizione, idtipointervento_default AS idtipointervento 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| ORDER BY ragione_sociale";
foreach ($elements as $element) {
$filter[] = 'an_anagrafiche.idanagrafica='.prepare($element);
@ -135,7 +135,7 @@ switch ($resource) {
$where[] = "descrizione='Vettore'";
if (empty($filter)) {
$where[] = 'deleted_at IS NULL';
$where[] = 'an_anagrafiche.deleted_at IS NULL';
}
if (!empty($search)) {
@ -152,7 +152,7 @@ switch ($resource) {
* - idanagrafica
*/
case 'agenti':
$query = "SELECT an_anagrafiche.idanagrafica AS id, CONCAT(ragione_sociale, IF(citta IS NULL OR citta = '', '', CONCAT(' (', citta, ')')), IF(deleted_at IS NULL, '', ' (".tr('eliminata').")'),' - ', an_anagrafiche.codice) AS descrizione, idtipointervento_default 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| ORDER BY ragione_sociale";
$query = "SELECT an_anagrafiche.idanagrafica AS id, CONCAT(ragione_sociale, IF(citta IS NULL OR citta = '', '', CONCAT(' (', citta, ')')), IF(an_anagrafiche.deleted_at IS NULL, '', ' (".tr('eliminata').")'),' - ', an_anagrafiche.codice) AS descrizione, idtipointervento_default 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| ORDER BY ragione_sociale";
foreach ($elements as $element) {
$filter[] = 'an_anagrafiche.idanagrafica='.prepare($element);
@ -160,7 +160,7 @@ switch ($resource) {
$where[] = "descrizione='Agente'";
if (empty($filter)) {
$where[] = 'deleted_at IS NULL';
$where[] = 'an_anagrafiche.deleted_at IS NULL';
}
if (!empty($search)) {
@ -188,7 +188,7 @@ switch ($resource) {
break;
case 'tecnici':
$query = "SELECT an_anagrafiche.idanagrafica AS id, CONCAT(ragione_sociale, IF(citta IS NULL OR citta = '', '', CONCAT(' (', citta, ')')), IF(deleted_at IS NULL, '', ' (".tr('eliminata').")'),' - ', an_anagrafiche.codice) AS descrizione, idtipointervento_default 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| ORDER BY ragione_sociale";
$query = "SELECT an_anagrafiche.idanagrafica AS id, CONCAT(ragione_sociale, IF(citta IS NULL OR citta = '', '', CONCAT(' (', citta, ')')), IF(an_anagrafiche.deleted_at IS NULL, '', ' (".tr('eliminata').")'),' - ', an_anagrafiche.codice) AS descrizione, idtipointervento_default 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| ORDER BY ragione_sociale";
foreach ($elements as $element) {
$filter[] = 'an_anagrafiche.idanagrafica='.prepare($element);
@ -196,7 +196,7 @@ switch ($resource) {
$where[] = "descrizione='Tecnico'";
if (empty($filter)) {
$where[] = 'deleted_at IS NULL';
$where[] = 'an_anagrafiche.deleted_at IS NULL';
if (setting('Permetti inserimento sessioni degli altri tecnici')) {
} else {
@ -218,7 +218,7 @@ switch ($resource) {
break;
case 'clienti_fornitori':
$query = "SELECT `an_anagrafiche`.`idanagrafica` AS id, CONCAT_WS('', ragione_sociale, IF(citta !='' OR provincia != '', CONCAT(' (', citta, IF(provincia!='', CONCAT(' ', provincia), ''), ')'), ''), IF(deleted_at IS NULL, '', ' (".tr('eliminata').")'),' - ', an_anagrafiche.codice) AS descrizione, `an_tipianagrafiche`.`descrizione` AS optgroup, idtipointervento_default, an_tipianagrafiche.idtipoanagrafica FROM `an_tipianagrafiche` INNER JOIN `an_tipianagrafiche_anagrafiche` ON `an_tipianagrafiche`.`idtipoanagrafica`=`an_tipianagrafiche_anagrafiche`.`idtipoanagrafica` INNER JOIN `an_anagrafiche` ON `an_anagrafiche`.`idanagrafica`=`an_tipianagrafiche_anagrafiche`.`idanagrafica` |where| ORDER BY `optgroup` ASC, ragione_sociale ASC";
$query = "SELECT `an_anagrafiche`.`idanagrafica` AS id, CONCAT_WS('', ragione_sociale, IF(citta !='' OR provincia != '', CONCAT(' (', citta, IF(provincia!='', CONCAT(' ', provincia), ''), ')'), ''), IF(an_anagrafiche.deleted_at IS NULL, '', ' (".tr('eliminata').")'),' - ', an_anagrafiche.codice) AS descrizione, `an_tipianagrafiche`.`descrizione` AS optgroup, idtipointervento_default, an_tipianagrafiche.idtipoanagrafica FROM `an_tipianagrafiche` INNER JOIN `an_tipianagrafiche_anagrafiche` ON `an_tipianagrafiche`.`idtipoanagrafica`=`an_tipianagrafiche_anagrafiche`.`idtipoanagrafica` INNER JOIN `an_anagrafiche` ON `an_anagrafiche`.`idanagrafica`=`an_tipianagrafiche_anagrafiche`.`idanagrafica` |where| ORDER BY `optgroup` ASC, ragione_sociale ASC";
foreach ($elements as $element) {
$filter[] = 'an_anagrafiche.idanagrafica='.prepare($element);
@ -226,7 +226,7 @@ switch ($resource) {
$where = [];
if (empty($filter)) {
$where[] = 'deleted_at IS NULL';
$where[] = 'an_anagrafiche.deleted_at IS NULL';
$where[] = "an_tipianagrafiche_anagrafiche.idtipoanagrafica IN (SELECT idtipoanagrafica FROM an_tipianagrafiche WHERE descrizione = 'Cliente' OR descrizione = 'Fornitore' OR descrizione = 'Azienda')";
}
@ -266,14 +266,14 @@ switch ($resource) {
// Nota Bene: nel campo id viene specificato idtipoanagrafica-idanagrafica -> modulo Utenti e permessi, creazione nuovo utente
case 'anagrafiche':
$query = "SELECT an_anagrafiche.idanagrafica AS id, CONCAT_WS('', ragione_sociale, IF(citta !='' OR provincia != '', CONCAT(' (', citta, IF(provincia!='', CONCAT(' ', provincia), ''), ')'), ''), IF(deleted_at IS NULL, '', ' (".tr('eliminata').")'),' - ', an_anagrafiche.codice) AS descrizione, `an_tipianagrafiche`.`descrizione` AS optgroup 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| ORDER BY `optgroup` ASC, ragione_sociale ASC";
$query = "SELECT an_anagrafiche.idanagrafica AS id, CONCAT_WS('', ragione_sociale, IF(citta !='' OR provincia != '', CONCAT(' (', citta, IF(provincia!='', CONCAT(' ', provincia), ''), ')'), ''), IF(an_anagrafiche.deleted_at IS NULL, '', ' (".tr('eliminata').")'),' - ', an_anagrafiche.codice) AS descrizione, `an_tipianagrafiche`.`descrizione` AS optgroup 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| ORDER BY `optgroup` ASC, ragione_sociale ASC";
foreach ($elements as $element) {
$filter[] = 'an_anagrafiche.idanagrafica='.prepare($element);
}
if (empty($filter)) {
$where[] = 'deleted_at IS NULL';
$where[] = 'an_anagrafiche.deleted_at IS NULL';
}
if (!empty($search)) {
@ -434,12 +434,16 @@ switch ($resource) {
case 'relazioni':
$query = 'SELECT id, descrizione, colore AS bgcolor FROM an_relazioni |where| ORDER BY descrizione';
$query = "SELECT id, CONCAT(descrizione, IF(an_relazioni.deleted_at IS NULL, '', ' (".tr('eliminata').")')) AS descrizione, colore AS _bgcolor_ FROM an_relazioni |where| ORDER BY descrizione";
foreach ($elements as $element) {
$filter[] = 'id='.prepare($element);
}
if (empty($filter)) {
$where[] = 'an_relazioni.deleted_at IS NULL';
}
if (!empty($search)) {
$search_fields[] = 'descrizione LIKE '.prepare('%'.$search.'%');
}
@ -498,7 +502,7 @@ switch ($resource) {
//$where[] = 'data_fine > NOW()';
if (empty($filter)) {
$where[] = 'deleted_at IS NULL';
$where[] = 'co_dichiarazioni_intento.deleted_at IS NULL';
}
$where[] = 'id_anagrafica='.prepare($superselect['idanagrafica']);

View File

@ -74,4 +74,10 @@ if (in_array($id_cliente, $tipi_anagrafica) or in_array($id_fornitore, $tipi_ana
echo '
</ul>
</div>';
} else if (in_array($id_agente, $tipi_anagrafica)) {
//Aggiunta liquidazione provvigioni per agente
echo'
<button type="button" class="btn btn-primary" data-title="'.tr('Liquida Provvigioni').'" data-href="'.base_path().'/modules/anagrafiche/liquida_provvigioni.php?nome_stampa=Provvigioni&id_record='.$id_record.'" ><i class="fa fa-print"></i>'.tr(' Liquida Provvigioni').'</button>
</div>';
}

View File

@ -529,7 +529,7 @@ if ($is_cliente or $is_fornitore or $is_tecnico) {
<div class="row">
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Tipo attività predefinita').'", "name": "idtipointervento_default", "values": "query=SELECT idtipointervento AS id, descrizione FROM in_tipiintervento ORDER BY descrizione ASC", "value": "$idtipointervento_default$" ]}
{[ "type": "select", "label": "'.tr('Tipo attività predefinita').'", "name": "idtipointervento_default", "ajax-source": "tipiintervento", "value": "$idtipointervento_default$" ]}
</div>
<div class="col-md-6">

View File

@ -0,0 +1,116 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../core.php';
use Models\Module;
use Carbon\Carbon;
$id_record = filter('id_record');
$dir = filter('dir');
$nome_stampa = filter('nome_stampa');
$id_print = $dbo->fetchOne('SELECT id FROM zz_prints WHERE name='.prepare($nome_stampa))['id'];
$id_module = Module::pool('Stampe contabili')->id;
$year = (new Carbon($_SESSION['period_end']))->format('Y');
// Trovo id_print della stampa
$link = Prints::getHref($nome_stampa, $id_record);
echo '
<div class="alert alert-info hidden" id="period">
<i class="fa fa-exclamation-circle"></i> '.tr('Non è possibile creare la stampa definitiva nel periodo selezionato, è necessario prima impostare un periodo!').'
</div>
<form action="" method="post" id="form" >
<div class="row">';
echo '
<div class="col-md-4">
{[ "type": "date", "label": "'.tr('Data inizio').'", "required": "1", "name": "date_start", "value": "'.$_SESSION['period_start'].'" ]}
</div>
<div class="col-md-4">
{[ "type": "date", "label": "'.tr('Data fine').'", "required": "1", "name": "date_end", "value": "'.$_SESSION['period_end'].'" ]}
</div>
<div class="col-md-4">
{[ "type": "checkbox", "label": "'.tr('Includi emesse').'", "name": "is_emessa" ]}
</div>
</div>
<div class="row">
<div class="col-md-4">
{[ "type": "select", "label": "'.tr('Formato').'", "name": "format", "required": "1", "values": "list=\"A4\": \"'.tr('A4').'\", \"A3\": \"'.tr('A3').'\"", "value": "'.$_SESSION['stampe_contabili']['format'].'" ]}
</div>
<div class="col-md-4">
{[ "type": "select", "label": "'.tr('Orientamento').'", "name": "orientation", "required": "1", "values": "list=\"L\": \"'.tr('Orizzontale').'\", \"P\": \"'.tr('Verticale').'\"", "value": "'.$_SESSION['stampe_contabili']['orientation'].'" ]}
</div>
<div class="col-md-4">
{[ "type": "checkbox", "label": "'.tr('Includi parzialmente pagate').'", "name": "is_parz_pagata" ]}
</div>
';
echo '
<div class="col-md-4 pull-right">
<p style="line-height:14px;">&nbsp;</p>
<button type="button" class="btn btn-primary btn-block" onclick="if($(\'#form\').parsley().validate()) { return avvia_stampa(); }">
<i class="fa fa-print"></i> '.tr('Stampa').'
</button>
</div>
</div>
</form>
<br>';
echo '
<script>
$(document).ready(init);
function avvia_stampa (){
var is_emessa = $("#is_emessa").is(":checked");
var is_parz_pagata = $("#is_parz_pagata").is(":checked");
window.open("'.$link.'&dir='.$dir.'&is_emessa="+is_emessa+"&is_parz_pagata="+is_parz_pagata+"&notdefinitiva=1&id_sezionale="+$("#id_sezionale").val()+"&date_start="+$("#date_start").val()+"&date_end="+$("#date_end").val()+"");
$("#modals > div").modal("hide");
}
$("#format").change(function() {
session_set("stampe_contabili,format", $(this).val(), 0, 0);
});
$("#orientation").change(function() {
session_set("stampe_contabili,orientation", $(this).val(), 0, 0);
});
$("#periodo").change(function() {
if ($(this).val()=="manuale") {
input("date_start").enable();
input("date_end").enable();
} else {
$("#date_start").data("DateTimePicker").date(new Date(input("periodo").getData().date_start));
$("#date_end").data("DateTimePicker").date(new Date(input("periodo").getData().date_end));
input("date_start").disable();
input("date_end").disable();
}';
if ($nome_stampa != 'Liquidazione IVA') {
echo 'eseguiControlli();';
}
echo '
});
</script>';

View File

@ -86,6 +86,7 @@ switch ($resource) {
$query .= '
round(mg_articoli.qta,'.setting('Cifre decimali per quantità').") AS qta,
mg_articoli.um,
mg_articoli.fattore_um_secondaria,
mg_articoli.servizio,
mg_articoli.idconto_vendita,

View File

@ -490,7 +490,7 @@ $operations['crea-preventivo'] = [
<br><br>{[ "type": "text", "label": "'.tr('Nome preventivo').'", "name": "nome", "required": 1 ]}
{[ "type": "select", "label": "'.tr('Cliente').'", "name": "id_cliente", "ajax-source": "clienti", "required": 1 ]}
{[ "type": "select", "label": "'.tr('Sezionale').'", "name": "id_segment", "required": 1, "ajax-source": "segmenti", "select-options": '.json_encode(["id_module" => $id_preventivi, 'is_sezionale' => 1]).', "value": "'.$id_segment.'", "select-options-escape": true ]}
{[ "type": "select", "label": "'.tr('Tipo di attività').'", "name": "id_tipo", "values": "query=SELECT idtipointervento AS id, descrizione FROM in_tipiintervento", "required": 1 ]}
{[ "type": "select", "label": "'.tr('Tipo di attività').'", "name": "id_tipo", "ajax-source": "tipiintervento", "required": 1 ]}
{[ "type": "date", "label": "'.tr('Data').'", "name": "data", "required": 1, "value": "-now-" ]}',
'button' => tr('Procedi'),
'class' => 'btn btn-lg btn-warning',

View File

@ -103,7 +103,7 @@ if (!empty($ordini)) {
</small>
</td>
<td class="text-right">
<small>'.numberFormat($qta).'</small>
<small>'.numberFormat($qta, 'qta').'</small>
</td>
</tr>';
}
@ -114,7 +114,7 @@ if (!empty($ordini)) {
<small><b>'.tr('Totale').'</b></small>
</td>
<td class="text-right">
<small>'.numberFormat($impegnato).'</small>
<small>'.numberFormat($impegnato, 'qta').'</small>
</td>
</tr>
@ -170,7 +170,7 @@ if (!empty($ordini)) {
</small>
</td>
<td class="text-right">
<small>'.numberFormat($qta).'</small>
<small>'.numberFormat($qta, 'qta').'</small>
</td>
</tr>';
}
@ -181,7 +181,7 @@ if (!empty($ordini)) {
<small><b>'.tr('Totale').'</b></small>
</td>
<td class="text-right">
<small>'.numberFormat($ordinato).'</small>
<small>'.numberFormat($ordinato, 'qta').'</small>
</td>
</tr>
@ -213,7 +213,7 @@ echo '
<div class="panel-body">
<div class="row">
<div class="col-md-12 text-center" style="font-size:35pt;">
'.numberFormat($da_ordinare).' '.$articolo->um.'
'.numberFormat($da_ordinare, 'qta').' '.$articolo->um.'
</div>
</div>
</div>
@ -235,7 +235,7 @@ echo '
<div class="row">
<div class="col-md-12 text-center" style="font-size:35pt;">
'.numberFormat($disponibile).' '.$articolo->um.'
'.numberFormat($disponibile, 'qta').' '.$articolo->um.'
</div>
</div>
@ -271,7 +271,7 @@ foreach ($sedi as $sede) {
echo '
<tr>
<td>'.$sede['nomesede'].'</td>
<td class="text-right">'.numberFormat($giacenze[$sede['id']][0]).' '.$articolo->um.'</td>
<td class="text-right">'.numberFormat($giacenze[$sede['id']][0], 'qta').' '.$articolo->um.'</td>
<td class="text-center">
<a class="btn btn-xs btn-info" title="Dettagli" onclick="getDettagli('.$sede['id'].');">
<i class="fa fa-eye"></i>

View File

@ -186,7 +186,7 @@ class Articolo extends Model
$prezzo_vendita = $prezzo_vendita * (1 + $percentuale_aliquota / 100);
}
$this->setPrezzoVendita($prezzo_vendita, $this->idiva_vendita);
$this->setPrezzoVendita(round($prezzo_vendita,2), $this->idiva_vendita);
}
}

View File

@ -39,7 +39,7 @@ function renderChecklist($check, $level = 1, $parent = 0) {
$result .= '
<td style="border-top:0px;">
<span class="text">'.$check->content.' </span>';
<span class="text" style="'.(!empty($check->checked_at)?'text-decoration:line-through;':'').'">'.$check->content.' </span>';
if (intval($check->assignedUsers->pluck('id')->toArray())>0){
$result .= ' <span class="label label-info pull-right" style="padding:6px 8px;" data-toggle="tooltip" title="Assegnato a '. implode(', ', $check->assignedUsers->pluck('username')->toArray()).'"><i class="fa fa-user"></i></span>';

View File

@ -573,6 +573,7 @@ switch (post('op')) {
case 'add_articolo':
$id_articolo = post('id_articolo');
$barcode = post('barcode');
$dir = 'entrata';
if (!empty($barcode)) {
$id_articolo = $dbo->selectOne('mg_articoli', 'id', ['deleted_at' => null, 'attivo' => 1, 'barcode' => $barcode])['id'];
@ -663,4 +664,38 @@ switch (post('op')) {
}
break;
}
case 'edit-price':
$righe = $post['righe'];
$numero_totale = 0;
foreach ($righe as $riga) {
if (($riga['id']) != null) {
$articolo = Articolo::find($riga['id']);
} else {
$originale = ArticoloOriginale::find(post('idarticolo'));
$articolo = Articolo::build($fattura, $originale);
$articolo->id_dettaglio_fornitore = post('id_dettaglio_fornitore') ?: null;
}
if ($articolo['prezzo_unitario'] != $riga['price']) {
$articolo->setPrezzoUnitario($riga['price'], $articolo->idiva);
$articolo->save();
++$numero_totale;
}
}
if ($numero_totale > 1) {
flash()->info(tr('_NUM_ prezzi modificati!', [
'_NUM_' => $numero_totale,
]));
} else if ($numero_totale == 1) {
flash()->info(tr('_NUM_ prezzo modificato!', [
'_NUM_' => $numero_totale,
]));
} else {
flash()->warning(tr('Nessun prezzo modificato!'));
}
break;
}

View File

@ -0,0 +1,155 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../../core.php';
use Carbon\Carbon;
use Modules\Contratti\Contratto;
$contratto = Contratto::find($id_record);
$id_anagrafica = $contratto->idanagrafica;
$direzione = $contratto->direzione;
$righe = $_GET['righe'];
$righe = $dbo->fetchArray(
'SELECT mg_articoli.descrizione, mg_articoli.codice, co_righe_contratti.*
FROM co_righe_contratti
JOIN mg_articoli ON mg_articoli.id = co_righe_contratti.idarticolo
WHERE co_righe_contratti.id IN ('.$righe.')'
);
?>
<form action="" method="post" id="add-form">
<table class="table table-striped table-hover table-condensed table-bordered m-3">
<thead>
<tr>
<th width="35" class="text-center" ><?php echo tr('Codice'); ?></th>
<th><?php echo tr('Descrizione'); ?></th>
<th class="text-center" width="150"><?php echo tr('Prezzo corrente'); ?></th>
<th class="text-center" width="150"><?php echo tr('Ultimo preventivo'); ?></th>
<th class="text-center" width="150"><?php echo tr('Ultima fattura'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($righe as $riga) { ?>
<?php
$prezzi_ivati = setting('Utilizza prezzi di vendita comprensivi di IVA');
$ultimo_prezzo_preventivo = $dbo->fetchArray(
'SELECT
co_righe_contratti.idarticolo,
co_righe_preventivi.prezzo_unitario,
DATE(co_righe_preventivi.updated_at) AS updated_at
FROM
co_preventivi
INNER JOIN co_righe_preventivi ON co_righe_preventivi.idpreventivo = co_preventivi.id
INNER JOIN mg_articoli ON mg_articoli.id = co_righe_preventivi.idarticolo
INNER JOIN co_righe_contratti ON co_righe_contratti.idarticolo = mg_articoli.id
WHERE
co_preventivi.idanagrafica ='.prepare($id_anagrafica).' AND co_righe_contratti.idarticolo ='.prepare($riga['idarticolo']).' AND co_preventivi.idstato NOT IN (SELECT id FROM co_statipreventivi WHERE descrizione = "Bozza" OR descrizione = "In attesa di conferma" OR descrizione = "Rifiutato")
GROUP BY
mg_articoli.id, co_righe_preventivi.id
ORDER BY
updated_at DESC'
)[0];
$ultimo_prezzo_vendita = $dbo->fetchArray(
'SELECT
co_righe_contratti.idarticolo,
co_righe_documenti.prezzo_unitario,
DATE(co_righe_documenti.updated_at) AS updated_at
FROM
co_documenti
INNER JOIN co_righe_documenti ON co_righe_documenti.iddocumento = co_documenti.id
INNER JOIN mg_articoli ON mg_articoli.id = co_righe_documenti.idarticolo
INNER JOIN co_righe_contratti ON co_righe_contratti.idarticolo = mg_articoli.id
WHERE
co_documenti.idanagrafica ='.prepare($id_anagrafica).' AND co_righe_documenti.idarticolo ='.prepare($riga['idarticolo']).' AND co_documenti.idstatodocumento IN (SELECT id FROM co_statidocumento WHERE descrizione = "Emessa" OR descrizione = "Pagato" OR descrizione = "Parzialmente pagato")
GROUP BY
mg_articoli.id, co_righe_documenti.id
ORDER BY
updated_at DESC'
)[0];
?>
<tr>
<td><?= $riga['codice'] ?></td>
<td><?= $riga['descrizione'] ?></td>
<td>
<div>
{[ "type": "number", "label": "", "data-id":"<?php echo $riga['id']; ?>","name": "nuovo_prezzo_unitario[]", "value": "<?php echo numberFormat($riga['prezzo_unitario'], 2); ?>"]}
</div>
</td>
<td class="text-center"><?php
if (isset($ultimo_prezzo_preventivo)) {
echo moneyFormat($ultimo_prezzo_preventivo['prezzo_unitario'], 2) . (!empty($ultimo_prezzo_preventivo['updated_at']) ? ' <br><small class="help-block tip" title="'.dateFormat($ultimo_prezzo_preventivo['updated_at']).'">' . (new Carbon($ultimo_prezzo_preventivo['updated_at']))->diffForHumans().'</small>' : '');
} else {
echo 'n.d.';
}
?></td>
<td class="text-center"><?php
if (isset($ultimo_prezzo_vendita)) {
echo moneyFormat($ultimo_prezzo_vendita['prezzo_unitario'], 2) . (!empty($ultimo_prezzo_vendita['updated_at']) ? ' <br><small class="help-block tip" title="'.dateFormat($ultimo_prezzo_vendita['updated_at']).'">' . (new Carbon($ultimo_prezzo_vendita['updated_at']))->diffForHumans().'</small>' : '');
} else {
echo 'n.d.';
}
?></td>
</tr>
<?php } ?>
</tbody>
</table>
<a class="btn btn-primary btn-edit">
<i class="fa fa-edit"></i> <?php echo tr('Modifica'); ?>
</a>
</form>
<script>
$(document).ready(function() {
init();
$('.btn-edit').on('click', function() {
var id = [];
$('input[name^="nuovo_prezzo_unitario"]').each(function() {
id.push({
'id': $(this).data('id'),
'price': $(this).val(),
});
});
$.ajax({
url: globals.rootdir + "/actions.php",
type: "POST",
dataType: "json",
data: {
id_module: globals.id_module,
id_record: globals.id_record,
op: "edit-price",
backto: "record-edit",
righe: id,
},
success: function (response) {
location.reload();
},
error: function() {
location.reload();
}
});
});
});
</script>

View File

@ -21,6 +21,7 @@ include_once __DIR__.'/init.php';
$block_edit = $record['is_completato'];
$righe = $contratto->getRighe();
$direzione = $contratto->direzione;
$colspan = ($block_edit ? '5' : '6');
echo '
@ -192,7 +193,7 @@ echo '
// Calcoli
$imponibile = abs($contratto->imponibile);
$sconto = $contratto->sconto;
$sconto = -$contratto->sconto;
$totale_imponibile = abs($contratto->totale_imponibile);
$iva = abs($contratto->iva);
$totale = abs($contratto->totale);
@ -216,10 +217,10 @@ if (!empty($sconto)) {
echo '
<tr>
<td colspan="'.$colspan.'" class="text-right">
<b><span class="tip" title="'.tr('Un importo positivo indica uno sconto, mentre uno negativo indica una maggiorazione').'"> <i class="fa fa-question-circle-o"></i> '.tr('Sconto/maggiorazione', [], ['upper' => true]).':</span></b>
<b><span class="tip" title="'.tr('Un importo negativo indica uno sconto, mentre uno positivo indica una maggiorazione').'"> <i class="fa fa-question-circle-o"></i> '.tr('Sconto/maggiorazione', [], ['upper' => true]).':</span></b>
</td>
<td class="text-right">
'.moneyFormat($contratto->sconto, 2).'
'.moneyFormat($sconto, 2).'
</td>
<td></td>
</tr>';
@ -253,7 +254,7 @@ echo '
echo '
<tr>
<td colspan="'.$colspan.'" class="text-right">
<b>'.tr('Totale', [], ['upper' => true]).':</b>
<b>'.tr('Totale documento', [], ['upper' => true]).':</b>
</td>
<td class="text-right">
'.moneyFormat($contratto->totale, 2).'
@ -325,7 +326,13 @@ if (!$block_edit && sizeof($righe) > 0) {
<button type="button" class="btn btn-xs btn-default disabled" id="elimina_righe" onclick="rimuoviRiga(getSelectData());">
<i class="fa fa-trash"></i>
</button>
</button>';
if ($direzione == 'entrata') {
echo'
<button type="button" class="btn btn-xs btn-default disabled" id="confronta_righe" onclick="confrontaRighe(getSelectData());">
Confronta prezzi
</button>';
} echo'
</div>';
}
echo '
@ -359,6 +366,11 @@ function getSelectData() {
return data;
}
function confrontaRighe(id) {
openModal("'.tr('Confronta prezzi').'", "'.$module->fileurl('modals/confronta_righe.php').'?id_module=" + globals.id_module + "&id_record=" + globals.id_record + "&righe=" + id + "&id_anagrafica='.$ordine->idanagrafica.'&direzione='.$dir.'");
}
function rimuoviRiga(id) {
swal({
title: "'.tr('Rimuovere queste righe?').'",
@ -446,9 +458,11 @@ $(".check").on("change", function() {
if (checked) {
$("#elimina_righe").removeClass("disabled");
$("#duplica_righe").removeClass("disabled");
$("#confronta_righe").removeClass("disabled");
} else {
$("#elimina_righe").addClass("disabled");
$("#duplica_righe").addClass("disabled");
$("#confronta_righe").addClass("disabled");
}
});

View File

@ -26,7 +26,7 @@ include_once __DIR__.'/../../core.php';
$stati_intervento = $dbo->fetchArray('SELECT idstatointervento AS id, descrizione, colore FROM in_statiintervento WHERE deleted_at IS NULL ORDER BY descrizione ASC');
// Tipi intervento
$tipi_intervento = $dbo->fetchArray('SELECT idtipointervento AS id, descrizione FROM in_tipiintervento ORDER BY descrizione ASC');
$tipi_intervento = $dbo->fetchArray('SELECT idtipointervento AS id, descrizione FROM in_tipiintervento WHERE deleted_at IS NULL ORDER BY descrizione ASC');
// Tecnici disponibili
$tecnici_disponibili = $dbo->fetchArray("SELECT an_anagrafiche.idanagrafica AS id, ragione_sociale, colore FROM an_anagrafiche

View File

@ -657,7 +657,7 @@ switch (filter('op')) {
if ($dir == 'entrata') {
$prezzo_unitario = $prezzo_unitario ?: ($prezzi_ivati ? $originale->prezzo_vendita_ivato : $originale->prezzo_vendita);
} else {
$prezzo_unitario = $originale->prezzo_acquisto;
$prezzo_unitario = $prezzo_unitario ?: $originale->prezzo_acquisto;
}
@ -688,9 +688,44 @@ switch (filter('op')) {
flash()->info(tr('Quantità aggiornata!'));
}
break;
case 'edit-price':
$righe = $post['righe'];
$numero_totale = 0;
foreach ($righe as $riga) {
if (($riga['id']) != null) {
$articolo = Articolo::find($riga['id']);
} else {
$originale = ArticoloOriginale::find(post('idarticolo'));
$articolo = Articolo::build($fattura, $originale);
$articolo->id_dettaglio_fornitore = post('id_dettaglio_fornitore') ?: null;
}
if ($articolo['prezzo_unitario'] != $riga['price']) {
$articolo->setPrezzoUnitario($riga['price'], $articolo->idiva);
$articolo->save();
++$numero_totale;
}
}
if ($numero_totale > 1) {
flash()->info(tr('_NUM_ prezzi modificati!', [
'_NUM_' => $numero_totale,
]));
} else if ($numero_totale == 1) {
flash()->info(tr('_NUM_ prezzo modificato!', [
'_NUM_' => $numero_totale,
]));
} else {
flash()->warning(tr('Nessun prezzo modificato!'));
}
break;
}
// Aggiornamento stato degli ordini presenti in questa fattura in base alle quantità totali evase
if (!empty($id_record) && setting('Cambia automaticamente stato ordini fatturati')) {
$rs = $dbo->fetchArray('SELECT idordine FROM dt_righe_ddt WHERE idddt='.prepare($id_record).' AND idordine!=0');

View File

@ -295,13 +295,10 @@ if ($dir == 'entrata') {
?>
<div class="row">
<div class="col-md-12">
<div class="col-md-6">
{[ "type": "textarea", "label": "<?php echo tr('Note'); ?>", "name": "note", "value": "$note$" ]}
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="col-md-6">
{[ "type": "textarea", "label": "<?php echo tr('Note aggiuntive'); ?>", "name": "note_aggiuntive", "help": "<?php echo tr('Note interne.'); ?>", "value": "$note_aggiuntive$" ]}
</div>
</div>

View File

@ -0,0 +1,154 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../../core.php';
use Carbon\Carbon;
use Modules\DDT\DDT;
$ddt = DDT::find($id_record);
$id_anagrafica = $ddt->idanagrafica;
$direzione = $ddt->direzione;
$righe = $_GET['righe'];
$righe = $dbo->fetchArray(
'SELECT mg_articoli.descrizione, mg_articoli.codice, dt_righe_ddt.*
FROM dt_righe_ddt
JOIN mg_articoli ON mg_articoli.id = dt_righe_ddt.idarticolo
WHERE dt_righe_ddt.id IN ('.$righe.')'
);
?>
<form action="" method="post" id="add-form">
<table class="table table-striped table-hover table-condensed table-bordered m-3">
<thead>
<tr>
<th width="35" class="text-center" ><?php echo tr('Codice'); ?></th>
<th><?php echo tr('Descrizione'); ?></th>
<th class="text-center" width="150"><?php echo tr('Prezzo corrente'); ?></th>
<th class="text-center" width="150"><?php echo tr('Ultimo preventivo'); ?></th>
<th class="text-center" width="150"><?php echo tr('Ultima fattura'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($righe as $riga) { ?>
<?php
$prezzi_ivati = setting('Utilizza prezzi di vendita comprensivi di IVA');
$ultimo_prezzo_preventivo = $dbo->fetchArray(
'SELECT
dt_righe_ddt.idarticolo,
co_righe_preventivi.prezzo_unitario,
DATE(co_righe_preventivi.updated_at) AS updated_at
FROM
co_preventivi
INNER JOIN co_righe_preventivi ON co_righe_preventivi.idpreventivo = co_preventivi.id
INNER JOIN mg_articoli ON mg_articoli.id = co_righe_preventivi.idarticolo
INNER JOIN dt_righe_ddt ON dt_righe_ddt.idarticolo = mg_articoli.id
WHERE
co_preventivi.idanagrafica = '.prepare($id_anagrafica).' AND dt_righe_ddt.idarticolo = '.prepare($riga['idarticolo']).' AND co_preventivi.idstato NOT IN (SELECT id FROM co_statipreventivi WHERE descrizione = "Bozza" OR descrizione = "In attesa di conferma" OR descrizione = "Rifiutato")
GROUP BY
mg_articoli.id, co_righe_preventivi.id
ORDER BY
updated_at DESC'
)[0];
$ultimo_prezzo_vendita = $dbo->fetchArray(
'SELECT
dt_righe_ddt.idarticolo,
co_righe_documenti.prezzo_unitario,
DATE(co_righe_documenti.updated_at) AS updated_at
FROM
co_documenti
INNER JOIN co_righe_documenti ON co_righe_documenti.iddocumento = co_documenti.id
INNER JOIN mg_articoli ON mg_articoli.id = co_righe_documenti.idarticolo
INNER JOIN dt_righe_ddt ON dt_righe_ddt.idarticolo = mg_articoli.id
WHERE
co_documenti.idanagrafica ='.prepare($id_anagrafica).' AND co_righe_documenti.idarticolo ='.prepare($riga['idarticolo']).' AND co_documenti.idstatodocumento IN (SELECT id FROM co_statidocumento WHERE descrizione = "Emessa" OR descrizione = "Pagato" OR descrizione = "Parzialmente pagato")
GROUP BY
mg_articoli.id, co_righe_documenti.id
ORDER BY
updated_at DESC'
)[0];
?>
<tr>
<td><?= $riga['codice'] ?></td>
<td><?= $riga['descrizione'] ?></td>
<td>
<div>
{[ "type": "number", "label": "", "data-id":"<?php echo $riga['id']; ?>","name": "nuovo_prezzo_unitario[]", "value": "<?php echo numberFormat($riga['prezzo_unitario'], 2); ?>"]}
</div>
</td>
<td class="text-center"><?php
if (isset($ultimo_prezzo_preventivo)) {
echo moneyFormat($ultimo_prezzo_preventivo['prezzo_unitario'], 2) . (!empty($ultimo_prezzo_preventivo['updated_at']) ? ' <br><small class="help-block tip" title="'.dateFormat($ultimo_prezzo_preventivo['updated_at']).'">' . (new Carbon($ultimo_prezzo_preventivo['updated_at']))->diffForHumans().'</small>' : '');
} else {
echo 'n.d.';
}
?></td>
<td class="text-center"><?php
if (isset($ultimo_prezzo_vendita)) {
echo moneyFormat($ultimo_prezzo_vendita['prezzo_unitario'], 2) . (!empty($ultimo_prezzo_vendita['updated_at']) ? ' <br><small class="help-block tip" title="'.dateFormat($ultimo_prezzo_vendita['updated_at']).'">' . (new Carbon($ultimo_prezzo_vendita['updated_at']))->diffForHumans().'</small>' : '');
} else {
echo 'n.d.';
}
?></td>
</tr>
<?php } ?>
</tbody>
</table>
<a class="btn btn-primary btn-edit">
<i class="fa fa-edit"></i> <?php echo tr('Modifica'); ?>
</a>
</form>
<script>
$(document).ready(function() {
$('.btn-edit').on('click', function() {
var id = [];
$('input[name^="nuovo_prezzo_unitario"]').each(function() {
id.push({
'id': $(this).data('id'),
'price': $(this).val(),
});
});
$.ajax({
url: globals.rootdir + "/actions.php",
type: "POST",
dataType: "json",
data: {
id_module: globals.id_module,
id_record: globals.id_record,
op: "edit-price",
backto: "record-edit",
righe: id,
},
success: function (response) {
location.reload();
},
error: function() {
location.reload();
}
});
});
});
</script>

View File

@ -22,6 +22,7 @@ include_once __DIR__.'/init.php';
$block_edit = $record['flag_completato'];
$righe = $ddt->getRighe();
$colspan = ($block_edit ? '5' : '6');
$direzione = $ddt->direzione;
echo '
<div class="table-responsive row-list">
@ -238,7 +239,7 @@ echo '
// Calcoli
$imponibile = abs($ddt->imponibile);
$sconto = $ddt->sconto;
$sconto = -$ddt->sconto;
$totale_imponibile = abs($ddt->totale_imponibile);
$iva = abs($ddt->iva);
$totale = abs($ddt->totale);
@ -262,7 +263,7 @@ if (!empty($sconto)) {
echo '
<tr>
<td colspan="'.$colspan.'" class="text-right">
<b><span class="tip" title="'.tr('Un importo positivo indica uno sconto, mentre uno negativo indica una maggiorazione').'"> <i class="fa fa-question-circle-o"></i> '.tr('Sconto/maggiorazione', [], ['upper' => true]).':</span></b>
<b><span class="tip" title="'.tr('Un importo negativo indica uno sconto, mentre uno positivo indica una maggiorazione').'"> <i class="fa fa-question-circle-o"></i> '.tr('Sconto/maggiorazione', [], ['upper' => true]).':</span></b>
</td>
<td class="text-right">
'.moneyFormat($sconto, 2).'
@ -299,7 +300,7 @@ echo '
echo '
<tr>
<td colspan="'.$colspan.'" class="text-right">
<b>'.tr('Totale', [], ['upper' => true]).':</b>
<b>'.tr('Totale documento', [], ['upper' => true]).':</b>
</td>
<td class="text-right">
'.moneyFormat($totale, 2).'
@ -371,7 +372,13 @@ if (!$block_edit && sizeof($righe) > 0) {
<button type="button" class="btn btn-xs btn-default disabled" id="elimina_righe" onclick="rimuoviRiga(getSelectData());">
<i class="fa fa-trash"></i>
</button>
</button>';
if ($dir == 'entrata') {
echo'
<button type="button" class="btn btn-xs btn-default disabled" id="confronta_righe" onclick="confrontaRighe(getSelectData());">
Confronta prezzi
</button>';
} echo'
</div>';
}
echo '
@ -405,6 +412,10 @@ function getSelectData() {
return data;
}
function confrontaRighe(id) {
openModal("'.tr('Confronta prezzi').'", "'.$module->fileurl('modals/confronta_righe.php').'?id_module=" + globals.id_module + "&id_record=" + globals.id_record + "&righe=" + id + "&id_anagrafica='.$ordine->idanagrafica.'&direzione='.$dir.'");
}
function rimuoviRiga(id) {
swal({
title: "'.tr('Rimuovere queste righe?').'",
@ -508,9 +519,11 @@ $(".check").on("change", function() {
if (checked) {
$("#elimina_righe").removeClass("disabled");
$("#duplica_righe").removeClass("disabled");
$("#confronta_righe").removeClass("disabled");
} else {
$("#elimina_righe").addClass("disabled");
$("#duplica_righe").addClass("disabled");
$("#confronta_righe").addClass("disabled");
}
});

View File

@ -89,7 +89,8 @@ class DDT extends Document
$model->tipo()->associate($tipo_documento);
$model->stato()->associate($stato_documento);
$model->id_segment = $id_segment;
$model->idagente = $anagrafica->idagente;
$model->save();
// Salvataggio delle informazioni

View File

@ -237,7 +237,7 @@ switch (post('op')) {
// Totale basato sul campo ImportoTotaleDocumento
$dati_generali = $xml['FatturaElettronicaBody']['DatiGenerali']['DatiGeneraliDocumento'];
if (isset($dati_generali['ImportoTotaleDocumento'])) {
$totale_documento_indicato = abs(floatval($dati_generali['ImportoTotaleDocumento']));
$totale_documento_indicato = floatval($dati_generali['ImportoTotaleDocumento']);
// Calcolo del totale basato sui DatiRiepilogo
if (empty($totale_documento_indicato) && empty($dati_generali['ScontoMaggiorazione'])) {
@ -903,7 +903,7 @@ switch (post('op')) {
// Aggiunta tipologia cliente se necessario
if (!$anagrafica->isTipo('Cliente')) {
$tipo_cliente = TipoAnagrafica::where('descrizione', '=', 'Cliente')->first();
$tipo_cliente = TipoAnagrafica::where('descrizione', 'Cliente')->first();
$tipi = $anagrafica->tipi->pluck('idtipoanagrafica')->toArray();
$tipi[] = $tipo_cliente->id;
@ -1017,7 +1017,7 @@ switch (post('op')) {
if ($dir == 'entrata') {
$prezzo_unitario = $prezzo_unitario ?: ($prezzi_ivati ? $originale->prezzo_vendita_ivato : $originale->prezzo_vendita);
} else {
$prezzo_unitario = $originale->prezzo_acquisto;
$prezzo_unitario = $prezzo_unitario ?: $originale->prezzo_acquisto;
}
$provvigione = $dbo->selectOne('an_anagrafiche', 'provvigione_default', ['idanagrafica' => $fattura->idagente])['provvigione_default'];
@ -1035,6 +1035,67 @@ switch (post('op')) {
echo json_encode($response);
}
break;
// Controllo se impostare anagrafica azienda in base a tipologia documento
case 'check_tipodocumento':
$idtipodocumento = post('idtipodocumento');
$tipologie = Tipo::wherein('codice_tipo_documento_fe', ['TD21','TD27'])->where('dir', 'entrata')->get()->pluck('id')->toArray();
$azienda = Anagrafica::find(setting('Azienda predefinita'));
$result = false;
if (in_array($idtipodocumento, $tipologie)) {
// Aggiunta tipologia cliente se necessario
if (!$azienda->isTipo('Cliente')) {
$tipo_cliente = TipoAnagrafica::where('descrizione', 'Cliente')->first();
$tipi = $azienda->tipi->pluck('idtipoanagrafica')->toArray();
$tipi[] = $tipo_cliente->id;
$azienda->tipologie = $tipi;
$azienda->save();
}
$result = [
'id' => $azienda->id,
'ragione_sociale' => $azienda->ragione_sociale
];
}
echo json_encode($result);
break;
case 'edit-price':
$righe = $post['righe'];
$numero_totale = 0;
foreach ($righe as $riga) {
if (($riga['id']) != null) {
$articolo = Articolo::find($riga['id']);
} else {
$originale = ArticoloOriginale::find(post('idarticolo'));
$articolo = Articolo::build($fattura, $originale);
$articolo->id_dettaglio_fornitore = post('id_dettaglio_fornitore') ?: null;
}
if ($articolo['prezzo_unitario'] != $riga['price']) {
$articolo->setPrezzoUnitario($riga['price'], $articolo->idiva);
$articolo->save();
++$numero_totale;
}
}
if ($numero_totale > 1) {
flash()->info(tr('_NUM_ prezzi modificati!', [
'_NUM_' => $numero_totale,
]));
} else if ($numero_totale == 1) {
flash()->info(tr('_NUM_ prezzo modificato!', [
'_NUM_' => $numero_totale,
]));
} else {
flash()->warning(tr('Nessun prezzo modificato!'));
}
break;
}

View File

@ -229,7 +229,28 @@ $(document).ready(function () {
$("#info").addClass("hidden");
return;
}
})
});
input("idtipodocumento").change(function () {
$.ajax({
url: globals.rootdir + "/actions.php",
type: "POST",
dataType: "json",
data: {
id_module: globals.id_module,
idtipodocumento:input(this).get(),
op: "check_tipodocumento",
},
success: function (result) {
if (result){
input("idanagrafica").getElement().selectSetNew(result.id, result.ragione_sociale);
input("idanagrafica").disable();
} else {
input("idanagrafica").enable();
}
}
});
});
})
</script>';
}

View File

@ -546,13 +546,10 @@ echo '
}
?>
<div class="row">
<div class="col-md-12">
<div class="col-md-6">
{[ "type": "textarea", "label": "<?php echo tr('Note'); ?>", "name": "note", "help": "<?php echo tr('Note visibili anche in fattura.'); ?>", "value": "$note$", "charcounter": 1 ]}
</div>
</div>
<div class="row">
<div class="col-md-12">
</div>
<div class="col-md-6">
{[ "type": "textarea", "label": "<?php echo tr('Note interne'); ?>", "name": "note_aggiuntive", "help": "<?php echo tr('Note interne.'); ?>", "value": "$note_aggiuntive$", "class": "unblockable" ]}
</div>
</div>

View File

@ -0,0 +1,153 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../../core.php';
use Carbon\Carbon;
use Modules\Fatture\Fattura;
$documento = Fattura::find($id_record);
$id_anagrafica = $documento->idanagrafica;
$direzione = $documento->direzione;
$righe = $_GET['righe'];
$righe = $dbo->fetchArray(
'SELECT mg_articoli.descrizione, mg_articoli.codice, co_righe_documenti.*
FROM co_righe_documenti
JOIN mg_articoli ON mg_articoli.id = co_righe_documenti.idarticolo
WHERE co_righe_documenti.id IN ('.$righe.')'
);
?>
<form action="" method="post" id="add-form">
<table class="table table-striped table-hover table-condensed table-bordered m-3">
<thead>
<tr>
<th width="35" class="text-center" ><?php echo tr('Codice'); ?></th>
<th><?php echo tr('Descrizione'); ?></th>
<th class="text-center" width="150"><?php echo tr('Prezzo corrente'); ?></th>
<th class="text-center" width="150"><?php echo tr('Ultimo preventivo'); ?></th>
<th class="text-center" width="150"><?php echo tr('Ultima fattura'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($righe as $riga) { ?>
<?php
$prezzi_ivati = setting('Utilizza prezzi di vendita comprensivi di IVA');
$ultimo_prezzo_preventivo = $dbo->fetchArray(
'SELECT
co_righe_documenti.idarticolo,
co_righe_preventivi.prezzo_unitario,
DATE(co_righe_preventivi.updated_at) AS updated_at
FROM
co_preventivi
INNER JOIN co_righe_preventivi ON co_righe_preventivi.idpreventivo = co_preventivi.id
INNER JOIN mg_articoli ON mg_articoli.id = co_righe_preventivi.idarticolo
INNER JOIN co_righe_documenti ON co_righe_documenti.idarticolo = mg_articoli.id
WHERE
co_preventivi.idanagrafica = '.prepare($id_anagrafica).' AND co_righe_documenti.idarticolo = '.prepare($riga['idarticolo']).' AND co_preventivi.idstato NOT IN (SELECT id FROM co_statipreventivi WHERE descrizione = "Bozza" OR descrizione = "In attesa di conferma" OR descrizione = "Rifiutato")
GROUP BY
mg_articoli.id, co_righe_preventivi.id
ORDER BY
updated_at DESC'
)[0];
$ultimo_prezzo_vendita = $dbo->fetchArray(
'SELECT
co_righe_documenti.idarticolo,
co_righe_documenti.prezzo_unitario,
DATE(co_righe_documenti.updated_at) AS updated_at
FROM
co_documenti
LEFT JOIN co_righe_documenti ON co_righe_documenti.iddocumento = co_documenti.id
LEFT JOIN mg_articoli ON mg_articoli.id = co_righe_documenti.idarticolo
WHERE
co_documenti.idanagrafica = '.prepare($id_anagrafica).' AND co_righe_documenti.idarticolo = '.prepare($riga['idarticolo']).' AND co_documenti.idstatodocumento IN (SELECT id FROM co_statidocumento WHERE descrizione = "Emessa" OR descrizione = "Pagato" OR descrizione = "Parzialmente pagato")
GROUP BY
mg_articoli.id, co_righe_documenti.id
ORDER BY
updated_at DESC'
)[0];
?>
<tr>
<td><?= $riga['codice'] ?></td>
<td><?= $riga['descrizione'] ?></td>
<td>
<div>
{[ "type": "number", "label": "", "data-id":"<?php echo $riga['id']; ?>","name": "nuovo_prezzo_unitario[]", "value": "<?php echo numberFormat($riga['prezzo_unitario'], 2); ?>"]}
</div>
</td>
<td class="text-center"><?php
if (isset($ultimo_prezzo_preventivo)) {
echo moneyFormat($ultimo_prezzo_preventivo['prezzo_unitario'], 2) . (!empty($ultimo_prezzo_preventivo['updated_at']) ? ' <br><small class="help-block tip" title="'.dateFormat($ultimo_prezzo_preventivo['updated_at']).'">' . (new Carbon($ultimo_prezzo_preventivo['updated_at']))->diffForHumans().'</small>' : '');
} else {
echo 'n.d.';
}
?></td>
<td class="text-center"><?php
if (isset($ultimo_prezzo_vendita)) {
echo moneyFormat($ultimo_prezzo_vendita['prezzo_unitario'], 2) . (!empty($ultimo_prezzo_vendita['updated_at']) ? ' <br><small class="help-block tip" title="'.dateFormat($ultimo_prezzo_vendita['updated_at']).'">' . (new Carbon($ultimo_prezzo_vendita['updated_at']))->diffForHumans().'</small>' : '');
} else {
echo 'n.d.';
}
?></td>
</tr>
<?php } ?>
</tbody>
</table>
<a class="btn btn-primary btn-edit">
<i class="fa fa-edit"></i> <?php echo tr('Modifica'); ?>
</a>
</form>
<script>
$(document).ready(function() {
$('.btn-edit').on('click', function() {
var id = [];
$('input[name^="nuovo_prezzo_unitario"]').each(function() {
id.push({
'id': $(this).data('id'),
'price': $(this).val(),
});
});
$.ajax({
url: globals.rootdir + "/actions.php",
type: "POST",
dataType: "json",
data: {
id_module: globals.id_module,
id_record: globals.id_record,
op: "edit-price",
backto: "record-edit",
righe: id,
},
success: function (response) {
location.reload();
},
error: function() {
location.reload();
}
});
});
});
</script>

View File

@ -21,6 +21,7 @@ use Modules\Interventi\Intervento;
include_once __DIR__.'/init.php';
$direzione = $fattura->direzione;
$block_edit = !empty($note_accredito) || in_array($record['stato'], ['Emessa', 'Pagato', 'Parzialmente pagato']) || !$abilita_genera;
$righe = $fattura->getRighe();
@ -326,7 +327,7 @@ if (!empty($sconto)) {
echo '
<tr>
<td colspan="6" class="text-right">
<b><span class="tip" title="'.tr('Un importo positivo indica uno sconto, mentre uno negativo indica una maggiorazione').'"><i class="fa fa-question-circle-o"></i> '.tr('Sconto/maggiorazione', [], ['upper' => true]).':</span></b>
<b><span class="tip" title="'.tr('Un importo negativo indica uno sconto, mentre uno positivo indica una maggiorazione').'"><i class="fa fa-question-circle-o"></i> '.tr('Sconto/maggiorazione', [], ['upper' => true]).':</span></b>
</td>
<td class="text-right">
'.moneyFormat($sconto, 2).'
@ -404,7 +405,7 @@ if (!empty($iva)) {
echo '
<tr>
<td colspan="6" class="text-right">
<b>'.tr('Totale', [], ['upper' => true]).':</b>
<b>'.tr('Totale documento', [], ['upper' => true]).':</b>
</td>
<td class="text-right">
'.moneyFormat($totale, 2).'
@ -505,7 +506,13 @@ if (!$block_edit && sizeof($righe) > 0) {
<button type="button" class="btn btn-xs btn-default disabled" id="elimina_righe" onclick="rimuoviRiga(getSelectData());">
<i class="fa fa-trash"></i>
</button>
</button>';
if ($direzione == 'entrata') {
echo'
<button type="button" class="btn btn-xs btn-default disabled" id="confronta_righe" onclick="confrontaRighe(getSelectData());">
Confronta prezzi
</button>';
} echo'
</div>';
}
echo '
@ -539,6 +546,10 @@ function getSelectData() {
return data;
}
function confrontaRighe(id) {
openModal("'.tr('Confronta prezzi').'", "'.$module->fileurl('modals/confronta_righe.php').'?id_module=" + globals.id_module + "&id_record=" + globals.id_record + "&righe=" + id + "&id_anagrafica='.$ordine->idanagrafica.'&direzione='.$dir.'");
}
function rimuoviRiga(id) {
swal({
title: "'.tr('Rimuovere queste righe?').'",
@ -642,9 +653,11 @@ $(".check").on("change", function() {
if (checked) {
$("#elimina_righe").removeClass("disabled");
$("#duplica_righe").removeClass("disabled");
$("#confronta_righe").removeClass("disabled");
} else {
$("#elimina_righe").addClass("disabled");
$("#duplica_righe").addClass("disabled");
$("#confronta_righe").addClass("disabled");
}
});

View File

@ -127,6 +127,7 @@ class Fattura extends Document
if ($numero_esterno) {
$model->numero_esterno = $numero_esterno;
}
$model->idagente = $anagrafica->idagente;
// Sede aziendale scelta tra le sedi disponibili per l'utente
$id_sede = $user->sedi[0];

View File

@ -1156,5 +1156,39 @@ switch (post('op')) {
flash()->info(tr('Quantità aggiornata!'));
}
break;
case 'edit-price':
$righe = $post['righe'];
$numero_totale = 0;
foreach ($righe as $riga) {
if (($riga['id']) != null) {
$articolo = Articolo::find($riga['id']);
} else {
$originale = ArticoloOriginale::find(post('idarticolo'));
$articolo = Articolo::build($fattura, $originale);
$articolo->id_dettaglio_fornitore = post('id_dettaglio_fornitore') ?: null;
}
if ($articolo['prezzo_unitario'] != $riga['price']) {
$articolo->setPrezzoUnitario($riga['price'], $articolo->idiva);
$articolo->save();
++$numero_totale;
}
}
if ($numero_totale > 1) {
flash()->info(tr('_NUM_ prezzi modificati!', [
'_NUM_' => $numero_totale,
]));
} else if ($numero_totale == 1) {
flash()->info(tr('_NUM_ prezzo modificato!', [
'_NUM_' => $numero_totale,
]));
} else {
flash()->warning(tr('Nessun prezzo modificato!'));
}
break;
}

View File

@ -21,11 +21,16 @@ include_once __DIR__.'/../../../core.php';
switch ($resource) {
case 'tipiintervento':
$query = 'SELECT idtipointervento AS id, CASE WHEN ISNULL(tempo_standard) OR tempo_standard <= 0 THEN descrizione WHEN tempo_standard > 0 THEN CONCAT(descrizione, \' (\', REPLACE(FORMAT(tempo_standard, 2), \'.\', \',\'), \' ore)\') END AS descrizione, tempo_standard FROM in_tipiintervento |where| ORDER BY descrizione';
$query = 'SELECT idtipointervento AS id, CASE WHEN ISNULL(tempo_standard) OR tempo_standard <= 0 THEN CONCAT(descrizione, IF(in_tipiintervento.deleted_at IS NULL, "", " ('.tr("eliminato").')")) WHEN tempo_standard > 0 THEN CONCAT(descrizione, \' (\', REPLACE(FORMAT(tempo_standard, 2), \'.\', \',\'), \' ore)\', IF(in_tipiintervento.deleted_at IS NULL, "", " ('.tr("eliminato").')")) END AS descrizione, tempo_standard FROM in_tipiintervento |where| ORDER BY descrizione';
foreach ($elements as $element) {
$filter[] = 'idtipointervento='.prepare($element);
}
if (empty($filter)) {
$where[] = 'in_tipiintervento.deleted_at IS NULL';
}
if (!empty($search)) {
$search_fields[] = 'descrizione LIKE '.prepare('%'.$search.'%');
}

View File

@ -80,7 +80,7 @@ if ($show_prezzi) {
// Calcoli
$imponibile = abs($intervento->imponibile);
$sconto = $intervento->sconto;
$sconto = -$intervento->sconto;
$totale_imponibile = abs($intervento->totale_imponibile);
$iva = abs($intervento->iva);
$totale = abs($intervento->totale);
@ -134,7 +134,7 @@ if ($show_prezzi) {
echo '
<tr>
<td colspan="3" class="text-right">
<b>'.tr('Totale', [], ['upper' => true]).':</b>
<b>'.tr('Totale documento', [], ['upper' => true]).':</b>
</td>
<td class="text-right">
'.moneyFormat($totale, 2).'

View File

@ -40,6 +40,7 @@ $query = 'SELECT
(in_interventi_tecnici.prezzo_km_unitario_tecnico * in_interventi_tecnici.km) AS prezzo_km_consuntivo,
an_anagrafiche.ragione_sociale,
an_anagrafiche.deleted_at AS anagrafica_deleted_at,
in_tipiintervento.deleted_at AS tipo_deleted_at,
in_tipiintervento.descrizione AS descrizione_tipo,
in_interventi_tecnici.tipo_scontokm AS tipo_sconto_km,
user.id AS id_user
@ -127,7 +128,7 @@ if (!empty($sessioni)) {
echo '
<tr data-id="'.$sessione['id'].'">
<td>
'.$sessione['descrizione_tipo'].'
'.$sessione['descrizione_tipo'].' '.(($sessione['tipo_deleted_at']) ? '<small class="text-danger"><em>('.tr('Eliminato').')</em></small>' : '').'
</td>';
// Orario di inizio
@ -144,7 +145,7 @@ if (!empty($sessioni)) {
// ORE
echo '
<td style="border-right:1px solid #aaa;">'.($ore<=0 ? '<i class="fa fa-warning tip" style="position:relative;margin-left:-16px;" title="'.tr("Questa sessione è vuota").'" ></i>': '' ).' '.Translator::numberToLocale($ore).'
<td style="border-right:1px solid #aaa;">'.($ore<=0 ? '<i class="fa fa-warning tip" style="position:relative;margin-left:-16px;" title="'.tr("Questa sessione è vuota").'" ></i>': '' ).' '.numberFormat($ore,'qta').'
<div class="extra hide">
<table class="table table-condensed table-bordered">
@ -173,7 +174,7 @@ if (!empty($sessioni)) {
// KM
echo '
<td style="border-right:1px solid #aaa;">
'.Translator::numberToLocale($km).'
'.numberFormat($km, 'qta').'
<div class="extra hide">
<table class="table table-condensed table-bordered">

View File

@ -0,0 +1,154 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../../core.php';
use Carbon\Carbon;
use Modules\Interventi\Intervento;
$intervento = Intervento::find($id_record);
$id_anagrafica = $intervento->idanagrafica;
$direzione = $intervento->direzione;
$righe = $_GET['righe'];
$righe = $dbo->fetchArray(
'SELECT mg_articoli.descrizione, mg_articoli.codice, in_righe_interventi.*
FROM in_righe_interventi
JOIN mg_articoli ON mg_articoli.id = in_righe_interventi.idarticolo
WHERE in_righe_interventi.id IN ('.$righe.')'
);
?>
<form action="" method="post" id="add-form">
<table class="table table-striped table-hover table-condensed table-bordered m-3">
<thead>
<tr>
<th width="35" class="text-center" ><?php echo tr('Codice'); ?></th>
<th><?php echo tr('Descrizione'); ?></th>
<th class="text-center" width="150"><?php echo tr('Prezzo corrente'); ?></th>
<th class="text-center" width="150"><?php echo tr('Ultimo preventivo'); ?></th>
<th class="text-center" width="150"><?php echo tr('Ultima fattura'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($righe as $riga) { ?>
<?php
$prezzi_ivati = setting('Utilizza prezzi di vendita comprensivi di IVA');
$ultimo_prezzo_preventivo = $dbo->fetchArray(
'SELECT
in_righe_interventi.idarticolo,
co_righe_preventivi.prezzo_unitario,
DATE(co_righe_preventivi.updated_at) AS updated_at
FROM
co_preventivi
INNER JOIN co_righe_preventivi ON co_righe_preventivi.idpreventivo = co_preventivi.id
INNER JOIN mg_articoli ON mg_articoli.id = co_righe_preventivi.idarticolo
INNER JOIN in_righe_interventi ON in_righe_interventi.idarticolo = mg_articoli.id
WHERE
co_preventivi.idanagrafica ='.prepare($id_anagrafica).' AND in_righe_interventi.idarticolo ='.prepare($riga['idarticolo']).' AND co_preventivi.idstato NOT IN (SELECT id FROM co_statipreventivi WHERE descrizione = "Bozza" OR descrizione = "In attesa di conferma" OR descrizione = "Rifiutato")
GROUP BY
mg_articoli.id, co_righe_preventivi.id
ORDER BY
updated_at DESC'
)[0];
$ultimo_prezzo_vendita = $dbo->fetchArray(
'SELECT
in_righe_interventi.idarticolo,
co_righe_documenti.prezzo_unitario,
DATE(co_righe_documenti.updated_at) AS updated_at
FROM
co_documenti
INNER JOIN co_righe_documenti ON co_righe_documenti.iddocumento = co_documenti.id
INNER JOIN mg_articoli ON mg_articoli.id = co_righe_documenti.idarticolo
INNER JOIN in_righe_interventi ON in_righe_interventi.idarticolo = mg_articoli.id
WHERE
co_documenti.idanagrafica ='.prepare($id_anagrafica).' AND co_righe_documenti.idarticolo ='.prepare($riga['idarticolo']).' AND co_documenti.idstatodocumento IN (SELECT id FROM co_statidocumento WHERE descrizione = "Emessa" OR descrizione = "Pagato" OR descrizione = "Parzialmente pagato")
GROUP BY
mg_articoli.id, co_righe_documenti.id
ORDER BY
updated_at DESC'
)[0];
?>
<tr>
<td><?= $riga['codice'] ?></td>
<td><?= $riga['descrizione'] ?></td>
<td>
<div>
{[ "type": "number", "label": "", "data-id":"<?php echo $riga['id']; ?>","name": "nuovo_prezzo_unitario[]", "value": "<?php echo numberFormat($riga['prezzo_unitario'], 2); ?>"]}
</div>
</td>
<td class="text-center"><?php
if (isset($ultimo_prezzo_preventivo)) {
echo moneyFormat($ultimo_prezzo_preventivo['prezzo_unitario'], 2) . (!empty($ultimo_prezzo_preventivo['updated_at']) ? ' <br><small class="help-block tip" title="'.dateFormat($ultimo_prezzo_preventivo['updated_at']).'">' . (new Carbon($ultimo_prezzo_preventivo['updated_at']))->diffForHumans().'</small>' : '');
} else {
echo 'n.d.';
}
?></td>
<td class="text-center"><?php
if (isset($ultimo_prezzo_vendita)) {
echo moneyFormat($ultimo_prezzo_vendita['prezzo_unitario'], 2) . (!empty($ultimo_prezzo_vendita['updated_at']) ? ' <br><small class="help-block tip" title="'.dateFormat($ultimo_prezzo_vendita['updated_at']).'">' . (new Carbon($ultimo_prezzo_vendita['updated_at']))->diffForHumans().'</small>' : '');
} else {
echo 'n.d.';
}
?></td>
</tr>
<?php } ?>
</tbody>
</table>
<a class="btn btn-primary btn-edit">
<i class="fa fa-edit"></i> <?php echo tr('Modifica'); ?>
</a>
</form>
<script>
$(document).ready(function() {
$('.btn-edit').on('click', function() {
var id = [];
$('input[name^="nuovo_prezzo_unitario"]').each(function() {
id.push({
'id': $(this).data('id'),
'price': $(this).val(),
});
});
$.ajax({
url: globals.rootdir + "/actions.php",
type: "POST",
dataType: "json",
data: {
id_module: globals.id_module,
id_record: globals.id_record,
op: "edit-price",
backto: "record-edit",
righe: id,
},
success: function (response) {
location.reload();
},
error: function() {
location.reload();
}
});
});
});
</script>

View File

@ -36,9 +36,9 @@ $button = '<i class="fa fa-edit"></i> '.tr('Modifica');
$intervento = Intervento::find($id_record);
if (!empty($intervento->id_contratto)) {
$query = 'SELECT in_tipiintervento.idtipointervento AS id, descrizione, co_contratti_tipiintervento.costo_ore AS prezzo_ore_unitario, co_contratti_tipiintervento.costo_km AS prezzo_km_unitario, co_contratti_tipiintervento.costo_dirittochiamata AS prezzo_dirittochiamata FROM in_tipiintervento JOIN co_contratti_tipiintervento ON in_tipiintervento.idtipointervento = co_contratti_tipiintervento.idtipointervento WHERE co_contratti_tipiintervento.idcontratto = '.prepare($intervento->id_contratto).' ORDER BY descrizione';
$query = 'SELECT in_tipiintervento.idtipointervento AS id, descrizione, co_contratti_tipiintervento.costo_ore AS prezzo_ore_unitario, co_contratti_tipiintervento.costo_km AS prezzo_km_unitario, co_contratti_tipiintervento.costo_dirittochiamata AS prezzo_dirittochiamata FROM in_tipiintervento JOIN co_contratti_tipiintervento ON in_tipiintervento.idtipointervento = co_contratti_tipiintervento.idtipointervento WHERE co_contratti_tipiintervento.idcontratto = '.prepare($intervento->id_contratto).' AND in_tipiintervento.deleted_at IS NULL ORDER BY descrizione';
} else{
$query = 'SELECT in_tipiintervento.idtipointervento AS id, descrizione, in_tariffe.costo_ore AS prezzo_ore_unitario, in_tariffe.costo_km AS prezzo_km_unitario, in_tariffe.costo_dirittochiamata AS prezzo_dirittochiamata FROM in_tipiintervento JOIN in_tariffe ON in_tipiintervento.idtipointervento = in_tariffe.idtipointervento WHERE in_tariffe.idtecnico = '.prepare($sessione['idtecnico']).' ORDER BY descrizione';
$query = 'SELECT in_tipiintervento.idtipointervento AS id, descrizione, in_tariffe.costo_ore AS prezzo_ore_unitario, in_tariffe.costo_km AS prezzo_km_unitario, in_tariffe.costo_dirittochiamata AS prezzo_dirittochiamata FROM in_tipiintervento JOIN in_tariffe ON in_tipiintervento.idtipointervento = in_tariffe.idtipointervento WHERE in_tariffe.idtecnico = '.prepare($sessione['idtecnico']).' AND in_tipiintervento.deleted_at IS NULL ORDER BY descrizione';
}
echo '
<form id="add_form" action="'.base_path().'/editor.php?id_module='.$id_module.'&id_record='.get('id_record').'" method="post">

View File

@ -201,7 +201,7 @@ function aggiungi_intervento_in_fattura($id_intervento, $id_fattura, $descrizion
$riga->id_rivalsa_inps = $id_rivalsa_inps;
$riga->prezzo_unitario = $sessione->prezzo_orario;
$riga->costo_unitario = $sessione->prezzo_ore_unitario_tecnico;
//Calcolo lo sconto unitario della sessione in base all'impostazione sui prezzi ivati
$iva = $dbo->table('co_iva')->where('id', $id_iva)->first();
if ($sessione->tipo_sconto == 'UNT' && setting('Utilizza prezzi di vendita comprensivi di IVA')) {
@ -245,7 +245,7 @@ function aggiungi_intervento_in_fattura($id_intervento, $id_fattura, $descrizion
$riga->id_rivalsa_inps = $id_rivalsa_inps;
$riga->prezzo_unitario = $diritto_chiamata->prezzo_diritto_chiamata;
$riga->costo_unitario = $sessione->prezzo_dirittochiamata_tecnico;
$riga->qta = $gruppo->count();
// Riferimento al documento di origine
@ -283,6 +283,7 @@ function aggiungi_intervento_in_fattura($id_intervento, $id_fattura, $descrizion
$riga->id_rivalsa_inps = $id_rivalsa_inps;
$riga->prezzo_unitario = $viaggio->prezzo_km_unitario;
$riga->costo_unitario = $sessione->prezzo_km_unitario_tecnico;
$riga->setSconto($viaggio->scontokm_unitario, $viaggio->tipo_scontokm);
// Riferimento al documento di origine

View File

@ -22,6 +22,7 @@ include_once __DIR__.'/init.php';
$block_edit = $record['flag_completato'];
$righe = $intervento->getRighe();
$colspan = ($block_edit ? '5' : '6');
$direzione = $intervento->direzione;
$show_prezzi = Auth::user()['gruppo'] != 'Tecnici' || (Auth::user()['gruppo'] == 'Tecnici' && setting('Mostra i prezzi al tecnico'));
@ -228,14 +229,14 @@ echo '
</tr>';
// SCONTO
if (!empty($intervento->sconto)) {
if (!empty($righe->sum('sconto'))) {
echo '
<tr>
<td colspan="'.$colspan.'" class="text-right">
<b><span class="tip" title="'.tr('Un importo positivo indica uno sconto, mentre uno negativo indica una maggiorazione').'"> <i class="fa fa-question-circle-o"></i> '.tr('Sconto/maggiorazione', [], ['upper' => true]).':</span></b>
<b><span class="tip" title="'.tr('Un importo negativo indica uno sconto, mentre uno positivo indica una maggiorazione').'"> <i class="fa fa-question-circle-o"></i> '.tr('Sconto/maggiorazione', [], ['upper' => true]).':</span></b>
</td>
<td class="text-right">
'.moneyFormat($intervento->sconto, 2).'
'.moneyFormat(-$righe->sum('sconto'), 2).'
</td>
<td></td>
</tr>';
@ -280,7 +281,13 @@ if (!$block_edit && sizeof($righe) > 0) {
<button type="button" class="btn btn-xs btn-default disabled" id="elimina_righe" onclick="rimuoviRiga(getSelectData());">
<i class="fa fa-trash"></i>
</button>
</button>';
if ($direzione == 'entrata') {
echo'
<button type="button" class="btn btn-xs btn-default disabled" id="confronta_righe" onclick="confrontaRighe(getSelectData());">
Confronta prezzi
</button>';
} echo'
</div>';
}
echo '
@ -314,6 +321,10 @@ function getSelectData() {
return data;
}
function confrontaRighe(id) {
openModal("'.tr('Confronta prezzi').'", "'.$module->fileurl('modals/confronta_righe.php').'?id_module=" + globals.id_module + "&id_record=" + globals.id_record + "&righe=" + id + "&id_anagrafica='.$ordine->idanagrafica.'&direzione='.$dir.'");
}
function rimuoviRiga(id) {
swal({
title: "'.tr('Rimuovere queste righe?').'",
@ -409,9 +420,11 @@ $(".check").on("change", function() {
if (checked) {
$("#elimina_righe").removeClass("disabled");
$("#duplica_righe").removeClass("disabled");
$("#confronta_righe").removeClass("disabled");
} else {
$("#elimina_righe").addClass("disabled");
$("#duplica_righe").addClass("disabled");
$("#confronta_righe").addClass("disabled");
}
});

View File

@ -65,7 +65,8 @@ class Intervento extends Document
$model->codice = static::getNextCodice($data_richiesta, $id_segment);
$model->data_richiesta = $data_richiesta;
$model->id_segment = $id_segment;
$model->idagente = $anagrafica->idagente;
$model->save();
return $model;

View File

@ -244,6 +244,7 @@ switch (post('op')) {
$sconto->descrizione = post('descrizione');
$sconto->note = post('note');
$sconto->setScontoUnitario(post('sconto_unitario'), post('idiva'));
$sconto->confermato = ($dir = 'entrata' ? setting('Conferma automaticamente le quantità negli ordini cliente') : setting('Conferma automaticamente le quantità negli ordini fornitore'));
$sconto->save();
@ -625,7 +626,7 @@ switch (post('op')) {
$qta_articolo = $dbo->selectOne('mg_articoli', 'qta', ['id' => $id_articolo])['qta'];
$originale = ArticoloOriginale::find($id_articolo);
$articolo = Articolo::build($ordine, $originale);
$qta = 1;
@ -650,6 +651,12 @@ switch (post('op')) {
FROM mg_prezzi_articoli
WHERE id_articolo = '.prepare($id_articolo).' AND dir = '.prepare($dir).' AND id_anagrafica = '.prepare($id_anagrafica));
// Per gli ordini fornitore imposta la quantità minima richiesta dal fornitore invece di 1
if ($dir == 'uscita') {
$qta_minima_fornitore = $dbo->fetchOne('SELECT qta_minima FROM mg_fornitore_articolo WHERE id_articolo = '.prepare($id_articolo).' AND id_fornitore = '.prepare($id_anagrafica))['qta_minima'];
$articolo->qta = ($qta_minima_fornitore ?: 1);
}
if ($prezzi) {
foreach ($prezzi as $prezzo) {
if ($qta >= $prezzo['minimo'] && $qta <= $prezzo['massimo']) {
@ -681,11 +688,12 @@ switch (post('op')) {
if ($dir == 'entrata') {
$prezzo_unitario = $prezzo_unitario ?: ($prezzi_ivati ? $originale->prezzo_vendita_ivato : $originale->prezzo_vendita);
} else {
$prezzo_unitario = $originale->prezzo_acquisto;
$prezzo_unitario = $prezzo_unitario ?: $originale->prezzo_acquisto;
}
$provvigione = $dbo->selectOne('an_anagrafiche', 'provvigione_default', ['idanagrafica' => $ordine->idagente])['provvigione_default'];
$articolo->confermato = ($dir = 'entrata' ? setting('Conferma automaticamente le quantità negli ordini cliente') : setting('Conferma automaticamente le quantità negli ordini fornitore'));
$articolo->setPrezzoUnitario($prezzo_unitario, $id_iva);
$articolo->setSconto($sconto, 'PRC');
$articolo->setProvvigione($provvigione ?: 0, 'PRC');
@ -693,6 +701,7 @@ switch (post('op')) {
flash()->info(tr('Nuovo articolo aggiunto!'));
} else {
$response['error'] = tr('Nessun articolo corrispondente a magazzino');
echo json_encode($response);
@ -714,4 +723,38 @@ switch (post('op')) {
}
break;
}
case 'edit-price':
$righe = $post['righe'];
$numero_totale = 0;
foreach ($righe as $riga) {
if (($riga['id']) != null) {
$articolo = Articolo::find($riga['id']);
} else {
$originale = ArticoloOriginale::find(post('idarticolo'));
$articolo = Articolo::build($fattura, $originale);
$articolo->id_dettaglio_fornitore = post('id_dettaglio_fornitore') ?: null;
}
if ($articolo['prezzo_unitario'] != $riga['price']) {
$articolo->setPrezzoUnitario($riga['price'], $articolo->idiva);
$articolo->save();
++$numero_totale;
}
}
if ($numero_totale > 1) {
flash()->info(tr('_NUM_ prezzi modificati!', [
'_NUM_' => $numero_totale,
]));
} else if ($numero_totale == 1) {
flash()->info(tr('_NUM_ prezzo modificato!', [
'_NUM_' => $numero_totale,
]));
} else {
flash()->warning(tr('Nessun prezzo modificato!'));
}
break;
}

View File

@ -157,13 +157,10 @@ echo '
</div>
<div class="row">
<div class="col-md-12">
<div class="col-md-6">
{[ "type": "textarea", "label": "<?php echo tr('Note'); ?>", "name": "note", "value": "$note$" ]}
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="col-md-6">
{[ "type": "textarea", "label": "<?php echo tr('Note interne'); ?>", "name": "note_aggiuntive", "value": "$note_aggiuntive$" ]}
</div>
</div>

View File

@ -0,0 +1,154 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../../core.php';
use Carbon\Carbon;
use Modules\Ordini\Ordine;
$ordine = Ordine::find($id_record);
$id_anagrafica = $ordine->idanagrafica;
$direzione = $ordine->direzione;
$righe = $_GET['righe'];
$righe = $dbo->fetchArray(
'SELECT mg_articoli.descrizione, mg_articoli.codice, or_righe_ordini.*
FROM or_righe_ordini
JOIN mg_articoli ON mg_articoli.id = or_righe_ordini.idarticolo
WHERE or_righe_ordini.id IN ('.$righe.')'
);
?>
<form action="" method="post" id="add-form">
<table class="table table-striped table-hover table-condensed table-bordered m-3">
<thead>
<tr>
<th width="35" class="text-center" ><?php echo tr('Codice'); ?></th>
<th><?php echo tr('Descrizione'); ?></th>
<th class="text-center" width="150"><?php echo tr('Prezzo corrente'); ?></th>
<th class="text-center" width="150"><?php echo tr('Ultimo preventivo'); ?></th>
<th class="text-center" width="150"><?php echo tr('Ultima fattura'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($righe as $riga) { ?>
<?php
$prezzi_ivati = setting('Utilizza prezzi di vendita comprensivi di IVA');
$ultimo_prezzo_preventivo = $dbo->fetchArray(
'SELECT
or_righe_ordini.idarticolo,
co_righe_preventivi.prezzo_unitario,
DATE(co_righe_preventivi.updated_at) AS updated_at
FROM
co_preventivi
INNER JOIN co_righe_preventivi ON co_righe_preventivi.idpreventivo = co_preventivi.id
INNER JOIN mg_articoli ON mg_articoli.id = co_righe_preventivi.idarticolo
INNER JOIN or_righe_ordini ON or_righe_ordini.idarticolo = mg_articoli.id
WHERE
co_preventivi.idanagrafica ='.prepare($id_anagrafica).' AND or_righe_ordini.idarticolo ='.prepare($riga['idarticolo']).' AND co_preventivi.idstato NOT IN (SELECT id FROM co_statipreventivi WHERE descrizione = "Bozza" OR descrizione = "In attesa di conferma" OR descrizione = "Rifiutato")
GROUP BY
mg_articoli.id, co_righe_preventivi.id
ORDER BY
updated_at DESC'
)[0];
$ultimo_prezzo_vendita = $dbo->fetchArray(
'SELECT
or_righe_ordini.idarticolo,
co_righe_documenti.prezzo_unitario,
DATE(co_righe_documenti.updated_at) AS updated_at
FROM
co_documenti
INNER JOIN co_righe_documenti ON co_righe_documenti.iddocumento = co_documenti.id
INNER JOIN mg_articoli ON mg_articoli.id = co_righe_documenti.idarticolo
INNER JOIN or_righe_ordini ON or_righe_ordini.idarticolo = mg_articoli.id
WHERE
co_documenti.idanagrafica ='.prepare($id_anagrafica).' AND co_righe_documenti.idarticolo ='.prepare($riga['idarticolo']).' AND co_documenti.idstatodocumento IN (SELECT id FROM co_statidocumento WHERE descrizione = "Emessa" OR descrizione = "Pagato" OR descrizione = "Parzialmente pagato")
GROUP BY
mg_articoli.id, co_righe_documenti.id
ORDER BY
updated_at DESC'
)[0];
?>
<tr>
<td><?= $riga['codice'] ?></td>
<td><?= $riga['descrizione'] ?></td>
<td>
<div>
{[ "type": "number", "label": "", "data-id":"<?php echo $riga['id']; ?>","name": "nuovo_prezzo_unitario[]", "value": "<?php echo numberFormat($riga['prezzo_unitario'], 2); ?>"]}
</div>
</td>
<td class="text-center"><?php
if (isset($ultimo_prezzo_preventivo)) {
echo moneyFormat($ultimo_prezzo_preventivo['prezzo_unitario'], 2) . (!empty($ultimo_prezzo_preventivo['updated_at']) ? ' <br><small class="help-block tip" title="'.dateFormat($ultimo_prezzo_preventivo['updated_at']).'">' . (new Carbon($ultimo_prezzo_preventivo['updated_at']))->diffForHumans().'</small>' : '');
} else {
echo 'n.d.';
}
?></td>
<td class="text-center"><?php
if (isset($ultimo_prezzo_vendita)) {
echo moneyFormat($ultimo_prezzo_vendita['prezzo_unitario'], 2) . (!empty($ultimo_prezzo_vendita['updated_at']) ? ' <br><small class="help-block tip" title="'.dateFormat($ultimo_prezzo_vendita['updated_at']).'">' . (new Carbon($ultimo_prezzo_vendita['updated_at']))->diffForHumans().'</small>' : '');
} else {
echo 'n.d.';
}
?></td>
</tr>
<?php } ?>
</tbody>
</table>
<a class="btn btn-primary btn-edit">
<i class="fa fa-edit"></i> <?php echo tr('Modifica'); ?>
</a>
</form>
<script>
$(document).ready(function() {
$('.btn-edit').on('click', function() {
var id = [];
$('input[name^="nuovo_prezzo_unitario"]').each(function() {
id.push({
'id': $(this).data('id'),
'price': $(this).val(),
});
});
$.ajax({
url: globals.rootdir + "/actions.php",
type: "POST",
dataType: "json",
data: {
id_module: globals.id_module,
id_record: globals.id_record,
op: "edit-price",
backto: "record-edit",
righe: id,
},
success: function (response) {
location.reload();
},
error: function() {
location.reload();
}
});
});
});
</script>

View File

@ -24,6 +24,7 @@ use Modules\Articoli\Articolo;
$block_edit = $record['flag_completato'];
$righe = $ordine->getRighe();
$colspan = ($block_edit ? '6' : '7');
$direzione = $ordine->direzione;
echo '
<div class="table-responsive row-list">
@ -283,7 +284,7 @@ echo '
// Calcoli
$imponibile = abs($ordine->imponibile);
$sconto = $ordine->sconto;
$sconto = -$ordine->sconto;
$totale_imponibile = abs($ordine->totale_imponibile);
$iva = abs($ordine->iva);
$totale = abs($ordine->totale);
@ -307,7 +308,7 @@ if (!empty($sconto)) {
echo '
<tr>
<td colspan="'.$colspan.'" class="text-right">
<b><span class="tip" title="'.tr('Un importo positivo indica uno sconto, mentre uno negativo indica una maggiorazione').'"> <i class="fa fa-question-circle-o"></i> '.tr('Sconto/maggiorazione', [], ['upper' => true]).':</span></b>
<b><span class="tip" title="'.tr('Un importo negativo indica uno sconto, mentre uno positivo indica una maggiorazione').'"> <i class="fa fa-question-circle-o"></i> '.tr('Sconto/maggiorazione', [], ['upper' => true]).':</span></b>
</td>
<td class="text-right">
'.moneyFormat($sconto, 2).'
@ -344,7 +345,7 @@ echo '
echo '
<tr>
<td colspan="'.$colspan.'" class="text-right">
<b>'.tr('Totale', [], ['upper' => true]).':</b>
<b>'.tr('Totale documento', [], ['upper' => true]).':</b>
</td>
<td class="text-right">
'.moneyFormat($totale, 2).'
@ -416,7 +417,13 @@ if (!$block_edit && sizeof($righe) > 0) {
<button type="button" class="btn btn-xs btn-default disabled" id="elimina_righe" onclick="rimuoviRiga(getSelectData());">
<i class="fa fa-trash"></i>
</button>
</button>';
if ($direzione == 'entrata') {
echo'
<button type="button" class="btn btn-xs btn-default disabled" id="confronta_righe" onclick="confrontaRighe(getSelectData());">
Confronta prezzi
</button>';
} echo'
</div>';
}
echo '
@ -450,6 +457,10 @@ function getSelectData() {
return data;
}
function confrontaRighe(id) {
openModal("'.tr('Confronta prezzi').'", "'.$module->fileurl('modals/confronta_righe.php').'?id_module=" + globals.id_module + "&id_record=" + globals.id_record + "&righe=" + id + "&id_anagrafica='.$ordine->idanagrafica.'&direzione='.$dir.'");
}
function rimuoviRiga(id) {
swal({
title: "'.tr('Rimuovere queste righe?').'",
@ -553,9 +564,11 @@ $(".check").on("change", function() {
if (checked) {
$("#elimina_righe").removeClass("disabled");
$("#duplica_righe").removeClass("disabled");
$("#confronta_righe").removeClass("disabled");
} else {
$("#elimina_righe").addClass("disabled");
$("#duplica_righe").addClass("disabled");
$("#confronta_righe").addClass("disabled");
}
});

View File

@ -82,7 +82,7 @@ class Ordine extends Document
$model->tipo()->associate($tipo_documento);
$model->stato()->associate($stato_documento);
$model->id_segment = $id_segment;
$model->idagente = $anagrafica->idagente;
$model->save();
// Salvataggio delle informazioni

View File

@ -282,7 +282,7 @@ switch (post('op')) {
$sconto->descrizione = post('descrizione');
$sconto->note = post('note');
$sconto->setScontoUnitario(post('sconto_unitario'), post('idiva'));
$sconto->confermato = setting('Conferma automaticamente le quantità nei preventivi');
$sconto->save();
if (post('idriga') != null) {
@ -447,6 +447,7 @@ switch (post('op')) {
case 'add_articolo':
$id_articolo = post('id_articolo');
$barcode = post('barcode');
$dir = 'entrata';
if (!empty($barcode)) {
$id_articolo = $dbo->selectOne('mg_articoli', 'id', ['deleted_at' => null, 'attivo' => 1, 'barcode' => $barcode])['id'];
@ -465,6 +466,7 @@ switch (post('op')) {
$articolo->um = $originale->um;
$articolo->qta = 1;
$articolo->costo_unitario = $originale->prezzo_acquisto;
$articolo->confermato = setting('Conferma automaticamente le quantità nei preventivi');
$id_iva = ($preventivo->anagrafica->idiva_vendite ?: $originale->idiva_vendita) ?: setting('Iva predefinita');
$id_anagrafica = $preventivo->idanagrafica;
@ -537,4 +539,38 @@ switch (post('op')) {
}
break;
}
case 'edit-price':
$righe = $post['righe'];
$numero_totale = 0;
foreach ($righe as $riga) {
if (($riga['id']) != null) {
$articolo = Articolo::find($riga['id']);
} else {
$originale = ArticoloOriginale::find(post('idarticolo'));
$articolo = Articolo::build($fattura, $originale);
$articolo->id_dettaglio_fornitore = post('id_dettaglio_fornitore') ?: null;
}
if ($articolo['prezzo_unitario'] != $riga['price']) {
$articolo->setPrezzoUnitario($riga['price'], $articolo->idiva);
$articolo->save();
++$numero_totale;
}
}
if ($numero_totale > 1) {
flash()->info(tr('_NUM_ prezzi modificati!', [
'_NUM_' => $numero_totale,
]));
} else if ($numero_totale == 1) {
flash()->info(tr('_NUM_ prezzo modificato!', [
'_NUM_' => $numero_totale,
]));
} else {
flash()->warning(tr('Nessun prezzo modificato!'));
}
break;
}

View File

@ -57,7 +57,7 @@ $stato = $database->query('SELECT id, descrizione FROM co_statipreventivi WHERE
</div>
<div class="row">
<div class="col-md-6">
{[ "type": "select", "label": "<?php echo tr('Tipo di Attività'); ?>", "name": "idtipointervento", "required": 1, "values": "query=SELECT idtipointervento AS id, descrizione FROM in_tipiintervento" ]}
{[ "type": "select", "label": "<?php echo tr('Tipo di Attività'); ?>", "name": "idtipointervento", "required": 1, "ajax-source": "tipiintervento" ]}
</div>
<div class="col-md-6">

View File

@ -126,7 +126,7 @@ echo '
</div>
<div class="col-md-3">
{[ "type": "select", "label": "<?php echo tr('Tipo di attività'); ?>", "name": "idtipointervento", "required": 1, "values": "query=SELECT idtipointervento AS id, descrizione FROM in_tipiintervento ORDER BY descrizione", "value": "$idtipointervento$" ]}
{[ "type": "select", "label": "<?php echo tr('Tipo di attività'); ?>", "name": "idtipointervento", "required": 1, "ajax-source": "tipiintervento", "value": "$idtipointervento$" ]}
</div>
<!--div class="col-md-3">
@ -145,13 +145,10 @@ echo '
</div>
<div class="row">
<div class="col-md-12">
<div class="col-md-6">
{[ "type": "textarea", "label": "<?php echo tr('Esclusioni'); ?>", "name": "esclusioni", "class": "autosize", "value": "$esclusioni$" ]}
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="col-md-6">
{[ "type": "textarea", "label": "<?php echo tr('Garanzia'); ?>", "name": "garanzia", "class": "autosize", "value": "$garanzia$" ]}
</div>
</div>

View File

@ -0,0 +1,153 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../../core.php';
use Carbon\Carbon;
use Modules\Preventivi\Preventivo;
$preventivo = Preventivo::find($id_record);
$id_anagrafica = $preventivo->idanagrafica;
$direzione = $preventivo->direzione;
$righe = $_GET['righe'];
$righe = $dbo->fetchArray(
'SELECT mg_articoli.descrizione, mg_articoli.codice, co_righe_preventivi.*
FROM co_righe_preventivi
JOIN mg_articoli ON mg_articoli.id = co_righe_preventivi.idarticolo
WHERE co_righe_preventivi.id IN ('.$righe.')'
);
?>
<form action="" method="post" id="add-form">
<table class="table table-striped table-hover table-condensed table-bordered m-3">
<thead>
<tr>
<th width="35" class="text-center" ><?php echo tr('Codice'); ?></th>
<th><?php echo tr('Descrizione'); ?></th>
<th class="text-center" width="150"><?php echo tr('Prezzo corrente'); ?></th>
<th class="text-center" width="150"><?php echo tr('Ultimo preventivo'); ?></th>
<th class="text-center" width="150"><?php echo tr('Ultima fattura'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($righe as $riga) { ?>
<?php
$prezzi_ivati = setting('Utilizza prezzi di vendita comprensivi di IVA');
$ultimo_prezzo_preventivo = $dbo->fetchArray(
'SELECT
co_righe_preventivi.idarticolo,
co_righe_preventivi.prezzo_unitario,
DATE(co_righe_preventivi.updated_at) AS updated_at
FROM
co_preventivi
INNER JOIN co_righe_preventivi ON co_righe_preventivi.idpreventivo = co_preventivi.id
INNER JOIN mg_articoli ON mg_articoli.id = co_righe_preventivi.idarticolo
WHERE
co_preventivi.idanagrafica ='.prepare($id_anagrafica).' AND co_righe_preventivi.idarticolo ='.prepare($riga['idarticolo']).' AND co_preventivi.idstato NOT IN (SELECT id FROM co_statipreventivi WHERE descrizione = "Bozza" OR descrizione = "In attesa di conferma" OR descrizione = "Rifiutato")
GROUP BY
mg_articoli.id, co_righe_preventivi.id
ORDER BY
updated_at DESC'
)[0];
$ultimo_prezzo_vendita = $dbo->fetchArray(
'SELECT
co_righe_preventivi.idarticolo,
co_righe_documenti.prezzo_unitario,
DATE(co_righe_documenti.updated_at) AS updated_at
FROM
co_documenti
INNER JOIN co_righe_documenti ON co_righe_documenti.iddocumento = co_documenti.id
INNER JOIN mg_articoli ON mg_articoli.id = co_righe_documenti.idarticolo
INNER JOIN co_righe_preventivi ON co_righe_preventivi.idarticolo = mg_articoli.id
WHERE
co_documenti.idanagrafica ='.prepare($id_anagrafica).' AND co_righe_documenti.idarticolo ='.prepare($riga['idarticolo']).' AND co_documenti.idstatodocumento IN (SELECT id FROM co_statidocumento WHERE descrizione = "Emessa" OR descrizione = "Pagato" OR descrizione = "Parzialmente pagato")
GROUP BY
mg_articoli.id, co_righe_documenti.id
ORDER BY
updated_at DESC'
)[0];
?>
<tr>
<td><?= $riga['codice'] ?></td>
<td><?= $riga['descrizione'] ?></td>
<td>
<div>
{[ "type": "number", "label": "", "data-id":"<?php echo $riga['id']; ?>","name": "nuovo_prezzo_unitario[]", "value": "<?php echo numberFormat($riga['prezzo_unitario'], 2); ?>"]}
</div>
</td>
<td class="text-center"><?php
if (isset($ultimo_prezzo_preventivo)) {
echo moneyFormat($ultimo_prezzo_preventivo['prezzo_unitario'], 2) . (!empty($ultimo_prezzo_preventivo['updated_at']) ? ' <br><small class="help-block tip" title="'.dateFormat($ultimo_prezzo_preventivo['updated_at']).'">' . (new Carbon($ultimo_prezzo_preventivo['updated_at']))->diffForHumans().'</small>' : '');
} else {
echo 'n.d.';
}
?></td>
<td class="text-center"><?php
if (isset($ultimo_prezzo_vendita)) {
echo moneyFormat($ultimo_prezzo_vendita['prezzo_unitario'], 2) . (!empty($ultimo_prezzo_vendita['updated_at']) ? ' <br><small class="help-block tip" title="'.dateFormat($ultimo_prezzo_vendita['updated_at']).'">' . (new Carbon($ultimo_prezzo_vendita['updated_at']))->diffForHumans().'</small>' : '');
} else {
echo 'n.d.';
}
?></td>
</tr>
<?php } ?>
</tbody>
</table>
<a class="btn btn-primary btn-edit">
<i class="fa fa-edit"></i> <?php echo tr('Modifica'); ?>
</a>
</form>
<script>
$(document).ready(function() {
$('.btn-edit').on('click', function() {
var id = [];
$('input[name^="nuovo_prezzo_unitario"]').each(function() {
id.push({
'id': $(this).data('id'),
'price': $(this).val(),
});
});
$.ajax({
url: globals.rootdir + "/actions.php",
type: "POST",
dataType: "json",
data: {
id_module: globals.id_module,
id_record: globals.id_record,
op: "edit-price",
backto: "record-edit",
righe: id,
},
success: function (response) {
location.reload();
},
error: function() {
location.reload();
}
});
});
});
</script>

View File

@ -22,6 +22,7 @@ include_once __DIR__.'/init.php';
$block_edit = $record['is_completato'];
$righe = $preventivo->getRighe();
$colspan = ($block_edit ? '6' : '7');
$direzione = $preventivo->direzione;
echo '
<div class="table-responsive row-list">
@ -225,7 +226,7 @@ echo '
// Calcoli
$imponibile = abs($preventivo->imponibile);
$sconto = $preventivo->sconto;
$sconto = -$preventivo->sconto;
$totale_imponibile = abs($preventivo->totale_imponibile);
$iva = abs($preventivo->iva);
$totale = abs($preventivo->totale);
@ -249,10 +250,10 @@ if (!empty($sconto)) {
echo '
<tr>
<td colspan="'.$colspan.'" class="text-right">
<b><span class="tip" title="'.tr('Un importo positivo indica uno sconto, mentre uno negativo indica una maggiorazione').'"> <i class="fa fa-question-circle-o"></i> '.tr('Sconto/maggiorazione', [], ['upper' => true]).':</span></b>
<b><span class="tip" title="'.tr('Un importo negativo indica uno sconto, mentre uno positivo indica una maggiorazione').'"> <i class="fa fa-question-circle-o"></i> '.tr('Sconto/maggiorazione', [], ['upper' => true]).':</span></b>
</td>
<td class="text-right">
'.moneyFormat($preventivo->sconto, 2).'
'.moneyFormat($sconto, 2).'
</td>
<td></td>
</tr>';
@ -286,7 +287,7 @@ echo '
echo '
<tr>
<td colspan="'.$colspan.'" class="text-right">
<b>'.tr('Totale', [], ['upper' => true]).':</b>
<b>'.tr('Totale documento', [], ['upper' => true]).':</b>
</td>
<td class="text-right">
'.moneyFormat($preventivo->totale, 2).'
@ -384,7 +385,13 @@ if (!$block_edit && sizeof($righe) > 0) {
<button type="button" class="btn btn-xs btn-default disabled" id="elimina_righe" onclick="rimuoviRiga(getSelectData());">
<i class="fa fa-trash"></i>
</button>
</button>';
if ($direzione == 'entrata') {
echo'
<button type="button" class="btn btn-xs btn-default disabled" id="confronta_righe" onclick="confrontaRighe(getSelectData());">
Confronta prezzi
</button>';
} echo'
</div>';
}
echo '
@ -418,6 +425,10 @@ function getSelectData() {
return data;
}
function confrontaRighe(id) {
openModal("'.tr('Confronta prezzi').'", "'.$module->fileurl('modals/confronta_righe.php').'?id_module=" + globals.id_module + "&id_record=" + globals.id_record + "&righe=" + id + "&id_anagrafica='.$ordine->idanagrafica.'&direzione='.$dir.'");
}
function rimuoviRiga(id) {
swal({
title: "'.tr('Rimuovere queste righe?').'",
@ -505,9 +516,11 @@ $(".check").on("change", function() {
if (checked) {
$("#elimina_righe").removeClass("disabled");
$("#duplica_righe").removeClass("disabled");
$("#confronta_righe").removeClass("disabled");
} else {
$("#elimina_righe").addClass("disabled");
$("#duplica_righe").addClass("disabled");
$("#confronta_righe").addClass("disabled");
}
});

View File

@ -0,0 +1,139 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace Modules\Preventivi\Import;
use Carbon\Carbon;
use Importer\CSVImporter;
use Modules\Anagrafiche\Anagrafica;
use Modules\Anagrafiche\Tipo as TipoAnagrafica;
use Modules\Articoli\Articolo as ArticoloOriginale;
use Modules\Preventivi\Components\Articolo;
use Modules\Preventivi\Preventivo;
use Modules\Preventivi\Stato;
use Modules\TipiIntervento\Tipo as TipoSessione;
/**
* Struttura per la gestione delle operazioni di importazione (da CSV) dei Preventivi.
*
* @since 2.4.44
*/
class CSV extends CSVImporter
{
public function getAvailableFields()
{
return [
[
'field' => 'numero',
'label' => 'Numero',
'primary_key' => true,
],
[
'field' => 'nome',
'label' => 'Nome preventivo',
],
[
'field' => 'descrizione',
'label' => 'Descrizione preventivo',
],
[
'field' => 'ragione_sociale',
'label' => 'Cliente',
],
[
'field' => 'idtipointervento',
'label' => 'Tipo attività',
],
[
'field' => 'data_bozza',
'label' => 'Data',
],
[
'field' => 'codice',
'label' => 'Codice articolo',
],
[
'field' => 'qta',
'label' => 'Quantità riga',
],
[
'field' => 'data_evasione',
'label' => 'Data prevista evasione riga',
],
[
'field' => 'prezzo_unitario',
'label' => 'Prezzo unitario riga',
],
];
}
public function import($record)
{
$database = database();
$primary_key = $this->getPrimaryKey();
$id_preventivo = $database->fetchOne('SELECT id FROM `co_preventivi` WHERE `numero`='.prepare($record['numero']))['id'];
$preventivo = Preventivo::find($id_preventivo);
if (empty($preventivo)) {
$anagrafica = Anagrafica::where('ragione_sociale', $record['ragione_sociale'])->first();
if (empty($anagrafica)) {
$anagrafica = Anagrafica::build($record['ragione_sociale']);
$tipo_cliente = TipoAnagrafica::where('descrizione', 'Cliente')->first();
$anagrafica->tipologie = [$tipo_cliente->id];
$anagrafica->save();
}
$tipo = TipoSessione::find($record['idtipointervento']) ?: TipoSessione::where('codice', 'GEN')->first();
$preventivo = Preventivo::build($anagrafica, $tipo, $record['nome'], new Carbon($record['data_bozza']), 0);
$preventivo->numero = $record['numero'];
$preventivo->idstato = Stato::where('descrizione', 'Bozza')->first()->id;
$preventivo->descrizione = $record['descrizione'];
$preventivo->save();
}
// Individuazione articolo
$articolo_orig = ArticoloOriginale::where('codice', $record['codice'])->first();
if (!empty($articolo_orig)) {
$articolo = Articolo::build($preventivo, $articolo_orig);
$articolo->descrizione = $articolo_orig->descrizione;
$articolo->um = $articolo_orig->um ?: null;
$articolo->data_evasione = new Carbon($record['data_evasione']) ?: null;
$idiva = $articolo_orig->idiva_vendita ?: ($anagrafica->idiva_vendite ?: setting('Iva predefinita'));
$articolo->setPrezzoUnitario($record['prezzo_unitario'], $idiva);
$articolo->qta = $record['qta'];
$articolo->save();
}
}
public static function getExample()
{
return [
['Numero', 'Nome Preventivo', 'Descrizione Preventivo', 'Cliente', 'Tipo Attività', 'Data', 'Codice Articolo', 'Quantità riga', 'Data prevista evasione riga', 'Prezzo unitario riga'],
['15', 'Preventivo Materiali', 'Preventivo iniziale', 'Rossi', 'Generico', '27/04/2023', '001', '2', '30/04/2023', '50'],
['15', 'Preventivo Materiali', 'Preventivo iniziale', 'Rossi', 'Generico', '27/04/2023', '043', '1', '10/05/2023', '100'],
];
}
}

View File

@ -107,6 +107,10 @@ class Preventivo extends Document
if (!empty($id_pagamento)) {
$model->idpagamento = $id_pagamento;
}
if (!empty($id_agente)) {
$model->idagente = $id_agente;
}
$model->condizioni_fornitura = setting('Condizioni generali di fornitura preventivi');
$model->id_segment = $id_segment;

View File

@ -70,16 +70,10 @@ switch (filter('op')) {
break;
case 'delete':
$righe = $dbo->fetchNum('SELECT idanagrafica FROM an_anagrafiche WHERE idrelazione='.prepare($id_record));
if (isset($id_record) && empty($righe)) {
$dbo->query('DELETE FROM `an_relazioni` WHERE `id`='.prepare($id_record));
flash()->info(tr('Relazione _NAME_ eliminata con successo!', [
'_NAME_' => $descrizione,
]));
} else {
flash()->error(tr('Sono presenti '.count($righe).' anagrafiche collegate a questa relazione.'));
}
$dbo->query('UPDATE `an_relazioni` SET deleted_at=NOW() WHERE `id`='.prepare($id_record));
flash()->info(tr('Relazione _NAME_ eliminata con successo!', [
'_NAME_' => $descrizione,
]));
break;
}

View File

@ -54,23 +54,18 @@ $righe = $dbo->fetchNum('SELECT idanagrafica FROM an_anagrafiche WHERE idrelazio
if (!empty($righe)) {
echo '
<div class="alert alert-danger">
<div class="alert alert-warning">
'.tr('Ci sono _NUM_ anagrafiche collegate', [
'_NUM_' => $righe,
]).'.
</div>';
} else {
?>
}
?>
<a class="btn btn-danger ask" data-backto="record-list">
<i class="fa fa-trash"></i> <?php echo tr('Elimina'); ?>
</a>
<?php
}
?>
<script>
$(document).ready( function() {
$('.colorpicker').colorpicker({ format: 'hex' }).on('changeColor', function() {

View File

@ -30,7 +30,7 @@ if (!empty($record['failed_at'])) {
echo '
<a class="btn btn-info ask" data-backto="record-edit" data-msg="'.tr("Inviare immediatamente l'email?").'" data-op="send" data-button="'.tr('Invia').'" data-class="btn btn-lg btn-info" >
<i class="fa fa-envelope"></i> '.tr('Invia immeditamente').'
<i class="fa fa-envelope"></i> '.tr('Invia immediatamente').'
</a>';
} elseif (!empty($record['sent_at'])) {
echo '

View File

@ -22,5 +22,5 @@ include_once __DIR__.'/../../core.php';
if (isset($id_record)) {
$record = $dbo->fetchOne('SELECT idanagrafica, ragione_sociale, colore FROM an_anagrafiche WHERE idanagrafica = '.prepare($id_record));
$tipi_interventi = $dbo->fetchArray('SELECT *, in_tipiintervento.idtipointervento AS id, in_tariffe.idtipointervento AS esiste FROM in_tipiintervento LEFT JOIN in_tariffe ON in_tipiintervento.idtipointervento = in_tariffe.idtipointervento AND in_tariffe.idtecnico = '.prepare($id_record).' ORDER BY descrizione');
$tipi_interventi = $dbo->fetchArray('SELECT *, in_tipiintervento.idtipointervento AS id, in_tariffe.idtipointervento AS esiste FROM in_tipiintervento LEFT JOIN in_tariffe ON in_tipiintervento.idtipointervento = in_tariffe.idtipointervento AND in_tariffe.idtecnico = '.prepare($id_record).' WHERE in_tipiintervento.deleted_at IS NULL ORDER BY descrizione');
}

View File

@ -99,40 +99,24 @@ switch (post('op')) {
break;
case 'delete':
// Permetto eliminazione tipo intervento solo se questo non è utilizzado da nessun'altra parte a gestionale
// UNION SELECT `in_tariffe`.`idtipointervento` FROM `in_tariffe` WHERE `in_tariffe`.`idtipointervento` = '.prepare($id_record).'
// UNION SELECT `co_contratti_tipiintervento`.`idtipointervento` FROM `co_contratti_tipiintervento` WHERE `co_contratti_tipiintervento`.`idtipointervento` = '.prepare($id_record).'
$elementi = $dbo->fetchArray('SELECT `in_interventi`.`idtipointervento` FROM `in_interventi` WHERE `in_interventi`.`idtipointervento` = '.prepare($id_record).'
UNION
SELECT `an_anagrafiche`.`idtipointervento_default` AS `idtipointervento` FROM `an_anagrafiche` WHERE `an_anagrafiche`.`idtipointervento_default` = '.prepare($id_record).'
UNION
SELECT `co_preventivi`.`idtipointervento` FROM `co_preventivi` WHERE `co_preventivi`.`idtipointervento` = '.prepare($id_record).'
UNION
SELECT `co_promemoria`.`idtipointervento` FROM `co_promemoria` WHERE `co_promemoria`.`idtipointervento` = '.prepare($id_record).'
UNION
SELECT `in_interventi_tecnici`.`idtipointervento` FROM `in_interventi_tecnici` WHERE `in_interventi_tecnici`.`idtipointervento` = '.prepare($id_record).'
ORDER BY `idtipointervento`');
// Elimino le tariffe collegate ai vari tecnici
$query = 'DELETE FROM in_tariffe WHERE idtipointervento='.prepare($id_record);
$dbo->query($query);
if (empty($elementi)) {
// Elimino anche le tariffe collegate ai vari tecnici
$query = 'DELETE FROM in_tariffe WHERE idtipointervento='.prepare($id_record);
$dbo->query($query);
// Elimino le tariffe collegate ai contratti
$query = 'DELETE FROM co_contratti_tipiintervento WHERE idtipointervento='.prepare($id_record);
$dbo->query($query);
// Elimino anche le tariffe collegate ai contratti
$query = 'DELETE FROM co_contratti_tipiintervento WHERE idtipointervento='.prepare($id_record);
$dbo->query($query);
$query = 'DELETE FROM in_fasceorarie_tipiintervento WHERE idtipointervento='.prepare($id_record);
$dbo->query($query);
$query = 'DELETE FROM in_fasceorarie_tipiintervento WHERE idtipointervento='.prepare($id_record);
$dbo->query($query);
$query = 'UPDATE `in_tipiintervento` SET deleted_at=NOW() WHERE idtipointervento='.prepare($id_record);
$dbo->query($query);
$query = 'DELETE FROM in_tipiintervento WHERE idtipointervento='.prepare($id_record);
$dbo->query($query);
flash()->info(tr('Tipo di intervento eliminato!'));
flash()->info(tr('Tipo di intervento eliminato!'));
break;
}
break;
// no break
case 'import':
$values = [
'costo_ore' => $record['costo_orario'],

View File

@ -137,7 +137,6 @@ SELECT `co_preventivi`.`idtipointervento`, id, numero, data_bozza AS data, "Prev
UNION
SELECT `co_promemoria`.`idtipointervento`, idcontratto AS id, numero, data_richiesta AS data, "Promemoria contratto" AS tipo_documento FROM `co_promemoria` LEFT JOIN co_contratti ON co_promemoria.idcontratto=co_contratti.id WHERE `co_promemoria`.`idtipointervento` = '.prepare($id_record).'
ORDER BY `idtipointervento`');
$class = '';
if (!empty($elementi)) {
echo '
@ -180,7 +179,6 @@ if (!empty($elementi)) {
echo '
<li>'.Modules::link($modulo, $id, $descrizione).'</li>';
}
$class = "disabled";
echo '
</ul>
@ -189,6 +187,6 @@ if (!empty($elementi)) {
}
echo '
<a class="btn btn-danger ask '.$class.'" data-backto="record-list">
<a class="btn btn-danger ask" data-backto="record-list">
<i class="fa fa-trash"></i> '.tr('Elimina').'
</a>';

View File

@ -12,7 +12,7 @@
"bootstrap-daterangepicker": "^2.1.25",
"bootstrap-maxlength": "^1.10.1",
"chart.js": "^3.8.0",
"ckeditor4": "ckeditor/ckeditor-releases#full/latest",
"ckeditor4": "ckeditor/ckeditor4-releases#full/latest",
"components-jqueryui": "^1.12.1",
"datatables.net-bs": "^1.10.15",
"datatables.net-buttons-bs": "^1.3.1",
@ -33,7 +33,7 @@
"moment": "^2.18.1",
"numeral": "^2.0.6",
"parsleyjs": "^2.7.2",
"pdf.js": "mozilla/pdf.js#gh-pages",
"pdf.js": "alekswebnet/pdfjs-viewer-element",
"pwstrength-bootstrap": "^3.0.4",
"select2": "^4.0.3",
"select2-bootstrap-theme": "^0.1.0-beta.10",
@ -72,7 +72,7 @@
"scripts": {
"gulp": "gulp",
"release-OSM": "yarn run develop-OSM && php composer.phar install --no-dev && gulp release",
"develop-OSM": "yarn install && yarn run install-OSM && yarn run assets-OSM",
"develop-OSM": "yarn install --ignore-engines && yarn run install-OSM && yarn run assets-OSM",
"install-OSM": "php composer.phar update",
"assets-OSM": "yarn upgrade && yarn run build-OSM",
"build-OSM": "gulp",

View File

@ -124,8 +124,12 @@ $(".checkbox").click(function(){
$.post("'.$checklist_module->fileurl('ajax.php').'", {
op: "save_checkbox",
id: $(this).attr("data-id"),
},function(result){
reload();
});
$(this).parent().parent().find(".text").css("text-decoration", "line-through");
parent = $(this).attr("data-id");
$("tr.sonof_"+parent).find("input[type=checkbox]").each(function(){
if(!$(this).is(":checked")){
@ -136,8 +140,12 @@ $(".checkbox").click(function(){
$.post("'.$checklist_module->fileurl('ajax.php').'", {
op: "remove_checkbox",
id: $(this).attr("data-id"),
},function(result){
reload();
});
$(this).parent().parent().find(".text").css("text-decoration", "none");
parent = $(this).attr("data-id");
$("tr.sonof_"+parent).find("input[type=checkbox]").each(function(){
if($(this).is(":checked")){
@ -162,6 +170,15 @@ function edit_check(id){
launch_modal("Modifica checklist", "'.$checklist_module->fileurl('components/edit-check.php').'?id_record="+id, 1);
}
function reload(){
$("#loading_'.$checks_id.'").removeClass("hide");
$("#loading_'.$checks_id.'").addClass("show");
$("#'.$checks_id.'").load(globals.rootdir + "/ajax.php?op=checklists&id_module='.$id_module.'&id_record='.$id_record.'&id_plugin='.$id_plugin.'", function() {
$("#loading_'.$checks_id.'").removeClass("show");
$("#loading_'.$checks_id.'").addClass("hide");
});
}
</script>';
?>

View File

@ -754,7 +754,7 @@ class Validator
'²' => '2',
'³' => '3',
'´' => ' ́',
'µ' => 'μ',
'µ' => 'u',
'¸' => ' ̧',
'¹' => '1',
'º' => 'o',
@ -1974,7 +1974,7 @@ class Validator
'㍿' => '株式会社',
'㎀' => 'pA',
'㎁' => 'nA',
'㎂' => 'μA',
'㎂' => 'uA',
'㎃' => 'mA',
'㎄' => 'kA',
'㎅' => 'KB',
@ -1984,8 +1984,8 @@ class Validator
'㎉' => 'kcal',
'㎊' => 'pF',
'㎋' => 'nF',
'㎌' => 'μF',
'㎍' => 'μg',
'㎌' => 'uF',
'㎍' => 'ug',
'㎎' => 'mg',
'㎏' => 'kg',
'㎐' => 'Hz',
@ -1993,13 +1993,13 @@ class Validator
'㎒' => 'MHz',
'㎓' => 'GHz',
'㎔' => 'THz',
'㎕' => 'μl',
'㎕' => 'ul',
'㎖' => 'ml',
'㎗' => 'dl',
'㎘' => 'kl',
'㎙' => 'fm',
'㎚' => 'nm',
'㎛' => 'μm',
'㎛' => 'um',
'㎜' => 'mm',
'㎝' => 'cm',
'㎞' => 'km',
@ -2022,17 +2022,17 @@ class Validator
'㎯' => 'rads2',
'㎰' => 'ps',
'㎱' => 'ns',
'㎲' => 'μs',
'㎲' => 'us',
'㎳' => 'ms',
'㎴' => 'pV',
'㎵' => 'nV',
'㎶' => 'μV',
'㎶' => 'uV',
'㎷' => 'mV',
'㎸' => 'kV',
'㎹' => 'MV',
'㎺' => 'pW',
'㎻' => 'nW',
'㎼' => 'μW',
'㎼' => 'uW',
'㎽' => 'mW',
'㎾' => 'kW',
'㎿' => 'MW',
@ -3846,7 +3846,7 @@ class Validator
'𝛊' => 'ι',
'𝛋' => 'κ',
'𝛌' => 'λ',
'𝛍' => 'μ',
'𝛍' => 'u',
'𝛎' => 'ν',
'𝛏' => 'ξ',
'𝛐' => 'ο',
@ -3904,7 +3904,7 @@ class Validator
'𝜄' => 'ι',
'𝜅' => 'κ',
'𝜆' => 'λ',
'𝜇' => 'μ',
'𝜇' => 'u',
'𝜈' => 'ν',
'𝜉' => 'ξ',
'𝜊' => 'ο',
@ -3962,7 +3962,7 @@ class Validator
'𝜾' => 'ι',
'𝜿' => 'κ',
'𝝀' => 'λ',
'𝝁' => 'μ',
'𝝁' => 'u',
'𝝂' => 'ν',
'𝝃' => 'ξ',
'𝝄' => 'ο',
@ -4020,7 +4020,7 @@ class Validator
'𝝸' => 'ι',
'𝝹' => 'κ',
'𝝺' => 'λ',
'𝝻' => 'μ',
'𝝻' => 'u',
'𝝼' => 'ν',
'𝝽' => 'ξ',
'𝝾' => 'ο',
@ -4078,7 +4078,7 @@ class Validator
'𝞲' => 'ι',
'𝞳' => 'κ',
'𝞴' => 'λ',
'𝞵' => 'μ',
'𝞵' => 'u',
'𝞶' => 'ν',
'𝞷' => 'ξ',
'𝞸' => 'ο',

View File

@ -524,15 +524,15 @@ switch (filter('op')) {
$match_documento_da_fe = false;
$query = "SELECT dt_righe_ddt.id, dt_righe_ddt.idddt AS id_documento, dt_righe_ddt.is_descrizione, dt_righe_ddt.idarticolo, dt_righe_ddt.is_sconto, 'ddt' AS ref,
CONCAT('DDT num. ', IF(numero_esterno != '', numero_esterno, numero), ' del ', DATE_FORMAT(data, '%d/%m/%Y'), ' [', (SELECT descrizione FROM dt_statiddt WHERE id = idstatoddt) , ']') AS opzione
FROM dt_righe_ddt
INNER JOIN dt_ddt ON dt_ddt.id = dt_righe_ddt.idddt
WHERE dt_ddt.idanagrafica = ".prepare($anagrafica->id)." AND |where_ddt| AND dt_righe_ddt.qta > dt_righe_ddt.qta_evasa
FROM dt_righe_ddt
INNER JOIN dt_ddt ON dt_ddt.id = dt_righe_ddt.idddt
WHERE dt_ddt.idanagrafica = ".prepare($anagrafica->id)." AND |where_ddt| AND dt_righe_ddt.qta > dt_righe_ddt.qta_evasa AND dt_ddt.idstatoddt IN (SELECT id FROM dt_statiddt WHERE descrizione != 'Fatturato') AND idtipoddt IN (SELECT id FROM dt_tipiddt WHERE dir='uscita')
UNION SELECT or_righe_ordini.id, or_righe_ordini.idordine AS id_documento, or_righe_ordini.is_descrizione, or_righe_ordini.idarticolo, or_righe_ordini.is_sconto, 'ordine' AS ref,
CONCAT('Ordine num. ', IF(numero_esterno != '', numero_esterno, numero), ' del ', DATE_FORMAT(data, '%d/%m/%Y'), ' [', (SELECT descrizione FROM or_statiordine WHERE id = idstatoordine) , ']') AS opzione
FROM or_righe_ordini
INNER JOIN or_ordini ON or_ordini.id = or_righe_ordini.idordine
WHERE or_ordini.idanagrafica = ".prepare($anagrafica->id).' AND |where_ordini| AND or_righe_ordini.qta > or_righe_ordini.qta_evasa';
UNION SELECT or_righe_ordini.id, or_righe_ordini.idordine AS id_documento, or_righe_ordini.is_descrizione, or_righe_ordini.idarticolo, or_righe_ordini.is_sconto, 'ordine' AS ref,
CONCAT('Ordine num. ', IF(numero_esterno != '', numero_esterno, numero), ' del ', DATE_FORMAT(data, '%d/%m/%Y'), ' [', (SELECT descrizione FROM or_statiordine WHERE id = idstatoordine) , ']') AS opzione
FROM or_righe_ordini
INNER JOIN or_ordini ON or_ordini.id = or_righe_ordini.idordine
WHERE or_ordini.idanagrafica = ".prepare($anagrafica->id)." AND |where_ordini| AND or_righe_ordini.qta > or_righe_ordini.qta_evasa AND or_ordini.idstatoordine IN (SELECT id FROM or_statiordine WHERE descrizione != 'Fatturato') AND idtipoordine IN (SELECT id FROM or_tipiordine WHERE dir ='uscita')";
// Ricerca di righe DDT/Ordine con stesso Articolo
if (!empty($id_articolo)) {

View File

@ -20,6 +20,7 @@
include_once __DIR__.'/../../core.php';
use Plugins\ImportFE\Interaction;
use Carbon\Carbon;
$list = Interaction::getInvoiceList();
@ -93,7 +94,7 @@ if (!empty($list)) {
</td>
<td>'.$element['sender'].'</td>
<td>'.dateFormat($element['date_sent']).'</td>
<td class="text-center">'.dateFormat(new Carbon($element['date_sent'])).'</td>
<td class="text-right">'.moneyFormat($element['amount']).'</td>
<td class="text-center">

View File

@ -237,15 +237,25 @@ class FatturaOrdinaria extends FatturaElettronica
// Nel caso il prezzo sia negativo viene gestito attraverso l'inversione della quantità (come per le note di credito)
// TODO: per migliorare la visualizzazione, sarebbe da lasciare negativo il prezzo e invertire gli sconti.
$prezzo = $totale_righe > 0 ? $riga['PrezzoUnitario'] : -$riga['PrezzoUnitario'];
$qta = $riga['Quantita'] ?: 1;
if (!empty($articolo->um) && !empty($articolo->fattore_um_secondaria) && $riga['UnitaMisura'] == $articolo->um_secondaria) {
$qta = (($riga['Quantita'] ?: 1) / $articolo->fattore_um_secondaria);
$prezzo = $totale_righe > 0 ? $totale_righe/$qta : -($totale_righe/$qta);
} else {
$qta = ($riga['Quantita'] ?: 1);
$prezzo = $totale_righe > 0 ? $riga['PrezzoUnitario'] : -$riga['PrezzoUnitario'];
}
// Prezzo e quantità
$obj->prezzo_unitario = $prezzo;
$obj->qta = $qta;
if (!empty($riga['UnitaMisura'])) {
$obj->um = $riga['UnitaMisura'];
if (!empty($articolo->um) && !empty($articolo->fattore_um_secondaria) && $riga['UnitaMisura'] == $articolo->um_secondaria) {
$obj->um = $articolo->um;
} else {
$obj->um = $riga['UnitaMisura'];
}
}
// Sconti e maggiorazioni

View File

@ -75,7 +75,9 @@ switch (filter('op')) {
// Rimozione dei prezzi cancellati
$registrati = filter('dettaglio');
if (!empty($registrati)) {
$dettagli = $dettagli->whereNotIn('id', $registrati)->delete();
$dettagli->whereNotIn('id', $registrati)->delete();
} else {
$dettagli->delete();
}
// Aggiornamento e creazione dei prezzi registrati

View File

@ -48,8 +48,7 @@ switch (filter('op')) {
// Generazione della descrizione del pagamento
if ($scadenze_documento->count() > 1) {
$descrizione .= tr('_DOC_, pagamento _NUM_/_TOT_', [
'_DOC_' => $descrizione,
$descrizione .= tr(', pagamento _NUM_/_TOT_', [
'_NUM_' => $pos + 1,
'_TOT_' => $scadenze_documento->count(),
]);

View File

@ -49,8 +49,8 @@ echo '
<div class="row">
<div class="col-md-12 text-right">
<button type="button" class="btn btn-primary '.(!empty($banca_azienda) ? '' : 'disabled').'" onclick="esporta(this)">
<i class="fa fa-download"></i> '.tr('Esporta').'
<button type="button" class="btn btn-primary '.(!empty($banca_azienda) ? '' : 'disabled'). '" onclick="esporta(this)">
<i class="fa fa-arrow-right"></i> '.tr('Continua').'...
</button>
</div>
</div>

View File

@ -275,38 +275,50 @@ class Gestore
$descrizione .= ' CUP:'.$controparte['cup'];
}
// Salvataggio della singola ricevuta nel RiBa
$ricevuta = new Ricevuta();
$ricevuta->numero_ricevuta = $identifier;
$ricevuta->scadenza = $data_scadenza;
$ricevuta->importo = $totale;
$ricevuta->abi_banca = $abi_cliente;
$ricevuta->cab_banca = $cab_cliente;
$ricevuta->iban = $banca_controparte['iban'];
$ricevuta->codice_cliente = $controparte['codice'];
$ricevuta->ctgypurp = $ctgypurp;
//controlli sulla ragione sociale
$ragione_sociale = utf8_decode($controparte['ragione_sociale']);
// Unifico ricevute per anagrafica
$identificativo_debitore = !empty($controparte->partita_iva) ? $controparte->partita_iva : $controparte->codice_fiscale;
$ricevute = $this->bonifico->getRicevute();
foreach ($ricevute as $ric) {
if ($ric->identificativo_debitore == $identificativo_debitore) {
$ricevuta = $ric;
}
}
// Sostituzione di alcuni simboli noti
$replaces = [
'&#039;' => "'",
'&quot;' => "'",
'&amp;' => '&',
];
$ragione_sociale = str_replace(array_keys($replaces), array_values($replaces), $ragione_sociale);
$ricevuta->nome_debitore = strtoupper($ragione_sociale);
$ricevuta->identificativo_debitore = !empty($controparte->partita_iva) ? $controparte->partita_iva : $controparte->codice_fiscale;
$ricevuta->indirizzo_debitore = strtoupper($controparte['indirizzo']);
$ricevuta->cap_debitore = $controparte['cap'];
$ricevuta->comune_debitore = strtoupper($controparte['citta']);
$ricevuta->provincia_debitore = $controparte['provincia'];
$ricevuta->descrizione_banca = $descrizione_banca;
$ricevuta->descrizione = strtoupper($descrizione);
$this->bonifico->addRicevuta($ricevuta);
if (empty($ricevuta)) {
$ricevuta = new Ricevuta();
$ricevuta->numero_ricevuta = $identifier;
$ricevuta->scadenza = $data_scadenza;
$ricevuta->importo = $totale;
$ricevuta->abi_banca = $abi_cliente;
$ricevuta->cab_banca = $cab_cliente;
$ricevuta->iban = $banca_controparte['iban'];
$ricevuta->codice_cliente = $controparte['codice'];
$ricevuta->ctgypurp = $ctgypurp;
//controlli sulla ragione sociale
$ragione_sociale = utf8_decode($controparte['ragione_sociale']);
// Sostituzione di alcuni simboli noti
$replaces = [
'&#039;' => "'",
'&quot;' => "'",
];
$ragione_sociale = str_replace(array_keys($replaces), array_values($replaces), $ragione_sociale);
$ricevuta->nome_debitore = strtoupper($ragione_sociale);
$ricevuta->identificativo_debitore = $identificativo_debitore;
$ricevuta->indirizzo_debitore = strtoupper($controparte['indirizzo']);
$ricevuta->cap_debitore = $controparte['cap'];
$ricevuta->comune_debitore = strtoupper($controparte['citta']);
$ricevuta->provincia_debitore = $controparte['provincia'];
$ricevuta->descrizione_banca = $descrizione_banca;
$ricevuta->descrizione = strtoupper($descrizione);
$this->bonifico->addRicevuta($ricevuta);
} else {
$ricevuta->importo += $totale;
$ricevuta->descrizione .= ' - '.strtoupper($descrizione);
}
return true;
}

View File

@ -877,10 +877,19 @@
Identificativo fiscale ai fini IVA:
<span>
<xsl:value-of select="IdFiscaleIVA/IdPaese" />
<xsl:value-of select="IdFiscaleIVA/IdCodice" />
<xsl:choose>
<xsl:when test="string(number(substring(IdFiscaleIVA/IdCodice,1,2)))='NaN'">
<xsl:if test="IdFiscaleIVA/IdPaese = 'FR' or (substring(IdFiscaleIVA/IdCodice,1,2)='GD') or (substring(IdFiscaleIVA/IdCodice,1,2)='HA')">
<xsl:value-of select="IdFiscaleIVA/IdPaese" />
</xsl:if>
<xsl:value-of select="IdFiscaleIVA/IdCodice" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="IdFiscaleIVA/IdPaese" />
<xsl:value-of select="IdFiscaleIVA/IdCodice" />
</xsl:otherwise>
</xsl:choose>
</span>
</xsl:if>
</div>
@ -1135,10 +1144,20 @@
<xsl:if test="IdFiscaleIVA">
Identificativo fiscale ai fini IVA:
<span>
<xsl:value-of select="IdFiscaleIVA/IdPaese" />
<xsl:value-of select="IdFiscaleIVA/IdCodice" />
</span>
<span>
<xsl:choose>
<xsl:when test="string(number(substring(IdFiscaleIVA/IdCodice,1,2)))='NaN'">
<xsl:if test="IdFiscaleIVA/IdPaese = 'FR' or (substring(IdFiscaleIVA/IdCodice,1,2)='GD') or (substring(IdFiscaleIVA/IdCodice,1,2)='HA')">
<xsl:value-of select="IdFiscaleIVA/IdPaese" />
</xsl:if>
<xsl:value-of select="IdFiscaleIVA/IdCodice" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="IdFiscaleIVA/IdPaese" />
<xsl:value-of select="IdFiscaleIVA/IdCodice" />
</xsl:otherwise>
</xsl:choose>
</span>
</xsl:if>
</div>
@ -1360,10 +1379,20 @@
<xsl:if test="IdFiscaleIVA">
Identificativo fiscale ai fini IVA:
<span>
<xsl:value-of select="IdFiscaleIVA/IdPaese" />
<xsl:value-of select="IdFiscaleIVA/IdCodice" />
</span>
<span>
<xsl:choose>
<xsl:when test="string(number(substring(IdFiscaleIVA/IdCodice,1,2)))='NaN'">
<xsl:if test="IdFiscaleIVA/IdPaese = 'FR' or (substring(IdFiscaleIVA/IdCodice,1,2)='GD') or (substring(IdFiscaleIVA/IdCodice,1,2)='HA')">
<xsl:value-of select="IdFiscaleIVA/IdPaese" />
</xsl:if>
<xsl:value-of select="IdFiscaleIVA/IdCodice" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="IdFiscaleIVA/IdPaese" />
<xsl:value-of select="IdFiscaleIVA/IdCodice" />
</xsl:otherwise>
</xsl:choose>
</span>
</xsl:if>
</div>
@ -1455,8 +1484,18 @@
Identificativo fiscale ai fini IVA:
<span>
<xsl:value-of select="IdFiscaleIVA/IdPaese" />
<xsl:value-of select="IdFiscaleIVA/IdCodice" />
<xsl:choose>
<xsl:when test="string(number(substring(IdFiscaleIVA/IdCodice,1,2)))='NaN'">
<xsl:if test="IdFiscaleIVA/IdPaese = 'FR' or (substring(IdFiscaleIVA/IdCodice,1,2)='GD') or (substring(IdFiscaleIVA/IdCodice,1,2)='HA')">
<xsl:value-of select="IdFiscaleIVA/IdPaese" />
</xsl:if>
<xsl:value-of select="IdFiscaleIVA/IdCodice" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="IdFiscaleIVA/IdPaese" />
<xsl:value-of select="IdFiscaleIVA/IdCodice" />
</xsl:otherwise>
</xsl:choose>
</span>
</xsl:if>
@ -1602,8 +1641,18 @@
Identificativo fiscale ai fini IVA:
<span>
<xsl:value-of select="IdFiscaleIVA/IdPaese" />
<xsl:value-of select="IdFiscaleIVA/IdCodice" />
<xsl:choose>
<xsl:when test="string(number(substring(IdFiscaleIVA/IdCodice,1,2)))='NaN'">
<xsl:if test="IdFiscaleIVA/IdPaese = 'FR' or (substring(IdFiscaleIVA/IdCodice,1,2)='GD') or (substring(IdFiscaleIVA/IdCodice,1,2)='HA')">
<xsl:value-of select="IdFiscaleIVA/IdPaese" />
</xsl:if>
<xsl:value-of select="IdFiscaleIVA/IdCodice" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="IdFiscaleIVA/IdPaese" />
<xsl:value-of select="IdFiscaleIVA/IdCodice" />
</xsl:otherwise>
</xsl:choose>
</span>
</xsl:if>

View File

@ -98,26 +98,59 @@ class Interventi extends AppResource
// Informazioni sull'utente
$id_tecnico = Auth::user()->id_anagrafica;
if (setting('Visualizza solo promemoria assegnati') == 1) {
$query = 'SELECT
in_interventi.id,
in_interventi.updated_at
FROM in_interventi WHERE
deleted_at IS NULL AND (
$query = '
SELECT
in_interventi.id,
in_interventi.updated_at
FROM
in_interventi
WHERE
deleted_at IS NULL AND (
in_interventi.id IN (
SELECT idintervento FROM in_interventi_tecnici
WHERE in_interventi_tecnici.idintervento = in_interventi.id
AND in_interventi_tecnici.orario_fine BETWEEN :period_start AND :period_end
AND in_interventi_tecnici.idtecnico = :id_tecnico
AND in_interventi_tecnici.idtecnico = :id_tecnico_q1
)
OR (
in_interventi.id NOT IN (
SELECT idintervento FROM in_interventi_tecnici
)
AND in_interventi.idstatointervento IN (SELECT idstatointervento FROM in_statiintervento WHERE is_completato = 0)
AND in_interventi.idstatointervento IN (SELECT idstatointervento FROM in_statiintervento WHERE is_completato = 0 AND in_interventi.id IN (
SELECT id_intervento FROM in_interventi_tecnici_assegnati WHERE in_interventi_tecnici_assegnati.id_tecnico = :id_tecnico_q2)
)
)
)';
} else {
$query = '
SELECT
in_interventi.id,
in_interventi.updated_at
FROM
in_interventi
WHERE
deleted_at IS NULL AND (
in_interventi.id IN (
SELECT idintervento FROM in_interventi_tecnici
WHERE in_interventi_tecnici.idintervento = in_interventi.id
AND in_interventi_tecnici.orario_fine BETWEEN :period_start AND :period_end
AND in_interventi_tecnici.idtecnico = :id_tecnico_q1
)
OR (
in_interventi.id NOT IN (
SELECT idintervento FROM in_interventi_tecnici
)
AND in_interventi.idstatointervento IN (SELECT idstatointervento FROM in_statiintervento WHERE is_completato = 0)
)
)';
}
// Filtro per data
// Gestione di tecnici assegnati o impianti modificati
// Possibile problematica: in caso di rimozione di un tecnico assegnato o impianto collegato, la modifica non viene rilevata
@ -131,13 +164,23 @@ class Interventi extends AppResource
)';
}
$records = database()->fetchArray($query, [
':period_start' => $start,
':period_end' => $end,
':id_tecnico' => $id_tecnico,
]);
if (setting('Visualizza solo promemoria assegnati') == 1) {
$records = database()->fetchArray($query, [
':period_start' => $start,
':period_end' => $end,
':id_tecnico_q1' => $id_tecnico,
':id_tecnico_q2' => $id_tecnico,
]);
} else {
$records = database()->fetchArray($query, [
':period_start' => $start,
':period_end' => $end,
':id_tecnico_q1' => $id_tecnico,
]);
}
return $this->mapModifiedRecords($records);
}
public function retrieveRecord($id)

View File

@ -177,7 +177,7 @@ class FileManager implements ManagerInterface
if (!$options['readonly']) {
$result .= '
<button type="button" class="btn btn-xs btn-warning" onclick="modificaAllegato(this,$(this).closest(\'tr\').data(\'id\'))">
<button type="button" class="btn btn-xs btn-warning" onclick="modificaAllegato(this,[$(this).closest(\'tr\').data(\'id\')])">
<i class="fa fa-edit"></i>
</button>';
if (!$file->isFatturaElettronica() || $options['abilita_genera']) {
@ -214,12 +214,12 @@ class FileManager implements ManagerInterface
</button>';
if (!$options['readonly']) {
$result .= '
<button type="button" class="btn btn-xs btn-default disabled" id="modifica_files" onclick="modificaAllegato(this,0,JSON.stringify(getSelectData()));">
<button type="button" class="btn btn-xs btn-default disabled" id="modifica_files" onclick="modificaAllegato(this,JSON.stringify(getSelectFiles()));">
<i class="fa fa-edit"></i>
</button>';
}
$result .= '
<button type="button" class="btn btn-xs btn-default disabled" id="zip_files" onclick="scaricaZipAllegati(this,JSON.stringify(getSelectData()));">
<button type="button" class="btn btn-xs btn-default disabled" id="zip_files" onclick="scaricaZipAllegati(this,JSON.stringify(getSelectFiles()));">
<i class="fa fa-file-archive-o"></i>
</button>
</div>';
@ -292,10 +292,10 @@ $("#'.$attachment_id.' #upload").click(function(){
});
// Estraggo le righe spuntate
function getSelectData() {
function getSelectFiles() {
let data=new Array();
$(\'.files\').find(\'.check_files:checked\').each(function (){
data.push($(this).closest(\'tr\').data(\'id\'));
$(".files").find(".check_files:checked").each(function (){
data.push($(this).closest("tr").data("id"));
});
return data;

View File

@ -201,25 +201,28 @@ class Query
$equal = string_starts_with($real_value, '=');
$notequal = string_starts_with($real_value, '!=');
if ($minus || $more || $equal || $notequal) {
if ($minus || $more) {
$sign = string_contains($real_value, '=') ? '=' : '';
if ($more) {
$sign = '>'.$sign;
} elseif ($minus) {
$sign = '<'.$sign;
} elseif ($equal) {
$sign = '=';
} else {
$sign = '!=';
}
$value = trim(str_replace(['&lt;', '=', '&gt;', '!'], '', $value));
$value = trim(str_replace(['&lt;', '&gt;'], '', $value));
if ($more || $minus) {
$search_filters[] = 'CAST('.$search_query.' AS UNSIGNED) '.$sign.' '.prepare($value);
} else {
$search_filters[] = $search_query.' '.$sign.' '.prepare($value);
}
} else if ($equal){
$value = trim(str_replace(['='], '', $value));
$search_filters[] = ($search_query.' = '.prepare($value). ' OR '.$search_query.' LIKE '.prepare('% '.$value) . ' OR '.$search_query.' LIKE '.prepare($value.' %').' OR '.$search_query.' LIKE '.prepare('% '.$value.' %'));
} else if ($notequal) {
$value = trim(str_replace(['!='], '', $value));
$search_filters[] = ($search_query.' != '.prepare($value). ' AND '.$search_query.' NOT LIKE '.prepare('% '.$value) . ' AND '.$search_query.' NOT LIKE '.prepare($value.' %').' AND '.$search_query.' NOT LIKE '.prepare('% '.$value.' %'));
} else {
$search_filters[] = $search_query.' LIKE '.prepare('%'.$value.'%');
}

View File

@ -44,7 +44,10 @@ $totale_iva_periodo_precedente = $totale_iva_vendite_periodo_precedente - $total
$totale_iva = $totale_iva_esigibile - $totale_iva_detraibile;
if ($periodo['valore'] == 'Trimestrale' && $totale_iva > 0) {
if ($periodo['valore'] == 'Trimestrale' && $totale_iva > 25.82) {
if ($totale_iva_periodo_precedente < 25.82 && $totale_iva_periodo_precedente > 0) {
$totale_iva += $totale_iva_periodo_precedente;
}
$maggiorazione = $totale_iva * 0.01;
$totale_iva_maggiorata = $totale_iva + $maggiorazione;
}
@ -256,10 +259,6 @@ echo '
<td>TOTALE IVA OGGETTIVAMENTE INDETRAIBILI SU ACQUISTI</td>
<td class=text-right>'.moneyFormat($totale_iva_nondetraibile, 2).'</td>
</tr>
<tr>
<td>TOTALE IVA DETRAIBILI</td>
<td class=text-right>'.moneyFormat($totale_iva_detraibile, 2).'</td>
</tr>
<tr>
<td>VARIAZIONE DI IMPOSTA RELATIVE A PERIODI PRECEDENTI</td>';
if ($totale_iva_periodo_precedente < 25.82 && $totale_iva_periodo_precedente > 0) {
@ -301,7 +300,7 @@ echo '
</tr>
<tr>
<td>IVA A DEBITO CON MAGGIORAZIONE</td>';
if ($totale_iva > '25.82' && $periodo['valore'] == 'Trimestrale') {
if ($totale_iva > 25.82 && $periodo['valore'] == 'Trimestrale') {
echo'
<td class=text-right>'.moneyFormat($totale_iva_maggiorata, 2).'</td>';
} else {
@ -313,8 +312,13 @@ echo '
<tr>
<td>IMPORTO DA VERSARE</td>';
if ($totale_iva > 25.82) {
echo'
<td class=text-right>'.($periodo['valore'] == 'Mensile' ? moneyFormat($totale_iva, 2) : moneyFormat($totale_iva_maggiorata, 2)).'</td>';
if ($periodo['valore'] == 'Mensile') {
echo'
<td class=text-right>'.moneyFormat($totale_iva, 2).'</td>';
} else {
echo'
<td class=text-right>'.moneyFormat($totale_iva_maggiorata, 2).'</td>';
}
} else {
echo'
<td class=text-right></td>';

View File

@ -346,7 +346,7 @@ $iva_acquisti_nondetraibile = $dbo->fetchArray('
co_iva.codice_natura_fe AS cod_iva,
co_iva.percentuale AS aliquota,
co_iva.descrizione AS descrizione,
SUM((subtotale-sconto+co_righe_documenti.rivalsainps) *percentuale/100 *(100-indetraibile)/100 *(IF(co_tipidocumento.reversed = 0, 1,-1 ))) AS iva,
SUM((subtotale-sconto+co_righe_documenti.rivalsainps) *percentuale/100 *indetraibile/100 *(IF(co_tipidocumento.reversed = 0, 1,-1 ))) AS iva,
SUM((co_righe_documenti.subtotale - co_righe_documenti.sconto + co_righe_documenti.rivalsainps) *(IF(co_tipidocumento.reversed = 0,1,-1))) AS subtotale
FROM
co_iva
@ -375,7 +375,7 @@ $iva_acquisti = $dbo->fetchArray('
GROUP BY
co_iva.id;');
$iva_acquisti_anno_precedente = $dbo->fetchArray('
$iva_acquisti_anno_precedente = $dbo->fetchArray('
SELECT
co_iva.codice_natura_fe AS cod_iva,
co_iva.percentuale AS aliquota,
@ -392,7 +392,7 @@ $iva_acquisti = $dbo->fetchArray('
GROUP BY
co_iva.id;');
$iva_acquisti_periodo_precedente = $dbo->fetchArray('
$iva_acquisti_periodo_precedente = $dbo->fetchArray('
SELECT
co_iva.codice_natura_fe AS cod_iva,
co_iva.percentuale AS aliquota,

View File

@ -190,7 +190,7 @@ foreach ($righe as $riga) {
echo '
<tr>
<td class="text-center" style="vertical-align: middle" width="25">
<td class="text-center" nowrap="nowrap" style="vertical-align: middle" width="25">
'.$num.'
</td>';

View File

@ -0,0 +1,32 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../core.php';
$totale_provvigioni = sum(array_column($records, 'provvigione'));
echo '
<tr>
<td colspan="4" class="text-right">
<b>'.tr('Totale provvigioni', [], ['upper' => true]).':</b>
</td>
<td class="text-center">'.moneyFormat($totale_provvigioni, 2).'</td>
</tr>
</tbody>
</table>';

View File

@ -0,0 +1,72 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../core.php';
$module = Modules::get('Fatture di vendita');
$id_module = $module['id'];
$module_query = '
SELECT
numero_esterno,
an_anagrafiche.ragione_sociale,
SUM(prezzo_unitario*qta) as \'Totale\',
provvigione_percentuale,
provvigione
FROM
`co_documenti`
LEFT JOIN `an_anagrafiche` ON `co_documenti`.`idanagrafica` = `an_anagrafiche`.`idanagrafica`
LEFT JOIN `co_tipidocumento` ON `co_documenti`.`idtipodocumento` = `co_tipidocumento`.`id`
LEFT JOIN (SELECT `iddocumento`, SUM(`subtotale` - `sconto`) AS `totale_imponibile`, SUM(`iva`) AS `iva` FROM `co_righe_documenti` GROUP BY `iddocumento`) AS righe ON `co_documenti`.`id` = `righe`.`iddocumento`
LEFT JOIN `co_statidocumento` ON `co_documenti`.`idstatodocumento` = `co_statidocumento`.`id`
LEFT JOIN an_anagrafiche as agenti ON agenti.idanagrafica = co_documenti.idagente
LEFT JOIN co_righe_documenti ON co_righe_documenti.iddocumento = co_documenti.id
WHERE
1=1 AND provvigione > 0
GROUP BY
co_documenti.id
HAVING
2=2
ORDER BY
`co_documenti`.`data` DESC';
if(!empty(get('date_start'))){
$module_query = str_replace('1=1', '1=1 AND DATE_FORMAT(`data`, "%Y%m%d") >= "'.date('Ymd', strtotime(get('date_start'))).'"', $module_query);
$date_start = get('date_start');
}
if(!empty(get('date_end'))){
$module_query = str_replace('1=1', '1=1 AND DATE_FORMAT(`data`, "%Y%m%d") <= "'.date('Ymd', strtotime(get('date_end'))).'"', $module_query);
$date_end = get('date_end');
}
$module_query = str_replace('1=1', '1=1 AND co_documenti.idstatodocumento IN (SELECT id FROM co_statidocumento WHERE descrizione = "Pagato")', $module_query);
if(get('is_emessa')=='true' && get('is_parz_pagata')=='true'){
$module_query = str_replace('1=1 AND co_documenti.idstatodocumento IN (SELECT id FROM co_statidocumento WHERE descrizione = "Pagato")', '1=1 AND co_documenti.idstatodocumento IN (SELECT id FROM co_statidocumento WHERE descrizione = "Pagato" OR descrizione = "Emessa" OR descrizione = "Parzialmente pagato")', $module_query);
} else if(get('is_emessa')=='true'){
$module_query = str_replace('1=1 AND co_documenti.idstatodocumento IN (SELECT id FROM co_statidocumento WHERE descrizione = "Pagato")', '1=1 AND co_documenti.idstatodocumento IN (SELECT id FROM co_statidocumento WHERE descrizione = "Pagato" OR descrizione = "Emessa")', $module_query);
} else if(get('is_parz_pagata')=='true'){
$module_query = str_replace('1=1 AND co_documenti.idstatodocumento IN (SELECT id FROM co_statidocumento WHERE descrizione = "Pagato")', '1=1 AND co_documenti.idstatodocumento IN (SELECT id FROM co_statidocumento WHERE descrizione = "Pagato" OR descrizione = "Parzialmente pagato")', $module_query);
}
$module_query = str_replace('1=1', '1=1 AND co_documenti.idagente='.prepare($id_record), $module_query);
$records = $dbo->fetchArray($module_query);

View File

@ -0,0 +1,29 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../core.php';
echo '
<tr>
<td> Fattura n. '.$record['numero_esterno'].'</td>
<td>'.$record['ragione_sociale'].'</td>
<td class="text-center">'.moneyFormat($record['Totale'], 2).'</td>
<td class="text-center">'.numberFormat($record['provvigione_percentuale'], 0).' % </td>
<td class="text-center">'.moneyFormat($record['provvigione'], 2).'</td>
</tr>';

View File

@ -0,0 +1,27 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
$format = (isset($_SESSION['stampe_contabili']['format'])) ? $_SESSION['stampe_contabili']['format'] : 'A4';
$orientation = (isset($_SESSION['stampe_contabili']['orientation'])) ? $_SESSION['stampe_contabili']['orientation'] : 'L';
return [
'format' => $format,
'orientation' => $orientation,
'font-size' => '11pt',
];

View File

@ -0,0 +1,71 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../core.php';
use Modules\Anagrafiche\Anagrafica;
$agente = Anagrafica::where([
['idanagrafica', '=', $id_record],
])->first();
if(get('is_parz_pagata')=='true'){
$text[] = "'Parzialmente pagato'";
}
if(get('is_emessa')=='true'){
$text[] = "'Emessa'";
}
echo '
<h4><b>'.tr('Liquidazione provvigioni agente _ANAG_', [
'_ANAG_' => $agente->ragione_sociale,
], ['upper' => true]).'</b></h4>';
if(!empty($date_start) AND !empty($date_end)) {
echo '
<h4><b>'.tr('Provvigioni dal _START_ al _END_', [
'_START_' => Translator::dateToLocale($date_start),
'_END_' => Translator::dateToLocale($date_end),
], ['upper' => true]).'</b>
</h4>';
}else{
echo '
<h5><b>'.tr('Provvigioni').'</b>
</h5>';
}
echo '
<p style="color:#aaa; font-size:10px;" class="text-right">
'.tr("_TEXT_",
[
"_TEXT_" => (empty($text) ? 'Solo fatture con stato \'Pagato\'' : 'Include fatture con stato \'Pagato\', '.implode(', ', $text)),
]).'
</p>
<table class="table table-striped table-bordered" id="contents">
<thead>
<tr>
<th width="20%">'.tr('Documento', [], ['upper' => true]).'</th>
<th width="50%">'.tr('Anagrafica', [], ['upper' => true]).'</th>
<th width="10%" class="text-center">'.tr('Importo', [], ['upper' => true]).'</th>
<th width="10%" class="text-center">'.tr('Percentuale', [], ['upper' => true]).'</th>
<th width="10%" class="text-center">'.tr('Provvigione', [], ['upper' => true]).'</th>
</tr>
</thead>
<tbody>';

View File

@ -29,31 +29,31 @@ $total = Util\Query::readQuery($module);
// Lettura parametri modulo
$module_query = $total['query'];
if(!empty(get('date_start'))){
if (!empty(get('date_start'))) {
$module_query = str_replace('1=1', '1=1 AND DATE_FORMAT(`scadenza`, "%Y%m%d") >= "'.date('Ymd', strtotime(get('date_start'))).'"', $module_query);
$date_start = get('date_start');
}
if(!empty(get('date_end'))){
if (!empty(get('date_end'))) {
$module_query = str_replace('1=1', '1=1 AND DATE_FORMAT(`scadenza`, "%Y%m%d") <= "'.date('Ymd', strtotime(get('date_end'))).'"', $module_query);
$date_end = get('date_end');
}
if(get('is_pagata')=='false'){
if (get('is_pagata')=='false') {
$module_query = str_replace('1=1', '1=1 AND ABS(`co_scadenziario`.`pagato`) < ABS(`co_scadenziario`.`da_pagare`) ', $module_query);
}
if(get('is_riba')=='true'){
if (get('is_riba')=='true') {
$module_query = str_replace('1=1', '1=1 AND co_pagamenti.codice_modalita_pagamento_fe="MP12"', $module_query);
}
if(get('is_cliente')=='true'){
if (get('is_cliente')=='true') {
$module_query = str_replace('1=1', '1=1 AND co_tipidocumento.dir="entrata"', $module_query);
}
if(get('is_fornitore')=='true'){
if (get('is_fornitore')=='true') {
$module_query = str_replace('1=1', '1=1 AND co_tipidocumento.dir="uscita"', $module_query);
}

View File

@ -64,7 +64,7 @@ FROM
LEFT JOIN `co_statipreventivi` ON `co_preventivi`.`idstato` = `co_statipreventivi`.`id`
LEFT JOIN (SELECT `idpreventivo`, SUM(`subtotale` - `sconto`) AS `totale_imponibile`, SUM(`subtotale` - `sconto` + `iva`) AS `totale` FROM `co_righe_preventivi` GROUP BY `idpreventivo`) AS righe ON `co_preventivi`.`id` = `righe`.`idpreventivo`
LEFT JOIN (SELECT `an_anagrafiche`.`idanagrafica`, `an_anagrafiche`.`ragione_sociale` AS nome FROM `an_anagrafiche`)AS agente ON `agente`.`idanagrafica`=`co_preventivi`.`idagente`
LEFT JOIN (SELECT GROUP_CONCAT(DISTINCT `co_documenti`.`numero_esterno` SEPARATOR ', ') AS `info`, `co_righe_documenti`.`original_document_id` AS `idpreventivo` FROM `co_documenti` INNER JOIN `co_righe_documenti` ON `co_documenti`.`id` = `co_righe_documenti`.`iddocumento` WHERE `original_document_type`='Modules\Preventivi\Preventivo' GROUP BY `idpreventivo`, `original_document_id`) AS `fattura` ON `fattura`.`idpreventivo` = `co_preventivi`.`id`
LEFT JOIN (SELECT GROUP_CONCAT(DISTINCT `co_documenti`.`numero_esterno` SEPARATOR ', ') AS `info`, `co_righe_documenti`.`original_document_id` AS `idpreventivo` FROM `co_documenti` INNER JOIN `co_righe_documenti` ON `co_documenti`.`id` = `co_righe_documenti`.`iddocumento` WHERE `original_document_type`='Modules\\Preventivi\\Preventivo' GROUP BY `idpreventivo`, `original_document_id`) AS `fattura` ON `fattura`.`idpreventivo` = `co_preventivi`.`id`
WHERE
1=1 |segment(`co_preventivi`.`id_segment`)| |date_period(custom,'|period_start|' >= `data_bozza` AND '|period_start|' <= `data_conclusione`,'|period_end|' >= `data_bozza` AND '|period_end|' <= `data_conclusione`,`data_bozza` >= '|period_start|' AND `data_bozza` <= '|period_end|',`data_conclusione` >= '|period_start|' AND `data_conclusione` <= '|period_end|',`data_bozza` >= '|period_start|' AND `data_conclusione` = NULL)| AND `default_revision` = 1
GROUP BY
@ -163,7 +163,7 @@ FROM
LEFT JOIN (SELECT `idordine`, SUM(`qta` - `qta_evasa`) AS `qta_da_evadere`, SUM(`subtotale` - `sconto`) AS `totale_imponibile`, SUM(`subtotale` - `sconto` + `iva`) AS `totale` FROM `or_righe_ordini` GROUP BY `idordine`) AS righe ON `or_ordini`.`id` = `righe`.`idordine`
LEFT JOIN (SELECT `idordine`, MIN(`data_evasione`) AS `data_evasione` FROM `or_righe_ordini` WHERE (`qta` - `qta_evasa`)>0 GROUP BY `idordine`) AS `righe_da_evadere` ON `righe`.`idordine`=`righe_da_evadere`.`idordine`
LEFT JOIN `or_statiordine` ON `or_statiordine`.`id` = `or_ordini`.`idstatoordine`
LEFT JOIN (SELECT GROUP_CONCAT(DISTINCT `co_documenti`.`numero_esterno` SEPARATOR ', ') AS `info`, `co_righe_documenti`.`original_document_id` AS `idordine` FROM `co_documenti` INNER JOIN `co_righe_documenti` ON `co_documenti`.`id` = `co_righe_documenti`.`iddocumento` WHERE `original_document_type`='Modules\Ordini\Ordine' GROUP BY `idordine`, `original_document_id`) AS `fattura` ON `fattura`.`idordine` = `or_ordini`.`id`
LEFT JOIN (SELECT GROUP_CONCAT(DISTINCT `co_documenti`.`numero_esterno` SEPARATOR ', ') AS `info`, `co_righe_documenti`.`original_document_id` AS `idordine` FROM `co_documenti` INNER JOIN `co_righe_documenti` ON `co_documenti`.`id` = `co_righe_documenti`.`iddocumento` WHERE `original_document_type`='Modules\\Ordini\\Ordine' GROUP BY `idordine`, `original_document_id`) AS `fattura` ON `fattura`.`idordine` = `or_ordini`.`id`
LEFT JOIN (SELECT `zz_operations`.`id_email`, `zz_operations`.`id_record` FROM `zz_operations` INNER JOIN `em_emails` ON `zz_operations`.`id_email` = `em_emails`.`id` INNER JOIN `em_templates` ON `em_emails`.`id_template` = `em_templates`.`id` INNER JOIN `zz_modules` ON `zz_operations`.`id_module` = `zz_modules`.`id` WHERE `zz_modules`.`name` = 'Ordini cliente' AND `zz_operations`.`op` = 'send-email' GROUP BY `zz_operations`.`id_record`, `id_email`) AS `email` ON `email`.`id_record` = `or_ordini`.`id`
WHERE
1=1 |segment(`or_ordini`.`id_segment`)| AND `dir` = 'entrata' |date_period(`or_ordini`.`data`)|
@ -279,4 +279,13 @@ HAVING
-- Fix vista Stampe
UPDATE `zz_prints` SET `options` = '{\"pricing\": true, \"last-page-footer\": true, \"hide-codice\": true, \"images\": true}' WHERE `zz_prints`.`name` = "Ordine cliente (senza codici)";
UPDATE `zz_prints` SET `options` = '{\"pricing\":true, \"hide-total\":true, \"images\": true}' WHERE `zz_prints`.`name` = "Preventivo (senza totali)";
UPDATE `zz_prints` SET `options` = '{\"pricing\":false, \"show-only-total\":true, \"images\": true}' WHERE `zz_prints`.`name` = "Preventivo (solo totale)";
UPDATE `zz_prints` SET `options` = '{\"pricing\":false, \"show-only-total\":true, \"images\": true}' WHERE `zz_prints`.`name` = "Preventivo (solo totale)";
-- Aggiunto deleted_at in tipi intervento e relazioni
ALTER TABLE `in_tipiintervento` ADD `deleted_at` TIMESTAMP NULL AFTER `tempo_standard`;
ALTER TABLE `an_relazioni` ADD `deleted_at` TIMESTAMP NULL AFTER `is_bloccata`;
UPDATE `zz_modules` SET `options` = 'SELECT \r\n|select|\r\nFROM\r\n `an_anagrafiche`\r\nLEFT JOIN `an_relazioni` ON `an_anagrafiche`.`idrelazione` = `an_relazioni`.`id`\r\nLEFT JOIN `an_tipianagrafiche_anagrafiche` ON `an_tipianagrafiche_anagrafiche`.`idanagrafica` = `an_anagrafiche`.`idanagrafica`\r\nLEFT JOIN `an_tipianagrafiche` ON `an_tipianagrafiche`.`idtipoanagrafica` = `an_tipianagrafiche_anagrafiche`.`idtipoanagrafica`\r\nLEFT JOIN (SELECT `idanagrafica`, GROUP_CONCAT(nomesede SEPARATOR \', \') AS nomi FROM `an_sedi` GROUP BY idanagrafica) AS sedi ON `an_anagrafiche`.`idanagrafica`= `sedi`.`idanagrafica`\r\nLEFT JOIN (SELECT `idanagrafica`, GROUP_CONCAT(nome SEPARATOR \', \') AS nomi FROM `an_referenti` GROUP BY idanagrafica) AS referenti ON `an_anagrafiche`.`idanagrafica` =`referenti`.`idanagrafica`\r\nLEFT JOIN (SELECT `co_pagamenti`.`descrizione`AS nome, `co_pagamenti`.`id` FROM `co_pagamenti`)AS pagvendita ON IF(`an_anagrafiche`.`idpagamento_vendite`>0,`an_anagrafiche`.`idpagamento_vendite`= `pagvendita`.`id`,\'\')\r\nLEFT JOIN (SELECT `co_pagamenti`.`descrizione`AS nome, `co_pagamenti`.`id` FROM `co_pagamenti`)AS pagacquisto ON IF(`an_anagrafiche`.`idpagamento_acquisti`>0,`an_anagrafiche`.`idpagamento_acquisti`= `pagacquisto`.`id`,\'\')\r\nWHERE\r\n 1=1 AND `an_anagrafiche`.`deleted_at` IS NULL\r\nGROUP BY\r\n `an_anagrafiche`.`idanagrafica`, `pagvendita`.`nome`, `pagacquisto`.`nome`\r\nHAVING\r\n 2=2\r\nORDER BY\r\n TRIM(`ragione_sociale`)' WHERE `zz_modules`.`name` = 'Anagrafiche';
UPDATE `zz_modules` SET `options` = 'SELECT |select| FROM `in_tipiintervento` WHERE 1=1 AND deleted_at IS NULL HAVING 2=2' WHERE `zz_modules`.`name` = 'Tipi di intervento';
UPDATE `zz_modules` SET `options` = 'SELECT |select|\r\nFROM `an_relazioni`\r\nWHERE 1=1 AND deleted_at IS NULL\r\nHAVING 2=2\r\nORDER BY `an_relazioni`.`created_at` DESC' WHERE `zz_modules`.`name` = 'Relazioni';

136
update/2_4_45.sql Normal file
View File

@ -0,0 +1,136 @@
-- Aggiunto import Preventivi
INSERT INTO `zz_imports` (`id`, `id_module`, `name`, `class`, `created_at`) VALUES (NULL, (SELECT `id` FROM `zz_modules` WHERE `name`='Preventivi'), 'Preventivi', 'Modules\\Preventivi\\Import\\CSV', NULL);
-- Modifica nomi colonne Totali
UPDATE `zz_views` SET `name` = 'Totale documento' WHERE `name` = 'Totale ivato';
UPDATE `zz_views` SET `name` = 'Imponibile' WHERE `name` = 'Totale';
-- Fix query Preventivi
UPDATE `zz_modules` SET `options` = "
SELECT
|select|
FROM
`co_preventivi`
LEFT JOIN `an_anagrafiche` ON `co_preventivi`.`idanagrafica` = `an_anagrafiche`.`idanagrafica`
LEFT JOIN `co_statipreventivi` ON `co_preventivi`.`idstato` = `co_statipreventivi`.`id`
LEFT JOIN (SELECT `idpreventivo`, SUM(`subtotale` - `sconto`) AS `totale_imponibile`, SUM(`subtotale` - `sconto` + `iva`) AS `totale` FROM `co_righe_preventivi` GROUP BY `idpreventivo`) AS righe ON `co_preventivi`.`id` = `righe`.`idpreventivo`
LEFT JOIN (SELECT `an_anagrafiche`.`idanagrafica`, `an_anagrafiche`.`ragione_sociale` AS nome FROM `an_anagrafiche`)AS agente ON `agente`.`idanagrafica`=`co_preventivi`.`idagente`
LEFT JOIN (SELECT GROUP_CONCAT(DISTINCT `co_documenti`.`numero_esterno` SEPARATOR ', ') AS `info`, `co_righe_documenti`.`original_document_id` AS `idpreventivo` FROM `co_documenti` INNER JOIN `co_righe_documenti` ON `co_documenti`.`id` = `co_righe_documenti`.`iddocumento` WHERE `original_document_type`='Modules\\\\Preventivi\\\\Preventivo' GROUP BY `idpreventivo`, `original_document_id`) AS `fattura` ON `fattura`.`idpreventivo` = `co_preventivi`.`id`
WHERE
1=1 |segment(`co_preventivi`.`id_segment`)| |date_period(custom,'|period_start|' >= `data_bozza` AND '|period_start|' <= `data_conclusione`,'|period_end|' >= `data_bozza` AND '|period_end|' <= `data_conclusione`,`data_bozza` >= '|period_start|' AND `data_bozza` <= '|period_end|',`data_conclusione` >= '|period_start|' AND `data_conclusione` <= '|period_end|',`data_bozza` >= '|period_start|' AND `data_conclusione` = NULL)| AND `default_revision` = 1
GROUP BY
`co_preventivi`.`id`, `fattura`.`info`
HAVING
2=2
ORDER BY
`co_preventivi`.`id` DESC" WHERE `name` = 'Preventivi';
-- Fix query vista Attività
UPDATE `zz_modules` SET `options` = "
SELECT
|select|
FROM
`in_interventi`
LEFT JOIN `an_anagrafiche` ON `in_interventi`.`idanagrafica` = `an_anagrafiche`.`idanagrafica`
LEFT JOIN `in_interventi_tecnici` ON `in_interventi_tecnici`.`idintervento` = `in_interventi`.`id`
LEFT JOIN `in_interventi_tecnici_assegnati` ON `in_interventi_tecnici_assegnati`.`id_intervento` = `in_interventi`.`id`
LEFT JOIN (SELECT `idintervento`, SUM(`prezzo_unitario`*`qta`-`sconto`) AS `ricavo_righe`, SUM(`costo_unitario`*`qta`) AS `costo_righe` FROM `in_righe_interventi` GROUP BY `idintervento`) AS `righe` ON `righe`.`idintervento` = `in_interventi`.`id`
LEFT JOIN `in_statiintervento` ON `in_interventi`.`idstatointervento`=`in_statiintervento`.`idstatointervento`
LEFT JOIN `an_referenti` ON `in_interventi`.`idreferente` = `an_referenti`.`id`
LEFT JOIN (SELECT `an_sedi`.`id`, CONCAT(`an_sedi`.`nomesede`, '<br />',IF(`an_sedi`.`telefono`!='',CONCAT(`an_sedi`.`telefono`,'<br />'),''),IF(`an_sedi`.`cellulare`!='',CONCAT(`an_sedi`.`cellulare`,'<br />'),''),`an_sedi`.`citta`,IF(`an_sedi`.`indirizzo`!='',CONCAT(' - ',`an_sedi`.`indirizzo`),'')) AS `info` FROM `an_sedi`) AS `sede_destinazione` ON `sede_destinazione`.`id` = `in_interventi`.`idsede_destinazione`
LEFT JOIN (SELECT GROUP_CONCAT(DISTINCT `co_documenti`.`numero_esterno` SEPARATOR ', ') AS `info`, `co_righe_documenti`.`original_document_id` AS `idintervento` FROM `co_documenti` INNER JOIN `co_righe_documenti` ON `co_documenti`.`id` = `co_righe_documenti`.`iddocumento` WHERE `original_document_type` = 'Modules\\\\Interventi\\\\Intervento' GROUP BY `idintervento`, `original_document_id`) AS `fattura` ON `fattura`.`idintervento` = `in_interventi`.`id`
LEFT JOIN (SELECT `in_interventi_tecnici_assegnati`.`id_intervento`, GROUP_CONCAT( DISTINCT `ragione_sociale` SEPARATOR ', ') AS `nomi` FROM `an_anagrafiche` INNER JOIN `in_interventi_tecnici_assegnati` ON `in_interventi_tecnici_assegnati`.`id_tecnico` = `an_anagrafiche`.`idanagrafica` GROUP BY `id_intervento`) AS `tecnici_assegnati` ON `in_interventi`.`id` = `tecnici_assegnati`.`id_intervento`
LEFT JOIN (SELECT `in_interventi_tecnici`.`idintervento`, GROUP_CONCAT( DISTINCT `ragione_sociale` SEPARATOR ', ') AS `nomi` FROM `an_anagrafiche` INNER JOIN `in_interventi_tecnici` ON `in_interventi_tecnici`.`idtecnico` = `an_anagrafiche`.`idanagrafica` GROUP BY `idintervento`) AS `tecnici` ON `in_interventi`.`id` = `tecnici`.`idintervento`
LEFT JOIN (SELECT `zz_operations`.`id_email`, `zz_operations`.`id_record` FROM `zz_operations` INNER JOIN `em_emails` ON `zz_operations`.`id_email` = `em_emails`.`id` INNER JOIN `em_templates` ON `em_emails`.`id_template` = `em_templates`.`id` INNER JOIN `zz_modules` ON `zz_operations`.`id_module` = `zz_modules`.`id` WHERE `zz_modules`.`name` = 'Interventi' AND `zz_operations`.`op` = 'send-email' GROUP BY `zz_operations`.`id_record`, `id_email`) AS `email` ON `email`.`id_record`=`in_interventi`.`id`
LEFT JOIN (SELECT GROUP_CONCAT(CONCAT(`matricola`, IF(`nome` != '', CONCAT(' - ', `nome`), '')) SEPARATOR '<br />') AS `descrizione`, `my_impianti_interventi`.`idintervento` FROM `my_impianti` INNER JOIN `my_impianti_interventi` ON `my_impianti`.`id` = `my_impianti_interventi`.`idimpianto` GROUP BY `my_impianti_interventi`.`idintervento`) AS `impianti` ON `impianti`.`idintervento` = `in_interventi`.`id`
LEFT JOIN (SELECT `co_contratti`.`id`, CONCAT(`co_contratti`.`numero`, ' del ', DATE_FORMAT(`data_bozza`, '%d/%m/%Y')) AS `info` FROM `co_contratti`) AS `contratto` ON `contratto`.`id` = `in_interventi`.`id_contratto`
LEFT JOIN (SELECT `co_preventivi`.`id`, CONCAT(`co_preventivi`.`numero`, ' del ', DATE_FORMAT(`data_bozza`, '%d/%m/%Y')) AS `info` FROM `co_preventivi`) AS `preventivo` ON `preventivo`.`id` = `in_interventi`.`id_preventivo`
LEFT JOIN (SELECT `or_ordini`.`id`, CONCAT(`or_ordini`.`numero`, ' del ', DATE_FORMAT(`data`, '%d/%m/%Y')) AS `info` FROM `or_ordini`) AS `ordine` ON `ordine`.`id` = `in_interventi`.`id_ordine`
LEFT JOIN `in_tipiintervento` ON `in_interventi`.`idtipointervento` = `in_tipiintervento`.`idtipointervento`
WHERE
1=1 |segment(`in_interventi`.`id_segment`)| |date_period(`orario_inizio`,`data_richiesta`)|
GROUP BY
`in_interventi`.`id`
HAVING
2=2
ORDER BY
IFNULL(`orario_fine`, `data_richiesta`) DESC" WHERE `name` = 'Interventi';
-- Fix query Ordini cliente
UPDATE `zz_modules` SET `options` = "
SELECT
|select|
FROM
`or_ordini`
LEFT JOIN `or_tipiordine` ON `or_ordini`.`idtipoordine` = `or_tipiordine`.`id`
LEFT JOIN `an_anagrafiche` ON `or_ordini`.`idanagrafica` = `an_anagrafiche`.`idanagrafica`
LEFT JOIN (SELECT `idordine`, SUM(`qta` - `qta_evasa`) AS `qta_da_evadere`, SUM(`subtotale` - `sconto`) AS `totale_imponibile`, SUM(`subtotale` - `sconto` + `iva`) AS `totale` FROM `or_righe_ordini` GROUP BY `idordine`) AS righe ON `or_ordini`.`id` = `righe`.`idordine`
LEFT JOIN (SELECT `idordine`, MIN(`data_evasione`) AS `data_evasione` FROM `or_righe_ordini` WHERE (`qta` - `qta_evasa`)>0 GROUP BY `idordine`) AS `righe_da_evadere` ON `righe`.`idordine`=`righe_da_evadere`.`idordine`
LEFT JOIN `or_statiordine` ON `or_statiordine`.`id` = `or_ordini`.`idstatoordine`
LEFT JOIN (SELECT GROUP_CONCAT(DISTINCT `co_documenti`.`numero_esterno` SEPARATOR ', ') AS `info`, `co_righe_documenti`.`original_document_id` AS `idordine` FROM `co_documenti` INNER JOIN `co_righe_documenti` ON `co_documenti`.`id` = `co_righe_documenti`.`iddocumento` WHERE `original_document_type`='Modules\\\\Ordini\\\\Ordine' GROUP BY `idordine`, `original_document_id`) AS `fattura` ON `fattura`.`idordine` = `or_ordini`.`id`
LEFT JOIN (SELECT `zz_operations`.`id_email`, `zz_operations`.`id_record` FROM `zz_operations` INNER JOIN `em_emails` ON `zz_operations`.`id_email` = `em_emails`.`id` INNER JOIN `em_templates` ON `em_emails`.`id_template` = `em_templates`.`id` INNER JOIN `zz_modules` ON `zz_operations`.`id_module` = `zz_modules`.`id` WHERE `zz_modules`.`name` = 'Ordini cliente' AND `zz_operations`.`op` = 'send-email' GROUP BY `zz_operations`.`id_record`, `id_email`) AS `email` ON `email`.`id_record` = `or_ordini`.`id`
WHERE
1=1 |segment(`or_ordini`.`id_segment`)| AND `dir` = 'entrata' |date_period(`or_ordini`.`data`)|
HAVING
2=2
ORDER BY
`data` DESC,
CAST(`numero_esterno` AS UNSIGNED) DESC" WHERE `name` = 'Ordini cliente';
-- Fix query Ordini fornitore
UPDATE `zz_modules` SET `options` = "
SELECT
|select|
FROM
`or_ordini`
LEFT JOIN `or_tipiordine` ON `or_ordini`.`idtipoordine` = `or_tipiordine`.`id`
LEFT JOIN `an_anagrafiche` ON `or_ordini`.`idanagrafica` = `an_anagrafiche`.`idanagrafica`
LEFT JOIN (SELECT `idordine`, SUM(`qta` - `qta_evasa`) AS `qta_da_evadere`, SUM(`subtotale` - `sconto`) AS `totale_imponibile`, SUM(`subtotale` - `sconto` + `iva`) AS `totale` FROM `or_righe_ordini` GROUP BY `idordine`) AS righe ON `or_ordini`.`id` = `righe`.`idordine`
LEFT JOIN (SELECT `idordine`, MIN(`data_evasione`) AS `data_evasione` FROM `or_righe_ordini` WHERE (`qta` - `qta_evasa`)>0 GROUP BY `idordine`) AS `righe_da_evadere` ON `righe`.`idordine`=`righe_da_evadere`.`idordine`
LEFT JOIN `or_statiordine` ON `or_statiordine`.`id` = `or_ordini`.`idstatoordine`
LEFT JOIN (SELECT GROUP_CONCAT(DISTINCT co_documenti.numero_esterno SEPARATOR ', ') AS info, co_righe_documenti.original_document_id AS idordine FROM co_documenti INNER JOIN co_righe_documenti ON co_documenti.id = co_righe_documenti.iddocumento WHERE original_document_type='Modules\\\\Ordini\\\\Ordine' GROUP BY idordine, original_document_id) AS fattura ON fattura.idordine = or_ordini.id
LEFT JOIN (SELECT `zz_operations`.`id_email`, `zz_operations`.`id_record` FROM `zz_operations` INNER JOIN `em_emails` ON `zz_operations`.`id_email` = `em_emails`.`id` INNER JOIN `em_templates` ON `em_emails`.`id_template` = `em_templates`.`id` INNER JOIN `zz_modules` ON `zz_operations`.`id_module` = `zz_modules`.`id` WHERE `zz_modules`.`name` = 'Ordini fornitore' AND `zz_operations`.`op` = 'send-email' GROUP BY `zz_operations`.`id_record`, `id_email`) AS `email` ON `email`.`id_record` = `or_ordini`.`id`
WHERE
1=1 |segment(`or_ordini`.`id_segment`)| AND `dir` = 'uscita' |date_period(`or_ordini`.`data`)|
HAVING
2=2
ORDER BY
`data` DESC,
CAST(`numero_esterno` AS UNSIGNED) DESC" WHERE `name` = 'Ordini fornitore';
-- Aggiornamento data ultima sessione in rapportino intervento
UPDATE `em_templates` SET `body` = '<p>Gentile Cliente,</p>\n<p>inviamo in allegato il rapportino numero {numero} del {data fine intervento}.</p>\n<p>Distinti saluti</p>', `subject` = 'Invio rapportino numero {numero} del {data fine intervento}' WHERE `em_templates`.`name` = "Rapportino intervento";
-- Aggiunta stampa liquidazione provvigioni
INSERT INTO `zz_prints` (`id_module`, `is_record`, `name`, `title`, `filename`, `directory`, `previous`, `options`, `icon`, `version`, `compatibility`, `order`, `predefined`, `default`, `enabled`, `available_options`) VALUES
((SELECT id FROM zz_modules WHERE `name` = 'Anagrafiche'), 1, 'Provvigioni', 'Provvigioni', 'Provvigioni {ragione_sociale}', 'provvigione', 'idanagrafica', '', 'fa fa-print', '', '', 0, 0, 0, 1, NULL);
INSERT INTO `zz_settings` (`nome`, `valore`, `tipo`, `editable`, `sezione`, `order`, `help`) VALUES ( "Visualizza solo promemoria assegnati", '0', 'boolean', '1', 'Applicazione', '7', 'Se abilitata permetti ai tecnici la visualizzazione dei soli promemoria in cui risultano come assegnati');
-- Fix query Fatture di acquisto
UPDATE `zz_modules` SET `options` = "
SELECT
|select|
FROM
`co_documenti`
LEFT JOIN `an_anagrafiche` ON `co_documenti`.`idanagrafica` = `an_anagrafiche`.`idanagrafica`
LEFT JOIN `co_tipidocumento` ON `co_documenti`.`idtipodocumento` = `co_tipidocumento`.`id`
LEFT JOIN `co_statidocumento` ON `co_documenti`.`idstatodocumento` = `co_statidocumento`.`id`
LEFT JOIN `co_ritenuta_contributi` ON `co_documenti`.`id_ritenuta_contributi` = `co_ritenuta_contributi`.`id`
LEFT JOIN `co_pagamenti` ON `co_documenti`.`idpagamento` = `co_pagamenti`.`id`
LEFT JOIN (SELECT `co_banche`.`id`, CONCAT(`nome`, ' - ', `iban`) AS `descrizione` FROM `co_banche`) AS `banche` ON `banche`.`id` = `co_documenti`.`id_banca_azienda`
LEFT JOIN (SELECT `iddocumento`, GROUP_CONCAT(`co_pianodeiconti3`.`descrizione`) AS `descrizione` FROM `co_righe_documenti` INNER JOIN `co_pianodeiconti3` ON `co_pianodeiconti3`.`id` = `co_righe_documenti`.`idconto` GROUP BY iddocumento) AS `conti` ON `conti`.`iddocumento` = `co_documenti`.`id`
LEFT JOIN (SELECT `iddocumento`, SUM(`subtotale` - `sconto`) AS `totale_imponibile`, SUM(`iva`) AS `iva` FROM `co_righe_documenti` GROUP BY `iddocumento`) AS `righe` ON `co_documenti`.`id` = `righe`.`iddocumento`
LEFT JOIN (SELECT COUNT(`d`.`id`) AS `conteggio`, IF(`d`.`numero_esterno` = '', `d`.`numero`, `d`.`numero_esterno`) AS `numero_documento`, `d`.`idanagrafica` AS `anagrafica`, `id_segment` FROM `co_documenti` AS `d`
LEFT JOIN `co_tipidocumento` AS `d_tipo` ON `d`.`idtipodocumento` = `d_tipo`.`id` WHERE 1=1 AND `d_tipo`.`dir` = 'uscita' AND('|period_start|' <= `d`.`data` AND '|period_end|' >= `d`.`data` OR '|period_start|' <= `d`.`data_competenza` AND '|period_end|' >= `d`.`data_competenza`) GROUP BY `id_segment`, `numero_documento`, `d`.`idanagrafica`) AS `d` ON (`d`.`numero_documento` = IF(`co_documenti`.`numero_esterno` = '',`co_documenti`.`numero`,`co_documenti`.`numero_esterno`) AND `d`.`anagrafica` = `co_documenti`.`idanagrafica` AND `d`.`id_segment` = `co_documenti`.`id_segment`)
WHERE
1=1
AND
`dir` = 'uscita' |segment(`co_documenti`.`id_segment`)| |date_period(custom, '|period_start|' <= `co_documenti`.`data` AND '|period_end|' >= `co_documenti`.`data`, '|period_start|' <= `co_documenti`.`data_competenza` AND '|period_end|' >= `co_documenti`.`data_competenza` )|
GROUP BY
`co_documenti`.`id`, `d`.`conteggio`
HAVING
2=2
ORDER BY
`co_documenti`.`data` DESC,
CAST(IF(`co_documenti`.`numero` = '', `co_documenti`.`numero_esterno`, `co_documenti`.`numero`) AS UNSIGNED) DESC" WHERE `name` = 'Fatture di acquisto';