1
0
mirror of https://github.com/devcode-it/openstamanager.git synced 2025-02-17 03:51:06 +01:00
This commit is contained in:
MatteoPistorello 2023-01-11 18:04:33 +01:00
commit cd0b84d606
12 changed files with 196 additions and 19 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.39 (2023-01-13)](#2439-2023-01-13)
- [2.4.38 (2022-12-07)](#2438-2022-12-07)
- [2.4.37 (2022-11-02)](#2437-2022-11-04)
- [2.4.36 (2022-09-16)](#2436-2022-09-16)
@ -49,7 +50,30 @@ 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.4.39 (2023-01-13)
### Aggiunto (Added)
- Aggiunto controllo eliminazione metodo di pagamento
- Aggiunte nazioni
- Aggiunta visualizzazione mappa all'aggiunta attività
- Aggiunta possibilità di creare campi aggiuntivi con testo libero
- Aggiunta impostazione per nascondere i promemoria su app
- Aggiunta ID utente nei movimenti articolo
### Modificato (Changed)
- Miglioria gestione codice REA e provincia
- Miglioria stampa mastrino saldo iniziale
### Fixed
- Corretta query vista contratti
- Corretta stampa inventario in Articoli
- Corretta query vista fatture di vendita
- Corretta query vista utenti e permessi
- Corretta lunghezza campo codice REA
- Corretto il calcolo del guadagno in aggiunta riga
- Corretto ordinamento riga bollo in fattura
- Corretta vulnerabilità XSS
- Corretto set pattern segmento attività
- Corretta query vista giacenze sedi
- Corretta visualizzazione rate contrattuali da plugin per anno precedente
- Corretta selezione conti e IVA durante importazione Fattura elettronica di acquisto
## 2.4.38 (2022-12-07)
### Aggiunto (Added)
- Aggiunto tempDir per mpdf
@ -78,6 +102,7 @@ Il formato utilizzato è basato sulle linee guida di [Keep a Changelog](http://k
- Miglioria ricerca di corrispondenza tra anagrafiche in fase di impostazione dei permessi
- Sostituita funzione deprecata formatLocalized con isoFormat
- Rimozione codice non raggiungibile
- Ridotte restrizioni cookie per problemi con app esterne
### Fixed
- Corretta la selezione dei colori
- Corretta la visualizzazione delle colonne datatables
@ -105,6 +130,11 @@ Il formato utilizzato è basato sulle linee guida di [Keep a Changelog](http://k
- Corretta logica riapertura fattura pagata
- Corretta valorizzazione codice REA in fase di importazione fattura elettronica
- Corretta creazione fattura da azioni di gruppo in Attività se valorizzato 'Per conto di'
- Corrette note interne riga documento
- Corretto invio notifica chiusura intervento
- Corretta emissione fatture da azioni di gruppo
- Corretta generazione fatture con totale negativo
- Corretto controllo sort-buffer-size
## 2.4.37 (2022-11-04)
### Aggiunto (Added)
- Aggiunto modulo Mappa per geolocalizzare le attività

View File

@ -25,7 +25,42 @@ switch ($resource) {
case 'clienti':
$id_azienda = setting('Azienda predefinita');
$query = "SELECT an_anagrafiche.idanagrafica AS id, is_bloccata, CONCAT(ragione_sociale, IF(citta IS NULL OR citta = '', '', CONCAT(' (', citta, ')')), IF(an_anagrafiche.deleted_at IS NULL, '', ' (".tr('eliminata').")'), IF(is_bloccata = 1, CONCAT(' (', an_relazioni.descrizione, ')'), '') ) AS descrizione, idtipointervento_default AS idtipointervento, in_tipiintervento.descrizione AS idtipointervento_descrizione, an_anagrafiche.idzona, contratto.id AS id_contratto, contratto.descrizione AS descrizione_contratto, co_pagamenti.id AS id_pagamento, co_pagamenti.descrizione AS desc_pagamento, banca_vendite.id AS id_banca_vendite, CONCAT(banca_vendite.nome, ' - ', banca_vendite.iban) AS descrizione_banca_vendite 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 LEFT JOIN in_tipiintervento ON an_anagrafiche.idtipointervento_default=in_tipiintervento.idtipointervento LEFT JOIN an_relazioni ON an_anagrafiche.idrelazione=an_relazioni.id LEFT JOIN (SELECT co_contratti.id, idanagrafica, CONCAT('Contratto ', numero, ' del ', DATE_FORMAT(data_bozza, '%d/%m/%Y'), ' - ', co_contratti.nome, ' [', `co_staticontratti`.`descrizione` , ']') AS descrizione FROM co_contratti LEFT JOIN co_staticontratti ON co_contratti.idstato=co_staticontratti.id WHERE co_contratti.predefined=1 AND is_pianificabile=1) AS contratto ON an_anagrafiche.idanagrafica=contratto.idanagrafica LEFT JOIN co_pagamenti ON an_anagrafiche.idpagamento_vendite=co_pagamenti.id LEFT JOIN co_banche banca_vendite ON co_pagamenti.idconto_vendite = banca_vendite.id_pianodeiconti3 AND banca_vendite.id_anagrafica = ".prepare($id_azienda)." AND banca_vendite.deleted_at IS NULL AND banca_vendite.predefined = 1 |where| ORDER BY ragione_sociale";
$query = "SELECT
an_anagrafiche.idanagrafica AS id,
an_anagrafiche.lat,
an_anagrafiche.lng,
is_bloccata,
CONCAT(ragione_sociale, IF(citta IS NULL OR citta = '', '', CONCAT(' (', citta, ')')), IF(an_anagrafiche.deleted_at IS NULL, '', ' (".tr('eliminata').")'), IF(is_bloccata = 1, CONCAT(' (', an_relazioni.descrizione, ')'), '') ) AS descrizione,
idtipointervento_default AS idtipointervento,
in_tipiintervento.descrizione AS idtipointervento_descrizione,
an_anagrafiche.idzona,
contratto.id AS id_contratto,
contratto.descrizione AS descrizione_contratto,
co_pagamenti.id AS id_pagamento,
co_pagamenti.descrizione AS desc_pagamento,
banca_vendite.id AS id_banca_vendite,
CONCAT(banca_vendite.nome, ' - ', banca_vendite.iban) AS descrizione_banca_vendite
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 LEFT JOIN in_tipiintervento ON an_anagrafiche.idtipointervento_default=in_tipiintervento.idtipointervento
LEFT JOIN
an_relazioni
ON an_anagrafiche.idrelazione=an_relazioni.id
LEFT JOIN
(SELECT co_contratti.id, idanagrafica, CONCAT('Contratto ', numero, ' del ', DATE_FORMAT(data_bozza, '%d/%m/%Y'), ' - ', co_contratti.nome, ' [', `co_staticontratti`.`descrizione` , ']') AS descrizione FROM co_contratti LEFT JOIN co_staticontratti ON co_contratti.idstato=co_staticontratti.id WHERE co_contratti.predefined=1 AND is_pianificabile=1) AS contratto
ON an_anagrafiche.idanagrafica=contratto.idanagrafica
LEFT JOIN
co_pagamenti
ON an_anagrafiche.idpagamento_vendite=co_pagamenti.id
LEFT JOIN
co_banche banca_vendite
ON co_pagamenti.idconto_vendite = banca_vendite.id_pianodeiconti3 AND banca_vendite.id_anagrafica = ".prepare($id_azienda)." AND banca_vendite.deleted_at IS NULL AND banca_vendite.predefined = 1
|where|
ORDER BY
ragione_sociale";
foreach ($elements as $element) {
$filter[] = 'an_anagrafiche.idanagrafica='.prepare($element);
@ -267,7 +302,24 @@ switch ($resource) {
*/
case 'sedi':
if (isset($superselect['idanagrafica'])) {
$query = "SELECT * FROM (SELECT '0' AS id, (SELECT idzona FROM an_anagrafiche |where|) AS idzona, CONCAT_WS(' - ', \"".tr('Sede legale')."\" , (SELECT CONCAT (citta, IF(indirizzo!='',CONCAT(' (', indirizzo, ')'), ''), ' (',ragione_sociale,')') FROM an_anagrafiche |where|)) AS descrizione UNION SELECT id, idzona, CONCAT_WS(' - ', nomesede, CONCAT(citta, IF(indirizzo!='',CONCAT(' (', indirizzo, ')'), '')) ) FROM an_sedi |where|) AS tab HAVING descrizione LIKE ".prepare('%'.$search.'%').' ORDER BY descrizione';
$query = "
SELECT
*
FROM
(SELECT '0' AS id, (SELECT lat FROM an_anagrafiche |where|) AS lat, (SELECT lng FROM an_anagrafiche |where|) AS lng, (SELECT idzona FROM an_anagrafiche |where|) AS idzona, CONCAT_WS(' - ', \"".tr('Sede legale')."\" , (SELECT CONCAT (citta, IF(indirizzo!='',CONCAT(' (', indirizzo, ')'), ''), ' (',ragione_sociale,')') FROM an_anagrafiche |where|)) AS descrizione
UNION
SELECT
id,
lat,
lng,
idzona,
CONCAT_WS(' - ', nomesede, CONCAT(citta, IF(indirizzo!='',CONCAT(' (', indirizzo, ')'), '')) ) FROM an_sedi |where|) AS tab
HAVING
descrizione LIKE ".prepare('%'.$search.'%').'
ORDER BY
descrizione';
foreach ($elements as $element) {
$filter[] = 'id='.prepare($element);

View File

@ -143,9 +143,12 @@ if (!empty($movimenti)) {
</td>';
// Data
$utente = $dbo->table('zz_users')->where('id',$movimento->idutente)->first();
$data = ($movimento->data ? $movimento->data : $movimento->data_movimento);
echo '
<td class="text-center">'.dateFormat($movimento->data).' <span class="tip" title="'.tr('Creazione movimento: _DATE_', [
<td class="text-center">'.dateFormat($data).' <span class="tip" title="'.tr('Creazione movimento: _DATE_ <br>Creatore movimento: _USER_', [
'_DATE_' => timestampFormat($movimento->data_movimento),
'_USER_' => $utente->username,
]).'"><i class="fa fa-question-circle-o"></i></span> </td>';
// Operazioni

View File

@ -103,6 +103,8 @@ class Articolo extends Model
return false;
}
global $user;
// Movimento il magazzino solo se l'articolo non è un servizio
if (empty($this->servizio)) {
// Registrazione della movimentazione
@ -112,6 +114,7 @@ class Articolo extends Model
'movimento' => $descrizone,
'data' => $data,
'manuale' => $manuale,
'idutente' => $user->id,
]));
}
$id = database()->lastInsertedID();
@ -307,7 +310,7 @@ class Articolo extends Model
{
$movimenti = $this->movimenti()
->selectRaw('*, mg_movimenti.created_at AS data_movimento, SUM(mg_movimenti.qta) as qta_documento, IFNULL(mg_movimenti.reference_type, mg_movimenti.id) as tipo_gruppo')
->groupBy(['tipo_gruppo', 'mg_movimenti.reference_id']);
->groupBy(['tipo_gruppo', 'mg_movimenti.reference_id', 'mg_movimenti.idutente']);
if (!empty($mostra_vuoti)) {
return $movimenti;

View File

@ -155,7 +155,7 @@ class IBAN
'IE' => [
'length' => 22,
'pattern' => '4c 14n',
'structure' => 'IEkk aaaa bbbb bbcc cccc cc',
'structure' => 'IEkk ssss bbbb bbcc cccc cc',
],
'IL' => [
'length' => 23,

View File

@ -29,7 +29,7 @@ switch (post('op')) {
'id_plugin' => $plugin,
'name' => post('name'),
'html_name' => post('html_name'),
'content' => post('content'),
'content' => $_POST['content'],
'on_add' => post('on_add'),
'top' => post('top'),
], ['id' => $id_record]);
@ -46,7 +46,7 @@ switch (post('op')) {
'id_module' => $module,
'id_plugin' => $plugin,
'name' => post('name'),
'content' => post('content'),
'content' => $_POST['content'],
'html_name' => secure_random_string(8),
]);
$id_record = $dbo->lastInsertedID();

View File

@ -218,6 +218,30 @@ echo '
</div>
</div>';
$api_key = setting('Google Maps API key');
$map_load_message = tr('Clicca per visualizzare');
if (!empty($api_key)) {
echo '
<!-- POSIZIONE -->
<div class="box box-info collapsable collapsed-box">
<div class="box-header with-border">
<h3 class="box-title">'.tr('Posizione').'</h3>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse" onclick="autoload_mappa=true; caricaMappa(current_lat, current_lng);">
<i class="fa fa-plus"></i>
</button>
</div>
</div>
<div class="box-body">
<div id="map-edit" style="height: 300px;width: 100%;display: flex;align-items: center;justify-content: center;"></div>
</div>
</div>';
}
$espandi_dettagli = setting('Espandi automaticamente la sezione "Dettagli aggiuntivi"');
echo '
<!-- DATI AGGIUNTIVI -->
@ -443,6 +467,7 @@ echo '
var ordine = input("idordine");
var referente = input("idreferente");
var cliente_finale = input("idclientefinale");
var autoload_mappa = false;
$(document).ready(function() {
if(!anagrafica.get()){
@ -531,6 +556,8 @@ echo '
input("idcontratto").getElement()
.selectSetNew(data.id_contratto, data.descrizione_contratto);
}
caricaMappa(data.lat, data.lng);
}
if (data !== undefined) {
@ -574,6 +601,8 @@ echo '
if (data) {
input("idzona").set(data.idzona ? data.idzona : "");
// session_set("superselect,idzona", $(this).selectData().idzona, 0);
caricaMappa(data.lat, data.lng);
}
});
@ -727,4 +756,54 @@ echo '
$("#data_fine_ricorrenza").attr("required", false);
}
});
var marker = null;
var position = null;
var map = null;
var current_lat = null;
var current_lng = null;
function caricaMappa(lat, lng) {
current_lat = lat;
current_lng = lng;
if (!autoload_mappa){
return false;
}
const map_div = $("#map-edit");
if (input("idanagrafica").getData("select-options")) {
if (map === null) {
if (lat || lng) {
$.getScript("//maps.googleapis.com/maps/api/js?libraries=places&key='.$api_key.'", function() {
const map_element = map_div[0];
position = new google.maps.LatLng(lat, lng);
// Create a Google Maps native view under the map_canvas div.
map = new google.maps.Map(map_element, {
zoom: 14,
scrollwheel: false,
mapTypeControl: true,
mapTypeId: "roadmap",
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU,
mapTypeIds: ["roadmap", "terrain"],
}
});
map.setCenter(position);
marker = new google.maps.Marker({
position: position,
map: map,
});
});
}
} else {
position = new google.maps.LatLng(lat, lng);
marker.setPosition(position);
map.setCenter(position);
}
}
}
</script>';

View File

@ -566,8 +566,8 @@ if (!empty($righe)) {
echo '
<script>
function copia() {
let aliquote = $("select[name^=iva");
let conti = $("select[name^=conto");
let aliquote = $("select[name^=iva]");
let conti = $("select[name^=conto]");
// Individuazione della prima IVA selezionata
let iva_selezionata = null;
@ -642,7 +642,7 @@ input("flag_crea_articoli").on("change", function (){
}
});
$("select[name^=selezione_riferimento").change(function() {
$("select[name^=selezione_riferimento]").change(function() {
if (!$(this).hasClass("already-loaded")) {
let $this = $(this);
let data = $this.selectData();
@ -823,7 +823,7 @@ $("[id^=\'articoli\']").change(function() {
});
function copy_rif() {
let rif_vendite = $("select[name^=selezione_riferimento_vendita");
let rif_vendite = $("select[name^=selezione_riferimento_vendita]");
// Individuazione della prima IVA selezionata
let iva_selezionata = null;

View File

@ -76,8 +76,8 @@ echo
<div class="col-md-2 col-md-offset-9">
<select class="form-control select-input openstamanager-input superselect select-year">';
for ($i=intval(date('Y')); $i<=intval(date('Y')) + 10; $i++) {
$selectType = ($i == date('m'))? "selected" : "";
for ($i=intval(date('Y')) -1; $i<=intval(date('Y')) + 10; $i++) {
$selectType = ($i == date('Y'))? "selected" : "";
echo
'<option value="' . $i . '" ' . $selectType . '>' . $i . '</option>';
}

View File

@ -129,7 +129,7 @@ echo '
<script>
function copy() {
let conti = $("select[name^=idconto");
let conti = $("select[name^=idconto]");
// Individuazione del primo conto selezionato
let conto_selezionato = null;

View File

@ -42,6 +42,10 @@ $query = Query::getQuery($structure, $where, 0, []);
$query = Modules::replaceAdditionals($id_module, $query);
// Modifiche alla query principale
$query = preg_replace('/FROM[\s\t\n]+`mg_articoli`/s', 'FROM mg_articoli LEFT JOIN (SELECT idarticolo, SUM(qta) AS qta_totale FROM mg_movimenti WHERE data <='.prepare($period_end).' GROUP BY idarticolo) movimenti ON movimenti.idarticolo=mg_articoli.id ', $query);
$query = preg_replace('/^SELECT/', 'SELECT movimenti.qta_totale, ', $query);
if (post('acquisto') == 'standard') {
$query = preg_replace('/^SELECT/', 'SELECT mg_articoli.prezzo_acquisto AS acquisto, ', $query);
$text = "al prezzo presente nella scheda articolo";
@ -57,7 +61,7 @@ if (post('acquisto') == 'standard') {
}
if (post('tipo') == 'nozero') {
$query = str_replace('2=2', '2=2 AND qta > 0', $query);
$query = str_replace('2=2', '2=2 AND qta_totale > 0', $query);
}
$data = Query::executeAndCount($query);
@ -93,7 +97,7 @@ $totale_qta = 0;
$totali = [];
foreach ($data['results'] as $r) {
$valore_magazzino = $r['Prezzo di acquisto'] * $r['Q.tà'];
$valore_magazzino = $r['Prezzo di acquisto'] * $r['qta_totale'];
echo '
<tr>
@ -101,7 +105,7 @@ foreach ($data['results'] as $r) {
<td>'.$r['Categoria'].'</td>
<td>'.$r['Descrizione'].'</td>
<td class="text-right">'.moneyFormat($r['Prezzo di vendita']).'</td>
<td class="text-right">'.Translator::numberToLocale($r['Q. disponibile']).' '.$r['um'].'</td>
<td class="text-right">'.Translator::numberToLocale($r['qta_totale']).' '.$r['um'].'</td>
<td class="text-right">'.moneyFormat($r['Prezzo di acquisto']).'</td>
<td class="text-right">'.moneyFormat($valore_magazzino).'</td>
</tr>';

View File

@ -81,4 +81,10 @@ WHERE
HAVING
2=2 AND `Q.` > 0
ORDER BY
`descrizione`" WHERE `name` = 'Giacenze sedi';
`descrizione`" WHERE `name` = 'Giacenze sedi';
-- Impostazione per visualizzare i promemoria su app
INSERT INTO `zz_settings` (`id`, `nome`, `valore`, `tipo`, `editable`, `sezione`, `order`, `help`) VALUES (NULL, 'Visualizza promemoria', '1', 'boolean', '1', 'Applicazione', '5', '');
-- Aggiunta del riferimento utente nei movimenti
ALTER TABLE `mg_movimenti` ADD `idutente` INT NULL DEFAULT NULL;