This commit is contained in:
Beppe 2021-10-06 12:03:33 +02:00
commit a37842c310
27 changed files with 342 additions and 105 deletions

View File

@ -126,6 +126,7 @@ function start_complete_calendar(id, callback) {
ranges[globals.translations.secondSemester] = [moment("06", "MM"), moment("12", "MM").endOf('month')];
ranges[globals.translations.thisMonth] = [moment().startOf('month'), moment().endOf('month')];
ranges[globals.translations.lastMonth] = [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')];
ranges[globals.translations.nextMonth] = [moment().add(1, 'month').startOf('month'), moment().add(1, 'month').endOf('month')];
ranges[globals.translations.thisYear] = [moment().startOf('year'), moment().endOf('year')];
ranges[globals.translations.lastYear] = [moment().subtract(1, 'year').startOf('year'), moment().subtract(1, 'year').endOf('year')];

View File

@ -90,6 +90,7 @@ if (Auth::check()) {
'secondSemester' => tr('II semestre'),
'thisMonth' => tr('Questo mese'),
'lastMonth' => tr('Mese scorso'),
'nextMonth' => tr('Mese prossimo'),
'thisYear' => tr("Quest'anno"),
'lastYear' => tr('Anno scorso'),
'apply' => tr('Applica'),

View File

@ -60,6 +60,8 @@ switch (post('op')) {
$articolo->threshold_qta = post('threshold_qta');
$articolo->prezzo_acquisto = post('prezzo_acquisto');
$articolo->setPrezzoVendita(post('prezzo_vendita'), post('idiva_vendita'));
$articolo->idconto_vendita = post('idconto_vendita');
$articolo->idconto_acquisto = post('idconto_acquisto');
$articolo->save();
// Aggiornamento delle varianti per i campi comuni

View File

@ -87,6 +87,16 @@ include_once __DIR__.'/../../core.php';
{[ "type": "select", "label": "<?php echo tr('Iva di vendita'); ?>", "name": "idiva_vendita", "ajax-source": "iva", "valore_predefinito": "Iva predefinita", "help": "<?php echo tr('Se non specificata, verrà utilizzata l\'iva di default delle impostazioni'); ?>" ]}
</div>
</div>
<div class="row">
<div class="col-md-6">
{[ "type": "select", "label": "<?php echo tr('Conto predefinito di acquisto'); ?>", "name": "idconto_acquisto", "ajax-source": "conti-acquisti" ]}
</div>
<div class="col-md-6">
{[ "type": "select", "label": "<?php echo tr('Conto predefinito di vendita'); ?>", "name": "idconto_vendita", "ajax-source": "conti-vendite" ]}
</div>
</div>
</div>
</div>

View File

@ -62,12 +62,12 @@ switch ($resource) {
if ($usare_iva_anagrafica) {
$query .= '
IFNULL(iva_anagrafica.id, IFNULL(iva_predefinita.id, iva_articolo.id)) AS idiva_vendita,
IFNULL(iva_anagrafica.descrizione, IFNULL(iva_predefinita.descrizione, iva_articolo.descrizione)) AS iva_vendita,';
IFNULL(iva_anagrafica.id, IFNULL(iva_articolo.id, iva_predefinita.id)) AS idiva_vendita,
IFNULL(iva_anagrafica.descrizione, IFNULL(iva_articolo.descrizione, iva_predefinita.descrizione)) AS iva_vendita,';
} else {
$query .= '
IFNULL(iva_predefinita.id, iva_articolo.id) AS idiva_vendita,
IFNULL(iva_predefinita.descrizione, iva_articolo.descrizione) AS iva_vendita,';
IFNULL(iva_articolo.id, iva_predefinita.id) AS idiva_vendita,
IFNULL(iva_articolo.descrizione, iva_predefinita.descrizione) AS iva_vendita,';
}
$query .= '

View File

@ -49,11 +49,14 @@ switch (post('op')) {
break;
case 'change-vendita':
$percentuale = post('percentuale');
$prezzo_partenza = post('prezzo_partenza');
foreach ($id_records as $id) {
$articolo = Articolo::find($id);
$percentuale = post('percentuale');
$prezzo_partenza = post('prezzo_partenza')=='vendita' ? $articolo->prezzo_vendita : $articolo->prezzo_acquisto;
$new_prezzo_vendita = $articolo->prezzo_vendita + ($articolo->prezzo_vendita * $percentuale / 100);
$new_prezzo_vendita = $prezzo_partenza + ($prezzo_partenza * $percentuale / 100);
$articolo->setPrezzoVendita($new_prezzo_vendita, $articolo->idiva_vendita);
$articolo->save();
}
@ -167,6 +170,51 @@ switch (post('op')) {
download($file, 'articoli.csv');
break;
case 'change-categoria':
$categoria = post('id_categoria');
$n_articoli = 0;
foreach ($id_records as $id) {
$articolo = Articolo::find($id);
$articolo->id_categoria = $categoria;
$articolo->id_sottocategoria = null;
$articolo->save();
++$n_articoli;
}
if ($n_articoli > 0) {
flash()->info(tr('Categoria cambiata a _NUM_ articoli!', [
'_NUM_' => $n_articoli,
]));
} else {
flash()->warning(tr('Nessun articolo modificato!'));
}
break;
case 'change-iva':
$iva = post('id_iva');
$n_articoli = 0;
foreach ($id_records as $id) {
$articolo = Articolo::find($id);
$articolo->idiva_vendita = $iva;
$articolo->save();
++$n_articoli;
}
if ($n_articoli > 0) {
flash()->info(tr('Categoria cambiata a _NUM_ articoli!', [
'_NUM_' => $n_articoli,
]));
} else {
flash()->warning(tr('Nessun articolo modificato!'));
}
break;
}
if (App::debug()) {
@ -205,7 +253,9 @@ $operations['change-vendita'] = [
'text' => '<span><i class="fa fa-refresh"></i> '.tr('Aggiorna prezzo di vendita').'</span>',
'data' => [
'title' => tr('Aggiornare il prezzo di vendita per gli articoli selezionati?'),
'msg' => 'Per indicare uno sconto inserire la percentuale con il segno meno, al contrario per un rincaro inserire la percentuale senza segno.<br><br>{[ "type": "number", "label": "'.tr('Percentuale sconto/magg.').'", "name": "percentuale", "required": 1, "icon-after": "%" ]}',
'msg' => 'Per indicare uno sconto inserire la percentuale con il segno meno, al contrario per un rincaro inserire la percentuale senza segno.<br><br>
{[ "type": "select", "label": "'.tr('Partendo da:').'", "name": "prezzo_partenza", "required": 1, "values": "list=\"acquisto\":\"Prezzo di acquisto\",\"vendita\":\"Prezzo di vendita\"" ]}<br>
{[ "type": "number", "label": "'.tr('Percentuale sconto/magg.').'", "name": "percentuale", "required": 1, "icon-after": "%" ]}',
'button' => tr('Procedi'),
'class' => 'btn btn-lg btn-warning',
'blank' => false,
@ -250,4 +300,26 @@ $operations['crea-preventivo'] = [
],
];
$operations['change-categoria'] = [
'text' => '<span><i class="fa fa-briefcase"></i> '.tr('Aggiorna categoria').'</span>',
'data' => [
'title' => tr('Cambiare la categoria?'),
'msg' => tr('Per ciascun articolo selezionato, verrà modificata la categoria').'
<br><br>{[ "type": "select", "label": "'.tr('Categoria').'", "name": "id_categoria", "required": 1, "ajax-source": "categorie" ]}',
'button' => tr('Procedi'),
'class' => 'btn btn-lg btn-warning',
],
];
$operations['change-iva'] = [
'text' => '<span><i class="fa fa-percent"></i> '.tr('Aggiorna aliquota iva').'</span>',
'data' => [
'title' => tr('Cambiare l\'aliquota iva?'),
'msg' => tr('Per ciascun articolo selezionato, verrà modificata l\'aliquota iva').'
<br><br>{[ "type": "select", "label": "'.tr('Iva').'", "name": "id_iva", "required": 1, "ajax-source": "iva" ]}',
'button' => tr('Procedi'),
'class' => 'btn btn-lg btn-warning',
],
];
return $operations;

View File

@ -97,7 +97,7 @@ switch (filter('op')) {
$id = $id_record;
}
if ($dbo->fetchNum('SELECT * FROM `mg_articoli` WHERE `id_categoria`='.prepare($id).' OR `id_sottocategoria`='.prepare($id).' OR `id_sottocategoria` IN (SELECT id FROM `mg_categorie` WHERE `parent`='.prepare($id).')') == 0) {
if ($dbo->fetchNum('SELECT * FROM `mg_articoli` WHERE (`id_categoria`='.prepare($id).' OR `id_sottocategoria`='.prepare($id).' OR `id_sottocategoria` IN (SELECT id FROM `mg_categorie` WHERE `parent`='.prepare($id).')) AND `deleted_at` IS NULL') == 0) {
$dbo->query('DELETE FROM `mg_categorie` WHERE `id`='.prepare($id));
flash()->info(tr('Tipologia di _TYPE_ eliminata con successo!', [

View File

@ -91,7 +91,7 @@ include_once __DIR__.'/../../core.php';
<?php
$elementi = $dbo->fetchArray('SELECT `mg_articoli`.`id`, `mg_articoli`.`codice`, `mg_articoli`.`barcode`, `mg_articoli`.`deleted_at` FROM `mg_articoli` WHERE `id_categoria`='.prepare($id_record).' OR `id_sottocategoria`='.prepare($id_record).' OR `id_sottocategoria` IN (SELECT id FROM `mg_categorie` WHERE `parent`='.prepare($id_record).')');
$elementi = $dbo->fetchArray('SELECT `mg_articoli`.`id`, `mg_articoli`.`codice`, `mg_articoli`.`barcode` FROM `mg_articoli` WHERE (`id_categoria`='.prepare($id_record).' OR `id_sottocategoria`='.prepare($id_record).' OR `id_sottocategoria` IN (SELECT id FROM `mg_categorie` WHERE `parent`='.prepare($id_record).')) AND `deleted_at` IS NULL');
if (!empty($elementi)) {
echo '
@ -108,9 +108,8 @@ if (!empty($elementi)) {
<ul>';
foreach ($elementi as $elemento) {
$descrizione = tr('Articolo _CODICE_ _DELETED_AT_', [
$descrizione = tr('Articolo _CODICE_', [
'_CODICE_' => !empty($elemento['codice']) ? $elemento['codice'] : $elemento['barcode'],
'_DELETED_AT_' => (!empty($elemento['deleted_at']) ? tr('Eliminato il:').' '.Translator::dateToLocale($elemento['deleted_at']) : ''),
]);
$modulo = 'Articoli';
$id = $elemento['id'];

View File

@ -564,7 +564,7 @@ echo '
// let end = info.end;
let intero_giorno = !start.hasTime() && !end.hasTime();
if (intero_giorno !== true) {
if (intero_giorno !== true || globals.dashboard.informazioni_aggiuntive==0) {
let data = moment(start).format("YYYY-MM-DD");
let data_fine = moment(end).format("YYYY-MM-DD");
let orario_inizio = moment(start).format("HH:mm");

View File

@ -441,7 +441,7 @@ elseif ($record['stato'] == 'Bozza') {
</div>
<div class="col-md-3">
{[ "type": "number", "label": "'.tr('Sconto finale').'", "name": "sconto_finale", "value": "'.($fattura->sconto_finale_percentuale ?: $fattura->sconto_finale).'", "icon-after": "choice|untprc|'.(empty($fattura->sconto_finale) ? 'PRC' : 'UNT').'", "help": "'.tr('Sconto finale in fattura, utilizzabile per applicare sconti sul Netto a pagare del documento e le relative scadenze').'. '.tr('Per utilizzarlo in relazione a una riga della Fattura Elettronica, inserire il testo di descrizione in \'\'Attributi avanzati\'\' -> \'\'Altri Dati Gestionali\'\' -> \'\'Riferimento Testo\'\' della specifica riga').'. '.tr('Nota: lo sconto finale in fattura non influenza i movimenti contabili').'." ]}
{[ "type": "number", "label": "'.tr('Sconto finale').'", "name": "sconto_finale", "value": "'.($fattura->sconto_finale_percentuale ?: $fattura->sconto_finale).'", "icon-after": "choice|untprc|'.(empty($fattura->sconto_finale) ? 'PRC' : 'UNT').'", "help": "'.tr('Sconto finale in fattura, utilizzabile per applicare sconti sul Netto a pagare del documento e le relative scadenze').'. '.tr('Per utilizzarlo in relazione a una riga della Fattura Elettronica, inserire il tipo di dato in \'\'Attributi avanzati\'\' -> \'\'Altri Dati Gestionali\'\' -> \'\'TipoDato\'\' e il testo di descrizione in \'\'Attributi avanzati\'\' -> \'\'Altri Dati Gestionali\'\' -> \'\'RiferimentoTesto\'\' della specifica riga').'. '.tr('Nota: lo sconto finale in fattura non influenza i movimenti contabili').'." ]}
</div>
</div>';

View File

@ -739,5 +739,14 @@ switch (post('op')) {
flash()->info(tr('Attività duplicata correttamente!'));
break;
case 'update_position':
$order = explode(',', post('order', true));
foreach ($order as $i => $id_riga) {
$dbo->query('UPDATE `in_righe_interventi` SET `order` = '.prepare($i + 1).' WHERE id='.prepare($id_riga));
}
break;
}

View File

@ -47,7 +47,7 @@ if (!$righe->isEmpty()) {
</tr>
</thead>
<tbody>';
<tbody class="sortable">';
foreach ($righe as $riga) {
$extra = '';
@ -158,6 +158,10 @@ if (!$righe->isEmpty()) {
<a class="btn btn-xs btn-danger" title="'.tr('Rimuovi riga').'" onclick="rimuoviRiga(this)">
<i class="fa fa-trash"></i>
</a>
<a class="btn btn-xs btn-default handle" title="'.tr('Modifica ordine delle righe').'">
<i class="fa fa-sort"></i>
</a>
</div>';
echo '
@ -234,4 +238,23 @@ function modificaSeriali(button) {
openModal("'.tr('Aggiorna SN').'", globals.rootdir + "/modules/fatture/add_serial.php?id_module=" + globals.id_module + "&id_record=" + globals.id_record + "&riga_id=" + id + "&riga_type=" + type);
}
$(document).ready(function() {
sortable(".sortable", {
axis: "y",
handle: ".handle",
cursor: "move",
dropOnEmpty: true,
scroll: true,
})[0].addEventListener("sortupdate", function(e) {
let order = $(".table tr[data-id]").toArray().map(a => $(a).data("id"))
$.post(globals.rootdir + "/actions.php", {
id_module: globals.id_module,
id_record: globals.id_record,
op: "update_position",
order: order.join(","),
});
});
});
</script>';

View File

@ -142,9 +142,6 @@ echo '
{[ "type": "number", "label": "<?php echo 'Sconto finale'; ?>", "name": "sconto_finale", "value": "<?php echo $preventivo->sconto_finale_percentuale ?: $preventivo->sconto_finale; ?>", "icon-after": "choice|untprc|<?php echo empty($preventivo->sconto_finale) ? 'PRC' : 'UNT'; ?>", "help": "<?php echo tr('Sconto finale, utilizzabile per applicare sconti sul Netto a pagare del documento'); ?>." ]}
</div>
</div>
<div class="row">
</div>
<div class="row">
@ -167,7 +164,7 @@ echo '
<div class="row">
<div class="col-md-12">
{[ "type": "ckeditor", "use_full_ckeditor": 1, "label": "<?php echo tr('Condizioni generali di fornitura'); ?>", "name": "condizioni_fornitura", "class": "autosize", "value": "$condizioni_fornitura$" ]}
{[ "type": "ckeditor", "use_full_ckeditor": 0, "label": "<?php echo tr('Condizioni generali di fornitura'); ?>", "name": "condizioni_fornitura", "class": "autosize", "value": "$condizioni_fornitura$" ]}
</div>
</div>

View File

@ -55,6 +55,8 @@ class Preventivo extends Document
'data_rifiuto',
];
protected $info = [];
/**
* Crea un nuovo preventivo.
*

View File

@ -20,6 +20,7 @@
include_once __DIR__.'/../../core.php';
use Modules\Anagrafiche\Anagrafica;
use Modules\Banche\Banca;
use Modules\Fatture\Fattura;
/**
@ -137,8 +138,9 @@ foreach ($id_documenti as $id_documento) {
$is_importo_avere = ($dir == 'entrata' && !$is_nota_credito && !$is_insoluto) || ($dir == 'uscita' && ($is_nota_credito || $is_insoluto));
// Predisposizione prima riga
$banca = Banca::find($fattura->id_banca_azienda);
$conto_field = 'idconto_'.($dir == 'entrata' ? 'vendite' : 'acquisti');
$id_conto_aziendale = $fattura->pagamento[$conto_field] ?: setting('Conto aziendale predefinito');
$id_conto_aziendale = $banca->id_pianodeiconti3 ?: ($fattura->pagamento[$conto_field] ?: setting('Conto aziendale predefinito'));
// Predisposizione conto crediti clienti
$conto_field = 'idconto_'.($dir == 'entrata' ? 'cliente' : 'fornitore');

View File

@ -312,7 +312,7 @@ $(document).on("keyup change", "input[id*=dare]", function() {
let row = $(this).parent().parent();
if (!$(this).prop("disabled")) {
row.find("input[id*=avere]").prop("disabled", !!$(this).val());
row.find("input[id*=avere]").prop("disabled", $(this).val().toEnglish());
controllaConti();
}
@ -322,7 +322,7 @@ $(document).on("keyup change", "input[id*=avere]", function() {
let row = $(this).parent().parent();
if (!$(this).prop("disabled")) {
row.find("input[id*=dare]").prop("disabled", !!$(this).val());
row.find("input[id*=dare]").prop("disabled", $(this).val().toEnglish());
controllaConti();
}

View File

@ -178,7 +178,7 @@ function init_calendar(calendar) {
</script>';
// Clienti top
$clienti = $dbo->fetchArray('SELECT SUM(IF(reversed=1, -(co_righe_documenti.subtotale - co_righe_documenti.sconto), (co_righe_documenti.subtotale - co_righe_documenti.sconto))) AS totale, (SELECT COUNT(*) FROM co_documenti WHERE co_documenti.idanagrafica =an_anagrafiche.idanagrafica AND co_documenti.data BETWEEN '.prepare($start).' AND '.prepare($end).") AS qta, an_anagrafiche.idanagrafica, an_anagrafiche.ragione_sociale FROM co_documenti INNER JOIN co_statidocumento ON co_statidocumento.id = co_documenti.idstatodocumento INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id INNER JOIN co_righe_documenti ON co_righe_documenti.iddocumento=co_documenti.id INNER JOIN an_anagrafiche ON an_anagrafiche.idanagrafica=co_documenti.idanagrafica WHERE co_tipidocumento.dir='entrata' AND (co_statidocumento.descrizione = 'Pagato' OR co_statidocumento.descrizione = 'Parzialmente pagato' OR co_statidocumento.descrizione = 'Emessa' ) AND co_documenti.data BETWEEN ".prepare($start).' AND '.prepare($end).' GROUP BY an_anagrafiche.idanagrafica ORDER BY SUM(subtotale - co_righe_documenti.sconto) DESC LIMIT 20');
$clienti = $dbo->fetchArray('SELECT SUM(IF(reversed=1, -(co_righe_documenti.subtotale - co_righe_documenti.sconto), (co_righe_documenti.subtotale - co_righe_documenti.sconto))) AS totale, (SELECT COUNT(*) FROM co_documenti INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id WHERE co_documenti.idanagrafica =an_anagrafiche.idanagrafica AND co_documenti.data BETWEEN '.prepare($start).' AND '.prepare($end)." AND co_tipidocumento.dir='entrata') AS qta, an_anagrafiche.idanagrafica, an_anagrafiche.ragione_sociale FROM co_documenti INNER JOIN co_statidocumento ON co_statidocumento.id = co_documenti.idstatodocumento INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id INNER JOIN co_righe_documenti ON co_righe_documenti.iddocumento=co_documenti.id INNER JOIN an_anagrafiche ON an_anagrafiche.idanagrafica=co_documenti.idanagrafica WHERE co_tipidocumento.dir='entrata' AND (co_statidocumento.descrizione = 'Pagato' OR co_statidocumento.descrizione = 'Parzialmente pagato' OR co_statidocumento.descrizione = 'Emessa' ) AND co_documenti.data BETWEEN ".prepare($start).' AND '.prepare($end).' GROUP BY an_anagrafiche.idanagrafica ORDER BY SUM(subtotale - co_righe_documenti.sconto) DESC LIMIT 20');
$totale = $dbo->fetchArray("SELECT SUM(IF(reversed=1, -(co_righe_documenti.subtotale - co_righe_documenti.sconto), (co_righe_documenti.subtotale - co_righe_documenti.sconto))) AS totale FROM co_documenti INNER JOIN co_statidocumento ON co_statidocumento.id = co_documenti.idstatodocumento INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id INNER JOIN co_righe_documenti ON co_righe_documenti.iddocumento=co_documenti.id WHERE (co_statidocumento.descrizione = 'Pagato' OR co_statidocumento.descrizione = 'Parzialmente pagato' OR co_statidocumento.descrizione = 'Emessa' ) AND co_tipidocumento.dir='entrata' AND co_documenti.data BETWEEN ".prepare($start).' AND '.prepare($end));

View File

@ -128,68 +128,71 @@ if (Services::isEnabled()) {
echo '
<hr><br>
<hr><br>
<div class="alert alert-warning hidden" role="alert" id="spazio-fe">
<i class="fa fa-warning"></i> '.tr('Spazio per Fatture Elettroniche in esaurimento: _NUM_/_TOT_', [
'_NUM_' => '<span id="spazio-fe-occupato"></span>',
'_TOT_' => '<span id="spazio-fe-totale"></span>',
]).'. '.tr("Contatta l'assistenza per maggiori informazioni").'.
</div>
<div class="alert alert-warning hidden" role="alert" id="spazio-fe">
<i class="fa fa-warning"></i> '.tr('Spazio per Fatture Elettroniche in esaurimento: _NUM_/_TOT_', [
'_NUM_' => '<span id="spazio-fe-occupato"></span>',
'_TOT_' => '<span id="spazio-fe-totale"></span>',
]).'. '.tr("Contatta l'assistenza per maggiori informazioni").'.
</div>
<h4>'.tr('Statistiche su Fatture Elettroniche').'</h4>
<table class="table table-striped">
<thead>
<tr>
<th>'.tr('Anno').'</th>
<th>
'.tr('Documenti archiviati').'
<span class="tip" title="'.tr('Fatture attive e relative ricevute, fatture passive').'.">
<i class="fa fa-question-circle-o"></i>
</span>
</th>
<h4>'.tr('Statistiche su Fatture Elettroniche').'</h4>
<table class="table table-striped">
<thead>
<tr>
<th>'.tr('Anno').'</th>
<th>
'.tr('Documenti archiviati').'
<span class="tip" title="'.tr('Fatture attive e relative ricevute, fatture passive').'.">
<i class="fa fa-question-circle-o"></i>
</span>
</th>
<th>
'.tr('Totale spazio occupato').'
<span class="tip" title="'.tr('Fatture attive con eventuali allegati e ricevute, fatture passive con eventuali allegati').'.">
<i class="fa fa-question-circle-o"></i>
</span>
</th>
</tr>
</thead>
<th>
'.tr('Totale spazio occupato').'
<span class="tip" title="'.tr('Fatture attive con eventuali allegati e ricevute, fatture passive con eventuali allegati').'.">
<i class="fa fa-question-circle-o"></i>
</span>
</th>
</tr>
</thead>
<tbody id="elenco-fe">
<tr class="info">
<td>'.tr('Totale').'</td>
<td id="fe_numero"></td>
<td id="fe_spazio"></td>
</tr>
</tbody>
</table>
<tbody id="elenco-fe">
<tr class="info">
<td>'.tr('Totale').'</td>
<td id="fe_numero"></td>
<td id="fe_spazio"></td>
</tr>
</tbody>
</table>
<script>
$(document).ready(function (){
aggiornaStatisticheFE();
});
</script>';
<script>
$(document).ready(function (){
aggiornaStatisticheFE();
});
</script>';
} else {
echo '
<div class="alert alert-warning" role="alert">
<i class="fa fa-warning"></i> '.tr('Nessuna risorsa Services abilitata').'.
</div>';
<div class="alert alert-warning" role="alert">
<i class="fa fa-warning"></i> '.tr('Nessuna risorsa Services abilitata').'.
</div>';
}
echo '
</div>
</div>
</div>';
} else {
/*
echo '
<div class="col-md-12 col-lg-6">
<div class="alert alert-warning" role="alert">
<i class="fa fa-warning"></i> '.tr("Configurazione per l'accesso Services non completata correttamente").'. '.tr('Per abilitare i servizi, compilare l\'impostazione "OSMCloud Services API Token"').'.
</div>
</div>';
*/
}
echo '

View File

@ -22,23 +22,38 @@ namespace Modules\StatoServizi;
use API\Services;
use Carbon\Carbon;
use Hooks\Manager;
use Models\Module;
class ServicesHook extends Manager
{
public function response()
{
// Elaborazione dei servizi in scadenza
$limite_scadenze = (new Carbon())->addDays(60);
$risorse_in_scadenza = Services::getRisorseInScadenza($limite_scadenze);
$message = '';
$message = tr('I seguenti servizi sono in scadenza: _LIST_', [
'_LIST_' => implode(', ', $risorse_in_scadenza->pluck('nome')->all()),
]);
// Elaborazione dei servizi in scadenza
$servizi_in_scadenza = Services::getServiziInScadenza($limite_scadenze);
if (!$servizi_in_scadenza->isEmpty()) {
$message .= tr('I seguenti servizi sono in scadenza: _LIST_', [
'_LIST_' => implode(', ', $servizi_in_scadenza->pluck('nome')->all()),
]).'. ';
}
// Elaborazione delle risorse Services in scadenza
$risorse_in_scadenza = Services::getRisorseInScadenza($limite_scadenze);
if (!$risorse_in_scadenza->isEmpty()) {
$message .= tr('Le seguenti risorse Services sono in scadenza: _LIST_', [
'_LIST_' => implode(', ', $risorse_in_scadenza->pluck('name')->all()),
]);
}
$module = Module::pool('Stato dei servizi');
return [
'icon' => 'fa fa-refresh text-warning',
'message' => $message,
'show' => !$risorse_in_scadenza->isEmpty(),
'link' => base_path().'/controller.php?id_module='.$module->id,
'show' => Services::isEnabled() && !empty($message),
];
}

View File

@ -132,6 +132,7 @@ switch (filter('op')) {
'movimentazione' => post('movimentazione'),
'crea_articoli' => post('crea_articoli'),
'is_ritenuta_pagata' => post('is_ritenuta_pagata'),
'update_info' => post('update_info'),
];
$fattura_pa = FatturaElettronica::manage($filename);

View File

@ -294,6 +294,14 @@ echo '
</div>';
// Righe
if (setting('Aggiorna info di acquisto')=='Non aggiornare'){
$update_info = 'update_not';
} elseif (setting('Aggiorna info di acquisto')=='Aggiorna prezzo di listino'){
$update_info ='update_price';
} else{
$update_info = 'update_all';
}
$righe = $fattura_pa->getRighe();
if (!empty($righe)) {
echo '
@ -346,11 +354,19 @@ if (!empty($righe)) {
if (!empty($codice_principale)) {
if (!empty($anagrafica) && empty($id_articolo)) {
$id_articolo = $database->fetchOne('SELECT id_articolo AS id FROM mg_fornitore_articolo WHERE codice_fornitore = '.prepare($codice_principale).' AND id_fornitore = '.prepare($anagrafica->id))['id'];
if (empty($id_articolo)) {
$id_articolo = $database->fetchOne('SELECT id_articolo AS id FROM mg_fornitore_articolo WHERE REPLACE(codice_fornitore, " ", "") = '.prepare($codice_principale).' AND id_fornitore = '.prepare($anagrafica->id))['id'];
}
}
if (empty($id_articolo)) {
$id_articolo = $database->fetchOne('SELECT id FROM mg_articoli WHERE codice = '.prepare($codice_principale))['id'];
if (empty($id_articolo)) {
$id_articolo = $database->fetchOne('SELECT id FROM mg_articoli WHERE REPLACE(codice, " ", "") = '.prepare($codice_principale))['id'];
}
}
$idconto_acquisto = $database->fetchOne('SELECT idconto_acquisto FROM mg_articoli WHERE id = '.prepare($id_articolo))['idconto_acquisto'];
}
$qta = $riga['Quantita'];
@ -405,34 +421,45 @@ if (!empty($righe)) {
<input type="hidden" name="id_riga_riferimento_vendita['.$key.']" id="id_riga_riferimento_vendita_'.$key.'" value="">
<input type="hidden" name="tipo_riga_riferimento_vendita['.$key.']" id="tipo_riga_riferimento_vendita_'.$key.'" value="">
<div class="col-md-12">
<div class="box collapsed-box" style="background:#eeeeee;">
<div class="box-header">
<div class="row">
<div class="col-md-5">
{[ "type": "select", "name": "articoli['.$key.']", "ajax-source": "articoli", "select-options": '.json_encode(['permetti_movimento_a_zero' => 1, 'dir' => 'entrata', 'idanagrafica' => $anagrafica ? $anagrafica->id : '']).', "icon-after": "add|'.Modules::get('Articoli')['id'].'|codice='.str_replace('\\', '/', htmlentities($codice_principale)).'&descrizione='.str_replace('\\', '/', str_replace('\'', '&lsquo;', htmlentities($riga['Descrizione']))).'", "value": "'.$id_articolo.'", "label": "'.tr('Articolo').'", "extra": "data-id=\''.$key.'\'" ]}
</div>
<div class="row">
<div class="col-md-6">
{[ "type": "select", "name": "articoli['.$key.']", "ajax-source": "articoli", "select-options": '.json_encode(['permetti_movimento_a_zero' => 1, 'dir' => 'entrata', 'idanagrafica' => $anagrafica ? $anagrafica->id : '']).', "icon-after": "add|'.Modules::get('Articoli')['id'].'|codice='.str_replace('\\', '/', htmlentities($codice_principale)).'&descrizione='.str_replace('\\', '/', str_replace('\'', '&lsquo;', htmlentities($riga['Descrizione']))).'", "value": "'.$id_articolo.'", "label": "'.tr('Articolo').'" ]}
</div>
<div class="col-md-3">
{[ "type": "select", "name": "conto['.$key.']", "id": "conto-'.$key.'", "ajax-source": "conti-acquisti", "required": 1, "label": "'.tr('Conto acquisti').'", "value": "'.$idconto_acquisto.'" ]}
</div>
<div class="col-md-3">
{[ "type": "select", "name": "conto['.$key.']", "ajax-source": "conti-acquisti", "required": 1, "label": "'.tr('Conto acquisti').'" ]}
</div>
<div class="col-md-3">
{[ "type": "select", "name": "iva['.$key.']", "values": '.json_encode('query='.$query).', "required": 1, "label": "'.tr('Aliquota IVA').'" ]}
</div>
<div class="col-md-3">
{[ "type": "select", "name": "iva['.$key.']", "values": '.json_encode('query='.$query).', "required": 1, "label": "'.tr('Aliquota IVA').'" ]}
<div class="col-md-1 box-tools">
<br>
<button type="button" class="btn btn-box-tool" data-widget="collapse" onclick="$(this).find(\'i\').toggleClass(\'fa-plus\').toggleClass(\'fa-minus\');">
<i class="fa fa-plus"></i> '.tr('Altro').'
</button>
</div>
</div>
</div>
<div class="box-body">
<div class="row">
<div class="col-md-3">
{[ "type": "select", "name": "selezione_riferimento['.$key.']", "ajax-source": "riferimenti-fe", "select-options": '.json_encode(['id_anagrafica' => $anagrafica ? $anagrafica->id : '']).', "label": "'.tr('Riferimento acquisto').'", "icon-after": '.json_encode('<button type="button" onclick="rimuoviRiferimento(this)" class="btn btn-primary disabled" id="rimuovi_riferimento_'.$key.'"><i class="fa fa-close"></i></button>').', "help": "'.tr('Articoli contenuti in Ordini o DDT del Fornitore').'" ]}
</div>
<div class="row">
<div class="col-md-3">
{[ "type": "select", "name": "selezione_riferimento['.$key.']", "ajax-source": "riferimenti-fe", "select-options": '.json_encode(['id_anagrafica' => $anagrafica ? $anagrafica->id : '']).', "label": "'.tr('Riferimento acquisto').'", "icon-after": '.json_encode('<button type="button" onclick="rimuoviRiferimento(this)" class="btn btn-primary disabled" id="rimuovi_riferimento_'.$key.'"><i class="fa fa-close"></i></button>').', "help": "'.tr('Articoli contenuti in Ordini o DDT del Fornitore').'" ]}
<div class="col-md-3">
{[ "type": "select", "name": "selezione_riferimento_vendita['.$key.']", "ajax-source": "riferimenti-vendita-fe", "select-options": '.json_encode(['id_articolo' => $id_articolo]).', "label": "'.tr('Riferimento vendita').'", "icon-after": '.json_encode('<button type="button" onclick="rimuoviRiferimentoVendita(this)" class="btn btn-primary disabled" id="rimuovi_riferimento_vendita_'.$key.'"><i class="fa fa-close"></i></button>').', "help": "'.tr('Articoli contenuti in Ordini Cliente').'" ]}
</div>
<div class="col-md-6">
{[ "type": "select", "name": "update_info['.$key.']", "values": "list=\"update_not\":\"Non aggiornare\", \"update_price\":\"Aggiorna prezzo di listino\", \"update_all\":\"Aggiorna prezzo di acquisto + imposta fornitore predefinito\"", "label": "'.tr('Aggiorna info di acquisto').'", "value": "'.$update_info.'" ]}
</div>
</div>
<div class="col-md-3">
{[ "type": "select", "name": "selezione_riferimento_vendita['.$key.']", "ajax-source": "riferimenti-vendita-fe", "select-options": '.json_encode(['id_articolo' => $id_articolo]).', "label": "'.tr('Riferimento vendita').'", "icon-after": '.json_encode('<button type="button" onclick="rimuoviRiferimentoVendita(this)" class="btn btn-primary disabled" id="rimuovi_riferimento_vendita_'.$key.'"><i class="fa fa-close"></i></button>').', "help": "'.tr('Articoli contenuti in Ordini Cliente').'" ]}
</div>
</div>
</div>
</div>
</td>
</tr>';
}
@ -675,6 +702,11 @@ function rimuoviRiferimentoVendita(button) {
}
$("[id^=\'articoli\']").change(function() {
$("#conto-"+$(this).data("id")).selectReset();
updateSelectOption("id_articolo", $(this).val());
let data = $(this).selectData();
if(data!==undefined){
$("#conto-"+$(this).data("id")).selectSetNew(data.idconto_acquisto, data.idconto_acquisto_title);
}
});
</script>';

View File

@ -21,6 +21,7 @@ namespace Plugins\ImportFE;
use Modules;
use Modules\Anagrafiche\Anagrafica;
use Modules\Banche\Banca;
use Modules\Anagrafiche\Nazione;
use Modules\Anagrafiche\Tipo as TipoAnagrafica;
use Modules\Fatture\Fattura;
@ -320,6 +321,15 @@ class FatturaElettronica
$fattura->idpagamento = $id_pagamento;
$fattura->is_ritenuta_pagata = $is_ritenuta_pagata;
// Banca addebito del cliente o banca collegata al pagamento
if (!empty($fattura->anagrafica->idbanca_acquisti)) {
$banca = $fattura->anagrafica->idbanca_acquisti;
} else {
$banca = Banca::where('id_pianodeiconti3', $fattura->pagamento->idconto_acquisti)->where('id_anagrafica', setting('Azienda predefinita'))->first()->id;
}
$fattura->id_banca_azienda = $banca;
// Riferimento per nota di credito e debito
$fattura->ref_documento = $ref_fattura ?: null;
@ -359,7 +369,7 @@ class FatturaElettronica
{
$this->saveFattura($info['id_pagamento'], $info['id_segment'], $info['id_tipo'], $info['data_registrazione'], $info['ref_fattura'], $info['is_ritenuta_pagata']);
$this->saveRighe($info['articoli'], $info['iva'], $info['conto'], $info['movimentazione'], $info['crea_articoli'], $info['tipo_riga_riferimento'], $info['id_riga_riferimento'], $info['tipo_riga_riferimento_vendita'], $info['id_riga_riferimento_vendita']);
$this->saveRighe($info['articoli'], $info['iva'], $info['conto'], $info['movimentazione'], $info['crea_articoli'], $info['tipo_riga_riferimento'], $info['id_riga_riferimento'], $info['tipo_riga_riferimento_vendita'], $info['id_riga_riferimento_vendita'], $info['update_info']);
$this->saveAllegati();

View File

@ -110,12 +110,14 @@ class FatturaOrdinaria extends FatturaElettronica
return $this->forceArray($result);
}
public function saveRighe($articoli, $iva, $conto, $movimentazione = true, $crea_articoli = false, $tipi_riferimenti = [], $id_riferimenti = [], $tipi_riferimenti_vendita = [], $id_riferimenti_vendita = [])
public function saveRighe($articoli, $iva, $conto, $movimentazione = true, $crea_articoli = false, $tipi_riferimenti = [], $id_riferimenti = [], $tipi_riferimenti_vendita = [], $id_riferimenti_vendita = [], $update_info = [])
{
$info = $this->getRitenutaRivalsa();
$righe = $this->getRighe();
$fattura = $this->getFattura();
$anagrafica = Anagrafica::find($fattura->idanagrafica);
$direzione = 'uscita';
$id_ritenuta_acconto = $info['id_ritenuta_acconto'];
$id_rivalsa = $info['id_rivalsa'];
@ -150,8 +152,6 @@ class FatturaOrdinaria extends FatturaElettronica
$articolo->idconto_acquisto = $conto[$key];
$articolo->save();
$direzione = 'uscita';
$anagrafica = Anagrafica::find($fattura->idanagrafica);
$dettaglio_prezzo = DettaglioPrezzo::build($articolo, $anagrafica, $direzione);
$dettaglio_prezzo->setPrezzoUnitario($riga['PrezzoUnitario']);
@ -162,7 +162,7 @@ class FatturaOrdinaria extends FatturaElettronica
if (!empty($articolo)) {
$articolo->idconto_acquisto = $conto[$key];
$articolo->save();
$obj = Articolo::build($fattura, $articolo);
$obj->movimentazione($movimentazione);
@ -254,7 +254,7 @@ class FatturaOrdinaria extends FatturaElettronica
'qta' => $obj->qta,
'cumulativo' => false,
]);
if ($tipo == 'PRC') {
$tot_sconto = $sconto_calcolato * 100 / $obj->imponibile;
} else {
@ -264,14 +264,42 @@ class FatturaOrdinaria extends FatturaElettronica
$tot_sconto = $sconto_riga;
}
$sconto_unitario += $tot_sconto;
$sconto_unitario += $tot_sconto;
}
$obj->setSconto($sconto_unitario, $tipo);
$tipo = null;
$obj->setSconto($sconto_unitario, $tipo);
}
// Aggiornamento prezzo di acquisto e fornitore predefinito in base alle impostazioni
if (!empty($articolo)) {
if ($update_info[$key]=='update_price' || $update_info[$key]=='update_all') {
$dettaglio_predefinito = DettaglioPrezzo::dettaglioPredefinito($articolo->id, $anagrafica->idanagrafica, $direzione)
->first();
// Aggiungo associazione fornitore-articolo se non presente
if (empty($dettaglio_predefinito)) {
$dettaglio_predefinito = DettaglioPrezzo::build($articolo, $anagrafica, $direzione);
}
// Aggiornamento listino
$dettaglio_predefinito->sconto_percentuale = 0;
$dettaglio_predefinito->setPrezzoUnitario($obj->prezzo_unitario);
$dettaglio_predefinito->save();
// Aggiornamento fornitore predefinito
if ($update_info[$key]=='update_all') {
// Aggiornamento prezzo di acquisto e fornitore predefinito
$articolo->prezzo_acquisto = $obj->prezzo_unitario;
$articolo->id_fornitore = $anagrafica->idanagrafica;
$articolo->save();
}
}
}
$tipo = null;
$sconto_unitario = null;
$obj->save();
}
// Ricaricamento della fattura

View File

@ -189,13 +189,13 @@ echo '
<div class="col-md-4">
<div class="info-box">
<span class="info-box-icon bg-'.($fatture_vendita->count() == 0 ? 'gray' : 'green').'"><i class="fa fa-money"></i></span>
<span class="info-box-icon bg-'.($fatture_vendita->count()+$note_credito->count() == 0 ? 'gray' : 'green').'"><i class="fa fa-money"></i></span>
<div class="info-box-content">
<span class="info-box-text pull-left">'.tr('Fatture').'</span>
'.($fatture_vendita->count() > 0 ? '<span class="info-box-text pull-right"><a href="'.base_path().'/controller.php?id_module='.Modules::get('Fatture di vendita')['id'].'&search_Ragione-sociale='.rawurlencode($anagrafica['ragione_sociale']).'">'.tr('Visualizza').' <i class="fa fa-chevron-circle-right"></i></a></span>' : '').'
'.($fatture_vendita->count()+$note_credito->count() > 0 ? '<span class="info-box-text pull-right"><a href="'.base_path().'/controller.php?id_module='.Modules::get('Fatture di vendita')['id'].'&search_Ragione-sociale='.rawurlencode($anagrafica['ragione_sociale']).'">'.tr('Visualizza').' <i class="fa fa-chevron-circle-right"></i></a></span>' : '').'
<br class="clearfix">
<span class="info-box-number">
<big>'.$fatture_vendita->count().'</big><br>
<big>'.($fatture_vendita->count()+$note_credito->count()).'</big><br>
<small class="help-block">'.moneyFormat($totale_fatture_vendita).'</small>
</span>
</div>

View File

@ -74,6 +74,22 @@ class Services
return collect(self::getInformazioni()['servizi']);
}
/**
* Restituisce i servizi in scadenza per data di conclusione prossima.
*
* @param Carbon $limite_scadenze
*
* @return \Illuminate\Support\Collection
*/
public static function getServiziInScadenza($limite_scadenze)
{
return self::getServiziAttivi()
->flatten(1)
->filter(function ($item) use ($limite_scadenze) {
return (isset($item['data_conclusione']) && Carbon::parse($item['data_conclusione'])->lessThan($limite_scadenze));
});
}
/**
* Restituisce le risorse attive in Services.
*

View File

@ -129,5 +129,4 @@ ALTER TABLE `em_accounts` ADD `id_oauth2` INT(11) DEFAULT NULL,
-- Aggiunta opt-out Newsletter per Referenti e Sedi
ALTER TABLE `an_referenti` ADD `enable_newsletter` BOOLEAN DEFAULT TRUE;
ALTER TABLE `an_sedi` ADD `enable_newsletter` BOOLEAN DEFAULT TRUE;
ALTER TABLE `an_sedi` ADD `enable_newsletter` BOOLEAN DEFAULT TRUE;

15
update/2_4_27.sql Normal file
View File

@ -0,0 +1,15 @@
-- Aggiunta impostazione aggiornamento prezzi e fornitore in fase di import FE
INSERT INTO `zz_settings` (`id`, `nome`, `valore`, `tipo`, `editable`, `sezione`, `order`, `help`) VALUES (NULL, 'Aggiorna info di acquisto', 'Non aggiornare', 'list[Non aggiornare,Aggiorna prezzo di listino,Aggiorna prezzo di acquisto + imposta fornitore predefinito]', '1', 'Fatturazione', '16', NULL);
-- Aggiunto filtro per mostrare gli impianti ai tecnici assegnati (Disabilitato di default)
INSERT INTO `zz_group_module` (`idgruppo`, `idmodule`, `name`, `clause`, `position`, `enabled`, `default`) VALUES
((SELECT `id` FROM `zz_groups` WHERE `nome`='Tecnici'), (SELECT `id` FROM `zz_modules` WHERE `name`='Impianti'), 'Mostra impianti ai tecnici assegnati', 'my_impianti.idtecnico=|id_anagrafica|', 'WHR', 0, 1);
-- Ridotto il valid time per la cache informazioni su Services
UPDATE `zz_cache` SET `valid_time` = '1 day' WHERE `zz_cache`.`name` = 'Informazioni su Services';
-- Ridotto il valid time per la cache informazioni su spazio FE
UPDATE `zz_cache` SET `valid_time` = '1 day' WHERE `zz_cache`.`name` = 'Informazioni su spazio FE';
-- Ordinamento righe intervento
ALTER TABLE `in_righe_interventi` ADD `order` INT NOT NULL AFTER `idsede_partenza`;