1
0
mirror of https://github.com/devcode-it/openstamanager.git synced 2025-02-02 08:56:48 +01:00

Fix sconto in nota di credito

This commit is contained in:
Thomas Zilio 2019-02-12 17:21:27 +01:00
parent fa6fe66f52
commit 2c2bd8091a
8 changed files with 184 additions and 109 deletions

View File

@ -12,6 +12,8 @@ abstract class Article extends Row
protected $serialRowID = 'documento';
protected $abilita_movimentazione = true;
protected $qta_movimentazione = 0;
public static function build(Document $document, Original $articolo)
{
$model = parent::build($document, true);
@ -30,7 +32,7 @@ abstract class Article extends Row
abstract public function getDirection();
/**
* Imposta i seriali collegati all'articolo del documento.
* Imposta i seriali collegati all'articolo.
*
* @param array $serials
*/
@ -45,6 +47,22 @@ abstract class Article extends Row
]);
}
/**
* Rimuove i seriali collegati all'articolo.
*
* @param array $serials
*/
public function removeSerials($serials)
{
database()->detach('mg_prodotti', [
'id_riga_'.$this->serialRowID => $this->id,
'dir' => $this->getDirection(),
'id_articolo' => $this->idarticolo,
], [
'serial' => array_clean($serials),
]);
}
/**
* Restituisce l'elenco dei seriali collegati all'articolo del documento.
*
@ -79,7 +97,7 @@ abstract class Article extends Row
$this->attributes['qta'] = $value;
if ($this->abilita_movimentazione) {
$this->movimenta($diff);
$this->qta_movimentazione += $diff;
}
$database = database();
@ -105,6 +123,22 @@ abstract class Article extends Row
$this->abilita_movimentazione = $value;
}
/**
* Salva l'articolo, eventualmente movimentandone il magazzino.
*
* @param array $options
*
* @return bool
*/
public function save(array $options = [])
{
if (!empty($this->qta_movimentazione)) {
$this->movimenta($this->qta_movimentazione);
}
return parent::save($options);
}
protected static function boot()
{
parent::boot(true);
@ -153,14 +187,22 @@ abstract class Article extends Row
return true;
}
protected function customBeforeCopiaIn($original)
protected function customInitCopiaIn($original)
{
$this->movimentazione(false);
$this->articolo()->associate($original->articolo);
}
protected function customAfterCopiaIn($original)
protected function customBeforeDataCopiaIn($original)
{
$this->movimentazione(false);
parent::customBeforeDataCopiaIn($original);
}
protected function customAfterDataCopiaIn($original)
{
$this->movimentazione(true);
parent::customAfterDataCopiaIn($original);
}
}

View File

@ -70,9 +70,9 @@ abstract class Description extends Model
// Creazione del nuovo oggetto
$model = new $object();
$model->setParent($document);
$model->customBeforeCopiaIn($this);
// Azioni specifiche di inizalizzazione
$model->customInitCopiaIn($this);
$model->save();
@ -80,15 +80,23 @@ abstract class Description extends Model
$model = $object::find($model->id);
$accepted = $model->getAttributes();
// Azioni specifiche precedenti
$model->customBeforeDataCopiaIn($this);
$attributes = array_intersect_key($attributes, $accepted);
$model->fill($attributes);
$model->customAfterCopiaIn($this);
// Impostazione del genitore
$model->setParent($document);
// Azioni specifiche successive
$model->customAfterDataCopiaIn($this);
$model->save();
// Rimozione quantità evasa
$this->qta_evasa = $this->qta_evasa + $attributes['qta'];
$this->qta_evasa = $this->qta_evasa + abs($attributes['qta']);
$this->save();
return $model;
}
@ -97,12 +105,27 @@ abstract class Description extends Model
abstract public function getParentID();
public function isDescrizione()
{
return $this->is_descrizione == 1;
}
public function isRiga()
{
return !$this->isDescrizione() && !$this->isArticolo();
}
public function isArticolo()
{
return !empty($this->idarticolo);
}
/**
* Azione personalizzata per la copia dell'oggetto (prima della copia).
* Azione personalizzata per la copia dell'oggetto (inizializzazione della copia).
*
* @param $original
*/
protected function customBeforeCopiaIn($original)
protected function customInitCopiaIn($original)
{
}
@ -111,7 +134,16 @@ abstract class Description extends Model
*
* @param $original
*/
protected function customAfterCopiaIn($original)
protected function customBeforeDataCopiaIn($original)
{
}
/**
* Azione personalizzata per la copia dell'oggetto (dopo la copia).
*
* @param $original
*/
protected function customAfterDataCopiaIn($original)
{
}

View File

@ -45,7 +45,9 @@ abstract class Discount extends Model
*/
public function getImponibileAttribute()
{
return $this->subtotale;
$result = $this->subtotale;
return $this->parent->tipo->reversed ? -$result : $result;
}
/**
@ -61,7 +63,9 @@ abstract class Discount extends Model
*/
public function getIvaAttribute()
{
return $this->attributes['iva'];
$result = $this->attributes['iva'];
return $this->parent->tipo->reversed ? -$result : $result;
}
protected static function boot()

View File

@ -36,7 +36,11 @@ abstract class Row extends Description
*/
public function getImponibileScontatoAttribute()
{
return $this->imponibile - $this->sconto;
$result = $this->prezzo_unitario_vendita > 0 ? $this->imponibile : -$this->imponibile;
$result -= $this->sconto;
return $this->prezzo_unitario_vendita > 0 ? $result : -$result;
}
/**
@ -193,7 +197,7 @@ abstract class Row extends Description
}
/**
* Save the model to the database.
* Salva la riga, impostando i campi dipendenti dai parametri singoli.
*
* @param array $options
*
@ -292,4 +296,16 @@ abstract class Row extends Description
{
$this->attributes['sconto'] = $this->sconto;
}
/**
* Azione personalizzata per la copia dell'oggetto (dopo la copia).
*
* @param $original
*/
protected function customAfterDataCopiaIn($original)
{
$this->prezzo_unitario_vendita = $original->prezzo_unitario_vendita;
parent::customAfterDataCopiaIn($original);
}
}

View File

@ -11,6 +11,14 @@ class Articolo extends Model
/**
* Funzione per inserire i movimenti di magazzino.
*
* @param $qta
* @param null $descrizone
* @param null $data
* @param bool $manuale
* @param array $array
*
* @return bool
*/
public function movimenta($qta, $descrizone = null, $data = null, $manuale = false, $array = [])
{
@ -27,6 +35,14 @@ class Articolo extends Model
/**
* Funzione per registrare i movimenti di magazzino.
*
* @param $qta
* @param null $descrizone
* @param null $data
* @param bool $manuale
* @param array $array
*
* @return bool
*/
public function registra($qta, $descrizone = null, $data = null, $manuale = false, $array = [])
{

View File

@ -1266,74 +1266,37 @@ switch (post('op')) {
$nota->idsede = $fattura->idsede;
$nota->save();
$id_record = $nota->id;
$righe = $fattura->getRighe();
foreach ($righe as $riga) {
if (post('evadere')[$riga->id] == 'on') {
$qta = post('qta_da_evadere')[$riga->id];
// Lettura di tutte le righe della tabella in arrivo
foreach (post('qta_da_evadere') as $i => $value) {
// Processo solo le righe da evadere
if (post('evadere')[$i] == 'on') {
$idriga = $i;
$idarticolo = post('idarticolo')[$i];
$descrizione = post('descrizione')[$i];
$copia = $riga->copiaIn($nota, -$qta);
$copia->ref_riga_documento = $riga->id;
$qta = -post('qta_da_evadere')[$i];
$um = post('um')[$i];
// Aggiornamento seriali dalla riga dell'ordine
if ($copia->isArticolo()) {
$copia->movimenta($copia->qta);
$subtot = post('subtot')[$i] * $qta;
$sconto = post('sconto')[$i];
$sconto = $sconto * $qta;
$serials = is_array(post('serial')[$riga->id]) ? post('serial')[$riga->id] : [];
$qprc = 'SELECT tipo_sconto, sconto_unitario FROM co_righe_documenti WHERE id='.prepare($idriga);
$rsprc = $dbo->fetchArray($qprc);
$sconto_unitario = $rsprc[0]['sconto_unitario'];
$tipo_sconto = $rsprc[0]['tipo_sconto'];
$idiva = post('idiva')[$i];
// Calcolo l'iva indetraibile
$q = 'SELECT percentuale, indetraibile FROM co_iva WHERE id='.prepare($idiva);
$rs = $dbo->fetchArray($q);
$iva = ($subtot - $sconto) / 100 * $rs[0]['percentuale'];
$iva_indetraibile = $iva / 100 * $rs[0]['indetraibile'];
// Leggo la descrizione iva
$query = 'SELECT * FROM co_iva WHERE id='.prepare($idiva);
$rs = $dbo->fetchArray($query);
$desc_iva = $rs[0]['descrizione'];
$qdesc = 'SELECT is_descrizione FROM co_righe_documenti WHERE id='.prepare($i);
$rsdesc = $dbo->fetchArray($qdesc);
// Se sto aggiungendo un articolo uso la funzione per inserirlo e incrementare la giacenza
if (!empty($idarticolo)) {
$idiva_acquisto = $idiva;
$prezzo_acquisto = $subtot;
$riga = add_articolo_infattura($id_record, $idarticolo, $descrizione, $idiva_acquisto, $qta, $prezzo_acquisto, $sconto, $sconto_unitario, $tipo_sconto);
// Aggiornamento seriali dalla riga dell'ordine
$serials = is_array(post('serial')[$i]) ? post('serial')[$i] : [];
$serials = array_clean($serials);
$dbo->sync('mg_prodotti', ['id_riga_documento' => $riga, 'dir' => 'uscita', 'id_articolo' => $idarticolo], ['serial' => $serials]);
$dbo->detach('mg_prodotti', ['id_riga_documento' => $idriga, 'dir' => 'entrata', 'id_articolo' => $idarticolo], ['serial' => $serials]);
$copia->serials = $serials;
$riga->removeSerials($serials);
}
// Inserimento riga normale
else {
$query = 'INSERT INTO co_righe_documenti(iddocumento, idarticolo, descrizione, idconto, idordine, idiva, desc_iva, iva, iva_indetraibile, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, is_descrizione, `order`) VALUES('.prepare($id_record).', '.prepare($idarticolo).', '.prepare($descrizione).', '.prepare($idconto).', '.prepare($idordine).', '.prepare($idiva).', '.prepare($desc_iva).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($subtot).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).', '.prepare($um).', '.prepare($qta).', '.prepare($rsdesc[0]['is_descrizione']).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM co_righe_documenti AS t WHERE iddocumento='.prepare($id_record).'))';
$dbo->query($query);
$riga = $dbo->lastInsertedID();
}
$dbo->query('UPDATE co_righe_documenti SET ref_riga_documento = '.prepare($idriga).' WHERE id='.prepare($riga));
// Scalo la quantità dall ordine
$dbo->query('UPDATE co_righe_documenti SET qta_evasa = qta_evasa+'.(-$qta).' WHERE id='.prepare($idriga));
}
}
// Aggiornamento sconto
if (post('evadere')[$fattura->scontoGlobale->id] == 'on') {
$nota->tipo_sconto_globale = $fattura->tipo_sconto_globale;
$nota->sconto_globale = $fattura->sconto_globale;
$nota->save();
$nota->updateSconto();
}
$id_record = $nota->id;
break;
case 'transform':

View File

@ -2,8 +2,6 @@
include_once __DIR__.'/../../core.php';
use Modules\Fatture\Components\Articolo;
use Modules\Fatture\Components\Descrizione;
use Modules\Fatture\Components\Riga;
// Righe fattura
@ -24,11 +22,13 @@ echo '
</thead>
<tbody class="sortable">';
foreach ($righe as $riga) {
foreach ($righe as $row) {
$riga = $row->toArray();
// Valori assoluti
$riga['qta'] = abs($riga['qta']);
$riga['prezzo_unitario_acquisto'] = abs($riga['prezzo_unitario_acquisto']);
$riga['subtotale'] = abs($riga['subtotale']);
$riga['imponibile_scontato'] = abs($row->imponibile_scontato);
$riga['sconto_unitario'] = abs($riga['sconto_unitario']);
$riga['sconto'] = abs($riga['sconto']);
$riga['iva'] = abs($riga['iva']);
@ -43,11 +43,11 @@ foreach ($righe as $riga) {
$ref_id = null;
// Articoli
if ($riga instanceof Articolo) {
if ($row->isArticolo()) {
$ref_modulo = Modules::get('Articoli')['id'];
$ref_id = $riga['idarticolo'];
$riga['descrizione'] = (!empty($riga->articolo) ? $riga->articolo->codice.' - ' : '').$riga['descrizione'];
$riga['descrizione'] = (!empty($rowarticolo) ? $rowarticolo->codice.' - ' : '').$riga['descrizione'];
$delete = 'unlink_articolo';
@ -97,7 +97,7 @@ foreach ($righe as $riga) {
// Individuazione dei seriali
if (!empty($riga['abilita_serial'])) {
$serials = $riga->serials;
$serials = $rowserials;
$mancanti = $riga['qta'] - count($serials);
if ($mancanti > 0) {
@ -161,9 +161,9 @@ foreach ($righe as $riga) {
echo '
<td class="text-center">';
if (!$riga instanceof Descrizione) {
if (!$row->isDescrizione()) {
echo '
'.Translator::numberToLocale($riga->qta, 'qta');
'.Translator::numberToLocale($riga['qta'], 'qta');
}
echo '
@ -173,7 +173,7 @@ foreach ($righe as $riga) {
echo '
<td class="text-center">';
if (!$riga instanceof Descrizione) {
if (!$row->isDescrizione()) {
echo '
'.$riga['um'];
}
@ -185,22 +185,22 @@ foreach ($righe as $riga) {
echo '
<td class="text-right">';
if (!$riga instanceof Descrizione) {
if (!$row->isDescrizione()) {
echo '
'.Translator::numberToLocale($riga->prezzo_unitario_vendita).' &euro;';
'.Translator::numberToLocale($row->prezzo_unitario_vendita).' &euro;';
if ($dir == 'entrata') {
echo '
<br><small>
'.tr('Acquisto').': '.Translator::numberToLocale($riga->prezzo_unitario_acquisto).' &euro;
'.tr('Acquisto').': '.Translator::numberToLocale($row->prezzo_unitario_acquisto).' &euro;
</small>';
}
if ($riga->sconto_unitario > 0) {
if ($rowsconto_unitario > 0) {
echo '
<br><small class="label label-danger">'.tr('sconto _TOT_ _TYPE_', [
'_TOT_' => Translator::numberToLocale($riga->sconto_unitario),
'_TYPE_' => ($riga->tipo_sconto == 'PRC' ? '%' : '&euro;'),
'_TOT_' => Translator::numberToLocale($row->sconto_unitario),
'_TYPE_' => ($row->tipo_sconto == 'PRC' ? '%' : '&euro;'),
]).'</small>';
}
}
@ -212,10 +212,10 @@ foreach ($righe as $riga) {
echo '
<td class="text-right">';
if (!$riga instanceof Descrizione) {
if (!$row->isDescrizione()) {
echo '
'.Translator::numberToLocale($riga->iva).' &euro;
<br><small class="'.(($riga->aliquota->deleted_at) ? 'text-red' : '').' help-block">'.$riga->desc_iva.(($riga->aliquota->esente) ? ' ('.$riga->aliquota->codice_natura_fe.')': null).'</small>';
'.Translator::numberToLocale($riga['iva']).' &euro;
<br><small class="'.(($row->aliquota->deleted_at) ? 'text-red' : '').' help-block">'.$row->desc_iva.(($row->aliquota->esente) ? ' ('.$row->aliquota->codice_natura_fe.')' : null).'</small>';
}
echo '
@ -224,12 +224,12 @@ foreach ($righe as $riga) {
// Importo
echo '
<td class="text-right">';
if (!$riga instanceof Descrizione) {
if (!$row->isDescrizione()) {
echo '
'.Translator::numberToLocale($riga->imponibile_scontato).' &euro;';
'.Translator::numberToLocale($riga['imponibile_scontato']).' &euro;';
/*
<br><small class="text-'.($riga->guadagno > 0 ? 'success' : 'danger').'">
'.tr('Guadagno').': '.Translator::numberToLocale($riga->guadagno).' &euro;
<br><small class="text-'.($rowguadagno > 0 ? 'success' : 'danger').'">
'.tr('Guadagno').': '.Translator::numberToLocale($row->guadagno).' &euro;
</small>';
*/
}
@ -247,7 +247,7 @@ foreach ($righe as $riga) {
<input type='hidden' name='idriga' value='".$riga['id']."'>
<input type='hidden' name='op' value='".$delete."'>";
if ($riga instanceof Articolo) {
if ($row->isArticolo()) {
echo "
<input type='hidden' name='idarticolo' value='".$riga['idarticolo']."'>";
}
@ -255,7 +255,7 @@ foreach ($righe as $riga) {
echo "
<div class='input-group-btn'>";
if (!$fattura->isNotaDiAccredito() && $riga instanceof Articolo && $riga['abilita_serial'] && (empty($riga['idddt']) || empty($riga['idintervento']))) {
if (!$fattura->isNotaDiAccredito() && $row->isArticolo() && $riga['abilita_serial'] && (empty($riga['idddt']) || empty($riga['idintervento']))) {
echo "
<a class='btn btn-primary btn-xs'data-toggle='tooltip' title='Aggiorna SN...' onclick=\"launch_modal( 'Aggiorna SN', '".$rootdir.'/modules/fatture/add_serial.php?id_module='.$id_module.'&id_record='.$id_record.'&idriga='.$riga['id'].'&idarticolo='.$riga['idarticolo']."', 1 );\"><i class='fa fa-barcode' aria-hidden='true'></i></a>";
}
@ -346,13 +346,13 @@ if (!empty($fattura->rivalsa_inps)) {
echo '
<tr>
<td colspan="5" class="text-right">';
if ($dir == 'entrata') {
echo '
if ($dir == 'entrata') {
echo '
<span class="tip" title="'.$database->fetchOne('SELECT CONCAT_WS(\' - \', codice, descrizione) AS descrizione FROM fe_tipo_cassa WHERE codice = '.prepare(setting('Tipo Cassa')))['descrizione'].'" > <i class="fa fa-question-circle-o"></i></span> ';
}
echo '
}
echo '
<b>'.tr('Rivalsa', [], ['upper' => true]).' :</b>
</td>
<td align="right">

View File

@ -385,9 +385,11 @@ switch (post('op')) {
$righe = $preventivo->getRighe();
foreach ($righe as $riga) {
$copia = $riga->copiaIn($fattura);
$copia->movimenta($copia->qta);
$copia->idconto = $id_conto;
if ($riga->isArticolo()) {
$copia->movimenta($copia->qta);
}
}
flash()->info(tr('Creata una nuova fattura!'));