This commit is contained in:
MatteoPistorello 2020-11-02 14:36:56 +01:00
commit 0e6862fc68
22 changed files with 248 additions and 153 deletions

View File

@ -4,7 +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.18 ()](#2418-)
- [2.4.18 (2020-10-30)](#2418-2020-10-30)
- [2.4.17.1 (2020-09-18)](#24171-2020-09-18)
- [2.4.17 (2020-08-24)](#2417-2020-08-24)
- [2.4.16 (2020-07-28)](#2416-2020-07-28)
@ -29,7 +29,7 @@ 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.18 ()
## 2.4.18 (2020-10-30)
### Aggiunto (Added)
- Sidebar per la gestione grafica dei Plugin all'interno dei record per i Moduli

View File

@ -421,6 +421,7 @@ function release(done) {
'vendor/mpdf/mpdf/ttfonts/DejaVu*Condensed*',
'!vendor/maximebf/debugbar/src/DebugBar/Resources/vendor/*',
'!vendor/respect/validation/tests/*',
'!vendor/willdurand/geocoder/tests/*',
], {
dot: true,
}).then(function (files) {

View File

@ -49,11 +49,8 @@ if (empty($result['idarticolo'])) {
<script>
$(document).ready(function (){
ottieniPrezziArticolo("'.$articolo['id'].'").then(function (){
ottieniDettagliArticolo("'.$articolo['id'].'").then(function (){
verificaPrezzoArticolo();
});
ottieniScontiArticolo("'.$articolo['id'].'").then(function (){
verificaScontoArticolo();
});
});
@ -108,22 +105,18 @@ if ($module['name'] != 'Contratti' && $module['name'] != 'Preventivi') {
echo '
<script>
var direzione = "'.$options['dir'].'";
globals.aggiunta_articolo = {
};
$(document).ready(function () {
if (direzione === "uscita") {
aggiorna_qta_minima();
$("#qta").keyup(aggiorna_qta_minima);
aggiornaQtaMinima();
$("#qta").keyup(aggiornaQtaMinima);
}
});
$("#tipo_sconto").on("change", function() {
let $data = $("#idarticolo").selectData();
ottieniScontiArticolo($data.id).then(function() {
if ($("#sconto").val().toEnglish() === 0){
aggiornaScontoArticolo();
} else {
verificaScontoArticolo();
}
});
verificaScontoArticolo();
});
$("#idarticolo").on("change", function() {
@ -149,15 +142,13 @@ $("#idarticolo").on("change", function() {
// Autoimpostazione dei campi relativi all\'articolo
let $data = $(this).selectData();
ottieniPrezziArticolo($data.id).then(function() {
ottieniDettagliArticolo($data.id).then(function() {
if ($("#prezzo_unitario").val().toEnglish() === 0){
aggiornaPrezzoArticolo()
aggiornaPrezzoArticolo();
} else {
verificaPrezzoArticolo();
}
});
ottieniScontiArticolo($data.id).then(function() {
if ($("#sconto").val().toEnglish() === 0){
aggiornaScontoArticolo();
} else {
@ -177,7 +168,7 @@ $("#idarticolo").on("change", function() {
else {
$("#id_dettaglio_fornitore").val($data.id_dettaglio_fornitore);
$("#qta_minima").val($data.qta_minima);
aggiorna_qta_minima();
aggiornaQtaMinima();
}
let id_conto = $data.idconto_'.($options['dir'] == 'entrata' ? 'vendita' : 'acquisto').';
@ -199,80 +190,58 @@ $(document).on("change", "input[name^=qta], input[name^=prezzo_unitario], input[
});
/**
* Restituisce il prezzo registrato per una specifica quantità dell\'articolo.
* Restituisce il dettaglio registrato per una specifica quantità dell\'articolo.
*/
function getPrezzoPerQuantita(qta) {
const data = $("#prezzo_unitario").data("prezzi");
if (!data) return 0;
function getDettaglioPerQuantita(qta) {
const data = globals.aggiunta_articolo.dettagli;
if (!data) return null;
let prezzo_predefinito = null;
let prezzo_selezionato = null;
for (const prezzo of data) {
if (prezzo.minimo == null && prezzo.massimo == null) {
prezzo_predefinito = prezzo.prezzo_unitario;
let dettaglio_predefinito = null;
let dettaglio_selezionato = null;
for (const dettaglio of data) {
if (dettaglio.minimo == null && dettaglio.massimo == null) {
dettaglio_predefinito = dettaglio;
continue;
}
if (qta >= prezzo.minimo && qta <= prezzo.massimo) {
prezzo_selezionato = prezzo.prezzo_unitario;
if (qta >= dettaglio.minimo && qta <= dettaglio.massimo) {
dettaglio_selezionato = dettaglio;
}
}
if (prezzo_selezionato == null) {
prezzo_selezionato = prezzo_predefinito;
if (dettaglio_selezionato == null) {
dettaglio_selezionato = dettaglio_predefinito;
}
return parseFloat(prezzo_selezionato);
return dettaglio_selezionato;
}
/**
* Restituisce il prezzo registrato per una specifica quantità dell\'articolo.
*/
function getPrezzoPerQuantita(qta) {
const dettaglio = getDettaglioPerQuantita(qta);
return dettaglio ? parseFloat(dettaglio.prezzo_unitario) : 0;
}
/**
* Restituisce lo sconto registrato per una specifica quantità dell\'articolo.
*/
function getScontoPerQuantita(qta) {
const data = $("#sconto").data("sconti");
if (!data) return 0;
const dettaglio = getDettaglioPerQuantita(qta);
let sconto_predefinito = null;
let sconto_selezionato = null;
for (const prezzo of data) {
if (prezzo.minimo == null && prezzo.massimo == null) {
sconto_predefinito = prezzo.sconto;
continue;
}
if (qta >= prezzo.minimo && qta <= prezzo.massimo) {
sconto_selezionato = prezzo.sconto;
}
}
if (sconto_selezionato == null) {
sconto_selezionato = sconto_predefinito;
}
return parseFloat(sconto_selezionato);
}
/**
* Funzione per registrare localmente i prezzi definiti per l\'articolo in relazione ad una specifica anagrafica.
*/
function ottieniPrezziArticolo(id_articolo) {
return $.get(globals.rootdir + "/ajax_complete.php?module=Articoli&op=prezzi_articolo&id_anagrafica='.$options['idanagrafica'].'&id_articolo=" + id_articolo + "&dir=" + direzione, function(response) {
const data = JSON.parse(response);
$("#prezzo_unitario").data("prezzi", data);
});
return dettaglio ? parseFloat(dettaglio.sconto_percentuale) : 0;
}
/**
* Funzione per registrare localmente gli sconti definiti per l\'articolo in relazione ad una specifica anagrafica.
* Funzione per registrare localmente i dettagli definiti per l\'articolo in relazione ad una specifica anagrafica.
*/
function ottieniScontiArticolo(id_articolo) {
return $.get(globals.rootdir + "/ajax_complete.php?module=Articoli&op=prezzi_articolo&id_anagrafica='.$options['idanagrafica'].'&id_articolo=" + id_articolo + "&dir=" + direzione, function(response) {
function ottieniDettagliArticolo(id_articolo) {
return $.get(globals.rootdir + "/ajax_complete.php?module=Articoli&op=dettagli_articolo&id_anagrafica='.$options['idanagrafica'].'&id_articolo=" + id_articolo + "&dir=" + direzione, function(response) {
const data = JSON.parse(response);
$("#sconto").data("sconti", data);
globals.aggiunta_articolo.dettagli = data;
});
}
@ -305,12 +274,12 @@ function verificaPrezzoArticolo() {
function verificaScontoArticolo() {
let qta = $("#qta").val().toEnglish();
let sconto_previsto = getScontoPerQuantita(qta);
console.log(sconto_previsto);
let sconto_input = $("#sconto");
let sconto = sconto_input.val().toEnglish();
let div = sconto_input.parent().next();
if (sconto_previsto === sconto || $("#tipo_sconto").val() === "UNT") {
if (sconto_previsto === 0 || sconto_previsto === sconto || $("#tipo_sconto").val() === "UNT") {
div.css("padding-top", "0");
div.html("");
@ -344,7 +313,7 @@ function aggiornaScontoArticolo() {
/**
* Funzione per l\'aggiornamento dinamico della quantità minima per l\'articolo.
*/
function aggiorna_qta_minima() {
function aggiornaQtaMinima() {
let qta_minima = parseFloat($("#qta_minima").val());
let qta = $("#qta").val().toEnglish();

View File

@ -116,7 +116,7 @@ switch ($resource) {
* - id_articolo
* - id_anagrafica
*/
case 'prezzi_articolo':
case 'dettagli_articolo':
$id_articolo = get('id_articolo');
$id_anagrafica = get('id_anagrafica');
$direzione = get('dir') == 'uscita' ? 'uscita' : 'entrata';
@ -127,7 +127,8 @@ switch ($resource) {
$prezzi_ivati = setting('Utilizza prezzi di vendita comprensivi di IVA');
$query = 'SELECT minimo, massimo, sconto,
$query = 'SELECT minimo, massimo,
sconto_percentuale,
'.($prezzi_ivati ? 'prezzo_unitario_ivato' : 'prezzo_unitario').' AS prezzo_unitario
FROM mg_prezzi_articoli
WHERE id_articolo = '.prepare($id_articolo).' AND dir = '.prepare($direzione).' |where|
@ -155,6 +156,7 @@ switch ($resource) {
[
'minimo' => null,
'massino' => null,
'sconto_percentuale' => 0,
'prezzo_unitario' => $direzione == 'uscita' ? $result['prezzo_acquisto'] : $result['prezzo_vendita'],
],
];

View File

@ -21,6 +21,9 @@ include_once __DIR__.'/../../core.php';
$id_anagrafica = filter('id_anagrafica');
$help_codice_bic = tr("Il codice BIC (o SWIFT) è composto da 8 a 11 caratteri (lettere e numeri) ed è suddiviso in:").'<br><br><ul><li>'.tr('AAAA - codice bancario').'</li><li>'.tr('BB - codice ISO della nazione').'</li><li>'.tr('CC - codice città presso la quale è ubicata la banca').'</li><li>'.tr('DD - codice della filiale (opzionale)').'</li></ul>';
echo '
<form action="" method="post" id="add-form">
<input type="hidden" name="op" value="add">
@ -41,7 +44,7 @@ echo '
{[ "type": "text", "label": "'.tr('IBAN').'", "name": "iban", "required": "1", "class": "alphanumeric-mask", "maxlength": 32, "value": "$iban$" ]}
</div>
<div class="col-md-4">
{[ "type": "text", "label": "'.tr('BIC').'", "name": "bic", "required": "1", "class": "alphanumeric-mask", "maxlength": 11, "value": "$bic$" ]}
{[ "type": "text", "label": "'.tr('BIC').'", "name": "bic", "required": "1", "class": "alphanumeric-mask", "minlength": 8, "maxlength": 11, "value": "$bic$", "help": "'.$help_codice_bic.'" ]}
</div>
</div>

View File

@ -171,6 +171,10 @@ if ($module['name'] == 'Ddt di vendita') {
</div>
<div class="col-md-3">
<?php
if (!empty($record['idvettore']))
echo Modules::link('Anagrafiche', $record['idvettore'], null, null, 'class="pull-right"');
?>
{[ "type": "select", "label": "<?php echo tr('Vettore'); ?>", "name": "idvettore", "ajax-source": "vettori", "value": "$idvettore$", "disabled": <?php echo intval($record['idspedizione'] == 3); ?>, "required": <?php echo (!empty($record['idspedizione'])) ? intval($record['idspedizione'] != 3) : 0; ?>, "icon-after": "add|<?php echo Modules::get('Anagrafiche')['id']; ?>|tipoanagrafica=Vettore&readonly_tipo=1|btn_idvettore|<?php echo (($record['idspedizione'] != 3 and intval(!$record['flag_completato']))) ? '' : 'disabled'; ?>" ]}
</div>

View File

@ -197,7 +197,7 @@ elseif ($record['stato'] == 'Bozza') {
echo '
<div class="col-md-'.($is_fiscale ? 2 : 6).'">
<!-- TODO: Rimuovere possibilità di selezionare lo stato pagato obbligando l\'utente ad aggiungere il movimento in prima nota -->
{[ "type": "select", "label": "'.tr('Stato').'", "name": "idstatodocumento", "required": 1, "values": "query='.$query.'", "value": "$idstatodocumento$", "class": "'.(!$abilita_genera ? '' : 'unblockable').'", "extra": "onchange=\"return cambiaStato()\"" ]}
{[ "type": "select", "label": "'.tr('Stato').'", "name": "idstatodocumento", "required": 1, "values": "query='.$query.'", "value": "$idstatodocumento$", "class": "'.(($record['stato'] != 'Bozza' && !$abilita_genera) ? '' : 'unblockable').'", "extra": "onchange=\"return cambiaStato()\"" ]}
</div>
</div>

View File

@ -53,7 +53,7 @@ foreach ($gruppi as $key => $gruppo) {
<!-- Impostazioni della singola sezione -->
<div class="box box-primary collapsed-box" title="'.$gruppo['nome'].'">
<div class="box-header clickable" id="impostazioni-'.$key.'">
<div class="box-title">'.tr('Impostazioni _SEZIONE_', [
<div class="box-title">'.tr('_SEZIONE_', [
'_SEZIONE_' => $gruppo['nome'],
]).'</div>
<div class="box-tools pull-right">

View File

@ -252,6 +252,7 @@ switch (post('op')) {
$riga->costo_unitario = post('costo_unitario') ?: 0;
$riga->data_evasione = post('data_evasione') ?: null;
$riga->confermato = post('confermato') ?: 0;
$riga->setPrezzoUnitario(post('prezzo_unitario'), post('idiva'));
$riga->setSconto(post('sconto'), post('tipo_sconto'));

View File

@ -92,7 +92,7 @@ if (!empty($utenti)) {
// Disabilitazione token API, se diverso da id_utente #1 (admin)
$token = $dbo->fetchOne('SELECT `enabled` FROM `zz_tokens` WHERE `id_utente` = '.prepare($utente['id']).'')['enabled'];
if ($utente['id'] == '1') {
echo '
<div data-toggle="tooltip" class="tip" title="'.tr("Non è possibile gestire l'accesso API per l'utente admin").'" ><span class="btn btn-xs btn-default disabled">
@ -170,14 +170,14 @@ if ($record['nome'] != 'Amministratori') {
$moduli = Modules::getHierarchy();
$permissions = [
$permessi_disponibili = [
'-' => tr('Nessun permesso'),
'r' => tr('Sola lettura'),
'rw' => tr('Lettura e scrittura'),
];
for ($m = 0; $m < count($moduli); ++$m) {
echo menuSelection($moduli[$m], $id_record, -1, array_keys($permissions), array_values($permissions));
echo menuSelection($moduli[$m], $id_record, -1, $permessi_disponibili);
}
echo '

View File

@ -19,46 +19,38 @@
include_once __DIR__.'/../../core.php';
function menuSelection($element, $group_id, $depth, $perms_values, $perms_names)
function menuSelection($element, $group_id, $depth, $permessi_disponibili)
{
$dbo = database();
++$depth;
$name = $element['title'];
$submenus = $element['all_children'];
if (!empty($submenus)) {
$temp = '';
foreach ($submenus as $submenu) {
$temp .= menuSelection($submenu, $group_id, $depth, $perms_values, $perms_names);
}
}
$result .= '
$result = '
<tr>
<td>'.str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;', $depth).$name.'</td>
<td>'.str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;', $depth).$element['title'].'</td>
<td>
<select name="permesso" class="form-control superselect" onchange="update_permissions('.$element['id'].', $(this).find(\'option:selected\').val())">';
// Permessi
$rsp = $dbo->fetchArray('SELECT permessi FROM zz_permissions WHERE idgruppo='.prepare($group_id).' AND idmodule='.prepare($element['id']));
<select name="permesso_'.$element['id'].'" id="permesso_'.$element['id'].'" class="form-control superselect openstamanager-input select-input" onchange="update_permissions('.$element['id'].', $(this).find(\'option:selected\').val())">';
if (count($rsp) == 0) {
$permessi = '-';
} else {
$permessi = $rsp[0]['permessi'];
}
// Permessi impostati per il gruppo
$permesso_salvato = $dbo->fetchOne('SELECT permessi FROM zz_permissions WHERE idgruppo = '.prepare($group_id).' AND idmodule = '.prepare($element['id']));
$permessi = $permesso_salvato ? $permesso_salvato['permessi'] : '-';
foreach ($permessi_disponibili as $id => $nome){
$attr = ($id == $permessi) ? ' selected="selected"' : '';
for ($i = 0; $i < count($perms_values); ++$i) {
$attr = ($perms_values[$i] == $permessi) ? ' selected="selected"' : '';
$result .= '
<option value="'.$perms_values[$i].'" '.$attr.'>'.$perms_names[$i].'</option>';
<option value="'.$id.'" '.$attr.'>'.$nome.'</option>';
}
$result .= '
</select>
</td>
</tr>
'.$temp;
</tr>';
$submenus = $element['all_children'];
if (!empty($submenus)) {
foreach ($submenus as $submenu) {
$result .= menuSelection($submenu, $group_id, $depth, $permessi_disponibili, $perms_names);
}
}
return $result;
}

View File

@ -75,7 +75,7 @@ switch (filter('op')) {
if (empty($dettaglio_predefinito)) {
$dettaglio_predefinito = DettaglioPrezzo::build($articolo, $anagrafica, $direzione);
}
$dettaglio_predefinito->sconto = $sconto;
$dettaglio_predefinito->sconto_percentuale = $sconto;
$dettaglio_predefinito->setPrezzoUnitario($prezzo_unitario);
$dettaglio_predefinito->save();
@ -102,7 +102,7 @@ switch (filter('op')) {
$dettaglio->minimo = $minimi[$key];
$dettaglio->massimo = $massimi[$key];
$dettaglio->sconto = $sconti[$key];
$dettaglio->sconto_percentuale = $sconti[$key];
$dettaglio->setPrezzoUnitario($prezzo_unitario);
$dettaglio->save();
}

View File

@ -123,7 +123,7 @@ if (!$clienti->isEmpty()) {
</td>
<td class="text-right">
'.numberFormat($dettaglio->sconto).'%
'.numberFormat($dettaglio->sconto_percentuale).'%
</td>
<td>';
@ -309,9 +309,11 @@ if (!$fornitori_disponibili->isEmpty()) {
<td class="text-right">
'.moneyFormat($dettaglio->prezzo_unitario).'
</td>
<td class="text-right">
'.numberFormat($dettaglio->sconto).'%
'.numberFormat($dettaglio->sconto_percentuale).'%
</td>
<td>';
if (!isset($dettaglio->minimo) && !isset($dettaglio->massimo)) {

View File

@ -76,7 +76,7 @@ switch (filter('op')) {
$type = filter('type');
$cambia_stato = $type != 'download';
$fattura = Ricevuta::process($name, false);
$fattura = Ricevuta::process($name, $cambia_stato);
$numero_esterno = $fattura ? $fattura->numero_esterno : null;

View File

@ -128,14 +128,14 @@ function gestioneRicevuta(button, name, type) {
success: function(response) {
buttonRestore(button, restore);
if(response.fattura) {
if (response.fattura) {
swal({
title: "'.tr('Importazione completata!').'",
title: type === "download" ? "'.tr('Ricevuta scaricata!').'" : "'.tr('Importazione della ricevuta completata!').'",
type: "success",
});
} else {
swal({
title: "'.tr('Importazione fallita!').'",
title: "'.tr('Operazione fallita!').'",
type: "error",
});
}

View File

@ -531,6 +531,34 @@ class FatturaElettronica
];
}
// Campi obbligatori per l'anagrafica di tipo Vettore
$id_vettore = $fattura['idvettore'];
if (!empty($id_vettore)) {
$data = Anagrafica::find($id_vettore);
$fields = [
'piva' => 'Partita IVA',
'nazione' => 'Nazione',
];
$missing = [];
if (!empty($data)) {
foreach ($fields as $key => $name) {
if (empty($data[$key]) && !empty($name)) {
$missing[] = $name;
}
}
}
if (!empty($missing)) {
$link = Modules::link('Anagrafiche', $data['id']);
$errors[] = [
'link' => $link,
'name' => tr('Anagrafica Vettore'),
'errors' => $missing,
];
}
}
return $errors;
}
@ -926,7 +954,7 @@ class FatturaElettronica
$result = [];
//Se imposto il vettore deve essere indicata anche la p.iva nella sua anagrafica
// Se imposto il vettore deve essere indicata anche la p.iva nella sua anagrafica
if ($documento['idvettore']) {
$vettore = Anagrafica::find($documento['idvettore']);
$result['DatiAnagraficiVettore'] = static::getDatiAnagrafici($vettore);
@ -1425,11 +1453,14 @@ class FatturaElettronica
if (!empty($banca->nome)) {
$pagamento['IstitutoFinanziario'] = $banca->nome;
}
if (!empty($banca->iban)) {
$pagamento['IBAN'] = clean($banca->iban);
}
// BIC senza parte per filiale (causa errori di validazione)
if (!empty($banca->bic)) {
$pagamento['BIC'] = $banca->bic;
$pagamento['BIC'] = substr($banca->bic, 0, 8);
}
$result[]['DettaglioPagamento'] = $pagamento;

View File

@ -19,28 +19,44 @@
include_once __DIR__.'/../../core.php';
use Carbon\Carbon;
use Modules\Fatture\Fattura;
use Plugins\ReceiptFE\Interaction;
echo '
<p>'.tr('Le ricevute delle Fatture Elettroniche permettono di individuare se una determinata fattura tramessa è stata accettata dal Sistema Di Interscambio').'.</p>';
if (Interaction::isEnabled()) {
echo '
<p>'.tr('Tramite il pulsante _BTN_ è possibile procedere al recupero delle ricevute, aggiornando automaticamente lo stato delle relative fatture e allegandole ad esse', [
'_BTN_' => '<i class="fa fa-refresh"></i> <b>'.tr('Ricerca ricevute').'</b>',
]).'.</p>';
//controllo se ci sono fatture in elaborazione da più di 7 giorni per le quali non ho ancora una ricevuta
$fatture_generate = $dbo->fetchArray('SELECT `co_documenti`.`numero_esterno`, `co_documenti`.`data`, `co_documenti`.`data_stato_fe` FROM `co_documenti` JOIN `co_tipidocumento` ON `co_tipidocumento`.`id` = `co_documenti`.`idtipodocumento` WHERE `co_tipidocumento`.`dir` = \'entrata\' AND `co_documenti`.`codice_stato_fe` = \'WAIT\' AND `co_documenti`.`data_stato_fe` >= "'.$_SESSION['period_start'].'" AND `co_documenti`.`data_stato_fe`<(NOW() - INTERVAL 7 DAY) ORDER BY `co_documenti`.`data_stato_fe`');
// Controllo se ci sono fatture in elaborazione da più di 7 giorni per le quali non ho ancora una ricevuta
$data_limite = (new Carbon())->subDays(7);
$fatture_generate = Fattura::vendite()
->where('codice_stato_fe', 'WAIT')
->where('data_stato_fe', '>=', $_SESSION['period_start'])
->where('data_stato_fe', '<', $data_limite)
->orderBy('data_stato_fe')
->get();
foreach ($fatture_generate as $fattura_generata) {
if (!empty($fatture_generate)){
echo '
<div class="alert alert-warning"><i class="fa fa-warning" ></i> '.tr('Attenzione: la fattura _NUM_ del _DATA_ è in attesa di una ricevuta dal _DATA_STATO_FE.', [
'_NUM_' => $fattura_generata['numero_esterno'],
'_DATA_' => Translator::dateToLocale($fattura_generata['data']),
'_DATA_STATO_FE' => Translator::timestampToLocale($fattura_generata['data_stato_fe']),
]).'</div>';
<div class="alert alert-warning">
<p><i class="fa fa-warning"></i> '.tr('Attenzione: le seguenti fatture sono in attesa di una ricevuta').'.</p>
<ul>';
foreach ($fatture_generate as $fattura_generata) {
echo '<li>'.reference($fattura_generata, $fattura_generata->getReference()).' ['.timestampFormat($fattura_generata['data_stato_fe']).']</li>';
}
echo '
</ul>
</div>';
}
}
echo '
<div class="box box-success">
<div class="box-header with-border">

View File

@ -157,7 +157,7 @@ class Ricevuta
$module = $fattura->getModule();
$upload_esistente = $module
->uploads($fattura->id)
->where('original', $filename)
->where('original_name', $filename)
->first();
if (!empty($upload_esistente)) {
return $upload_esistente;

View File

@ -277,7 +277,7 @@ class HTMLWrapper implements WrapperInterface
$value = (empty($pieces[2]) || !in_array($pieces[2], array_column($choices, 'id'))) ? $choices[0]['id'] : $pieces[2];
$result = '{[ "type": "select", "name": "tipo_'.prepareToField($values['name']).'", "value": "'.prepareToField($value).'", "values": '.json_encode($choices).', "class": "no-search", "extra": "'.$extra.'" ]}';
$result = '{[ "type": "select", "name": "tipo_'.prepareToField($values['name']).'", "id": "tipo_'.prepareToField($values['name']).'_'.rand(0, 99).'", "value": "'.prepareToField($value).'", "values": '.json_encode($choices).', "class": "no-search", "extra": "'.$extra.'" ]}';
$result = \HTMLBuilder\HTMLBuilder::replace($result);

View File

@ -40,7 +40,7 @@ class Task extends Model
public function log($level, $message, $context = [])
{
$log = new static();
$log = new Log();
$log->level = $level;
$log->message = $message;

View File

@ -1,24 +1,98 @@
<?php
use Update\v2_4_10\Anagrafica;
use Update\v2_4_10\Fattura;
$database = database();
error_reporting(E_ALL & ~E_WARNING & ~E_CORE_WARNING & ~E_NOTICE & ~E_USER_DEPRECATED & ~E_STRICT);
// Fix del calcolo del bollo
$fatture = Fattura::all();
$fatture = $database->fetchArray('SELECT id, bollo, split_payment FROM co_documenti');
foreach ($fatture as $fattura) {
$fattura->manageRigaMarcaDaBollo();
$bollo = $fattura['bollo'];
if (empty($bollo)) {
if (empty($fattura['split_payment'])) {
$totale = 'subtotale - sconto + iva + rivalsainps';
} else {
$totale = 'subtotale - sconto + rivalsainps';
}
$righe = $database->fetchArray('SELECT ('.$totale.') AS netto FROM co_righe_documenti INNER JOIN co_iva ON co_iva.id = co_righe_documenti.idiva WHERE iddocumento = '.prepare($fattura['id'])." AND codice_natura_fe IN ('N1', 'N2', 'N3', 'N4')");
$totale = sum(array_column($righe, 'netto'));
$importo_bollo = setting('Importo marca da bollo');
if (abs($importo_bollo) > 0 && abs($totale) > setting("Soglia minima per l'applicazione della marca da bollo")) {
$bollo = $importo_bollo;
}
}
$bollo = floatval($bollo);
if ($bollo > 0) {
$fatture = $database->query(
'insert into `co_righe_documenti` (`iddocumento`, `order`, `descrizione`, `um`, `idiva`, `idconto`, `calcolo_ritenuta_acconto`, `idritenutaacconto`, `ritenuta_contributi`, `idrivalsainps`, `prezzo_unitario_acquisto`, `sconto_unitario`, `tipo_sconto`, `qta`, `data_inizio_periodo`, `data_fine_periodo`, `riferimento_amministrazione`, `tipo_cessione_prestazione`, `ritenutaacconto`, `rivalsainps`, `subtotale`, `sconto`, `iva`, `desc_iva`, `iva_indetraibile`, `created_at`) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [
0 => $fattura['id'],
1 => 0,
2 => 'Marca da bollo',
3 => null,
4 => '110',
5 => '99',
6 => null,
7 => null,
8 => false,
9 => null,
10 => 0,
11 => 0.0,
12 => 'PRC',
13 => 1.0,
14 => null,
15 => null,
16 => '',
17 => '',
18 => 0.0,
19 => 0.0,
20 => $bollo,
21 => 0.0,
22 => 0.0,
23 => 'Escluso art. 15',
24 => 0.0,
25 => '2020-10-17 10:00:00',
]);
$id_riga_bollo = $database->lastInsertedId();
$database->query('UPDATE co_documenti SET id_riga_bollo = '.prepare($id_riga_bollo).' WHERE id = '.prepare($fattura['id']));
}
}
// Fix per le relazioni tariffe-tecnici
$tecnici = Anagrafica::fromTipo('Tecnico')->get();
$tecnici = $database->fetchArray("SELECT DISTINCT(an_anagrafiche.idanagrafica) AS id FROM an_anagrafiche
INNER JOIN an_tipianagrafiche ON an_anagrafiche.idanagrafica = an_anagrafiche.idanagrafica
INNER JOIN an_tipianagrafiche_anagrafiche ON an_tipianagrafiche.idtipoanagrafica = an_tipianagrafiche_anagrafiche.idtipoanagrafica
WHERE an_tipianagrafiche.descrizione = 'Tecnico'");
foreach ($tecnici as $tecnico) {
Anagrafica::fixTecnico($tecnico);
$presenti = $database->fetchArray('SELECT idtipointervento AS id FROM in_tariffe WHERE idtecnico = '.prepare($tecnico['id']));
// Aggiunta associazioni costi unitari al contratto
$query = 'SELECT * FROM in_tipiintervento';
$elenco_presenti = array_column($presenti, 'id');
if (!empty($elenco_presenti)) {
$query .= ' WHERE idtipointervento NOT IN ('.implode(', ', $elenco_presenti).')';
}
$tipi = $database->fetchArray($query);
foreach ($tipi as $tipo) {
$database->insert('in_tariffe', [
'idtecnico' => $tecnico['id'],
'idtipointervento' => $tipo['id'],
'costo_ore' => $tipo['costo_orario'],
'costo_km' => $tipo['costo_km'],
'costo_dirittochiamata' => $tipo['costo_diritto_chiamata'],
'costo_ore_tecnico' => $tipo['costo_orario_tecnico'],
'costo_km_tecnico' => $tipo['costo_km_tecnico'],
'costo_dirittochiamata_tecnico' => $tipo['costo_diritto_chiamata_tecnico'],
]);
}
}
// Spostamento automezzi su sedi
$automezzi = $dbo->fetchArray('SELECT * FROM dt_automezzi');
$automezzi = $database->fetchArray('SELECT * FROM dt_automezzi');
foreach ($automezzi as $automezzo) {
$nomesede = [];
@ -26,7 +100,7 @@ foreach ($automezzi as $automezzo) {
(!empty($automezzo['descrizione'])) ? $nomesede[] = $automezzo['descrizione'] : null;
(!empty($automezzo['targa'])) ? $nomesede[] = $automezzo['targa'] : null;
$dbo->insert(
$database->insert(
'an_sedi',
[
'nomesede' => implode(' - ', $nomesede),
@ -34,10 +108,10 @@ foreach ($automezzi as $automezzo) {
]
);
$idsede = $dbo->lastInsertedId();
$idsede = $database->lastInsertedId();
// Aggiornamento sede di partenza su
$dbo->update(
$database->update(
'in_interventi',
[
'idsede_partenza' => $idsede,
@ -48,23 +122,23 @@ foreach ($automezzi as $automezzo) {
}
// Aggiornamento della sede azienda nei movimenti degli interventi
$dbo->query('UPDATE mg_movimenti SET idsede_azienda=(SELECT idsede_partenza FROM in_interventi WHERE in_interventi.id=mg_movimenti.idintervento) WHERE idintervento IS NOT NULL');
$database->query('UPDATE mg_movimenti SET idsede_azienda=(SELECT idsede_partenza FROM in_interventi WHERE in_interventi.id=mg_movimenti.idintervento) WHERE idintervento IS NOT NULL');
// Cancellazione idautomezzo da mg_movimenti e in_interventi
$dbo->query('ALTER TABLE in_interventi DROP idautomezzo');
$dbo->query('ALTER TABLE mg_movimenti DROP idautomezzo');
$dbo->query('ALTER TABLE co_promemoria_articoli DROP idautomezzo');
$dbo->query('ALTER TABLE co_righe_documenti DROP idautomezzo');
$dbo->query('ALTER TABLE mg_articoli_interventi DROP idautomezzo');
$database->query('ALTER TABLE in_interventi DROP idautomezzo');
$database->query('ALTER TABLE mg_movimenti DROP idautomezzo');
$database->query('ALTER TABLE co_promemoria_articoli DROP idautomezzo');
$database->query('ALTER TABLE co_righe_documenti DROP idautomezzo');
$database->query('ALTER TABLE mg_articoli_interventi DROP idautomezzo');
// Eliminazione tabelle degli automezzi non più usate
$dbo->query('DROP TABLE mg_articoli_automezzi');
$dbo->query('DROP TABLE dt_automezzi');
$dbo->query('DROP TABLE dt_automezzi_tecnici');
$dbo->query('DELETE FROM zz_modules WHERE name="Automezzi"');
$database->query('DROP TABLE mg_articoli_automezzi');
$database->query('DROP TABLE dt_automezzi');
$database->query('DROP TABLE dt_automezzi_tecnici');
$database->query('DELETE FROM zz_modules WHERE name="Automezzi"');
//Rimuovo il codice come indice per in_interventi
$dbo->query('ALTER TABLE `in_interventi` DROP INDEX `codice`');
$database->query('ALTER TABLE `in_interventi` DROP INDEX `codice`');
// File e cartelle deprecate
$files = [

View File

@ -329,7 +329,7 @@ UPDATE `zz_modules` SET `options` = 'SELECT |select| FROM `co_scadenziario`\r\n
DELETE FROM `zz_tokens` WHERE `zz_tokens`.`enabled` = 0;
-- Aggiunto colonna sconto per le coppie anagrafica articolo
ALTER TABLE `mg_prezzi_articoli` ADD `sconto` DECIMAL(15,6) NOT NULL AFTER `massimo`;
ALTER TABLE `mg_prezzi_articoli` ADD `sconto_percentuale` DECIMAL(15,6) NOT NULL AFTER `massimo`;
-- Aggiunta impostazione per mostrare o nascondere barra plugin
INSERT INTO `zz_settings` (`id`, `nome`, `valore`, `tipo`, `editable`, `sezione`, `order`, `help`) VALUES (NULL, 'Nascondere la barra dei plugin di default', '0', 'boolean', '1', 'Generali', '2', NULL);