Compare commits
12 Commits
37dafc4eaa
...
a85830d7ff
Author | SHA1 | Date |
---|---|---|
|
a85830d7ff | |
|
5b76886dd6 | |
|
134093eaac | |
|
e1943eba93 | |
|
5245a52c33 | |
|
88a1703e1a | |
|
bfd6d33f69 | |
|
0575117b7a | |
|
d0ed5a2844 | |
|
a1b3be69fa | |
|
037fbdcee1 | |
|
ce518e32b1 |
68
CHANGELOG.md
68
CHANGELOG.md
|
@ -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.5.3 (2024-07-18)](#253-2024-07-18)
|
||||
- [2.5.2 (2024-05-31)](#252-2024-05-31)
|
||||
- [2.5.1 (2024-04-24)](#251-2024-04-24)
|
||||
- [2.5 (2024-03-28)](#25-2024-03-28)
|
||||
|
@ -68,6 +69,73 @@ Il formato utilizzato è basato sulle linee guida di [Keep a Changelog](http://k
|
|||
- [2.2 (2016-11-10)](#22-2016-11-10)
|
||||
- [2.1 (2015-04-02)](#21-2015-04-02)
|
||||
|
||||
## 2.5.3 (2024-07-18)
|
||||
### Aggiunto (Added)
|
||||
- Aggiunto il valore delle **Vendite al banco** sul grafico del Fatturato
|
||||
- Aggiunta legenda in **Articoli**
|
||||
- Aggiunta la possibilità di spostare il marcatore della mappa manualmente
|
||||
- Aggiunta plugin LeafletJS per mappe a schermo intero
|
||||
- Aggiunto riferimento articolo in Pianificazione fatturazione in **Contratti**
|
||||
- Aggiunta la gestione dell'invio automatico dei promemoria delle scadenze
|
||||
- Aggiunto avviso nel caso di scadenza durante il mese di chiusura aziendale
|
||||
- Aggiunta gestione caratteri speciali in fattura elettronica
|
||||
- Aggiunta impostazione per utilizzare codice come barcode
|
||||
|
||||
### Modificato (Changed)
|
||||
- Rimozione agenti secondari in **Anagrafiche**
|
||||
- Migliorati gli stili grafici
|
||||
- Ripristinata l'impostazione per limitare la visualizzazione degli **Impianti** a quelli gestiti dal tecnico da **App**
|
||||
- Migliorata la gestione dell'invio automatico di solleciti di pagamento
|
||||
- Spostata la gestione dei **Tag** in Strumenti
|
||||
- Replicato l'header anche sui plugin del modulo
|
||||
- Migliorato l'header delle **Attività**
|
||||
- Unificati i pulsanti su un'unica riga
|
||||
- Corretta la colorazione degli **Hooks**
|
||||
- Ottimizzata l'apertura del riquadro **Mappa**
|
||||
- Rimossi i file header.php non completati
|
||||
- Modificato l'avviso in plugin **Componenti**
|
||||
- Migliorata la tabella **Scadenzario**
|
||||
|
||||
### Fixed
|
||||
- Corretta la procedura di installazione dei moduli e plugins
|
||||
- Corretta l'esportazione delle scadenze con più banche
|
||||
- Corretta gestione dei plugin
|
||||
- Corretti i requisiti di installazione
|
||||
- Corretti i plugins **Statistiche di vendita**, **Listino fornitori**, **Pianificazione fatturazione contratti**, **Impianti del cliente**, **Statistiche anagrafiche**, **Allegati**,**Contratti del cliente**, **DDT del cliente**, **Listino clienti**, **Componenti**, **Dichiarazioni d'intento** e **Note**
|
||||
- Corretti i widgets **Promemoria attività da pianificare**, **Stampa calendario** e **Anagrafiche**
|
||||
- Corrette le informazioni per tipo di anagrafica
|
||||
- Corretto il controllo documento duplicato in **Fatture di vendita**
|
||||
- Corretti i link al modulo **Attività**
|
||||
- Corretto il salvataggio dell'immagine **Impianto**
|
||||
- Corretta la compressione dei JS
|
||||
- Corretto il click su **Dashboard** da mobile
|
||||
- Corretto il filtro nelle selezioni
|
||||
- Corretti i moduli **Liste**, **Template email**
|
||||
- Corretta la vista delle sottocategorie in **Articoli**
|
||||
- Corretta la sincronizzazione dei campi personalizzati e degli impianti in App
|
||||
- Corretta la creazione di **Attività** collegate ad Impianti
|
||||
- Corretti i campi personalizzati
|
||||
- Corretta l'importazione delle Note di credito
|
||||
- Corretto il controllo dei valori delle **Fatture di acquisto**
|
||||
- Corretta la gestione degli arrotondamenti in fase di importazione **Fattura di acquisto**
|
||||
- Corretta la gestione dei periodi multipli in **Statistiche**
|
||||
- Corretta la modifica delle **Fasce orarie**, **Scadenze** e **Causali movimento**
|
||||
- Corretto temporaneamente l'avviso del componente di videoscrittura
|
||||
- Corretta la verifica della connessione SMTP in **Account email**
|
||||
- Corretta l'eliminazione delle **Regole di pagamento**
|
||||
- Corretto il filtro per data e numero delle tabelle
|
||||
- Corretta la creazione di **Attributi** e **Combinazioni**
|
||||
- Corretta l'eliminazione **Articoli** da azioni di gruppo
|
||||
- Corretta la query di rinnovo contratto
|
||||
- Corretta l'eliminazione, esportazione, calcolo coordinate e aggiunta listino **Anagrafiche** da azioni di gruppo
|
||||
- Corretto il cambio stato degli **Ordini** da azioni di gruppo
|
||||
- Corretto il salvataggio e la visualizzazione delle note delle **Checklists**
|
||||
- Corretta la creazione preventivo da azioni di gruppo in **Articoli**
|
||||
- Corretta la pagina di login
|
||||
- Corrette le **Stampe contabili**, **Automezzi** e **Inventario**
|
||||
- Corretta la tipologia attività in modifica sessione
|
||||
- Corretto l'avviso di occupazione dei tecnici
|
||||
|
||||
## 2.5.2 (2024-05-31)
|
||||
### Aggiunto (Added)
|
||||
- Migrazione a tema grafico AdminLTE 3
|
||||
|
|
|
@ -618,7 +618,7 @@ if (Auth::check()) {
|
|||
|
||||
if (!empty($messages['warning']) || !empty($messages['error'])) {
|
||||
echo '
|
||||
<div class="card card-warning card-center">
|
||||
<div class="card card-warning card-center card-center-large">
|
||||
<div class="card-header with-border text-center">
|
||||
<h3 class="card-title">'.tr('Informazioni').'</h3>
|
||||
</div>
|
||||
|
|
|
@ -266,8 +266,12 @@ switch (post('op')) {
|
|||
|
||||
$new->codice = $codice;
|
||||
$new->qta = 0;
|
||||
$nome_immagine = $articolo->immagine;
|
||||
$new->immagine = $nome_immagine;
|
||||
$new->save();
|
||||
|
||||
$id_record = $new->id;
|
||||
|
||||
// Copia degli allegati
|
||||
$copia_allegati = post('copia_allegati');
|
||||
if (!empty($copia_allegati)) {
|
||||
|
@ -280,13 +284,6 @@ switch (post('op')) {
|
|||
}
|
||||
}
|
||||
|
||||
// Salvataggio immagine relativa
|
||||
$nome_immagine = $articolo->immagine_upload->getTranslation('title');
|
||||
$new->immagine = $new->uploads()->where('name', $nome_immagine)->first()->filename;
|
||||
$new->save();
|
||||
|
||||
$id_record = $new->id;
|
||||
|
||||
flash()->info(tr('Articolo duplicato correttamente!'));
|
||||
|
||||
break;
|
||||
|
|
|
@ -148,7 +148,7 @@ percentuale = 0;
|
|||
|
||||
$(document).ready(function () {
|
||||
var sub = $('#add-form').find('#subcategoria_add');
|
||||
var original = sub.parent().find(".input-group-addon button").attr("onclick");
|
||||
var original = sub.parent().find(".input-group-append button").attr("onclick");
|
||||
|
||||
$('#add-form').find('#categoria').change(function() {
|
||||
updateSelectOption("id_categoria", $(this).val());
|
||||
|
@ -157,11 +157,11 @@ $(document).ready(function () {
|
|||
sub.selectReset();
|
||||
|
||||
if($(this).val()){
|
||||
sub.parent().find(".input-group-addon button").removeClass("hide");
|
||||
sub.parent().find(".input-group-addon button").attr("onclick", original.replace('&ajax=yes', "&ajax=yes&id_original=" + $(this).val()));
|
||||
sub.parent().find(".input-group-append button").removeClass("hide");
|
||||
sub.parent().find(".input-group-append button").attr("onclick", original.replace('&ajax=yes', "&ajax=yes&id_original=" + $(this).val()));
|
||||
}
|
||||
else {
|
||||
sub.parent().find(".input-group-addon button").addClass("hide");
|
||||
sub.parent().find(".input-group-append button").addClass("hide");
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -19,12 +19,12 @@
|
|||
|
||||
include_once __DIR__.'/../../core.php';
|
||||
|
||||
echo '
|
||||
<button type="button" class="btn btn-primary" onclick="if( confirm(\'Confermando, tutte le checklist degli impianti di questa categoria verranno aggiornate. Continuare?\') ){ $(\'#check-impianto\').submit(); }"> <i class="fa fa-refresh"></i> '.tr('Sincronizza checklist impianti').'</button>';
|
||||
|
||||
// Sincronizza checklist impianti
|
||||
echo '
|
||||
<form action="" method="post" id="check-impianto">
|
||||
<input type="hidden" name="backto" value="record-edit">
|
||||
<input type="hidden" name="op" value="sync_checklist">
|
||||
</form>';
|
||||
</form>
|
||||
|
||||
<button type="button" class="btn btn-primary" onclick="if( confirm(\'Confermando, tutte le checklist degli impianti di questa categoria verranno aggiornate. Continuare?\') ){ $(\'#check-impianto\').submit(); }"> <i class="fa fa-refresh"></i> '.tr('Sincronizza checklist impianti').'</button>';
|
||||
|
||||
|
|
|
@ -33,10 +33,10 @@ switch (post('op')) {
|
|||
$fascia_oraria_new = FasciaOraria::where('id', '=', (new FasciaOraria())->getByField('title', $descrizione))->where('id', '!=', $id_record)->first();
|
||||
if (empty($fascia_oraria_new)) {
|
||||
if (!empty($is_predefined)) {
|
||||
$dbo->query('UPDATE `in_fasceorarie` SET `predefined` = 0');
|
||||
$dbo->query('UPDATE `in_fasceorarie` SET `is_predefined` = 0');
|
||||
}
|
||||
$fascia_oraria->setTranslation('title', $descrizione);
|
||||
$fascia_oraria->giorni = $giorni;
|
||||
$fascia_oraria->giorni = implode(',', $giorni);
|
||||
$fascia_oraria->ora_inizio = $ora_inizio;
|
||||
$fascia_oraria->ora_fine = $ora_fine;
|
||||
$fascia_oraria->include_bank_holidays = $include_bank_holidays;
|
||||
|
|
|
@ -71,7 +71,7 @@ $id_modulo_categorie_impianti = Module::where('name', 'Categorie impianti')->fir
|
|||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
var sub = $('#add-form').find('#sottocategoria_add');
|
||||
var original = sub.parent().find(".input-group-addon button").attr("onclick");
|
||||
var original = sub.parent().find(".input-group-append button").attr("onclick");
|
||||
|
||||
$('#add-form').find('#id_categoria').change(function() {
|
||||
updateSelectOption("id_categoria", $(this).val());
|
||||
|
@ -80,11 +80,11 @@ $(document).ready(function () {
|
|||
sub.selectReset();
|
||||
|
||||
if($(this).val()){
|
||||
sub.parent().find(".input-group-addon button").removeClass("hide");
|
||||
sub.parent().find(".input-group-addon button").attr("onclick", original.replace('&ajax=yes', "&ajax=yes&id_original=" + $(this).val()));
|
||||
sub.parent().find(".input-group-append button").removeClass("hide");
|
||||
sub.parent().find(".input-group-append button").attr("onclick", original.replace('&ajax=yes', "&ajax=yes&id_original=" + $(this).val()));
|
||||
}
|
||||
else {
|
||||
sub.parent().find(".input-group-addon button").addClass("hide");
|
||||
sub.parent().find(".input-group-append button").addClass("hide");
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -493,6 +493,10 @@ echo '
|
|||
$("#dettagli_cliente").html(data);
|
||||
});
|
||||
}
|
||||
|
||||
let data = anagrafica.getData();
|
||||
input("idcontratto").getElement()
|
||||
.selectSetNew(data.id_contratto, data.descrizione_contratto);
|
||||
|
||||
// Quando modifico orario inizio, allineo anche l\'orario fine
|
||||
let orario_inizio = input("orario_inizio").getElement();
|
||||
|
|
|
@ -239,7 +239,8 @@ switch (post('op')) {
|
|||
|
||||
// Calcolo del nuovo codice sulla base della data di richiesta
|
||||
$new->codice = Intervento::getNextCodice($data_richiesta, $new->id_segment);
|
||||
|
||||
$new->firma_file = '';
|
||||
$new->firma_data = '';
|
||||
$new->save();
|
||||
|
||||
$id_record = $new->id;
|
||||
|
@ -317,6 +318,7 @@ switch (post('op')) {
|
|||
|
||||
flash()->info(tr('Attività duplicate correttamente!'));
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case 'delete-bulk':
|
||||
|
|
|
@ -36,7 +36,7 @@ $button = '<i class="fa fa-edit"></i> '.tr('Modifica');
|
|||
$intervento = Intervento::find($id_record);
|
||||
|
||||
if (!empty($intervento->id_contratto)) {
|
||||
$query = 'SELECT `in_tipiintervento`.`id`, `title`, `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` LEFT JOIN `in_tipiintervento_lang` ON (`in_tipiintervento`.`id` = `in_tipiintervento_lang`.`id_record` AND `in_tipiintervento_lang`.`id_lang` = '.prepare(Models\Locale::getDefault()->id).') INNER JOIN `co_contratti_tipiintervento` ON `in_tipiintervento`.`id` = `co_contratti_tipiintervento`.`idtipointervento` WHERE `co_contratti_tipiintervento`.`idcontratto` = '.prepare($intervento->id_contratto).' AND `in_tipiintervento`.`deleted_at` IS NULL ORDER BY `title`';
|
||||
$query = 'SELECT `in_tipiintervento`.`id`, `title` as `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` LEFT JOIN `in_tipiintervento_lang` ON (`in_tipiintervento`.`id` = `in_tipiintervento_lang`.`id_record` AND `in_tipiintervento_lang`.`id_lang` = '.prepare(Models\Locale::getDefault()->id).') INNER JOIN `co_contratti_tipiintervento` ON `in_tipiintervento`.`id` = `co_contratti_tipiintervento`.`idtipointervento` WHERE `co_contratti_tipiintervento`.`idcontratto` = '.prepare($intervento->id_contratto).' AND `in_tipiintervento`.`deleted_at` IS NULL ORDER BY `title`';
|
||||
} else {
|
||||
$query = 'SELECT `in_tipiintervento`.`id`, `title` as `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` LEFT JOIN `in_tipiintervento_lang` ON (`in_tipiintervento`.`id` = `in_tipiintervento_lang`.`id_record` AND `in_tipiintervento_lang`.`id_lang` = '.prepare(Models\Locale::getDefault()->id).') INNER JOIN `in_tariffe` ON `in_tipiintervento`.`id` = `in_tariffe`.`idtipointervento` WHERE `in_tariffe`.`idtecnico` = '.prepare($sessione['idtecnico']).' AND `in_tipiintervento`.`deleted_at` IS NULL ORDER BY `title`';
|
||||
}
|
||||
|
|
|
@ -75,10 +75,10 @@ foreach ($tecnici as $id_tecnico => $ore) {
|
|||
|
||||
// Conflitti ristretti per orario
|
||||
foreach ($ore as $orario) {
|
||||
$query_conflitto = $query.' AND ((orario_inizio > '.prepare($orario['inizio']).' AND orario_inizio < '.prepare($orario['fine']).') OR
|
||||
(orario_fine > '.prepare($orario['inizio']).' AND orario_fine < '.prepare($orario['fine']).') OR
|
||||
(orario_inizio < '.prepare($orario['inizio']).' AND orario_fine > '.prepare($orario['inizio']).') OR
|
||||
(orario_inizio < '.prepare($orario['fine']).' AND orario_fine > '.prepare($orario['fine']).'))';
|
||||
$query_conflitto = $query.' AND ((orario_inizio >= '.prepare($orario['inizio']).' AND orario_inizio <= '.prepare($orario['fine']).') OR
|
||||
(orario_fine >= '.prepare($orario['inizio']).' AND orario_fine <= '.prepare($orario['fine']).') OR
|
||||
(orario_inizio <= '.prepare($orario['inizio']).' AND orario_fine >= '.prepare($orario['inizio']).') OR
|
||||
(orario_inizio <= '.prepare($orario['fine']).' AND orario_fine >= '.prepare($orario['fine']).'))';
|
||||
|
||||
$conflitto = $database->fetchArray($query_conflitto);
|
||||
if (!empty($conflitto)) {
|
||||
|
@ -96,44 +96,47 @@ if (empty($elenco_conflitti)) {
|
|||
}
|
||||
|
||||
echo '
|
||||
<div class="alert alert-warning">
|
||||
<p>'.tr('Sono presenti dei conflitti con le sessioni di lavoro di alcuni tecnici').'.</p>
|
||||
<div class="card card-danger">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">'.tr('⚠️ Sono presenti dei conflitti con le sessioni di lavoro di alcuni tecnici').'</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table table-condensed table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>'.tr('Tecnico').'</th>
|
||||
<th>'.tr('Attività').'</th>
|
||||
<th>'.tr('Orario di conflitto').'</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<table class="table table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>'.tr('Tecnico').'</th>
|
||||
<th>'.tr('Attività').'</th>
|
||||
<th>'.tr('Orario di conflitto').'</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>';
|
||||
<tbody>';
|
||||
|
||||
foreach ($elenco_conflitti as $id_tecnico => $elenco_conflitti_tecnico) {
|
||||
$anagrafica_tecnico = $database->fetchOne('SELECT ragione_sociale, deleted_at FROM an_anagrafiche WHERE idanagrafica = '.prepare($id_tecnico));
|
||||
|
||||
foreach ($elenco_conflitti_tecnico as $conflitto) {
|
||||
echo '
|
||||
<tr>
|
||||
<td>'.$anagrafica_tecnico['ragione_sociale'].' '.(!empty($anagrafica_tecnico['deleted_at']) ? '<small class="text-danger">('.tr('Eliminato').')' : '').'</td>
|
||||
<td></td>
|
||||
<td>'.timestampFormat($conflitto['inizio']).' - '.timestampFormat($conflitto['fine']).'</td>
|
||||
</tr>';
|
||||
<tr>
|
||||
<td>'.$anagrafica_tecnico['ragione_sociale'].' '.(!empty($anagrafica_tecnico['deleted_at']) ? '<small class="text-danger">('.tr('Eliminato').')' : '').'</td>
|
||||
<td>Attività corrente</td>
|
||||
<td>'.timestampFormat($conflitto['inizio']).' - '.timestampFormat($conflitto['fine']).'</td>
|
||||
</tr>';
|
||||
|
||||
foreach ($conflitto['conflitti'] as $conflitto_intervento) {
|
||||
$intervento = Intervento::find($conflitto_intervento['idintervento']);
|
||||
echo '
|
||||
<tr>
|
||||
<td>'.$anagrafica_tecnico['ragione_sociale'].' '.(!empty($anagrafica_tecnico['deleted_at']) ? '<small class="text-danger">('.tr('Eliminato').')' : '').'</td>
|
||||
<td>'.Modules::link('Interventi', $intervento->id, $intervento->getReference()).'</td>
|
||||
<td>'.timestampFormat($conflitto_intervento['orario_inizio']).' - '.timestampFormat($conflitto_intervento['orario_fine']).'</td>
|
||||
</tr>';
|
||||
<tr>
|
||||
<td>'.$anagrafica_tecnico['ragione_sociale'].' '.(!empty($anagrafica_tecnico['deleted_at']) ? '<small class="text-danger">('.tr('Eliminato').')' : '').'</td>
|
||||
<td>'.Modules::link('Interventi', $intervento->id, $intervento->getReference()).'</td>
|
||||
<td>'.timestampFormat($conflitto_intervento['orario_inizio']).' - '.timestampFormat($conflitto_intervento['orario_fine']).'</td>
|
||||
</tr>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo '
|
||||
</tbody>
|
||||
</table>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>';
|
||||
|
|
|
@ -60,7 +60,7 @@ foreach ($articoli as $elenco) {
|
|||
LEFT JOIN `or_statiordine_lang` ON (`or_statiordine`.`id` = `or_statiordine_lang`.`id_record` AND `or_statiordine_lang`.`id_lang` = '.prepare(Models\Locale::getDefault()->id).")
|
||||
INNER JOIN `or_tipiordine` ON `or_tipiordine`.`id` = `or_ordini`.`idtipoordine`
|
||||
WHERE
|
||||
`or_statiordine`.`title` = 'Bozza'
|
||||
`or_statiordine_lang`.`title` = 'Bozza'
|
||||
AND `dir` = 'entrata'
|
||||
AND `confermato` = 1
|
||||
AND `idarticolo`=".prepare($articolo->id).'
|
||||
|
|
|
@ -20,5 +20,5 @@
|
|||
include_once __DIR__.'/../../core.php';
|
||||
|
||||
if (!empty($id_record)) {
|
||||
$record = $dbo->fetchOne('SELECT *, `co_staticontratti`.`is_pianificabile` AS is_pianificabile FROM `co_contratti` INNER JOIN `co_stationtratti` ON `co_contratti`.`idstato` = `co_staticontratti`.`id` WHERE `co_contratti`.`id`='.prepare($id_record));
|
||||
$record = $dbo->fetchOne('SELECT *, `co_staticontratti`.`is_pianificabile` AS is_pianificabile FROM `co_contratti` INNER JOIN `co_staticontratti` ON `co_contratti`.`idstato` = `co_staticontratti`.`id` WHERE `co_contratti`.`id`='.prepare($id_record));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue