Gestione provvigioni

This commit is contained in:
MatteoPistorello 2022-05-19 17:42:41 +02:00
parent 41e1867774
commit 9de11cf91a
33 changed files with 535 additions and 22 deletions

View File

@ -66,7 +66,9 @@ if (empty($result['idarticolo'])) {
}
echo '
<input type="hidden" name="qta_minima" id="qta_minima" value="'.$qta_minima.'">';
<input type="hidden" name="qta_minima" id="qta_minima" value="'.$qta_minima.'">
<input type="hidden" name="provvigione_default" id="provvigione_default" value="'.$result['provvigione_default'].'">
<input type="hidden" name="tipo_provvigione_default" id="provvigione_default" value="'.$result['tipo_provvigione_default'].'">';
// Selezione impianto per gli Interventi
if ($module['name'] == 'Interventi') {
@ -185,6 +187,14 @@ $("#idarticolo").on("change", function() {
}
$("#um").selectSetNew($data.um, $data.um);
if ($data.provvigione) {
input("provvigione").set($data.provvigione);
input("tipo_provvigione").set($data.tipo_provvigione);
} else {
input("provvigione").set(input("provvigione_default").get());
input("tipo_provvigione").set(input("tipo_provvigione_default").get());
}
});
});

View File

@ -43,7 +43,7 @@ echo '
<table class="table table-stripped hide" id="articoli_barcode">
<tr>
<th>'.tr('Articolo').'</th>
<th width="25%">'.$intestazione_prezzo.'</th>
<th width="25%" class="text-center">'.$intestazione_prezzo.'</th>
<th width="20%" class="text-center">'.tr('Sconto').'</th>
<th width="10%" class="text-center">'.tr('Q.').'</th>
<th width="5%" class="text-center">#</th>

View File

@ -77,11 +77,15 @@ if ($options['dir'] == 'entrata') {
if ($("#modals select[id^=\'tipo_sconto\']").val() === "PRC") {
sconto = sconto / 100 * prezzo;
}
var provvigione = $("#provvigione").val().toEnglish();
if ($("#modals select[id^=\'tipo_provvigione\']").val() === "PRC") {
provvigione = provvigione / 100 * (prezzo - sconto);
}
var guadagno = prezzo - sconto - costo_unitario;
var margine = (((prezzo - sconto) * 100) / costo_unitario) - 100;
var guadagno = prezzo - sconto - provvigione - costo_unitario;
var margine = (((prezzo - sconto) * 100) / (costo_unitario + provvigione)) - 100;
var parent = $("#costo_unitario").closest("div").parent();
var div = parent.find("div[id*=\"errors\"]");
var div = $(".margine");
var mediaponderata = 0;
margine = isNaN(margine) || !isFinite(margine) ? 0: margine; // Fix per magine NaN
@ -90,7 +94,7 @@ if ($options['dir'] == 'entrata') {
mediaponderata = parseFloat($("#idarticolo").selectData().media_ponderata);
}
div.html("<table class=\"table table-extra-condensed\" style=\"margin-top:7px;\" >\
div.html("<table class=\"table table-extra-condensed table-margine\" style=\"margin-top:-13px;\" >\
<tr>\
<td>\
<small>&nbsp;'.tr('Guadagno').':</small>\
@ -128,10 +132,10 @@ if ($options['dir'] == 'entrata') {
if (guadagno < 0) {
parent.addClass("has-error");
div.addClass("label-danger").removeClass("label-success");
$(".table-margine").addClass("label-danger").removeClass("label-success");
} else {
parent.removeClass("has-error");
div.removeClass("label-danger").addClass("label-success");
$(".table-margine").removeClass("label-danger").addClass("label-success");
}
}
@ -143,6 +147,8 @@ if ($options['dir'] == 'entrata') {
$("#costo_unitario").keyup(aggiorna_guadagno);
$("#sconto").keyup(aggiorna_guadagno);
$("#modals select[id^=\'tipo_sconto\']").change(aggiorna_guadagno);
$("#provvigione").keyup(aggiorna_guadagno);
$("#modals select[id^=\'tipo_provvigione\']").change(aggiorna_guadagno);
</script>';
}
@ -159,6 +165,19 @@ echo '
</div>
</div>';
if ($options['dir'] == 'entrata') {
echo '
<div class="row">
<div class="col-md-4 margine"></div>';
// Provvigione
echo '
<div class="col-md-offset-4 col-md-4">
{[ "type": "number", "label": "'.tr('Provvigione unitaria').'", "name": "provvigione", "value": "'.($result['provvigione_percentuale'] ?: ($result['provvigione_unitaria'] ?: $result['provvigione_default'])).'", "icon-after": "choice|untprc|'.($result['tipo_provvigione'] ?: $result['tipo_provvigione_default']).'", "help": "'.tr('Provvigione destinata all\'agente.').'", "min-value": "0" ]}
</div>
</div>';
}
// Data prevista evasione (per ordini)
if (in_array($module['name'], ['Ordini cliente', 'Ordini fornitore', 'Preventivi'])) {

View File

@ -95,6 +95,7 @@ switch (post('op')) {
$anagrafica->riferimento_amministrazione = post('riferimento_amministrazione');
$anagrafica->colore = post('colore');
$anagrafica->idtipointervento_default = post('idtipointervento_default') ?: null;
$anagrafica->provvigione_default = post('provvigione_default');
$anagrafica->id_ritenuta_acconto_acquisti = post('id_ritenuta_acconto_acquisti');
$anagrafica->id_ritenuta_acconto_vendite = post('id_ritenuta_acconto_vendite');
$anagrafica->split_payment = post('split_payment');

View File

@ -25,6 +25,7 @@ include_once __DIR__.'/../../core.php';
$is_fornitore = in_array($id_fornitore, $tipi_anagrafica);
$is_cliente = in_array($id_cliente, $tipi_anagrafica);
$is_tecnico = in_array($id_tecnico, $tipi_anagrafica);
$is_agente = in_array($id_agente, $tipi_anagrafica);
if (!$is_cliente && !$is_fornitore && $is_tecnico) {
$ignore = $dbo->fetchArray("SELECT id FROM zz_plugins WHERE name='Sedi' OR name='Referenti' OR name='Dichiarazioni d\'intento'");
@ -640,15 +641,15 @@ if ($is_cliente or $is_fornitore or $is_tecnico) {
<div class="col-md-3">
{[ "type": "text", "label": "<?php echo tr('Riferimento Amministrazione'); ?>", "name": "riferimento_amministrazione", "value": "$riferimento_amministrazione$", "maxlength": "20" ]}
</div>
<!-- campi già specificati in Codice R.E.A., da eliminare nelle prossime release -->
<!--div class="col-md-3">
{[ "type": "text", "label": "<?php echo tr('Num. iscr. C.C.I.A.A.'); ?>", "name": "cciaa", "value": "$cciaa$" ]}
</div>
<div class="col-md-3">
{[ "type": "text", "label": "<?php echo tr('Città iscr. C.C.I.A.A.'); ?>", "name": "cciaa_citta", "value": "$cciaa_citta$" ]}
</div-->
<?php
if ($is_agente) {
?>
<div class="col-md-3">
{[ "type": "number", "label": "<?php echo tr('Provvigione predefinita'); ?>", "name": "provvigione_default", "value": "$provvigione_default$", "icon-after": "%" ]}
</div>
<?php
}
?>
</div>
<div class="row">

View File

@ -33,6 +33,7 @@ switch ($resource) {
$usare_dettaglio_fornitore = $superselect['dir'] == 'uscita';
$usare_iva_anagrafica = $superselect['dir'] == 'entrata' && !empty($superselect['idanagrafica']);
$solo_non_varianti = $superselect['solo_non_varianti'];
$idagente = $superselect['idagente'];
$query = "SELECT
IF(`categoria`.`nome` IS NOT NULL, CONCAT(`categoria`.`nome`, IF(`sottocategoria`.`nome` IS NOT NULL, CONCAT(' (', `sottocategoria`.`nome`, ')'), '-')), '<i>".tr('Nessuna categoria')."</i>') AS optgroup,
@ -73,6 +74,12 @@ switch ($resource) {
IFNULL(iva_articolo.percentuale, iva_predefinita.percentuale) AS percentuale,';
}
if ($idagente) {
$query .= '
co_provvigioni.provvigione AS provvigione,
co_provvigioni.tipo_provvigione AS tipo_provvigione,';
}
$query .= '
round(mg_articoli.qta,'.setting('Cifre decimali per quantità').") AS qta,
mg_articoli.um,
@ -107,6 +114,11 @@ switch ($resource) {
LEFT JOIN co_iva AS iva_anagrafica ON iva_anagrafica.id = (SELECT idiva_vendite FROM an_anagrafiche WHERE idanagrafica = '.prepare($superselect['idanagrafica']).')';
}
if ($idagente) {
$query .= '
LEFT JOIN co_provvigioni ON co_provvigioni.idarticolo = mg_articoli.id AND co_provvigioni.idagente='.prepare($idagente);
}
$query .= '
LEFT JOIN mg_fornitore_articolo ON mg_fornitore_articolo.id_articolo = mg_articoli.id AND mg_fornitore_articolo.deleted_at IS NULL AND mg_fornitore_articolo.id_fornitore = '.prepare($superselect['idanagrafica']);

View File

@ -351,6 +351,34 @@ switch (post('op')) {
flash()->warning(tr('Nessun articolo modificato!'));
}
break;
case 'set-provvigione':
$n_art = 0;
foreach ($id_records as $id) {
$exist = $dbo->selectOne('co_provvigioni', 'id', ['idarticolo' => $id, 'idagente' => post('idagente')]);
if ($exist) {
$dbo->update('co_provvigioni', [
'idagente' => post('idagente'),
'provvigione' => post('provvigione'),
'tipo_provvigione' => post('tipo_provvigione'),
], ['idarticolo' => $id, 'idagente' => post('idagente')]);
} else {
$dbo->insert('co_provvigioni', [
'idarticolo' => $id,
'idagente' => post('idagente'),
'provvigione' => post('provvigione'),
'tipo_provvigione' => post('tipo_provvigione'),
]);
}
$n_art++;
}
flash()->info(tr('Provvigioni inserite correttamente!', [
'_NUM_' => $n_art,
]));
break;
}
@ -517,4 +545,16 @@ $operations['change-conto-vendita'] = [
],
];
$operations['set-provvigione'] = [
'text' => '<span><i class="fa fa-percent"></i> '.tr('Imposta una provvigione').'</span>',
'data' => [
'title' => tr('Impostare una provvigione?'),
'msg' => tr('Selezionare un agente e la provvigione prevista:').'
<br><br>{[ "type": "select", "label": "'.tr('Agente').'", "name": "idagente", "required": 1, "ajax-source": "agenti" ]}
<br>{[ "type": "number", "label": "'.tr('Provvigione').'", "name": "provvigione", "required": 1, "icon-after": "choice|untprc|" ]}',
'button' => tr('Procedi'),
'class' => 'btn btn-lg btn-warning',
],
];
return $operations;

View File

@ -211,6 +211,7 @@ switch (post('op')) {
$articolo->costo_unitario = post('costo_unitario') ?: 0;
$articolo->setPrezzoUnitario(post('prezzo_unitario'), post('idiva'));
$articolo->setSconto(post('sconto'), post('tipo_sconto'));
$articolo->setProvvigione(post('provvigione'), post('tipo_provvigione'));
try {
$articolo->qta = $qta;
@ -265,6 +266,7 @@ switch (post('op')) {
$riga->costo_unitario = post('costo_unitario') ?: 0;
$riga->setPrezzoUnitario(post('prezzo_unitario'), post('idiva'));
$riga->setSconto(post('sconto'), post('tipo_sconto'));
$riga->setProvvigione(post('provvigione'), post('tipo_provvigione'));
$riga->qta = $qta;
@ -524,6 +526,7 @@ switch (post('op')) {
$contratto->descrizione = $documento->descrizione;
$contratto->esclusioni = $documento->esclusioni;
$contratto->idreferente = $documento->idreferente;
$contratto->idagente = $documento->idagente;
$contratto->save();

View File

@ -37,6 +37,7 @@ $options = [
'idanagrafica' => $documento->idanagrafica,
'dir' => $documento->direzione,
'permetti_movimento_a_zero' => 1,
'idagente' => $documento->idagente,
],
],
];
@ -50,8 +51,13 @@ $result = [
'sconto_unitario' => 0,
'tipo_sconto' => '',
'idiva' => '',
'provvigione_default' => 0,
'tipo_provvigione_default' => 'PRC',
];
// Leggo la provvigione predefinita per l'anagrafica
$result['provvigione_default'] = $dbo->fetchOne('SELECT provvigione_default FROM an_anagrafiche WHERE idanagrafica='.prepare($documento->idagente))['provvigione_default'];
// Leggo l'iva predefinita per l'anagrafica e se non c'è leggo quella predefinita generica
$iva = $dbo->fetchArray('SELECT idiva_vendite AS idiva FROM an_anagrafiche WHERE idanagrafica='.prepare($documento['idanagrafica']));
$result['idiva'] = $iva[0]['idiva'] ?: setting('Iva predefinita');

View File

@ -260,6 +260,20 @@ if ($totale != $netto_a_pagare) {
</tr>';
}
// Provvigione
if(!empty($contratto->provvigione)) {
echo '
<tr>
<td colspan="6" class="text-right">
'.tr('Provvigioni').':
</td>
<td class="text-right">
'.moneyFormat($contratto->provvigione).'
</td>
<td></td>
</tr>';
}
echo '
</table>';
if (!$block_edit && sizeof($righe) > 0) {

View File

@ -207,7 +207,10 @@ switch (filter('op')) {
$articolo->costo_unitario = post('costo_unitario') ?: 0;
$articolo->setPrezzoUnitario(post('prezzo_unitario'), post('idiva'));
$articolo->setSconto(post('sconto'), post('tipo_sconto'));
if ($dir == 'entrata') {
$articolo->setProvvigione(post('provvigione'), post('tipo_provvigione'));
}
try {
$articolo->qta = post('qta');
} catch (UnexpectedValueException $e) {
@ -263,6 +266,9 @@ switch (filter('op')) {
$riga->costo_unitario = post('costo_unitario') ?: 0;
$riga->setPrezzoUnitario(post('prezzo_unitario'), post('idiva'));
$riga->setSconto(post('sconto'), post('tipo_sconto'));
if ($dir == 'entrata') {
$riga->setProvvigione(post('provvigione'), post('tipo_provvigione'));
}
$riga->qta = post('qta');
@ -330,6 +336,7 @@ switch (filter('op')) {
$ddt->idcausalet = post('id_causale_trasporto');
$ddt->idreferente = $documento->idreferente;
$ddt->idagente = $documento->idagente;
$ddt->save();

View File

@ -40,6 +40,7 @@ $options = [
'idsede_partenza' => $documento->idsede_partenza,
'idsede_destinazione' => $documento->idsede_destinazione,
'permetti_movimento_a_zero' => intval($documento->direzione == 'uscita'),
'idagente' => $documento->idagente,
],
],
];
@ -53,8 +54,13 @@ $result = [
'sconto_unitario' => 0,
'tipo_sconto' => '',
'idiva' => '',
'provvigione_default' => 0,
'tipo_provvigione_default' => 'PRC',
];
// Leggo la provvigione predefinita per l'anagrafica
$result['provvigione_default'] = $dbo->fetchOne('SELECT provvigione_default FROM an_anagrafiche WHERE idanagrafica='.prepare($documento->idagente))['provvigione_default'];
// Leggo l'iva predefinita per l'anagrafica e se non c'è leggo quella predefinita generica
$iva = $dbo->fetchArray('SELECT idiva_'.($dir == 'uscita' ? 'acquisti' : 'vendite').' AS idiva FROM an_anagrafiche WHERE idanagrafica='.prepare($documento['idanagrafica']));
$result['idiva'] = $iva[0]['idiva'] ?: setting('Iva predefinita');

View File

@ -318,6 +318,20 @@ if ($totale != $netto_a_pagare) {
</tr>';
}
// Provvigione
if(!empty($ddt->provvigione)) {
echo '
<tr>
<td colspan="6" class="text-right">
'.tr('Provvigioni').':
</td>
<td class="text-right">
'.moneyFormat($ddt->provvigione).'
</td>
<td></td>
</tr>';
}
echo '
</table>';
if (!$block_edit && sizeof($righe) > 0) {

View File

@ -500,6 +500,9 @@ switch (post('op')) {
$articolo->costo_unitario = post('costo_unitario') ?: 0;
$articolo->setPrezzoUnitario(post('prezzo_unitario'), post('idiva'));
$articolo->setSconto(post('sconto'), post('tipo_sconto'));
if ($dir == 'entrata') {
$articolo->setProvvigione(post('provvigione'), post('tipo_provvigione'));
}
try {
$articolo->qta = $qta;
@ -573,6 +576,9 @@ switch (post('op')) {
$riga->costo_unitario = post('costo_unitario') ?: 0;
$riga->setPrezzoUnitario(post('prezzo_unitario'), post('idiva'));
$riga->setSconto(post('sconto'), post('tipo_sconto'));
if ($dir == 'entrata') {
$riga->setProvvigione(post('provvigione'), post('tipo_provvigione'));
}
$riga->qta = $qta;
@ -727,6 +733,7 @@ switch (post('op')) {
$fattura->idsede_destinazione = $documento->idsede;
$fattura->id_ritenuta_contributi = post('id_ritenuta_contributi') ?: null;
$fattura->idreferente = $documento->idreferente;
$fattura->idagente = $documento->idagente;
$fattura->save();

View File

@ -42,6 +42,7 @@ $options = [
'idsede_partenza' => $documento->idsede_partenza,
'idsede_destinazione' => $documento->idsede_destinazione,
'permetti_movimento_a_zero' => intval($documento->direzione == 'uscita'),
'idagente' => $documento->idagente,
],
'iva' => [
'split_payment' => $documento['split_payment'],
@ -66,8 +67,13 @@ $result = [
'idiva' => '',
'idconto' => $idconto,
'ritenuta_contributi' => true,
'provvigione_default' => 0,
'tipo_provvigione_default' => 'PRC',
];
// Leggo la provvigione predefinita per l'anagrafica
$result['provvigione_default'] = $dbo->fetchOne('SELECT provvigione_default FROM an_anagrafiche WHERE idanagrafica='.prepare($documento->idagente))['provvigione_default'];
// Leggo l'iva predefinita per l'anagrafica e se non c'è leggo quella predefinita generica
$iva = $dbo->fetchArray('SELECT idiva_'.($dir == 'uscita' ? 'acquisti' : 'vendite').' AS idiva FROM an_anagrafiche WHERE idanagrafica='.prepare($documento['idanagrafica']));
$result['idiva'] = $iva[0]['idiva'] ?: setting('Iva predefinita');

View File

@ -424,6 +424,20 @@ if ($totale != $netto_a_pagare) {
</tr>';
}
// Provvigione
if(!empty($fattura->provvigione)) {
echo '
<tr>
<td colspan="6" class="text-right">
'.tr('Provvigioni').':
</td>
<td class="text-right">
'.moneyFormat($fattura->provvigione).'
</td>
<td></td>
</tr>';
}
echo '
</table>';
if (!$block_edit && sizeof($righe) > 0) {

View File

@ -55,6 +55,7 @@ switch (post('op')) {
$intervento->idanagrafica = post('idanagrafica');
$intervento->idclientefinale = post('idclientefinale');
$intervento->idreferente = post('idreferente');
$intervento->idagente = post('idagente');
$intervento->idtipointervento = post('idtipointervento');
$intervento->idstatointervento = post('idstatointervento');
@ -497,6 +498,7 @@ switch (post('op')) {
$articolo->costo_unitario = post('costo_unitario') ?: 0;
$articolo->setPrezzoUnitario(post('prezzo_unitario'), post('idiva'));
$articolo->setSconto(post('sconto'), post('tipo_sconto'));
$articolo->setProvvigione(post('provvigione'), post('tipo_provvigione'));
try {
$articolo->qta = $qta;
@ -562,6 +564,7 @@ switch (post('op')) {
$riga->costo_unitario = post('costo_unitario') ?: 0;
$riga->setPrezzoUnitario(post('prezzo_unitario'), post('idiva'));
$riga->setSconto(post('sconto'), post('tipo_sconto'));
$riga->setProvvigione(post('provvigione'), post('tipo_provvigione'));
$riga->qta = $qta;
@ -615,6 +618,7 @@ switch (post('op')) {
$intervento->codice_cig = $documento->codice_cig;
$intervento->num_item = $documento->num_item;
$intervento->idreferente = $documento->idreferente;
$intervento->idagente = $documento->idagente;
$intervento->save();

View File

@ -120,6 +120,14 @@ echo '
{[ "type": "select", "label": "'.tr('Ordine').'", "name": "idordine", "value": "'.$record['id_ordine'].'", "ajax-source": "ordini-cliente", "select-options": '.json_encode(['idanagrafica' => $record['idanagrafica']]).', "readonly": "'.$record['flag_completato'].'" ]}
</div>
<div class="col-md-6">';
if ($record['idagente'] != 0) {
echo Modules::link('Anagrafiche', $record['idagente'], null, null, 'class="pull-right"');
}
echo '
{[ "type": "select", "label": "'.tr('Agente').'", "name": "idagente", "ajax-source": "agenti", "select-options": {"idanagrafica": '.$record['idanagrafica'].'}, "value": "$idagente$" ]}
</div>
</div>
</div>

View File

@ -41,6 +41,7 @@ $options = [
'idsede_partenza' => $documento->idsede_partenza,
'idsede_destinazione' => $documento->idsede_destinazione,
'permetti_movimento_a_zero' => 0,
'idagente' => $documento->idagente,
],
'impianti' => [
'idintervento' => $documento->id,
@ -59,8 +60,13 @@ $result = [
'idiva' => '',
'idconto' => $idconto,
'ritenuta_contributi' => true,
'provvigione_default' => 0,
'tipo_provvigione_default' => 'PRC',
];
// Leggo la provvigione predefinita per l'anagrafica
$result['provvigione_default'] = $dbo->fetchOne('SELECT provvigione_default FROM an_anagrafiche WHERE idanagrafica='.prepare($documento->idagente))['provvigione_default'];
// Leggo l'iva predefinita per l'anagrafica e se non c'è leggo quella predefinita generica
$iva = $dbo->fetchArray('SELECT idiva_vendite AS idiva FROM an_anagrafiche WHERE idanagrafica='.prepare($documento['idanagrafica']));
$result['idiva'] = $iva[0]['idiva'] ?: setting('Iva predefinita');

View File

@ -229,6 +229,20 @@ echo '
</tr>';
}
// Provvigione
if(!empty($intervento->provvigione)) {
echo '
<tr>
<td colspan="'.((!$record['flag_completato']) ? 6 : 5).'" class="text-right">
'.tr('Provvigioni').':
</td>
<td class="text-right">
'.moneyFormat($intervento->provvigione).'
</td>
<td></td>
</tr>';
}
}
echo'

View File

@ -186,6 +186,9 @@ switch (post('op')) {
$articolo->confermato = post('confermato') ?: 0;
$articolo->setPrezzoUnitario(post('prezzo_unitario'), post('idiva'));
$articolo->setSconto(post('sconto'), post('tipo_sconto'));
if ($dir == 'entrata') {
$articolo->setProvvigione(post('provvigione'), post('tipo_provvigione'));
}
try {
$articolo->qta = post('qta');
@ -265,6 +268,9 @@ switch (post('op')) {
$riga->confermato = post('confermato') ?: 0;
$riga->setPrezzoUnitario(post('prezzo_unitario'), post('idiva'));
$riga->setSconto(post('sconto'), post('tipo_sconto'));
if ($dir == 'entrata') {
$riga->setProvvigione(post('provvigione'), post('tipo_provvigione'));
}
$riga->qta = post('qta');
@ -425,6 +431,7 @@ switch (post('op')) {
$ordine->codice_cig = $documento->codice_cig;
$ordine->num_item = $documento->num_item;
$ordine->idreferente = $documento->idreferente;
$ordine->idagente = $documento->idagente;
$ordine->save();

View File

@ -38,6 +38,7 @@ $options = [
'idanagrafica' => $documento->idanagrafica,
'dir' => $documento->direzione,
'permetti_movimento_a_zero' => 1,
'idagente' => $documento->idagente,
],
],
];
@ -51,8 +52,13 @@ $result = [
'sconto_unitario' => 0,
'tipo_sconto' => '',
'idiva' => '',
'provvigione_default' => 0,
'tipo_provvigione_default' => 'PRC',
];
// Leggo la provvigione predefinita per l'anagrafica
$result['provvigione_default'] = $dbo->fetchOne('SELECT provvigione_default FROM an_anagrafiche WHERE idanagrafica='.prepare($documento->idagente))['provvigione_default'];
// Leggo l'iva predefinita per l'anagrafica e se non c'è leggo quella predefinita generica
$iva = $dbo->fetchArray('SELECT idiva_'.($dir == 'uscita' ? 'acquisti' : 'vendite').' AS idiva FROM an_anagrafiche WHERE idanagrafica='.prepare($documento['idanagrafica']));
$result['idiva'] = $iva[0]['idiva'] ?: setting('Iva predefinita');

View File

@ -347,6 +347,20 @@ if ($totale != $netto_a_pagare) {
</tr>';
}
// Provvigione
if(!empty($ordine->provvigione)) {
echo '
<tr>
<td colspan="7" class="text-right">
'.tr('Provvigioni').':
</td>
<td class="text-right">
'.moneyFormat($ordine->provvigione).'
</td>
<td></td>
</tr>';
}
echo '
</table>';
if (!$block_edit && sizeof($righe) > 0) {

View File

@ -225,6 +225,7 @@ switch (post('op')) {
$articolo->costo_unitario = post('costo_unitario') ?: 0;
$articolo->setPrezzoUnitario(post('prezzo_unitario'), post('idiva'));
$articolo->setSconto(post('sconto'), post('tipo_sconto'));
$articolo->setProvvigione(post('provvigione'), post('tipo_provvigione'));
try {
$articolo->qta = $qta;
@ -300,6 +301,7 @@ switch (post('op')) {
$riga->costo_unitario = post('costo_unitario') ?: 0;
$riga->setPrezzoUnitario(post('prezzo_unitario'), post('idiva'));
$riga->setSconto(post('sconto'), post('tipo_sconto'));
$riga->setProvvigione(post('provvigione'), post('tipo_provvigione'));
$riga->qta = $qta;

View File

@ -37,6 +37,7 @@ $options = [
'idanagrafica' => $documento->idanagrafica,
'dir' => $documento->direzione,
'permetti_movimento_a_zero' => 1,
'idagente' => $documento->idagente,
],
],
];
@ -50,8 +51,13 @@ $result = [
'sconto_unitario' => 0,
'tipo_sconto' => '',
'idiva' => '',
'provvigione_default' => 0,
'tipo_provvigione_default' => 'PRC',
];
// Leggo la provvigione predefinita per l'anagrafica
$result['provvigione_default'] = $dbo->fetchOne('SELECT provvigione_default FROM an_anagrafiche WHERE idanagrafica='.prepare($documento->idagente))['provvigione_default'];
// Leggo l'iva predefinita per l'anagrafica e se non c'è leggo quella predefinita generica
$iva = $dbo->fetchArray('SELECT idiva_vendite AS idiva FROM an_anagrafiche WHERE idanagrafica='.prepare($documento['idanagrafica']));
$result['idiva'] = $iva[0]['idiva'] ?: setting('Iva predefinita');

View File

@ -313,8 +313,23 @@ echo '
'.moneyFormat($preventivo->spesa).'
</td>
<td></td>
</tr>
</tr>';
// Provvigione
if(!empty($preventivo->provvigione)) {
echo '
<tr>
<td colspan="7" class="text-right">
'.tr('Provvigioni').':
</td>
<td class="text-right">
'.moneyFormat($preventivo->provvigione).'
</td>
<td></td>
</tr>';
}
echo '
<tr>
<td colspan="7" class="text-right">
'.tr('Margine (_PRC_%)', [

View File

@ -0,0 +1,55 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../core.php';
$operazione = filter('op');
switch ($operazione) {
case 'addprovvigione':
$dbo->insert('co_provvigioni', [
'idarticolo' => $id_parent,
'idagente' => post('idagente'),
'provvigione' => post('provvigione'),
'tipo_provvigione' => post('tipo_provvigione'),
]);
$id_record = $dbo->lastInsertedID();
flash()->info(tr('Aggiunta nuova provvigione!'));
break;
case 'updateprovvigione':
$dbo->update('co_provvigioni', [
'idagente' => post('idagente'),
'provvigione' => post('provvigione'),
'tipo_provvigione' => post('tipo_provvigione'),
], ['id' => $id_record]);
flash()->info(tr('Salvataggio completato!'));
break;
case 'deletereferente':
$dbo->query('DELETE FROM `co_provvigioni` WHERE `id`='.prepare($id_record));
flash()->info(tr('Provvigione eliminata!'));
break;
}

View File

@ -0,0 +1,51 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../core.php';
echo '
<form action="" method="post" role="form">
<input type="hidden" name="id_parent" value="'.$id_parent.'">
<input type="hidden" name="backto" value="record-edit">
<input type="hidden" name="op" value="addprovvigione">
<!-- Fix creazione da Anagrafica -->
<input type="hidden" name="id_record" value="">
<div class="row">
<div class="col-md-4">
{[ "type": "select", "label": "'.tr('Articolo').'", "name": "articolo", "ajax-source": "articoli", "value": "'.$id_parent.'", "disabled": "1" ]}
</div>
<div class="col-md-4">
{[ "type": "select", "label": "'.tr('Agente').'", "name": "idagente", "values": "query=SELECT an_anagrafiche.idanagrafica AS id, CONCAT(ragione_sociale, IF(citta IS NULL OR citta = \'\', \'\', CONCAT(\' (\', citta, \')\')), IF(deleted_at IS NULL, \'\', \' ('.tr('eliminata').')\')) AS descrizione, idtipointervento_default FROM an_anagrafiche INNER JOIN (an_tipianagrafiche_anagrafiche INNER JOIN an_tipianagrafiche ON an_tipianagrafiche_anagrafiche.idtipoanagrafica=an_tipianagrafiche.idtipoanagrafica) ON an_anagrafiche.idanagrafica=an_tipianagrafiche_anagrafiche.idanagrafica WHERE deleted_at IS NULL AND descrizione=\'Agente\' AND an_anagrafiche.idanagrafica NOT IN (SELECT idagente FROM co_provvigioni) ORDER BY ragione_sociale", "required": 1, "icon-after": "add|'.Modules::get('Anagrafiche')['id'].'|tipoanagrafica=Agente&readonly_tipo=1" ]}
</div>
<div class="col-md-4">
{[ "type": "number", "label": "'.tr('Provvigione').'", "name": "provvigione", "icon-after": "choice|untprc|UNT" ]}
</div>
</div>
<!-- PULSANTI -->
<div class="row">
<div class="col-md-12 text-right">
<button type="submit" class="btn btn-primary"><i class="fa fa-plus"></i> '.tr('Aggiungi').'</button>
</div>
</div>
</form>';

View File

@ -0,0 +1,54 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../core.php';
echo '
<form action="" method="post" role="form">
<input type="hidden" name="id_plugin" value="'.$id_plugin.'">
<input type="hidden" name="id_parent" value="'.$id_parent.'">
<input type="hidden" name="id_record" value="'.$id_record.'">
<input type="hidden" name="backto" value="record-edit">
<input type="hidden" name="op" value="updateprovvigione">
<div class="row">
<div class="col-md-4">
{[ "type": "select", "label": "'.tr('Articolo').'", "name": "articolo", "ajax-source": "articoli", "value": "'.$id_parent.'", "disabled": "1" ]}
</div>
<div class="col-md-4">
{[ "type": "select", "label": "'.tr('Agente').'", "name": "idagente", "value": "$idagente$", "values": "query=SELECT an_anagrafiche.idanagrafica AS id, CONCAT(ragione_sociale, IF(citta IS NULL OR citta = \'\', \'\', CONCAT(\' (\', citta, \')\')), IF(deleted_at IS NULL, \'\', \' ('.tr('eliminata').')\')) AS descrizione, idtipointervento_default FROM an_anagrafiche INNER JOIN (an_tipianagrafiche_anagrafiche INNER JOIN an_tipianagrafiche ON an_tipianagrafiche_anagrafiche.idtipoanagrafica=an_tipianagrafiche.idtipoanagrafica) ON an_anagrafiche.idanagrafica=an_tipianagrafiche_anagrafiche.idanagrafica WHERE deleted_at IS NULL AND descrizione=\'Agente\' AND an_anagrafiche.idanagrafica NOT IN (SELECT idagente FROM co_provvigioni WHERE idagente!='.prepare($record['idagente']).') ORDER BY ragione_sociale", "required": 1, "icon-after": "add|'.Modules::get('Anagrafiche')['id'].'|tipoanagrafica=Agente&readonly_tipo=1" ]}
</div>
<div class="col-md-4">
{[ "type": "number", "label": "'.tr('Provvigione').'", "name": "provvigione", "value": "'.$record['provvigione'].'", "icon-after": "choice|untprc|'.$record['tipo_provvigione'].'" ]}
</div>
</div>
<!-- PULSANTI -->
<div class="row">
<div class="col-md-12">
<a class="btn btn-danger ask" data-backto="record-edit" data-op="deleteprovvigione" data-id_record="'.$record['id'].'" data-id_plugin="'.$id_plugin.'" data-id_module="'.$id_module.'" data-id_parent="'.$id_parent.'">
<i class="fa fa-trash"></i> '.tr('Elimina').'
</a>
<button type="submit" class="btn btn-success pull-right"><i class="fa fa-check"></i> '.tr('Salva').'</button>
</div>
</div>
</form>';

View File

@ -0,0 +1,27 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../core.php';
use Modules\Articoli\Articolo;
if (isset($id_record)) {
$record = $dbo->fetchOne('SELECT * FROM co_provvigioni WHERE id='.prepare($id_record));
$articolo = Articolo::withTrashed()->find($id_parent);
}

View File

@ -62,6 +62,8 @@ abstract class Accounting extends Component
'sconto_unitario' => 'float',
'sconto_iva_unitario' => 'float',
'sconto_unitario_ivato' => 'float',
'provvigione_percentuale' => 'float',
'provvigione_unitaria' => 'float',
//'qta_evasa' => 'float',
];
@ -72,6 +74,7 @@ abstract class Accounting extends Component
'spesa',
'imponibile',
'sconto',
'provvigione',
'totale_imponibile',
'iva',
'totale',
@ -152,7 +155,7 @@ abstract class Accounting extends Component
*/
public function getMargineAttribute()
{
return $this->totale_imponibile - $this->spesa;
return $this->totale_imponibile - $this->spesa - $this->provvigione;
}
/**
@ -270,6 +273,27 @@ abstract class Accounting extends Component
}
}
/**
* Imposta la provvigione secondo le informazioni indicate per valore e tipologia (UNT o PRC).
*
* @param $value
* @param $type
*/
public function setProvvigione($value, $type)
{
$provvigione_unitaria = 0;
if ($type == 'PRC') {
$this->provvigione_percentuale = $value;
$provvigione_unitaria = ($this->prezzo_unitario - $this->sconto_unitario) / 100 * floatval($value);
$this->provvigione_unitaria = $provvigione_unitaria;
} else {
$this->provvigione_percentuale = 0;
$provvigione_unitaria = $value;
$this->provvigione_unitaria = $provvigione_unitaria;
}
}
public function incorporaIVA()
{
return $this->getDocument()->direzione == 'entrata' && setting('Utilizza prezzi di vendita comprensivi di IVA');
@ -299,6 +323,17 @@ abstract class Accounting extends Component
return $this->qta * $this->sconto_unitario;
}
/**
* Restituisce la provvigione della riga corrente in euro.
*
* @return float
*/
public function getProvvigioneAttribute()
{
return $this->qta * $this->provvigione_unitaria;
}
/**
* Restituisce il prezzo unitario corrente (unitario oppure unitario ivato a seconda dell'impostazione 'Utilizza prezzi di vendita comprensivi di IVA') per la riga.
*
@ -321,7 +356,7 @@ abstract class Accounting extends Component
*/
public function getMarginePercentualeAttribute()
{
return $this->imponibile ? (($this->imponibile / $this->spesa) - 1) * 100 : 100;
return ($this->totale_imponibile && ($this->spesa || $this->provvigione)) ? (($this->totale_imponibile / ($this->spesa + $this->provvigione)) - 1) * 100 : 100;
}
/**
@ -378,6 +413,7 @@ abstract class Accounting extends Component
// Fix dei campi statici
$this->fixSubtotale();
$this->fixSconto();
$this->fixProvvigione();
$this->fixIva();
@ -424,6 +460,15 @@ abstract class Accounting extends Component
$this->attributes['tipo_sconto'] = $this->sconto_percentuale ? 'PRC' : 'UNT';
}
/**
* Effettua i conti per lo sconto totale.
*/
protected function fixProvvigione()
{
$this->attributes['provvigione'] = $this->provvigione;
$this->attributes['tipo_provvigione'] = $this->provvigione_percentuale ? 'PRC' : 'UNT';
}
protected static function boot()
{
parent::boot();

View File

@ -169,6 +169,17 @@ abstract class Document extends Model implements ReferenceInterface, DocumentInt
return $this->calcola('sconto');
}
/**
* Calcola la provvigione totale del documento.
*
* @return float
*/
public function getProvvigioneAttribute()
{
return $this->calcola('provvigione');
}
/**
* Calcola il totale imponibile del documento.
*
@ -226,7 +237,7 @@ abstract class Document extends Model implements ReferenceInterface, DocumentInt
*/
public function getMarginePercentualeAttribute()
{
return ($this->totale_imponibile && $this->spesa) ? (($this->totale_imponibile / $this->spesa) - 1) * 100 : 100;
return ($this->totale_imponibile && ($this->spesa || $this->provvigione)) ? (($this->totale_imponibile / ($this->spesa + $this->provvigione)) - 1) * 100 : 100;
}
public function delete()

View File

@ -8,3 +8,31 @@ INSERT INTO `zz_views` (`id_module`, `name`, `query`, `order`, `search`, `slow`,
-- Aggiunta permessi viste ai gruppi
INSERT INTO `zz_group_view` (`id_gruppo`, `id_vista`) ( SELECT `zz_groups`.`id`, `zz_views`.`id` FROM `zz_groups`, `zz_views` INNER JOIN `zz_modules` ON `zz_views`.`id_module` = `zz_modules`.`id` WHERE `zz_modules`.`name` = 'Interventi' AND `zz_views`.`name` IN('Ore', 'Costi', 'Ricavi') );
-- Nuovo plugin "Provvigioni"
CREATE TABLE IF NOT EXISTS `co_provvigioni` (
`id` int NOT NULL AUTO_INCREMENT,
`idagente` int NOT NULL,
`idarticolo` int NOT NULL,
`provvigione` decimal(12,6) NOT NULL,
`tipo_provvigione` enum('UNT','PRC') NOT NULL DEFAULT 'UNT',
PRIMARY KEY (`id`)
);
INSERT INTO `zz_plugins` (`id`, `name`, `title`, `idmodule_from`, `idmodule_to`, `position`, `script`, `enabled`, `default`, `order`, `compatibility`, `version`, `options2`, `options`, `directory`, `help`) VALUES (NULL, 'Provvigioni', 'Provvigioni', (SELECT `id` FROM `zz_modules` WHERE `name` = 'Articoli'), (SELECT `id` FROM `zz_modules` WHERE `name` = 'Articoli'), 'tab', '', '1', '1', '0', '', '', NULL, '{ \"main_query\": [ { \"type\": \"table\", \"fields\": \"Agente, Provvigione\", \"query\": \"SELECT co_provvigioni.id, an_anagrafiche.ragione_sociale AS `Agente`, CONCAT(FORMAT(co_provvigioni.provvigione,2), \' \', IF(co_provvigioni.tipo_provvigione=\'UNT\', \'\', \'%\')) AS `Provvigione` FROM co_provvigioni LEFT JOIN an_anagrafiche ON co_provvigioni.idagente=an_anagrafiche.idanagrafica WHERE co_provvigioni.idarticolo=|id_parent| HAVING 2=2 ORDER BY co_provvigioni.id DESC\"} ]}', 'provvigioni', '');
ALTER TABLE `co_righe_contratti` ADD `provvigione` DECIMAL(12,6) NOT NULL AFTER `prezzo_unitario_ivato`, ADD `provvigione_unitaria` DECIMAL(12,6) NOT NULL AFTER `provvigione`, ADD `provvigione_percentuale` DECIMAL(12,6) NOT NULL AFTER `provvigione_unitaria`, ADD `tipo_provvigione` ENUM('UNT','PRC') NOT NULL DEFAULT 'UNT' AFTER `provvigione_percentuale`;
ALTER TABLE `co_righe_preventivi` ADD `provvigione` DECIMAL(12,6) NOT NULL AFTER `prezzo_unitario_ivato`, ADD `provvigione_unitaria` DECIMAL(12,6) NOT NULL AFTER `provvigione`, ADD `provvigione_percentuale` DECIMAL(12,6) NOT NULL AFTER `provvigione_unitaria`, ADD `tipo_provvigione` ENUM('UNT','PRC') NOT NULL DEFAULT 'UNT' AFTER `provvigione_percentuale`;
ALTER TABLE `co_righe_documenti` ADD `provvigione` DECIMAL(12,6) NOT NULL AFTER `prezzo_unitario_ivato`, ADD `provvigione_unitaria` DECIMAL(12,6) NOT NULL AFTER `provvigione`, ADD `provvigione_percentuale` DECIMAL(12,6) NOT NULL AFTER `provvigione_unitaria`, ADD `tipo_provvigione` ENUM('UNT','PRC') NOT NULL DEFAULT 'UNT' AFTER `provvigione_percentuale`;
ALTER TABLE `dt_righe_ddt` ADD `provvigione` DECIMAL(12,6) NOT NULL AFTER `prezzo_unitario_ivato`, ADD `provvigione_unitaria` DECIMAL(12,6) NOT NULL AFTER `provvigione`, ADD `provvigione_percentuale` DECIMAL(12,6) NOT NULL AFTER `provvigione_unitaria`, ADD `tipo_provvigione` ENUM('UNT','PRC') NOT NULL DEFAULT 'UNT' AFTER `provvigione_percentuale`;
ALTER TABLE `in_righe_interventi` ADD `provvigione` DECIMAL(12,6) NOT NULL AFTER `prezzo_unitario_ivato`, ADD `provvigione_unitaria` DECIMAL(12,6) NOT NULL AFTER `provvigione`, ADD `provvigione_percentuale` DECIMAL(12,6) NOT NULL AFTER `provvigione_unitaria`, ADD `tipo_provvigione` ENUM('UNT','PRC') NOT NULL DEFAULT 'UNT' AFTER `provvigione_percentuale`;
ALTER TABLE `or_righe_ordini` ADD `provvigione` DECIMAL(12,6) NOT NULL AFTER `prezzo_unitario_ivato`, ADD `provvigione_unitaria` DECIMAL(12,6) NOT NULL AFTER `provvigione`, ADD `provvigione_percentuale` DECIMAL(12,6) NOT NULL AFTER `provvigione_unitaria`, ADD `tipo_provvigione` ENUM('UNT','PRC') NOT NULL DEFAULT 'UNT' AFTER `provvigione_percentuale`;
ALTER TABLE `an_anagrafiche` ADD `provvigione_default` DECIMAL(12,6) NOT NULL AFTER `idtipointervento_default`;
ALTER TABLE `in_interventi` ADD `idagente` INT NOT NULL AFTER `idreferente`;