Merge branch 'master' into 2.4.2

This commit is contained in:
Thomas Zilio 2018-07-28 18:02:17 +02:00
commit b61f754d13
12 changed files with 230 additions and 74 deletions

View File

@ -326,12 +326,25 @@ if ($read_only || !empty($block_edit)) {
content_was_modified = false; content_was_modified = false;
}); });
// questo controllo blocca il modulo vendita al banco, dopo la lettura con barcode, appare il messaggio di conferma // questo controllo blocca il modulo vendita al banco, dopo la lettura con barcode, appare il messaggio di conferma
window.onbeforeunload = function(){ window.onbeforeunload = function(e){
if(content_was_modified) { if(content_was_modified) {
return 'Uscire senza salvare?'; var dialogText = "Uscire senza salvare?";
e.returnValue = dialogText;
$("#main_loading").fadeOut();
return dialogText;
} }
}; };
window.addEventListener("unload", function(e) {
//console.log(e);
$("#main_loading").show();
});
<?php <?php
if ($advanced_sessions) { if ($advanced_sessions) {
?> ?>

View File

@ -15,6 +15,7 @@ if ($module['name'] == 'Fatture di acquisto' || $module['name'] == 'Fatture di v
// Percentuale rivalsa INPS e Percentuale ritenuta d'acconto // Percentuale rivalsa INPS e Percentuale ritenuta d'acconto
if ($options['action'] == 'edit') { if ($options['action'] == 'edit') {
if ($options['dir'] == 'uscita') { if ($options['dir'] == 'uscita') {
//Luca S. questi campi non dovrebbero essere impostati a 1 di default, ma solo se il fornitore ha effettivamente rivalsa inps o ritenuta
$show_idrivalsainps = 1; $show_idrivalsainps = 1;
$show_idritenutaacconto = 1; $show_idritenutaacconto = 1;
$show_calcolo_ritenutaacconto = 1; $show_calcolo_ritenutaacconto = 1;
@ -45,8 +46,10 @@ if ($module['name'] == 'Fatture di acquisto' || $module['name'] == 'Fatture di v
$show_idritenutaacconto = 1; $show_idritenutaacconto = 1;
$show_calcolo_ritenutaacconto = 1; $show_calcolo_ritenutaacconto = 1;
// Luca S. questi campi non dovrebbero essere definiti all'interno della scheda fornitore?
$idrivalsainps = ''; $idrivalsainps = '';
$idritenutaacconto = ''; $idritenutaacconto = '';
// questo campo non andrebbe letto da impostazioni
$calcolo_ritenutaacconto = setting("Metodologia calcolo ritenuta d'acconto predefinito"); $calcolo_ritenutaacconto = setting("Metodologia calcolo ritenuta d'acconto predefinito");
} elseif ($options['dir'] == 'entrata' && $options['op'] == 'addriga' && (setting('Percentuale rivalsa INPS') != '' || setting("Percentuale ritenuta d'acconto") != '')) { } elseif ($options['dir'] == 'entrata' && $options['op'] == 'addriga' && (setting('Percentuale rivalsa INPS') != '' || setting("Percentuale ritenuta d'acconto") != '')) {
if (setting('Percentuale rivalsa INPS') != '') { if (setting('Percentuale rivalsa INPS') != '') {
@ -117,7 +120,7 @@ if ($module['name'] == 'Fatture di acquisto' || $module['name'] == 'Fatture di v
if ($show_calcolo_ritenutaacconto == 1) { if ($show_calcolo_ritenutaacconto == 1) {
echo ' echo '
<div class="col-md-4"> <div class="col-md-4">
{[ "type": "select", "label": "'.tr("Calcola ritenuta d'acconto su").'", "name": "calcolo_ritenutaacconto", "value": "'.$calcolo_ritenutaacconto.'", "values": "list=\"Imponibile\":\"Imponibile\", \"Imponibile + rivalsa inps\":\"Imponibile + rivalsa inps\"", "required": "1" ]} {[ "type": "select", "label": "'.tr("Calcola ritenuta d'acconto su").'", "name": "calcolo_ritenutaacconto", "value": "'.((empty($calcolo_ritenutaacconto)) ? 'Imponibile' : $calcolo_ritenutaacconto).'", "values": "list=\"Imponibile\":\"Imponibile\", \"Imponibile + rivalsa inps\":\"Imponibile + rivalsa inps\"", "required": "1" ]}
</div>'; </div>';
} }

View File

@ -69,6 +69,8 @@ switch (post('op')) {
case 'update': case 'update':
if (post('id_record') !== null) { if (post('id_record') !== null) {
include_once Modules::filepath($module['name'], 'modutil.php');
$idstatodocumento = post('idstatodocumento'); $idstatodocumento = post('idstatodocumento');
$idpagamento = post('idpagamento'); $idpagamento = post('idpagamento');
@ -525,7 +527,7 @@ switch (post('op')) {
// Calcolo iva // Calcolo iva
$query = 'SELECT * FROM co_iva WHERE id='.prepare($idiva); $query = 'SELECT * FROM co_iva WHERE id='.prepare($idiva);
$rs = $dbo->fetchArray($query); $rs = $dbo->fetchArray($query);
$iva = ($prezzo-$sconto) / 100 * $rs[0]['percentuale']; $iva = ($prezzo - $sconto) / 100 * $rs[0]['percentuale'];
$iva_indetraibile = $iva / 100 * $rs[0]['indetraibile']; $iva_indetraibile = $iva / 100 * $rs[0]['indetraibile'];
$desc_iva = $rs[0]['descrizione']; $desc_iva = $rs[0]['descrizione'];
@ -590,8 +592,16 @@ switch (post('op')) {
} }
} else { } else {
// Aggiunta riga preventivo sul documento // Aggiunta riga preventivo sul documento
$query = 'INSERT INTO co_righe_documenti(iddocumento, idpreventivo, idconto, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, idritenutaacconto, ritenutaacconto, idrivalsainps, rivalsainps, `order`) VALUES('.prepare($id_record).', '.prepare($idpreventivo).', '.prepare($idconto).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($prezzo).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).", '-', 1, ".prepare(setting("Percentuale ritenuta d'acconto")).', '.prepare($ritenutaacconto).', '.prepare(setting('Percentuale rivalsa INPS')).', '.prepare($rivalsainps).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))'; $query = 'INSERT INTO co_righe_documenti(iddocumento, idpreventivo, is_preventivo, idconto, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, idritenutaacconto, ritenutaacconto, idrivalsainps, rivalsainps, `order`) VALUES('.prepare($id_record).', '.prepare($idpreventivo).', "1", '.prepare($idconto).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($prezzo).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).", '-', 1, ".prepare(setting("Percentuale ritenuta d'acconto")).', '.prepare($ritenutaacconto).', '.prepare(setting('Percentuale rivalsa INPS')).', '.prepare($rivalsainps).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))';
$dbo->query($query); $dbo->query($query);
// Scarico gli articoli nel preventivo
$righe = $dbo->fetchArray('SELECT * FROM co_righe_preventivi WHERE idpreventivo='.prepare($idpreventivo));
foreach ($righe as $key => $riga) {
if (!empty($riga['idarticolo'])) {
add_movimento_magazzino($riga['idarticolo'], -$riga['qta'], ['iddocumento' => $id_record]);
}
}
} }
// Aggiorno lo stato degli interventi collegati al preventivo se ce ne sono // Aggiorno lo stato degli interventi collegati al preventivo se ce ne sono
@ -653,7 +663,7 @@ switch (post('op')) {
// Calcolo iva // Calcolo iva
$query = 'SELECT * FROM co_iva WHERE id='.prepare($idiva); $query = 'SELECT * FROM co_iva WHERE id='.prepare($idiva);
$rs = $dbo->fetchArray($query); $rs = $dbo->fetchArray($query);
$iva = ($prezzo-$sconto) / 100 * $rs[0]['percentuale']; $iva = ($prezzo - $sconto) / 100 * $rs[0]['percentuale'];
$iva_indetraibile = $iva / 100 * $rs[0]['indetraibile']; $iva_indetraibile = $iva / 100 * $rs[0]['indetraibile'];
$desc_iva = $rs[0]['descrizione']; $desc_iva = $rs[0]['descrizione'];
@ -672,12 +682,20 @@ switch (post('op')) {
} }
// Aggiunta riga contratto sul documento // Aggiunta riga contratto sul documento
$query = 'INSERT INTO co_righe_documenti(iddocumento, idcontratto, idconto, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, idrivalsainps, rivalsainps, idritenutaacconto, ritenutaacconto, calcolo_ritenutaacconto, `order`) VALUES('.prepare($id_record).', '.prepare($idcontratto).', '.prepare($idconto).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($prezzo).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).", '-', 1, ".prepare(setting('Percentuale rivalsa INPS')).', '.prepare($rivalsainps).', '.prepare(setting("Percentuale ritenuta d'acconto")).', '.prepare($ritenutaacconto).', '.prepare(setting("Metodologia calcolo ritenuta d'acconto predefinito")).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))'; $query = 'INSERT INTO co_righe_documenti(iddocumento, idcontratto, is_contratto, idconto, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, idrivalsainps, rivalsainps, idritenutaacconto, ritenutaacconto, calcolo_ritenutaacconto, `order`) VALUES('.prepare($id_record).', '.prepare($idcontratto).', "1", '.prepare($idconto).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($prezzo).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).", '-', 1, ".prepare(setting('Percentuale rivalsa INPS')).', '.prepare($rivalsainps).', '.prepare(setting("Percentuale ritenuta d'acconto")).', '.prepare($ritenutaacconto).', '.prepare(setting("Metodologia calcolo ritenuta d'acconto predefinito")).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))';
if ($dbo->query($query)) { if ($dbo->query($query)) {
flash()->info(tr('Contratto _NUM_ aggiunto!', [ flash()->info(tr('Contratto _NUM_ aggiunto!', [
'_NUM_' => $numero, '_NUM_' => $numero,
])); ]));
//Scalo le qta degli articoli nel contratto
$righe = $dbo->fetchArray('SELECT * FROM co_righe_contratti WHERE idcontratto='.prepare($idcontratto));
foreach ($righe as $key => $riga) {
if (!empty($riga['idarticolo'])) {
add_movimento_magazzino($riga['idarticolo'], -$riga['qta'], ['iddocumento' => $id_record]);
}
}
// Aggiorno il budget sul contratto con l'importo inserito in fattura e imposto lo stato del contratto "In attesa di pagamento" (se selezionato) // Aggiorno il budget sul contratto con l'importo inserito in fattura e imposto lo stato del contratto "In attesa di pagamento" (se selezionato)
if ($aggiorna_budget) { if ($aggiorna_budget) {
$dbo->query('UPDATE co_contratti SET budget='.prepare($prezzo).' WHERE id='.prepare($idcontratto)); $dbo->query('UPDATE co_contratti SET budget='.prepare($prezzo).' WHERE id='.prepare($idcontratto));
@ -703,9 +721,9 @@ switch (post('op')) {
$idiva = post('idiva'); $idiva = post('idiva');
$idconto = post('idconto'); $idconto = post('idconto');
$idum = post('um'); $idum = post('um');
$idrivalsainps = post('idrivalsainps'); $idrivalsainps = post('idrivalsainps');
$idritenutaacconto = post('idritenutaacconto'); $idritenutaacconto = post('idritenutaacconto');
$calcolo_ritenutaacconto = post('calcolo_ritenutaacconto'); $calcolo_ritenutaacconto = post('calcolo_ritenutaacconto');
$qta = post('qta'); $qta = post('qta');
if (!empty($record['is_reversed'])) { if (!empty($record['is_reversed'])) {
@ -726,7 +744,7 @@ switch (post('op')) {
add_articolo_infattura($id_record, $idarticolo, $descrizione, $idiva, $qta, $prezzo * $qta, $sconto, $sconto_unitario, $tipo_sconto, '0', $idconto, $idum, $idrivalsainps, $idritenutaacconto, $calcolo_ritenutaacconto); add_articolo_infattura($id_record, $idarticolo, $descrizione, $idiva, $qta, $prezzo * $qta, $sconto, $sconto_unitario, $tipo_sconto, '0', $idconto, $idum, $idrivalsainps, $idritenutaacconto, $calcolo_ritenutaacconto);
ricalcola_costiagg_fattura($id_record); ricalcola_costiagg_fattura($id_record);
flash()->info(tr('Articolo aggiunto!')); flash()->info(tr('Articolo aggiunto!'));
} }
@ -1253,26 +1271,28 @@ switch (post('op')) {
$idriga = post('idriga'); $idriga = post('idriga');
// Lettura preventivi collegati // Lettura preventivi collegati
$query = 'SELECT iddocumento, idpreventivo, idarticolo FROM co_righe_documenti WHERE id='.prepare($idriga); $query = 'SELECT iddocumento, idpreventivo, is_preventivo, idarticolo FROM co_righe_documenti WHERE id='.prepare($idriga);
$rsp = $dbo->fetchArray($query); $rsp = $dbo->fetchArray($query);
$id_record = $rsp[0]['iddocumento']; $id_record = $rsp[0]['iddocumento'];
$idpreventivo = $rsp[0]['idpreventivo']; $idpreventivo = $rsp[0]['idpreventivo'];
$idarticolo = $rsp[0]['idarticolo']; $is_preventivo = $rsp[0]['is_preventivo'];
$idarticolo = $rsp[0]['idarticolo'];
//preventivo su unica riga, perdo il riferimento dell'articolo quindi lo vado a leggere da co_righe_preventivi
if (empty($idarticolo)){
//rimetto a magazzino gli articoli collegati al preventivo
$rsa = $dbo->fetchArray('SELECT idarticolo, qta FROM co_righe_preventivi WHERE idpreventivo = '.prepare($idpreventivo));
for ($i = 0; $i < sizeof($rsa); ++$i) {
if (!empty($rsa[$i]['idarticolo']))
add_movimento_magazzino($rsa[$i]['idarticolo'], $rsa[$i]['qta'], ['iddocumento' => $id_record]);
//rimuovi_articolo_dafattura($rsa[$i]['idarticolo'], $id_record, $idriga);
}
}else{
$rs5 = $dbo->fetchArray('SELECT idarticolo, id, qta FROM co_righe_documenti WHERE id = '.prepare($idriga).' AND idintervento IS NULL');
rimuovi_articolo_dafattura($rs5[0]['idarticolo'], $id_record, $idriga);
}
//preventivo su unica riga, perdo il riferimento dell'articolo quindi lo vado a leggere da co_righe_preventivi
if (empty($idarticolo) && $is_preventivo) {
//rimetto a magazzino gli articoli collegati al preventivo
$rsa = $dbo->fetchArray('SELECT idarticolo, qta FROM co_righe_preventivi WHERE idpreventivo = '.prepare($idpreventivo));
for ($i = 0; $i < sizeof($rsa); ++$i) {
if (!empty($rsa[$i]['idarticolo'])) {
add_movimento_magazzino($rsa[$i]['idarticolo'], $rsa[$i]['qta'], ['iddocumento' => $id_record]);
}
}
} else {
if (!empty($idarticolo)) {
$rs5 = $dbo->fetchArray('SELECT idarticolo, id, qta FROM co_righe_documenti WHERE id = '.prepare($idriga).' AND idintervento IS NULL');
rimuovi_articolo_dafattura($rs5[0]['idarticolo'], $id_record, $idriga);
}
}
$query = 'DELETE FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND id='.prepare($idriga); $query = 'DELETE FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND id='.prepare($idriga);
@ -1319,7 +1339,7 @@ switch (post('op')) {
$idriga = post('idriga'); $idriga = post('idriga');
// Lettura contratti collegati // Lettura contratti collegati
$query = 'SELECT iddocumento, idcontratto FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND idcontratto IS NOT NULL AND NOT idcontratto=0'; $query = 'SELECT iddocumento, idcontratto, is_contratto FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND idcontratto IS NOT NULL AND NOT idcontratto=0';
$rsp = $dbo->fetchArray($query); $rsp = $dbo->fetchArray($query);
$id_record = $rsp[0]['iddocumento']; $id_record = $rsp[0]['iddocumento'];
$idcontratto = $rsp[0]['idcontratto']; $idcontratto = $rsp[0]['idcontratto'];
@ -1351,6 +1371,14 @@ switch (post('op')) {
} }
} }
//Riporto a magazzino gli articoli nelle righe del contratto
$rsa = $dbo->fetchArray('SELECT idarticolo, qta FROM co_righe_contratti WHERE idcontratto='.prepare($idcontratto));
for ($i = 0; $i < sizeof($rsa); ++$i) {
if (!empty($rsa[$i]['idarticolo'])) {
add_movimento_magazzino($rsa[$i]['idarticolo'], $rsa[$i]['qta'], ['iddocumento' => $id_record]);
}
}
// Ricalcolo inps, ritenuta e bollo // Ricalcolo inps, ritenuta e bollo
if ($dir == 'entrata') { if ($dir == 'entrata') {
ricalcola_costiagg_fattura($id_record); ricalcola_costiagg_fattura($id_record);

View File

@ -6,15 +6,17 @@ $module = Modules::get($id_module);
if ($module['name'] == 'Fatture di vendita') { if ($module['name'] == 'Fatture di vendita') {
$dir = 'entrata'; $dir = 'entrata';
$module_origin = 'Ddt di vendita';
} else { } else {
$dir = 'uscita'; $dir = 'uscita';
$module_origin = 'Ddt di acquisto';
} }
$info = $dbo->fetchOne('SELECT * FROM co_documenti WHERE id='.prepare($id_record)); $info = $dbo->fetchOne('SELECT * FROM co_documenti WHERE id='.prepare($id_record));
$numero = ($info['numero_esterno'] != '') ? $info['numero_esterno'] : $info['numero']; $numero = ($info['numero_esterno'] != '') ? $info['numero_esterno'] : $info['numero'];
$idanagrafica = $info['idanagrafica']; $idanagrafica = $info['idanagrafica'];
// Preventivo // Ddt
echo ' echo '
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
@ -36,6 +38,6 @@ echo '
$('#id_ddt').change( function(){ $('#id_ddt').change( function(){
$('#righeddt').html('<i>Caricamento in corso...</i>'); $('#righeddt').html('<i>Caricamento in corso...</i>');
$('#righeddt').load(globals.rootdir + '/modules/fatture/crea_documento.php?id_module=' + <?php echo Modules::get('Ddt di vendita')['id']; ?> + '&id_record=' + $(this).find('option:selected').val() + '&documento=fattura&op=add_ddt&iddocumento=' + globals.id_record); $('#righeddt').load(globals.rootdir + '/modules/fatture/crea_documento.php?id_module=' + <?php echo Modules::get($module_origin)['id']; ?> + '&id_record=' + $(this).find('option:selected').val() + '&documento=fattura&op=add_ddt&iddocumento=' + globals.id_record);
}); });
</script> </script>

View File

@ -16,7 +16,7 @@ $info = $dbo->fetchOne('SELECT * FROM co_documenti WHERE id='.prepare($id_record
$numero = ($info['numero_esterno'] != '') ? $info['numero_esterno'] : $info['numero']; $numero = ($info['numero_esterno'] != '') ? $info['numero_esterno'] : $info['numero'];
$idanagrafica = $info['idanagrafica']; $idanagrafica = $info['idanagrafica'];
// Preventivo // Ordine
echo ' echo '
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">

View File

@ -278,36 +278,41 @@ if ($record['stato'] != 'Pagato' && $record['stato'] != 'Emessa') {
} }
echo ' echo '
<a class="btn btn-sm btn-primary tip" '.(!empty($interventi) ? '' : ' disabled').' data-toggle="tooltip" title="'.tr('Interventi non collegati a preventivi o contratti.').'" data-href="'.$rootdir.'/modules/fatture/add_intervento.php?id_module='.$id_module.'&id_record='.$id_record.'" data-title="Aggiungi intervento" data-target="#bs-popup"> <div class="tip" data-toggle="tooltip" title="'.tr('Interventi non collegati a preventivi o contratti.').'" style="display:inline;">
<a class="btn btn-sm btn-primary '.(!empty($interventi) ? '' : ' disabled').'" data-href="'.$rootdir.'/modules/fatture/add_intervento.php?id_module='.$id_module.'&id_record='.$id_record.'" data-title="Aggiungi intervento" data-target="#bs-popup">
<i class="fa fa-plus"></i> Intervento <i class="fa fa-plus"></i> Intervento
</a>'; </a>
</div>';
// Lettura preventivi accettati, in attesa di conferma o in lavorazione // Lettura preventivi accettati, in attesa di conferma o in lavorazione
$prev_query = 'SELECT COUNT(*) AS tot FROM co_preventivi WHERE idanagrafica='.prepare($record['idanagrafica'])." AND id NOT IN (SELECT idpreventivo FROM co_righe_documenti WHERE NOT idpreventivo=NULL) AND idstato IN( SELECT id FROM co_statipreventivi WHERE descrizione='Accettato' OR descrizione='In lavorazione' OR descrizione='In attesa di conferma')"; $prev_query = 'SELECT COUNT(*) AS tot FROM co_preventivi WHERE idanagrafica='.prepare($record['idanagrafica'])." AND id NOT IN (SELECT idpreventivo FROM co_righe_documenti WHERE NOT idpreventivo=NULL) AND idstato IN( SELECT id FROM co_statipreventivi WHERE descrizione='Accettato' OR descrizione='In lavorazione' OR descrizione='In attesa di conferma')";
$preventivi = $dbo->fetchArray($prev_query)[0]['tot']; $preventivi = $dbo->fetchArray($prev_query)[0]['tot'];
echo ' echo '
<a class="btn btn-sm btn-primary tip" '.(!empty($preventivi) ? '' : ' disabled').' title="'.tr('Preventivi accettati, in attesa di conferma o in lavorazione.').'" data-href="'.$rootdir.'/modules/fatture/add_preventivo.php?id_module='.$id_module.'&id_record='.$id_record.'" data-toggle="tooltip" data-title="Aggiungi preventivo" data-target="#bs-popup"> <div class="tip" data-toggle="tooltip" title="'.tr('Preventivi accettati, in attesa di conferma o in lavorazione.').'" style="display:inline;">
<a class="btn btn-sm btn-primary '.(!empty($preventivi) ? '' : ' disabled').'" data-href="'.$rootdir.'/modules/fatture/add_preventivo.php?id_module='.$id_module.'&id_record='.$id_record.'" data-title="Aggiungi preventivo" data-target="#bs-popup">
<i class="fa fa-plus"></i> Preventivo <i class="fa fa-plus"></i> Preventivo
</a>'; </a>
</div>';
// Lettura contratti accettati, in attesa di conferma o in lavorazione // Lettura contratti accettati, in attesa di conferma o in lavorazione
$contr_query = 'SELECT COUNT(*) AS tot FROM co_contratti WHERE idanagrafica='.prepare($record['idanagrafica']).' AND id NOT IN (SELECT idcontratto FROM co_righe_documenti WHERE NOT idcontratto=NULL) AND idstato IN( SELECT id FROM co_staticontratti WHERE fatturabile = 1) AND NOT EXISTS (SELECT id FROM co_righe_documenti WHERE co_righe_documenti.idcontratto = co_contratti.id)'; $contr_query = 'SELECT COUNT(*) AS tot FROM co_contratti WHERE idanagrafica='.prepare($record['idanagrafica']).' AND id NOT IN (SELECT idcontratto FROM co_righe_documenti WHERE NOT idcontratto=NULL) AND idstato IN( SELECT id FROM co_staticontratti WHERE fatturabile = 1) AND NOT EXISTS (SELECT id FROM co_righe_documenti WHERE co_righe_documenti.idcontratto = co_contratti.id)';
$contratti = $dbo->fetchArray($contr_query)[0]['tot']; $contratti = $dbo->fetchArray($contr_query)[0]['tot'];
echo ' echo '
<div class="tip" data-toggle="tooltip" title="'.tr('Contratti accettati, in attesa di conferma o in lavorazione.').'" style="display:inline;">
<a class="btn btn-sm btn-primary tip" '.(!empty($contratti) ? '' : ' disabled').' title="'.tr('Contratti accettati, in attesa di conferma o in lavorazione.').'" data-href="'.$rootdir.'/modules/fatture/add_contratto.php?id_module='.$id_module.'&id_record='.$id_record.'" data-toggle="tooltip" data-title="Aggiungi contratto" data-target="#bs-popup"> <a class="btn btn-sm btn-primary '.(!empty($contratti) ? '' : ' disabled').'" data-href="'.$rootdir.'/modules/fatture/add_contratto.php?id_module='.$id_module.'&id_record='.$id_record.'" data-title="Aggiungi contratto" data-target="#bs-popup">
<i class="fa fa-plus"></i> Contratto <i class="fa fa-plus"></i> Contratto
</a>'; </a>
</div>';
// Lettura ddt
$ddt_query = 'SELECT COUNT(*) AS tot FROM dt_ddt WHERE idanagrafica='.prepare($record['idanagrafica']).' AND idstatoddt IN (SELECT id FROM dt_statiddt WHERE descrizione IN(\'Bozza\', \'Evaso\', \'Parzialmente evaso\', \'Parzialmente fatturato\')) AND idtipoddt IN (SELECT id FROM dt_tipiddt WHERE dir='.prepare($dir).') AND dt_ddt.id IN (SELECT idddt FROM dt_righe_ddt WHERE dt_righe_ddt.idddt = dt_ddt.id AND (qta - qta_evasa) > 0)';
$ddt = $dbo->fetchArray($ddt_query)[0]['tot'];
echo '
<a class="btn btn-sm btn-primary'.(!empty($ddt) ? '' : ' disabled').'" data-href="'.$rootdir.'/modules/fatture/add_ddt.php?id_module='.$id_module.'&id_record='.$id_record.'" data-toggle="tooltip" data-title="Aggiungi ddt" data-target="#bs-popup">
<i class="fa fa-plus"></i> Ddt
</a>';
} }
// Lettura ddt
$ddt_query = 'SELECT COUNT(*) AS tot FROM dt_ddt WHERE idanagrafica='.prepare($records[0]['idanagrafica']).' AND idstatoddt IN (SELECT id FROM dt_statiddt WHERE descrizione IN(\'Bozza\', \'Evaso\', \'Parzialmente evaso\', \'Parzialmente fatturato\')) AND idtipoddt IN (SELECT id FROM dt_tipiddt WHERE dir='.prepare($dir).') AND dt_ddt.id IN (SELECT idddt FROM dt_righe_ddt WHERE dt_righe_ddt.idddt = dt_ddt.id AND (qta - qta_evasa) > 0)';
$ddt = $dbo->fetchArray($ddt_query)[0]['tot'];
echo '
<a class="btn btn-sm btn-primary'.(!empty($ddt) ? '' : ' disabled').'" data-href="'.$rootdir.'/modules/fatture/add_ddt.php?id_module='.$id_module.'&id_record='.$id_record.'" data-toggle="tooltip" data-title="Aggiungi ddt" data-target="#bs-popup">
<i class="fa fa-plus"></i> Ddt
</a>';
// Lettura ordini // Lettura ordini
$ordini_query = 'SELECT COUNT(*) AS tot FROM or_ordini WHERE idanagrafica='.prepare($record['idanagrafica']).' AND idstatoordine IN (SELECT id FROM or_statiordine WHERE descrizione IN(\'Bozza\', \'Evaso\', \'Parzialmente evaso\', \'Parzialmente fatturato\')) AND idtipoordine=(SELECT id FROM or_tipiordine WHERE dir='.prepare($dir).') AND or_ordini.id IN (SELECT idordine FROM or_righe_ordini WHERE or_righe_ordini.idordine = or_ordini.id AND (qta - qta_evasa) > 0)'; $ordini_query = 'SELECT COUNT(*) AS tot FROM or_ordini WHERE idanagrafica='.prepare($record['idanagrafica']).' AND idstatoordine IN (SELECT id FROM or_statiordine WHERE descrizione IN(\'Bozza\', \'Evaso\', \'Parzialmente evaso\', \'Parzialmente fatturato\')) AND idtipoordine=(SELECT id FROM or_tipiordine WHERE dir='.prepare($dir).') AND or_ordini.id IN (SELECT idordine FROM or_righe_ordini WHERE or_righe_ordini.idordine = or_ordini.id AND (qta - qta_evasa) > 0)';
$ordini = $dbo->fetchArray($ordini_query)[0]['tot']; $ordini = $dbo->fetchArray($ordini_query)[0]['tot'];
@ -429,3 +434,86 @@ if (!empty($operations)) {
<a class="btn btn-danger ask" data-backto="record-list"> <a class="btn btn-danger ask" data-backto="record-list">
<i class="fa fa-trash"></i> <?php echo tr('Elimina'); ?> <i class="fa fa-trash"></i> <?php echo tr('Elimina'); ?>
</a> </a>
<?php
echo '
<script>
$( ".btn-sm[data-toggle=\"tooltip\"]" ).each(function() {
$(this).on("click", function(){
form = $("#edit-form");
btn = $(this);
prev_html = btn.html();
prev_class = btn.attr("class");
btn.html("<i class=\"fa fa-spinner fa-pulse fa-fw\"></i> Attendere...");
btn.addClass("btn-warning");
btn.prop("disabled", true);
function restore_btn(btn, prev_html, prev_class){
btn.attr("class", "");
btn.addClass(prev_class);
btn.html(prev_html);
btn.prop("disabled", false);
}
//Procedo al salvataggio solo se tutti i campi obbligatori sono compilati, altimenti mostro avviso
if (form.parsley().isValid()){
content_was_modified = false;
form.find("input:disabled, select:disabled").removeAttr("disabled");
$.ajax({
url: "'.ROOTDIR.'/modules/fatture/actions.php?id_module=" + globals.id_module ,
cache: false,
type: "POST",
processData: false,
dataType : "html",
data: form.serialize(),
success: function(data) {
$("#main_loading").fadeOut();
restore_btn(btn, prev_html, prev_class);
},
error: function(data) {
$("#main_loading").fadeOut();
swal("'.tr('Errore').'", "'.tr('Errore durante il salvataggio').'", "error");
session_set ("errors,0", 0, 1);
restore_btn(btn, prev_html, prev_class);
}
});
}else{
swal({
type: "error",
text: "'.tr('Alcuni campi obbligatori non sono stati compilati correttamente.').'",
title: "'.tr('Errore').'",
onClose: hide_popup
}).then(function () {
});
function hide_popup(){
$("#bs-popup").modal("hide");
session_set ("errors,0", 0, 1);
form.parsley().validate();
}
restore_btn(btn, prev_html, prev_class);
}
});
});
</script>';
?>

View File

@ -867,6 +867,26 @@ function rimuovi_riga_fattura($id_documento, $id_riga, $dir)
} }
} }
// Rimozione articoli collegati ad un preventivo importato con riga unica
if(empty($riga['idarticolo']) && $riga['is_preventivo']){
//rimetto a magazzino gli articoli collegati al preventivo
$rsa = $dbo->fetchArray('SELECT idarticolo, qta FROM co_righe_preventivi WHERE idpreventivo = '.prepare($riga['idpreventivo']));
for ($i = 0; $i < sizeof($rsa); ++$i) {
if (!empty($rsa[$i]['idarticolo']))
add_movimento_magazzino($rsa[$i]['idarticolo'], $rsa[$i]['qta'], ['iddocumento' => $id_documento]);
}
}
// Rimozione articoli collegati ad un contratto importato con riga unica
if(empty($riga['idarticolo']) && $riga['is_contratto']){
//rimetto a magazzino gli articoli collegati al contratto
$rsa = $dbo->fetchArray('SELECT idarticolo, qta FROM co_righe_contratti WHERE idcontratto = '.prepare($riga['idcontratto']));
for ($i = 0; $i < sizeof($rsa); ++$i) {
if (!empty($rsa[$i]['idarticolo']))
add_movimento_magazzino($rsa[$i]['idarticolo'], $rsa[$i]['qta'], ['iddocumento' => $id_documento]);
}
}
// Aggiorno lo stato dell'ordine // Aggiorno lo stato dell'ordine
if (!empty($riga['idordine']) && setting('Cambia automaticamente stato ordini fatturati')) { if (!empty($riga['idordine']) && setting('Cambia automaticamente stato ordini fatturati')) {
$dbo->query('UPDATE or_ordini SET idstatoordine = (SELECT id FROM or_statiordine WHERE descrizione = '.prepare(get_stato_ordine($riga['idordine'])).') WHERE id = '.prepare($riga['idordine'])); $dbo->query('UPDATE or_ordini SET idstatoordine = (SELECT id FROM or_statiordine WHERE descrizione = '.prepare(get_stato_ordine($riga['idordine'])).') WHERE id = '.prepare($riga['idordine']));

View File

@ -55,7 +55,7 @@ $( "#example" ).click(function(event) {
data: {op: 'example', module: module}, data: {op: 'example', module: module},
success: function(data){ success: function(data){
window.location = file; window.location = file;
$('#main_loading').hide(); $('#main_loading').fadeOut();
return false; return false;
} }
}); });

View File

@ -2,7 +2,7 @@
include_once __DIR__.'/../../core.php'; include_once __DIR__.'/../../core.php';
if (!in_array($record['stato'], ['Evaso', 'Fatturato'])) { if (!in_array($record['stato'], ['Bozza', 'Evaso', 'Fatturato'])) {
echo ' echo '
<div class="dropdown"> <div class="dropdown">
<button class="btn btn-info dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"> <button class="btn btn-info dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
@ -11,23 +11,23 @@ if (!in_array($record['stato'], ['Evaso', 'Fatturato'])) {
</button> </button>
<ul class="dropdown-menu dropdown-menu-right">'; <ul class="dropdown-menu dropdown-menu-right">';
if (in_array($records[0]['stato'], ['Parzialmente evaso'])){ if (in_array($records[0]['stato'], ['Parzialmente evaso'])) {
echo ' echo '
<li> <li>
<a data-href="'.$rootdir.'/modules/fatture/crea_documento.php?id_module='.$id_module.'&id_record='.$id_record.'&documento=ddt" data-toggle="modal" data-title="'.tr('Crea ddt').'" data-target="#bs-popup"><i class="fa fa-file-o"></i>&nbsp;'.tr('ddt').' <a data-href="'.$rootdir.'/modules/fatture/crea_documento.php?id_module='.$id_module.'&id_record='.$id_record.'&documento=ddt" data-toggle="modal" data-title="'.tr('Crea ddt').'" data-target="#bs-popup"><i class="fa fa-file-o"></i>&nbsp;'.tr('ddt').'
</a> </a>
</li>'; </li>';
} }
if (in_array($records[0]['stato'], ['Parzialmente fatturato'])){ if (in_array($records[0]['stato'], ['Parzialmente fatturato'])) {
echo ' echo '
<li> <li>
<a data-href="'.$rootdir.'/modules/fatture/crea_documento.php?id_module='.$id_module.'&id_record='.$id_record.'&documento=fattura" data-toggle="modal" data-title="'.tr('Crea fattura').'" data-target="#bs-popup"><i class="fa fa-file"></i>&nbsp;'.tr('fattura').' <a data-href="'.$rootdir.'/modules/fatture/crea_documento.php?id_module='.$id_module.'&id_record='.$id_record.'&documento=fattura" data-toggle="modal" data-title="'.tr('Crea fattura').'" data-target="#bs-popup"><i class="fa fa-file"></i>&nbsp;'.tr('fattura').'
</a> </a>
</li>'; </li>';
} }
echo ' echo '
</ul> </ul>
</div>'; </div>';
} }

View File

@ -23,5 +23,6 @@ return '
<p>'.(!empty($f_capsoc) ? tr('Cap.Soc.').': '.$f_capsoc : '').'</p> <p>'.(!empty($f_capsoc) ? tr('Cap.Soc.').': '.$f_capsoc : '').'</p>
<p>'.(!empty($f_telefono) ? tr('Tel').': '.$f_telefono : '').'</p> <p>'.(!empty($f_telefono) ? tr('Tel').': '.$f_telefono : '').'</p>
<p>'.(!empty($f_email) ? tr('Email').': '.$f_email : '').'</p> <p>'.(!empty($f_email) ? tr('Email').': '.$f_email : '').'</p>
<p>'.(!empty($f_sitoweb) ? tr('Web').': '.$f_sitoweb : '').'</p>
</div> </div>
</div>'; </div>';

View File

@ -44,7 +44,7 @@ switch ($periodo[0]) {
break; break;
}*/ }*/
$query = 'SELECT *, SUM(subtotale-co_righe_documenti.sconto) AS subtotale, SUM(iva) AS iva, (SELECT ragione_sociale FROM an_anagrafiche WHERE an_anagrafiche.idanagrafica=co_documenti.idanagrafica) AS ragione_sociale FROM co_documenti INNER JOIN co_righe_documenti ON co_documenti.id=co_righe_documenti.iddocumento INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id WHERE dir = '.prepare($dir).' AND is_descrizione = 0 AND co_documenti.data >= '.prepare($date_start).' AND co_documenti.data <= '.prepare($date_end).' GROUP BY co_documenti.id, co_righe_documenti.idiva ORDER BY co_documenti.data'; $query = 'SELECT *, SUM(subtotale-co_righe_documenti.sconto) AS subtotale, SUM(iva) AS iva, (SELECT ragione_sociale FROM an_anagrafiche WHERE an_anagrafiche.idanagrafica=co_documenti.idanagrafica) AS ragione_sociale FROM co_documenti INNER JOIN co_righe_documenti ON co_documenti.id=co_righe_documenti.iddocumento INNER JOIN co_tipidocumento ON co_documenti.idtipodocumento=co_tipidocumento.id WHERE dir = '.prepare($dir).' AND idstatodocumento NOT IN (SELECT id FROM co_statidocumento WHERE descrizione="Bozza" OR descrizione="Annullata") AND is_descrizione = 0 AND co_documenti.data >= '.prepare($date_start).' AND co_documenti.data <= '.prepare($date_end).' GROUP BY co_documenti.id, co_righe_documenti.idiva ORDER BY co_documenti.data';
$rs = $dbo->fetchArray($query); $rs = $dbo->fetchArray($query);
if ('entrata' == $dir) { if ('entrata' == $dir) {
@ -61,12 +61,14 @@ if ('entrata' == $dir) {
$body .= " $body .= "
<table cellspacing='0' style='table-layout:fixed;'> <table cellspacing='0' style='table-layout:fixed;'>
<col width='90'><col width='90'><col width='450'><col width='120'><col width='120'><col width='90'><col width='90'> <col width='90'><col width='90'><col width='90'><col width='275'><col width='120'><col width='90'><col width='90'><col width='90'>
<thead> <thead>
<tr> <tr>
<th bgcolor='#dddddd' class='full_cell1 cell-padded'> doc.</th> <th bgcolor='#dddddd' class='full_cell1 cell-padded'>N<sup>o</sup> prot.</th>
<th bgcolor='#dddddd' class='full_cell1 cell-padded'>N<sup>o</sup> doc.</th>
<th bgcolor='#dddddd' class='full_cell cell-padded'>Data</th> <th bgcolor='#dddddd' class='full_cell cell-padded'>Data</th>
<th bgcolor='#dddddd' class='full_cell cell-padded'>Causale<br>Ragione sociale</th> <th bgcolor='#dddddd' class='full_cell cell-padded'>".(($dir=='entrata') ? 'Cliente': 'Fornitore')."</th>
<th bgcolor='#dddddd' class='full_cell cell-padded'>Causale</th>
<th bgcolor='#dddddd' class='full_cell cell-padded'>Aliquota</th> <th bgcolor='#dddddd' class='full_cell cell-padded'>Aliquota</th>
<th bgcolor='#dddddd' class='full_cell cell-padded'>Imponibile</th> <th bgcolor='#dddddd' class='full_cell cell-padded'>Imponibile</th>
<th bgcolor='#dddddd' class='full_cell cell-padded'>Imposta</th> <th bgcolor='#dddddd' class='full_cell cell-padded'>Imposta</th>
@ -76,25 +78,21 @@ $body .= "
for ($i = 0; $i < sizeof($rs); ++$i) { for ($i = 0; $i < sizeof($rs); ++$i) {
$body .= '<tr>'; $body .= '<tr>';
if ($rs[$i]['numero'] == $rs[$i - 1]['numero']) { if ($rs[$i]['numero'] == $rs[$i - 1]['numero']) {
$body .= " <td class='first_cell cell-padded text-center'></td>"; $body .= " <td class='first_cell cell-padded text-center'></td>";
$body .= " <td class='table_cell cell-padded text-center'></td>"; $body .= " <td class='table_cell cell-padded text-center'></td>";
$body .= " <td class='table_cell cell-padded text-center'></td>";
} else { } else {
$body .= " <td class='first_cell cell-padded text-center'>".(!empty($rs[$i]['numero_esterno']) ? $rs[$i]['numero_esterno'] : $rs[$i]['numero']).'</td>'; $body .= " <td class='first_cell cell-padded text-center'>".$rs[$i]['numero'].'</td>';
$body .= " <td class='table_cell cell-padded text-center'>".$rs[$i]['numero_esterno'].'</td>';
$body .= " <td class='table_cell cell-padded text-center'>".date('d/m/Y', strtotime($rs[$i]['data'])).'</td>'; $body .= " <td class='table_cell cell-padded text-center'>".date('d/m/Y', strtotime($rs[$i]['data'])).'</td>';
} }
if ('entrata' == $dir) { $body .= "<td class='table_cell cell-padded'>".$rs[$i]['ragione_sociale']."</td>";
$body .= "<td class='table_cell cell-padded'>
Fattura di vendita<br> $body .= " <td class='table_cell cell-padded'>".(($dir=='entrata') ? 'Fattura di vendita': 'Fattura di acquisto').'</td>';
".$rs[$i]['ragione_sociale'].'
</td>';
} elseif ('uscita' == $dir) {
$body .= "<td class='table_cell cell-padded'>
Fattura di acquisto<br>
".$rs[$i]['ragione_sociale'].'
</td>';
}
$body .= " <td class='table_cell cell-padded'>".$rs[$i]['desc_iva'].'</td>'; $body .= " <td class='table_cell cell-padded'>".$rs[$i]['desc_iva'].'</td>';
$body .= " <td class='table_cell cell-padded text-right'>".Translator::numberToLocale($rs[$i]['subtotale']).' &euro;</td>'; $body .= " <td class='table_cell cell-padded text-right'>".Translator::numberToLocale($rs[$i]['subtotale']).' &euro;</td>';
$body .= " <td class='table_cell cell-padded text-right'>".Translator::numberToLocale($rs[$i]['iva']).' &euro;</td>'; $body .= " <td class='table_cell cell-padded text-right'>".Translator::numberToLocale($rs[$i]['iva']).' &euro;</td>';

View File

@ -146,10 +146,10 @@ ALTER TABLE `in_tipiintervento` ADD `tempo_standard` DECIMAL(10,2) NULL AFTER `
UPDATE `zz_widgets` SET `text` = 'Promemoria contratti da pianificare' WHERE `zz_widgets`.`name` = 'Interventi da pianificare'; UPDATE `zz_widgets` SET `text` = 'Promemoria contratti da pianificare' WHERE `zz_widgets`.`name` = 'Interventi da pianificare';
-- Fix arrotondamenti per fatture di vendita -- Fix arrotondamenti per fatture di vendita
UPDATE `zz_views` SET `query` = '(SELECT SUM(round(subtotale,2) - round(sconto,2) + round(iva,2) + round(rivalsainps,2) - round(ritenutaacconto,2)) FROM co_righe_documenti WHERE co_righe_documenti.iddocumento=co_documenti.id GROUP BY iddocumento) + round(bollo,2) + round(iva_rivalsainps,2)' WHERE `zz_views`.`id_module` = (SELECT `id` FROM `zz_modules` WHERE `name` = 'Fatture di vendita') AND name = 'Totale'; --UPDATE `zz_views` SET `query` = '(SELECT SUM(round(subtotale,2) - round(sconto,2) + round(iva,2) + round(rivalsainps,2) - round(ritenutaacconto,2)) FROM co_righe_documenti WHERE co_righe_documenti.iddocumento=co_documenti.id GROUP BY iddocumento) + round(bollo,2) + round(iva_rivalsainps,2)' WHERE `zz_views`.`id_module` = (SELECT `id` FROM `zz_modules` WHERE `name` = 'Fatture di vendita') AND name = 'Totale';
-- Fix arrotondamenti per fatture di acquisto -- Fix arrotondamenti per fatture di acquisto
UPDATE `zz_views` SET `query` = '(SELECT SUM(round(subtotale,2) - round(sconto,2) + round(iva,2) + round(rivalsainps,2) - round(ritenutaacconto,2)) FROM co_righe_documenti WHERE co_righe_documenti.iddocumento=co_documenti.id GROUP BY iddocumento ) + round(bollo,2) + round(iva_rivalsainps,2)' WHERE `zz_views`.`id_module` = (SELECT `id` FROM `zz_modules` WHERE `name` = 'Fatture di acquisto') AND name = 'Totale'; --UPDATE `zz_views` SET `query` = '(SELECT SUM(round(subtotale,2) - round(sconto,2) + round(iva,2) + round(rivalsainps,2) - round(ritenutaacconto,2)) FROM co_righe_documenti WHERE co_righe_documenti.iddocumento=co_documenti.id GROUP BY iddocumento ) + round(bollo,2) + round(iva_rivalsainps,2)' WHERE `zz_views`.`id_module` = (SELECT `id` FROM `zz_modules` WHERE `name` = 'Fatture di acquisto') AND name = 'Totale';
-- Aggiunta impostazioni per cambio stato automatici -- Aggiunta impostazioni per cambio stato automatici
INSERT INTO `zz_settings` (`idimpostazione`, `nome`, `valore`, `tipo`, `editable`, `sezione`) VALUES (NULL, 'Cambia automaticamente stato ddt fatturati', '1', 'boolean', '1', 'Ddt'); INSERT INTO `zz_settings` (`idimpostazione`, `nome`, `valore`, `tipo`, `editable`, `sezione`) VALUES (NULL, 'Cambia automaticamente stato ddt fatturati', '1', 'boolean', '1', 'Ddt');
@ -461,3 +461,6 @@ UPDATE `zz_settings` SET `tipo` = REPLACE(
-- Fix id delle Banche -- Fix id delle Banche
UPDATE `zz_views` SET `enabled` = 0 WHERE `id_module` = (SELECT `id` FROM `zz_modules` WHERE `name` = 'Banche') AND `name` = 'id'; UPDATE `zz_views` SET `enabled` = 0 WHERE `id_module` = (SELECT `id` FROM `zz_modules` WHERE `name` = 'Banche') AND `name` = 'id';
-- Aggiunta campi per specificare se la riga importata è un import unico di pù righe
ALTER TABLE `co_righe_documenti` ADD `is_preventivo` TINYINT(1) NOT NULL AFTER `is_descrizione`, ADD `is_contratto` TINYINT(1) NOT NULL AFTER `is_preventivo`;