1
0
mirror of https://github.com/devcode-it/openstamanager.git synced 2025-02-24 15:27:43 +01:00

Miglioramenti distribuiti

Gestione della gerarchia per qta_evasa, stati dei documenti relativi (con priorità a "Fatturato") e eliminazione dei documenti.
Miglioramento gestione schermata di importazione documento in un altro.
Standardizzazione rimozione righe per le fatture.
This commit is contained in:
Thomas Zilio 2019-07-23 15:39:00 +02:00
parent 2450c638b5
commit c2eb43c308
32 changed files with 795 additions and 1399 deletions

View File

@ -1,197 +1,270 @@
<?php
$id_record = $result['id_record'];
$id_documento_finale = $result['id_documento'];
$final_module = Modules::get($options['final_module']);
$original_module = Modules::get($options['original_module']);
$dir = $options['dir'];
$op = $options['op'];
$table = $options['sql']['table'];
$rows = $options['sql']['rows'];
$id_rows = $options['sql']['id_rows'];
// Info documento
$documento = $dbo->fetchOne('SELECT * FROM '.$table.' WHERE id = '.prepare($id_record));
$numero = !empty($documento['numero_esterno']) ? $documento['numero_esterno'] : $documento['numero'];
$id_anagrafica = $documento['idanagrafica'];
$id_pagamento = $documento['idpagamento'];
$id_conto = $documento['idconto'];
if (empty($documento)) {
// Inizializzazione
$documento = $options['documento'];
$documento_finale = $options['documento_finale'];
if (empty($documento) || (!empty($documento_finale) && $documento_finale->direzione != $documento->direzione)) {
return;
}
// Informazioi utili
$dir = $documento->direzione;
$original_module = Modules::get($documento->module);
$name = !empty($documento_finale) ? $documento_finale->module : $options['module'];
$final_module = Modules::get($name);
// IVA predefinta
$id_iva = $id_iva ?: setting('Iva predefinita');
if (empty($id_conto)) {
$id_conto = ($dir == 'entrata') ? setting('Conto predefinito fatture di vendita') : setting('Conto predefinito fatture di acquisto');
$righe = $documento->getRighe()->where('qta_rimanente', '>', 0);
if (empty($righe)) {
echo '
<p>'.tr('Non ci sono elementi da evadere').'...</p>';
return;
}
// Selezione articoli dell'ordine da portare nel ddt
$righe = $dbo->fetchArray('SELECT *, IFNULL((SELECT codice FROM mg_articoli WHERE id=idarticolo),"") AS codice, (qta - qta_evasa) AS qta_rimanente FROM '.$table.' INNER JOIN '.$rows.' ON '.$table.'.id='.$rows.'.'.$id_rows.' WHERE '.$table.'.id='.prepare($id_record).' HAVING qta_rimanente > 0 ORDER BY `order`');
$link = !empty($documento_finale) ? ROOTDIR.'/editor.php?id_module='.$final_module['id'].'&id_record='.$documento_finale->id : ROOTDIR.'/controller.php?id_module='.$final_module['id'];
if (!empty($righe)) {
echo '
echo '
<form action="'.ROOTDIR.'/controller.php?id_module='.$final_module['id'].(!empty($id_documento_finale) ? '&id_record='.$id_documento_finale : '').'" method="post">
<input type="hidden" name="'.$options['id_importazione'].'" value="'.$id_record.'">
<input type="hidden" name="idanagrafica" value="'.$id_anagrafica.'">
<input type="hidden" name="idconto" value="'.$id_conto.'">
<input type="hidden" name="idpagamento" value="'.$id_pagamento.'">
<input type="hidden" name="iddocumento" value="'.$id_record.'">
<input type="hidden" name="op" value="'.$op.'">
<form action="'.$link.'" method="post">
<input type="hidden" name="op" value="'.$options['op'].'">
<input type="hidden" name="backto" value="record-edit">
<input type="hidden" name="dir" value="'.$dir.'">';
<input type="hidden" name="id_documento" value="'.$documento->id.'">
<input type="hidden" name="type" value="'.$options['type'].'">';
// Creazione fattura dal documento
if (!empty($options['create_document'])) {
echo '
<div class="row">
<input type="hidden" name="create_document" value="on"/>
// Creazione fattura dal documento
if (!empty($options['create_document'])) {
echo '
<div class="box box-warning">
<div class="box-header with-border">
<h3 class="box-title">'.tr('Nuovo documento').'</h3>
</div>
<div class="box-body">
<div class="row">
<input type="hidden" name="create_document" value="on" />
<div class="col-md-6">
{[ "type": "date", "label": "'.tr('Data del documento').'", "name": "data", "required": 1, "value": "-now-" ]}
</div>';
<div class="col-md-6">
{[ "type": "date", "label": "'.tr('Data del documento').'", "name": "data", "required": 1, "value": "-now-" ]}
</div>';
if (in_array($final_module['name'], ['Fatture di vendita', 'Fatture di acquisto'])) {
if ($op == 'nota_accredito' && !empty($segmenti)) {
$segmento = $dbo->fetchOne("SELECT * FROM zz_segments WHERE predefined_accredito='1'");
if ($final_module['name'] == 'Fatture di vendita' || $final_module['name'] == 'Fatture di acquisto') {
if ($op == 'nota_accredito' && !empty($segmenti)) {
$segmento = $dbo->fetchOne("SELECT * FROM zz_segments WHERE predefined_accredito='1'");
$id_segment = $segmento['id'];
} else {
$id_segment = $_SESSION['module_'.$final_module['id']]['id_segment'];
}
echo '
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Sezionale').'", "name": "id_segment", "required": 1, "values": "query=SELECT id, name AS descrizione FROM zz_segments WHERE id_module='.prepare($final_module['id']).' ORDER BY name", "value": "'.$id_segment.'" ]}
</div>';
$id_segment = $segmento['id'];
} else {
$id_segment = $_SESSION['module_'.$final_module['id']]['id_segment'];
}
echo '
<div class="col-md-6">
{[ "type": "select", "label": "'.tr('Ritenuta contributi').'", "name": "id_ritenuta_contributi", "value": "$id_ritenuta_contributi$", "values": "query=SELECT * FROM co_ritenuta_contributi" ]}
</div>
<div class="col-md-12">
{[ "type": "select", "label": "'.tr('Sezionale').'", "name": "id_segment", "required": 1, "values": "query=SELECT id, name AS descrizione FROM zz_segments WHERE id_module='.prepare($final_module['id']).' ORDER BY name", "value": "'.$id_segment.'" ]}
</div>';
}
echo '
</div>
</div>
</div>';
}
// Conto, rivalsa INPS, ritenuta d'acconto e ritenuta contributi
if (in_array($final_module['name'], ['Fatture di vendita', 'Fatture di acquisto']) && !in_array($original_module['name'], ['Fatture di vendita', 'Fatture di acquisto'])) {
$id_rivalsa_inps = setting('Percentuale rivalsa');
if ($dir == 'uscita') {
$id_ritenuta_acconto = $documento->anagrafica->id_ritenuta_acconto_acquisti;
} else {
$id_ritenuta_acconto = $documento->anagrafica->id_ritenuta_acconto_vendite ?: setting("Percentuale ritenuta d'acconto");
}
$calcolo_ritenuta_acconto = setting("Metodologia calcolo ritenuta d'acconto predefinito");
$show_rivalsa = !empty($id_rivalsa_inps);
$show_ritenuta_acconto = setting("Percentuale ritenuta d'acconto") != '' || !empty($id_ritenuta_acconto);
$show_ritenuta_contributi = !empty($documento_finale['id_ritenuta_contributi']);
$id_conto = $documento_finale['idconto'];
if (empty($id_conto)) {
$id_conto = ($dir == 'entrata') ? setting('Conto predefinito fatture di vendita') : setting('Conto predefinito fatture di acquisto');
}
echo '
<div class="box box-info">
<div class="box-header with-border">
<h3 class="box-title">'.tr('Opzioni generali delle righe').'</h3>
</div>
<div class="box-body">';
if ($show_rivalsa || $show_ritenuta_acconto) {
echo '
<div class="row">';
// Rivalsa INPS
if ($show_rivalsa) {
echo '
<div class="col-md-4">
{[ "type": "select", "label": "'.tr('Rivalsa').'", "name": "id_rivalsa_inps", "value": "'.$id_rivalsa_inps.'", "values": "query=SELECT * FROM co_rivalse", "help": "'.(($options['dir'] == 'entrata') ? setting('Tipo Cassa Previdenziale') : null).'" ]}
</div>';
}
// Ritenuta d'acconto
if ($show_ritenuta_acconto) {
echo '
<div class="col-md-4">
{[ "type": "select", "label": "'.tr("Ritenuta d'acconto").'", "name": "id_ritenuta_acconto", "value": "'.$id_ritenuta_acconto.'", "values": "query=SELECT * FROM co_ritenutaacconto" ]}
</div>';
// Calcola ritenuta d'acconto su
echo '
<div class="col-md-4">
{[ "type": "select", "label": "'.tr("Calcola ritenuta d'acconto su").'", "name": "calcolo_ritenuta_acconto", "value": "'.$calcolo_ritenuta_acconto.'", "values": "list=\"IMP\":\"Imponibile\", \"IMP+RIV\":\"Imponibile + rivalsa\"", "required": "1" ]}
</div>';
}
echo '
</div>';
}
$width = $show_ritenuta_contributi ? 6 : 12;
echo '
<div class="row">';
// Ritenuta contributi
if ($show_ritenuta_contributi) {
echo '
<div class="col-md-'.$width.'">
{[ "type": "checkbox", "label": "'.tr('Ritenuta contributi').'", "name": "ritenuta_contributi", "value": "1" ]}
</div>';
}
// Conto
if (($final_module['name'] == 'Fatture di vendita' || $final_module['name'] == 'Fatture di acquisto') && !($original_module['name'] == 'Fatture di vendita' || $original_module['name'] == 'Fatture di acquisto')) {
echo '
<div class="row">
<div class="col-md-12">
{[ "type": "select", "label": "'.tr('Conto').'", "name": "id_conto", "required": 1, "value": "'.$id_conto.'", "ajax-source": "'.($dir == 'entrata' ? 'conti-vendite' : 'conti-acquisti').'" ]}
echo '
<div class="col-md-'.$width.'">
{[ "type": "select", "label": "'.tr('Conto').'", "name": "id_conto", "required": 1, "value": "'.$id_conto.'", "ajax-source": "'.($dir == 'entrata' ? 'conti-vendite' : 'conti-acquisti').'" ]}
</div>
</div>
</div>
</div>';
}
}
echo '
<div class="clearfix"></div>
<br>
<div class="box box-success">
<div class="box-header with-border">
<h3 class="box-title">'.tr('Righe da importare').'</h3>
</div>
<p>'.tr('Seleziona le righe e le relative quantità da inserire nel documento').'.</p>
<table class="box-body table table-striped table-hover table-condensed">
<tr>
<th>'.tr('Descrizione').'</th>
<th width="10%">'.tr('Q.').'</th>
<th width="15%">'.tr('Q. da evadere').'</th>
<th width="20%">'.tr('Subtot.').'</th>';
<table class="table table-striped table-hover table-condensed">
<tr>
<th>'.tr('Descrizione').'</th>
<th width="10%">'.tr('Q.').'</th>
<th width="15%">'.tr('Q. da evadere').'</th>
<th width="20%">'.tr('Subtot.').'</th>';
if (!empty($options['serials'])) {
echo '
<th width="20%">'.tr('Seriali').'</th>';
}
echo '
</tr>';
foreach ($righe as $i => $r) {
// Descrizione
echo '
<tr>
<td>
<input type="hidden" id="subtot_'.$i.'" name="subtot['.$r['id'].']" value="'.$r['prezzo_unitario_vendita'].'" />
<input type="hidden" id="sconto_'.$i.'" name="sconto['.$r['id'].']" value="'.$r['sconto'] / $r['qta'].'" />
<input type="hidden" id="iva_'.$i.'" name="iva['.$r['id'].']" value="'.$r['iva'] / $r['qta'].'" />
<input type="hidden" id="qtamax_'.$i.'" value="'.($r['qta_rimanente']).'" />';
// Checkbox - da evadere?
echo '
<input type="checkbox" checked="checked" id="checked_'.$i.'" name="evadere['.$r['id'].']" value="on" onclick="ricalcola_subtotale_riga('.$i.');" />';
$descrizione = ($r->isArticolo() ? $r->articolo->codice.' - ' : '').$r['descrizione'];
echo '&nbsp;'.nl2br($descrizione);
echo '
</td>';
// Q.tà rimanente
echo '
<td class="text-center">
'.Translator::numberToLocale($r['qta_rimanente']).'
</td>';
// Q.tà da evadere
echo '
<td>
{[ "type": "number", "name": "qta_da_evadere['.$r['id'].']", "id": "qta_'.$i.'", "required": 1, "value": "'.$r['qta_rimanente'].'", "decimals": "qta", "min-value": "0", "extra": "'.(($r['is_descrizione']) ? 'readonly' : '').' onkeyup=\"ricalcola_subtotale_riga('.$i.');\"" ]}
</td>';
echo '
<td>
<big id="subtotale_'.$i.'">'.moneyFormat($r->totale).'</big><br/>
<small style="color:#777;" id="subtotaledettagli_'.$i.'">'.Translator::numberToLocale($r->totale_imponibile).' + '.Translator::numberToLocale($r->iva).'</small>
</td>';
// Seriali
if (!empty($options['serials'])) {
echo '
<th width="20%">'.tr('Seriali').'</th>';
}
<td>';
echo '
</tr>';
if (!empty($r['abilita_serial'])) {
$serials = $r->serials;
foreach ($righe as $i => $r) {
// Descrizione
echo '
<tr>
<td>';
// Checkbox - da evadere?
echo '
<input type="checkbox" checked="checked" id="checked_'.$i.'" name="evadere['.$r['id'].']" value="on" onclick="ricalcola_subtotale_riga('.$i.');" />';
$descrizione = (!empty($r['codice']) ? $r['codice'].' - ' : '').$r['descrizione'];
echo '&nbsp;'.nl2br($descrizione);
echo '
</td>';
// Q.tà rimanente
echo '
<td>
<input type="hidden" id="qtamax_'.$i.'" value="'.($r['qta'] - $r['qta_evasa']).'" />
<p class="text-center">'.Translator::numberToLocale($r['qta_rimanente']).'</p>
</td>';
// Q.tà da evadere
echo '
<td>
{[ "type": "number", "name": "qta_da_evadere['.$r['id'].']", "id": "qta_'.$i.'", "required": 1, "value": "'.$r['qta_rimanente'].'", "decimals": "qta", "min-value": "0", "extra": "'.(($r['is_descrizione']) ? 'readonly' : '').' onkeyup=\"ricalcola_subtotale_riga('.$i.');\"" ]}
</td>';
// Subtotale
$subtotale = $r['subtotale'] / $r['qta'] * ($r['qta'] - $r['qta_evasa']);
$sconto = $r['sconto'] / $r['qta'] * ($r['qta'] - $r['qta_evasa']);
$iva = $r['iva'] / $r['qta'] * ($r['qta'] - $r['qta_evasa']);
echo '
<td>
<input type="hidden" id="subtot_'.$i.'" name="subtot['.$r['id'].']" value="'.$r['subtotale'] / $r['qta'].'" />
<input type="hidden" id="sconto_'.$i.'" name="sconto['.$r['id'].']" value="'.$r['sconto'] / $r['qta'].'" />
<input type="hidden" id="iva_'.$i.'" name="iva['.$r['id'].']" value="'.$r['iva'] / $r['qta'].'" />
<big id="subtotale_'.$i.'">'.moneyFormat($subtotale - $sconto + $iva).'</big><br/>
<small style="color:#777;" id="subtotaledettagli_'.$i.'">'.Translator::numberToLocale($subtotale - $sconto).' + '.Translator::numberToLocale($iva).'</small>
</td>';
// Seriali
if (!empty($options['serials'])) {
echo '
<td>';
if (!empty($r['abilita_serial'])) {
$query = 'SELECT DISTINCT serial AS id, serial AS descrizione FROM mg_prodotti WHERE dir='.prepare($dir).' AND '.$options['serials']['id_riga'].' = '.prepare($r['id']).' AND serial IS NOT NULL AND serial NOT IN (SELECT serial FROM mg_prodotti AS t WHERE serial IS NOT NULL AND dir='.prepare($dir).' AND '.$options['serials']['condition'].')';
$values = $dbo->fetchArray($query);
if (!empty($values)) {
echo '
{[ "type": "select", "name": "serial['.$r['id'].'][]", "id": "serial_'.$i.'", "multiple": 1, "values": "query='.$query.'", "value": "'.implode(',', array_column($values, 'id')).'", "extra": "data-maximum=\"'.intval($r['qta_rimanente']).'\"" ]}';
}
$list = [];
foreach ($serials as $serial) {
$list[] = [
'id' => $serial,
'text' => $serial,
];
}
if (empty($r['abilita_serial']) || empty($values)) {
echo '-';
if (!empty($serials)) {
echo '
{[ "type": "select", "name": "serial['.$r['id'].'][]", "id": "serial_'.$i.'", "multiple": 1, "values": '.json_encode($list).', "value": "'.implode(',', $serials).'", "extra": "data-maximum=\"'.intval($r['qta_rimanente']).'\"" ]}';
}
}
echo '
</td>';
if (empty($r['abilita_serial']) || empty($serials)) {
echo '-';
}
echo '
</tr>';
</td>';
}
// Totale
echo '
<tr>
<td colspan="'.(!empty($options['serials']) ? 4 : 3).'" align="right" class="text-right">
<b>'.tr('Totale').':</b>
</td>
<td class="text-right" colspan="2">
<big id="totale"></big>
</td>
</tr>
</table>';
</tr>';
}
echo '
// Totale
echo '
<tr>
<td colspan="'.(!empty($options['serials']) ? 4 : 3).'" align="right" class="text-right">
<b>'.tr('Totale').':</b>
</td>
<td class="text-right" colspan="2">
<big id="totale"></big>
</td>
</tr>
</table>
</div>';
echo '
<!-- PULSANTI -->
<div class="row">
@ -202,10 +275,6 @@ if (!empty($righe)) {
</div>
</div>
</form>';
} else {
echo '
<p>'.tr('Non ci sono elementi da evadere').'...</p>';
}
echo '
<script src="'.ROOTDIR.'/lib/init.js"></script>';
@ -255,13 +324,13 @@ echo '
}
function ricalcola_totale() {
tot_qta = 0;
r = 0;
totale = 0.00;
$('input[id*=qta_]').each(function() {
qta = $(this).val().toEnglish();
r = $(this).attr("id").replace("qta_", "");
if (!$('#checked_' + r).is(':checked') || isNaN(qta)) {
if (!$("#checked_" + r).is(":checked") || isNaN(qta)) {
qta = 0;
}
@ -278,17 +347,13 @@ echo '
if(subtot) {
totale += subtot * qta + iva * qta;
}
r++;
tot_qta += qta;
});
$('#totale').html((totale.toLocale()) + " " + globals.currency);
<?php
if (empty($options['sql']['allow-empty'])) {
if (empty($options['allow-empty'])) {
echo '
if (tot_qta > 0)
$("#submit_btn").show();

View File

@ -16,7 +16,7 @@ echo '
// Quantità
echo '
<div class="col-md-4">
{[ "type": "number", "label": "'.tr('Q.tà').'", "name": "qta", "required": 1, "value": "'.$result['qta'].'", "decimals": "qta" ]}
{[ "type": "number", "label": "'.tr('Q.tà').'", "name": "qta", "required": 1, "value": "'.$result['qta'].'", "decimals": "qta"'.(isset($result['max_qta']) ? ', "icon-after": "/ '.numberFormat($result['max_qta'], 'qta').'", "help": "'.tr("Quantità dell'elemento / quantità totale massima").'"' : '').' ]}
</div>';
// Unità di misura

View File

@ -169,8 +169,19 @@ abstract class Article extends Row
return parent::save($options);
}
public function canDelete()
{
$serials = $this->usedSerials();
return empty($serials);
}
public function delete()
{
if (!$this->canDelete()) {
throw new \InvalidArgumentException();
}
$this->serials = [];
$this->qta = 0; // Fix movimentazione automatica

View File

@ -12,6 +12,10 @@ abstract class Description extends Model
protected $guarded = [];
protected $appends = [
'max_qta',
];
public static function build(Document $document, $bypass = false)
{
$model = parent::build();
@ -26,6 +30,17 @@ abstract class Description extends Model
return $model;
}
public function getMaxQtaAttribute()
{
if (!$this->hasOriginal()) {
return null;
}
$original = $this->getOriginal();
return $original->qta_rimanente + $this->qta;
}
/**
* Modifica la quantità dell'elemento.
*
@ -69,12 +84,21 @@ abstract class Description extends Model
return $this->qta - $this->qta_evasa;
}
public function canDelete()
{
return true;
}
public function delete()
{
if (!$this->canDelete()) {
throw new \InvalidArgumentException();
}
$this->qta = 0;
$result = parent::delete();
$this->parent->controllo($this);
$this->parent->fixStato($this);
return $result;
}
@ -190,7 +214,7 @@ abstract class Description extends Model
{
$result = parent::save($options);
$this->parent->controllo($this);
$this->parent->fixStato($this);
return $result;
}

View File

@ -125,6 +125,16 @@ abstract class Document extends Model
public function delete()
{
$righe = $this->getRighe();
$can_delete = true;
foreach ($righe as $riga) {
$can_delete &= $riga->canDelete();
}
if (!$can_delete) {
throw new \InvalidArgumentException();
}
foreach ($righe as $riga) {
$riga->delete();
}
@ -138,7 +148,7 @@ abstract class Document extends Model
*
* @param Description $trigger
*/
public function controllo(Description $trigger)
public function fixStato(Description $trigger)
{
$this->load('righe');
$this->load('articoli');

View File

@ -248,11 +248,22 @@ $(document).ready(function () {
$('.nav-tabs').tabs();
// Entra nel tab indicato al caricamento della pagina
var hash = window.location.hash ? window.location.hash : getUrlVars().hash;
var hash = location.hash ? location.hash : getUrlVars().hash;
if (hash && hash != '#tab_0') {
$('ul.nav-tabs a[href="' + hash + '"]').tab('show').trigger('shown.bs.tab');
} else {
location.hash = '';
}
$(window).bind("hashchange", function(){
var hash = location.hash;
console.log(hash);
if (!hash || hash == '#tab_0') {
location.hash = '';
}
});
// Nel caso la navigazione sia da mobile, disabilito il ritorno al punto precedente
if (!isMobile.any()) {
// Salvo lo scroll per riportare qui l'utente al reload

View File

@ -2,26 +2,17 @@
include_once __DIR__.'/../../core.php';
$module = Modules::get($id_module);
use Modules\Contratti\Contratto;
$documento = Contratto::find($id_record);
$options = [
'op' => 'add_contratto',
'id_importazione' => 'id_contratto',
'final_module' => 'Fatture di vendita',
'original_module' => $module['name'],
'sql' => [
'table' => 'co_contratti',
'rows' => 'co_righe_contratti',
'id_rows' => 'idcontratto',
],
'op' => 'add_documento',
'type' => 'contratto',
'module' => 'Fatture di vendita',
'button' => tr('Aggiungi'),
'dir' => 'entrata',
'create_document' => true,
'documento' => $documento,
];
$result = [
'id_record' => $id_record,
'id_documento' => get('iddocumento'),
];
echo App::load('importa.php', $result, $options, true);
echo App::load('importa.php', [], $options, true);

View File

@ -7,7 +7,6 @@ use Common\Components\Description;
use Common\Document;
use Modules\Anagrafiche\Anagrafica;
use Modules\Interventi\Intervento;
use Modules\Ordini\Ordine;
use Modules\TipiIntervento\Tipo as TipoSessione;
use Traits\RecordTrait;
use Util\Generator;
@ -157,9 +156,9 @@ class Contratto extends Document
*
* @param Description $trigger
*/
public function controllo(Description $trigger)
public function fixStato(Description $trigger)
{
parent::controllo($trigger);
parent::fixStato($trigger);
$righe = $this->getRighe();
@ -171,9 +170,6 @@ class Contratto extends Document
if ($qta_evasa == 0) {
$descrizione = 'In lavorazione';
$descrizione_intervento = 'Completato';
} elseif ($trigger->parent instanceof Ordine) {
$descrizione = $this->stato->descrizione;
$descrizione_intervento = 'Completato';
} else {
$descrizione = $parziale ? 'Parzialmente fatturato' : 'Fatturato';
$descrizione_intervento = 'Fatturato';

View File

@ -2,6 +2,7 @@
include_once __DIR__.'/../../core.php';
use Modules\Articoli\Articolo as ArticoloOriginale;
use Modules\Anagrafiche\Anagrafica;
use Modules\DDT\Components\Articolo;
use Modules\DDT\Components\Descrizione;
@ -115,75 +116,36 @@ switch (post('op')) {
}
break;
case 'addarticolo':
if (post('idarticolo') !== null) {
$dir = post('dir');
$idarticolo = post('idarticolo');
$descrizione = post('descrizione');
$idiva = post('idiva');
$qta = post('qta');
$prezzo = post('prezzo');
// Calcolo dello sconto
$sconto_unitario = post('sconto');
$tipo_sconto = post('tipo_sconto');
$sconto = calcola_sconto([
'sconto' => $sconto_unitario,
'prezzo' => $prezzo,
'tipo' => $tipo_sconto,
'qta' => $qta,
]);
add_articolo_inddt($id_record, $idarticolo, $descrizione, $idiva, $qta, post('um'), $prezzo * $qta, $sconto, $sconto_unitario, $tipo_sconto);
// Ricalcolo inps, ritenuta e bollo
ricalcola_costiagg_ddt($id_record);
aggiorna_sedi_movimenti('ddt', $id_record);
flash()->info(tr('Articolo aggiunto!'));
}
break;
case 'addriga':
// Selezione costi da intervento
$descrizione = post('descrizione');
$idiva = post('idiva');
$um = post('um');
$prezzo = post('prezzo');
$qta = post('qta');
// Calcolo dello sconto
$sconto_unitario = post('sconto');
$tipo_sconto = post('tipo_sconto');
$sconto = calcola_sconto([
'sconto' => $sconto_unitario,
'prezzo' => $prezzo,
'tipo' => $tipo_sconto,
'qta' => $qta,
]);
$subtot = $prezzo * $qta;
// Calcolo iva
$query = 'SELECT descrizione, percentuale, indetraibile FROM co_iva WHERE id='.prepare($idiva);
$rs = $dbo->fetchArray($query);
$iva = ($subtot - $sconto) / 100 * $rs[0]['percentuale'];
$iva_indetraibile = $iva / 100 * $rs[0]['indetraibile'];
$query = 'INSERT INTO dt_righe_ddt(idddt, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, is_descrizione, `order`) VALUES('.prepare($id_record).', '.prepare($idiva).', '.prepare($rs[0]['descrizione']).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($subtot).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).', '.prepare($um).', '.prepare($qta).', '.prepare(empty($qta)).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM dt_righe_ddt AS t WHERE idddt='.prepare($id_record).'))';
$dbo->query($query);
// Messaggi informativi
if (!empty($idarticolo)) {
flash()->info(tr('Articolo aggiunto!'));
} elseif (!empty($qta)) {
flash()->info(tr('Riga aggiunta!'));
case 'manage_articolo':
if (post('idriga') != null) {
$articolo = Articolo::find(post('idriga'));
} else {
flash()->info(tr('Riga descrittiva aggiunta!'));
$originale = ArticoloOriginale::find(post('idarticolo'));
$articolo = Articolo::build($ddt, $originale);
}
$articolo->descrizione = post('descrizione');
$articolo->um = post('um') ?: null;
$articolo->id_iva = post('idiva');
$articolo->prezzo_unitario_acquisto = post('prezzo_acquisto') ?: 0;
$articolo->prezzo_unitario_vendita = post('prezzo');
$articolo->sconto_unitario = post('sconto');
$articolo->tipo_sconto = post('tipo_sconto');
try {
$articolo->qta = post('qta');
} catch (UnexpectedValueException $e) {
flash()->error(tr('Alcuni serial number sono già stati utilizzati!'));
}
$articolo->save();
if (post('idriga') != null) {
flash()->info(tr('Articolo modificato!'));
} else {
flash()->info(tr('Articolo aggiunto!'));
}
// Ricalcolo inps, ritenuta e bollo
@ -217,9 +179,59 @@ switch (post('op')) {
break;
case 'manage_riga':
if (post('idriga') != null) {
$riga = Riga::find(post('idriga'));
} else {
$riga = Riga::build($ddt);
}
$riga->descrizione = post('descrizione');
$riga->um = post('um') ?: null;
$riga->id_iva = post('idiva');
$riga->prezzo_unitario_acquisto = post('prezzo_acquisto') ?: 0;
$riga->prezzo_unitario_vendita = post('prezzo');
$riga->sconto_unitario = post('sconto');
$riga->tipo_sconto = post('tipo_sconto');
$riga->qta = post('qta');
$riga->save();
if (post('idriga') != null) {
flash()->info(tr('Riga modificata!'));
} else {
flash()->info(tr('Riga aggiunta!'));
}
// Ricalcolo inps, ritenuta e bollo
ricalcola_costiagg_ddt($id_record);
break;
case 'manage_descrizione':
if (post('idriga') != null) {
$riga = Descrizione::find(post('idriga'));
} else {
$riga = Descrizione::build($ddt);
}
$riga->descrizione = post('descrizione');
$riga->save();
if (post('idriga') != null) {
flash()->info(tr('Riga descrittiva modificata!'));
} else {
flash()->info(tr('Riga descrittiva aggiunta!'));
}
break;
// Aggiunta di un ordine in ddt
case 'add_ordine':
$ordine = \Modules\Ordini\Ordine::find(post('id_ordine'));
$ordine = \Modules\Ordini\Ordine::find(post('id_documento'));
// Creazione della fattura al volo
if (post('create_document') == 'on') {
@ -238,7 +250,6 @@ switch (post('op')) {
$id_record = $ddt->id;
}
$parziale = false;
$righe = $ordine->getRighe();
foreach ($righe as $riga) {
if (post('evadere')[$riga->id] == 'on') {
@ -257,22 +268,10 @@ switch (post('op')) {
$copia->save();
}
if ($riga->qta != $riga->qta_evasa) {
$parziale = true;
}
}
// Impostazione del nuovo stato
$descrizione = $parziale ? 'Parzialmente evaso' : 'Evaso';
$stato = \Modules\Ordini\Stato::where('descrizione', $descrizione)->first();
$ordine->stato()->associate($stato);
$ordine->save();
ricalcola_costiagg_ddt($id_record);
aggiorna_sedi_movimenti('ddt', $id_record);
flash()->info(tr('Ordine _NUM_ aggiunto!', [
'_NUM_' => $ordine->numero,
]));
@ -297,8 +296,6 @@ switch (post('op')) {
ricalcola_costiagg_ddt($id_record, 0, 0, 0);
}
aggiorna_sedi_movimenti('ddt', $id_record);
flash()->info(tr('Articolo rimosso!'));
break;
@ -335,139 +332,18 @@ switch (post('op')) {
}
break;
// Modifica riga
case 'editriga':
if (post('idriga') !== null) {
// Selezione costi da intervento
$idriga = post('idriga');
$descrizione = post('descrizione');
$prezzo = post('prezzo');
$qta = post('qta');
// Calcolo dello sconto
$sconto_unitario = post('sconto');
$tipo_sconto = post('tipo_sconto');
$sconto = calcola_sconto([
'sconto' => $sconto_unitario,
'prezzo' => $prezzo,
'tipo' => $tipo_sconto,
'qta' => $qta,
]);
$idiva = post('idiva');
$um = post('um');
$subtot = $prezzo * $qta;
// Lettura idarticolo dalla riga ddt
$rs = $dbo->fetchArray('SELECT * FROM dt_righe_ddt WHERE id='.prepare($idriga));
$idarticolo = $rs[0]['idarticolo'];
$idordine = $rs[0]['idordine'];
$old_qta = $rs[0]['qta'];
$is_descrizione = $rs[0]['is_descrizione'];
// Controllo per gestire i serial
if (!empty($idarticolo)) {
if (!controlla_seriali('id_riga_ddt', $idriga, $old_qta, $qta, $dir)) {
flash()->error(tr('Alcuni serial number sono già stati utilizzati!'));
return;
}
}
// Se c'è un collegamento ad un ordine, aggiorno la quantità evasa
if (!empty($idordine)) {
$dbo->query('UPDATE or_righe_ordini SET qta_evasa=qta_evasa-'.$old_qta.' + '.$qta.' WHERE descrizione='.prepare($rs[0]['descrizione']).' AND idarticolo='.prepare($rs[0]['idarticolo']).' AND idordine='.prepare($idordine).' AND idiva='.prepare($rs[0]['idiva']));
}
// Calcolo iva
$query = 'SELECT * FROM co_iva WHERE id='.prepare($idiva);
$rs = $dbo->fetchArray($query);
$iva = ($subtot - $sconto) / 100 * $rs[0]['percentuale'];
$iva_indetraibile = $iva / 100 * $rs[0]['indetraibile'];
$desc_iva = $rs[0]['descrizione'];
// Modifica riga generica sul ddt
if ($is_descrizione == 0) {
$query = 'UPDATE dt_righe_ddt SET idiva='.prepare($idiva).', desc_iva='.prepare($desc_iva).', iva='.prepare($iva).', iva_indetraibile='.prepare($iva_indetraibile).', descrizione='.prepare($descrizione).', subtotale='.prepare($subtot).', sconto='.prepare($sconto).', sconto_unitario='.prepare($sconto_unitario).', tipo_sconto='.prepare($tipo_sconto).', um='.prepare($um).', qta='.prepare($qta).' WHERE id='.prepare($idriga);
} else {
$query = 'UPDATE dt_righe_ddt SET descrizione='.prepare($descrizione).' WHERE id='.prepare($idriga);
}
if ($dbo->query($query)) {
if (!empty($idarticolo)) {
// Controlli aggiuntivi sulle quantità evase degli ordini
if (!empty($idordine) && $qta > 0) {
$rs = $dbo->fetchArray('SELECT qta_evasa, qta FROM or_righe_ordini WHERE idordine='.prepare($idordine).' AND idarticolo='.prepare($idarticolo));
$qta_ordine = $qta;
if ($qta > $rs[0]['qta_evasa']) {
$qta_ordine = ($qta > $rs[0]['qta']) ? $rs[0]['qta'] : $qta;
}
$dbo->query('UPDATE or_righe_ordini SET qta_evasa = '.prepare($qta_ordine).' WHERE idordine='.prepare($idordine).' AND idarticolo='.prepare($idarticolo));
}
$new_qta = $qta - $old_qta;
$new_qta = ($dir == 'entrata') ? -$new_qta : $new_qta;
add_movimento_magazzino($idarticolo, $new_qta, ['idddt' => $id_record]);
}
flash()->info(tr('Riga modificata!'));
// Ricalcolo inps, ritenuta e bollo
if ($dir == 'entrata') {
ricalcola_costiagg_ddt($id_record);
} else {
ricalcola_costiagg_ddt($id_record);
}
}
}
aggiorna_sedi_movimenti('ddt', $id_record);
break;
// eliminazione ddt
case 'delete':
// Se ci sono degli articoli collegati
$rs = $dbo->fetchArray('SELECT id, idarticolo FROM dt_righe_ddt WHERE idddt='.prepare($id_record));
try {
$ddt->delete();
foreach ($rs as $value) {
$non_rimovibili = seriali_non_rimuovibili('id_riga_ddt', $value['id'], $dir);
if (!empty($non_rimovibili)) {
flash()->error(tr('Alcuni serial number sono già stati utilizzati!'));
$dbo->query('DELETE FROM mg_movimenti WHERE idddt='.prepare($id_record));
return;
}
flash()->info(tr('Ddt eliminato!'));
} catch (InvalidArgumentException $e) {
flash()->error(tr('Sono stati utilizzati alcuni serial number nel documento: impossibile procedere!'));
}
for ($i = 0; $i < sizeof($rs); ++$i) {
if ($rs[$i]['idarticolo']) {
rimuovi_articolo_daddt($rs[$i]['idarticolo'], $id_record, $rs[$i]['id']);
}
}
// Se delle righe sono state create da un ordine, devo riportare la quantità evasa nella tabella degli ordini
// al valore di prima, riaggiungendo la quantità che sto togliendo
$rs = $dbo->fetchArray('SELECT qta, descrizione, idarticolo, idordine, idiva FROM dt_righe_ddt WHERE idddt='.prepare($id_record).' AND idarticolo="0"');
// Rimpiazzo la quantità negli ordini
for ($i = 0; $i < sizeof($rs); ++$i) {
$dbo->query('UPDATE or_righe_ordini SET qta_evasa=qta_evasa-'.$rs[$i]['qta'].' WHERE descrizione='.prepare($rs[$i]['descrizione']).' AND idarticolo='.prepare($rs[$i]['idarticolo']).' AND idordine='.prepare($rs[$i]['idordine']).' AND idiva='.prepare($rs[$i]['idiva']));
}
$dbo->query('DELETE FROM dt_ddt WHERE id='.prepare($id_record));
$dbo->query('DELETE FROM dt_righe_ddt WHERE idddt='.prepare($id_record));
$dbo->query('DELETE FROM mg_movimenti WHERE idddt='.prepare($id_record));
//Aggiorno gli stati degli ordini
if (setting('Cambia automaticamente stato ordini fatturati')) {
for ($i = 0; $i < sizeof($rs); ++$i) {
$dbo->query('UPDATE or_ordini SET idstatoordine=(SELECT id FROM or_statiordine WHERE descrizione="'.get_stato_ordine($rs[$i]['idordine']).'") WHERE id = '.prepare($rs[$i]['idordine']));
}
}
flash()->info(tr('Ddt eliminato!'));
break;
case 'add_serial':

View File

@ -2,33 +2,24 @@
include_once __DIR__.'/../../core.php';
use Modules\DDT\DDT;
$documento = DDT::find($id_record);
$module = Modules::get($id_module);
$final_module = $module['name'] == 'Ddt di vendita' ? 'Fatture di vendita' : 'Fatture di acquisto';
$dir = $module['name'] == 'Ddt di vendita' ? 'entrata' : 'uscita';
$options = [
'op' => 'add_ddt',
'id_importazione' => 'id_ddt',
'final_module' => $final_module,
'original_module' => $module['name'],
'sql' => [
'table' => 'dt_ddt',
'rows' => 'dt_righe_ddt',
'id_rows' => 'idddt',
],
'serials' => [
'id_riga' => 'id_riga_ddt',
'condition' => '(id_riga_documento IS NOT NULL)',
],
'op' => 'add_documento',
'type' => 'ddt',
'module' => $final_module,
'serials'=>true,
'button' => tr('Aggiungi'),
'dir' => $dir,
'create_document' => true,
'documento' => $documento,
];
$result = [
'id_record' => $id_record,
'id_documento' => get('iddocumento'),
];
echo App::load('importa.php', $result, $options, true);
echo App::load('importa.php', [], $options, true);

View File

@ -10,7 +10,7 @@ $dir = $documento->direzione;
// Impostazioni per la gestione
$options = [
'op' => 'addriga',
'op' => 'manage_riga',
'action' => 'add',
'dir' => $documento->direzione,
'idanagrafica' => $documento['idanagrafica'],
@ -36,6 +36,8 @@ $result['idiva'] = $iva[0]['idiva'] ?: setting('Iva predefinita');
$file = 'riga';
if (get('is_descrizione') !== null) {
$file = 'descrizione';
$options['op'] = 'manage_descrizione';
} elseif (get('is_articolo') !== null) {
$file = 'articolo';
@ -47,7 +49,7 @@ if (get('is_descrizione') !== null) {
$result['tipo_sconto'] = 'PRC';
}
$options['op'] = 'addarticolo';
$options['op'] = 'manage_articolo';
} elseif (get('is_sconto') !== null) {
$file = 'sconto';

View File

@ -9,7 +9,7 @@ $documento = DDT::find($id_record);
// Impostazioni per la gestione
$options = [
'op' => 'editriga',
'op' => 'manage_riga',
'action' => 'edit',
'dir' => $documento->direzione,
'idanagrafica' => $documento['idanagrafica'],
@ -27,12 +27,17 @@ $result['prezzo'] = $riga->prezzo_unitario_vendita;
$file = 'riga';
if ($riga->isDescrizione()) {
$file = 'descrizione';
$options['op'] = 'manage_descrizione';
} elseif ($riga->isArticolo()) {
$file = 'articolo';
$options['op'] = 'manage_articolo';
} elseif ($riga->isSconto()) {
$file = 'sconto';
$options['op'] = 'manage_sconto';
}
echo App::load($file.'.php', $result, $options);

View File

@ -47,8 +47,13 @@ class Articolo extends Article
'_NUM_' => $numero,
]);
$partenza = $ddt->direzione == 'uscita' ? $ddt->idsede_destinazione : $ddt->idsede_partenza;
$arrivo = $ddt->direzione == 'uscita' ? $ddt->idsede_partenza : $ddt->idsede_destinazione;
$this->articolo->movimenta(-$qta, $movimento, $data, false, [
'idddt' => $ddt->id,
'idsede_azienda' => $partenza,
'idsede_controparte' => $arrivo,
]);
}

View File

@ -137,9 +137,9 @@ class DDT extends Document
*
* @param Description $trigger
*/
public function controllo(Description $trigger)
public function fixStato(Description $trigger)
{
parent::controllo($trigger);
parent::fixStato($trigger);
if (setting('Cambia automaticamente stato ddt fatturati')) {
$righe = $this->getRighe();

View File

@ -32,7 +32,6 @@ switch (post('op')) {
$fattura = Fattura::build($anagrafica, $tipo, $data, $id_segment);
$id_record = $fattura->id;
aggiorna_sedi_movimenti('documenti', $id_record);
flash()->info(tr('Aggiunta fattura numero _NUM_!', [
'_NUM_' => $fattura->numero,
]));
@ -151,48 +150,20 @@ switch (post('op')) {
// eliminazione documento
case 'delete':
$rs = $dbo->fetchArray('SELECT id FROM co_righe_documenti WHERE iddocumento='.prepare($id_record));
try {
$fattura->delete();
// Controllo sui seriali
foreach ($rs as $r) {
$non_rimovibili = seriali_non_rimuovibili('id_riga_documento', $r['id'], $dir);
if (!empty($non_rimovibili)) {
flash()->error(tr('Alcuni serial number sono già stati utilizzati!'));
$dbo->query('DELETE FROM co_scadenziario WHERE iddocumento='.prepare($id_record));
$dbo->query('DELETE FROM co_movimenti WHERE iddocumento='.prepare($id_record));
return;
}
// Azzeramento collegamento della rata contrattuale alla pianificazione
$dbo->query('UPDATE co_ordiniservizio_pianificazionefatture SET iddocumento=0 WHERE iddocumento='.prepare($id_record));
flash()->info(tr('Fattura eliminata!'));
} catch (InvalidArgumentException $e) {
flash()->error(tr('Sono stati utilizzati alcuni serial number nel documento: impossibile procedere!'));
}
// Rimozione righe
foreach ($rs as $r) {
rimuovi_riga_fattura($id_record, $r['id'], $dir);
}
// Se ci sono dei preventivi collegati li rimetto nello stato "In attesa di pagamento"
$rs = $dbo->fetchArray('SELECT idpreventivo FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND idpreventivo IS NOT NULL');
for ($i = 0; $i < sizeof($rs); ++$i) {
$dbo->query("UPDATE co_preventivi SET idstato=(SELECT id FROM co_statipreventivi WHERE descrizione='In lavorazione') WHERE id=".prepare($rs[$i]['idpreventivo']));
$dbo->query('UPDATE co_righe_preventivi SET qta_evasa=0 WHERE idpreventivo='.prepare($rs[$i]['idpreventivo']));
}
// Se ci sono degli interventi collegati li rimetto nello stato "Completato"
$rs = $dbo->fetchArray('SELECT idintervento FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND idintervento IS NOT NULL');
for ($i = 0; $i < sizeof($rs); ++$i) {
$dbo->query("UPDATE in_interventi SET idstatointervento = (SELECT idstatointervento FROM in_statiintervento WHERE descrizione = 'Completato') WHERE id=".prepare($rs[$i]['idintervento']));
}
elimina_scadenza($id_record);
elimina_movimento($id_record);
$dbo->query('DELETE FROM co_documenti WHERE id='.prepare($id_record));
$dbo->query('DELETE FROM co_scadenziario WHERE iddocumento='.prepare($id_record));
$dbo->query('DELETE FROM co_movimenti WHERE iddocumento='.prepare($id_record));
// Azzeramento collegamento della rata contrattuale alla pianificazione
$dbo->query('UPDATE co_ordiniservizio_pianificazionefatture SET iddocumento=0 WHERE iddocumento='.prepare($id_record));
flash()->info(tr('Fattura eliminata!'));
break;
// Duplicazione fattura
@ -360,15 +331,8 @@ switch (post('op')) {
flash()->error(tr('Alcuni serial number sono già stati utilizzati!'));
}
// Informazioni aggiuntive FE
$articolo->data_inizio_periodo = post('data_inizio_periodo') ?: null;
$articolo->data_fine_periodo = post('data_fine_periodo') ?: null;
$articolo->riferimento_amministrazione = post('riferimento_amministrazione');
$articolo->tipo_cessione_prestazione = post('tipo_cessione_prestazione');
$articolo->save();
aggiorna_sedi_movimenti('documenti', $id_record);
if (post('idriga') != null) {
flash()->info(tr('Articolo modificato!'));
} else {
@ -443,12 +407,6 @@ switch (post('op')) {
$riga->qta = $qta;
// Informazioni aggiuntive FE
$riga->data_inizio_periodo = post('data_inizio_periodo') ?: null;
$riga->data_fine_periodo = post('data_fine_periodo') ?: null;
$riga->riferimento_amministrazione = post('riferimento_amministrazione');
$riga->tipo_cessione_prestazione = post('tipo_cessione_prestazione');
$riga->save();
if (post('idriga') != null) {
@ -486,37 +444,15 @@ switch (post('op')) {
if (!empty($id_record) && post('idriga') !== null) {
$idriga = post('idriga');
// Lettura preventivi collegati
$query = 'SELECT iddocumento, idintervento FROM co_righe_documenti WHERE id='.prepare($idriga);
$rsp = $dbo->fetchArray($query);
$id_record = $rsp[0]['iddocumento'];
$idintervento = $rsp[0]['idintervento'];
$righe = $fattura->getRighe();
$riga = $righe->find($id_riga);
// Ricalcolo inps, ritenuta e bollo
if ($dir == 'entrata') {
ricalcola_costiagg_fattura($id_record);
} else {
ricalcola_costiagg_fattura($id_record);
$righe_intervento = $righe->where('idintervento', $riga->idintervento);
foreach ($righe_intervento as $r) {
$r->delete();
}
// Lettura interventi collegati
// $query = 'SELECT id, idintervento FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND idintervento IS NOT NULL';
// $rs = $dbo->fetchArray($query);
// Se ci sono degli interventi collegati li rimetto nello stato "Completato"
// for ($i = 0; $i < sizeof($rs); ++$i) {
$dbo->query("UPDATE in_interventi SET idstatointervento = (SELECT idstatointervento FROM in_statiintervento WHERE descrizione = 'Completato') WHERE id=".prepare($idintervento));
// Rimuovo dalla fattura gli articoli collegati all'intervento
$rs2 = $dbo->fetchArray('SELECT idarticolo FROM mg_articoli_interventi WHERE idintervento='.prepare($idintervento));
for ($j = 0; $j < sizeof($rs2); ++$j) {
rimuovi_articolo_dafattura($rs[0]['idarticolo'], $id_record, $rs[0]['idrigadocumento']);
}
// }
// rimuovo riga da co_righe_documenti
$query = 'DELETE FROM `co_righe_documenti` WHERE iddocumento='.prepare($id_record).' AND id='.prepare($idriga);
$dbo->query($query);
//$dbo->query("UPDATE in_interventi SET idstatointervento = (SELECT idstatointervento FROM in_statiintervento WHERE descrizione = 'Completato') WHERE id=".prepare($idintervento));
flash()->info(tr('Intervento _NUM_ rimosso!', [
'_NUM_' => $idintervento,
@ -524,131 +460,23 @@ switch (post('op')) {
}
break;
// Scollegamento articolo da documento
case 'unlink_articolo':
if (!empty($id_record)) {
$idriga = post('idriga');
if (!rimuovi_riga_fattura($id_record, $idriga, $dir)) {
flash()->error(tr('Alcuni serial number sono già stati utilizzati!'));
return;
}
// Ricalcolo inps, ritenuta e bollo
if ($dir == 'entrata') {
ricalcola_costiagg_fattura($id_record);
} else {
ricalcola_costiagg_fattura($id_record);
}
aggiorna_sedi_movimenti('documenti', $id_record);
flash()->info(tr('Articolo rimosso!'));
}
break;
// Scollegamento preventivo da documento
case 'unlink_preventivo':
if (post('idriga') !== null) {
$idriga = post('idriga');
// Lettura preventivi collegati
$query = 'SELECT iddocumento, idpreventivo, idarticolo, id, qta, descrizione FROM co_righe_documenti WHERE id='.prepare($idriga);
$rsp = $dbo->fetchArray($query);
$id_record = $rsp[0]['iddocumento'];
$idpreventivo = $rsp[0]['idpreventivo'];
$idarticolo = $rsp[0]['idarticolo'];
$qta = $rsp[0]['qta'];
if (!empty($idarticolo)) {
rimuovi_articolo_dafattura($rsp[0]['idarticolo'], $id_record, $idriga);
}
// Ripristino le quantità da evadere nel preventivo
$query = 'UPDATE co_righe_preventivi SET qta_evasa = qta_evasa - '.$rsp[0]['qta'].' WHERE idarticolo='.prepare($rsp[0]['idarticolo']).' AND descrizione='.prepare($rsp[0]['descrizione']).' AND idpreventivo = '.prepare($idpreventivo);
$dbo->query($query);
$query = 'DELETE FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND id='.prepare($idriga);
$dbo->query($query);
$rs_righe = $dbo->fetchArray('SELECT * FROM co_righe_documenti WHERE idpreventivo='.prepare($idpreventivo));
if (empty($rs_righe)) {
// Se ci sono dei preventivi collegati li rimetto nello stato "In attesa di pagamento"
$dbo->query("UPDATE co_preventivi SET idstato=(SELECT id FROM co_statipreventivi WHERE descrizione='In lavorazione') WHERE id=".prepare($idpreventivo));
// Aggiorno anche lo stato degli interventi collegati ai preventivi
$dbo->query("UPDATE in_interventi SET idstatointervento = (SELECT idstatointervento FROM in_statiintervento WHERE descrizione = 'Completato') WHERE id_preventivo=".prepare($idpreventivo));
}
// Ricalcolo inps, ritenuta e bollo
if ($dir == 'entrata') {
ricalcola_costiagg_fattura($id_record);
} else {
ricalcola_costiagg_fattura($id_record);
}
flash()->info(tr('Preventivo rimosso!'));
}
break;
// Scollegamento contratto da documento
case 'unlink_contratto':
if (post('idriga') !== null) {
$idriga = post('idriga');
// Lettura contratti collegati
$query = 'SELECT iddocumento, idcontratto, idarticolo, id, qta, descrizione FROM co_righe_documenti WHERE id='.prepare($idriga);
$rsp = $dbo->fetchArray($query);
$id_record = $rsp[0]['iddocumento'];
$idcontratto = $rsp[0]['idcontratto'];
$idarticolo = $rsp[0]['idarticolo'];
if (!empty($idarticolo)) {
rimuovi_articolo_dafattura($rsp[0]['idarticolo'], $id_record, $idriga);
}
// Ripristino le quantità da evadere nel contratto
$query = 'UPDATE co_righe_contratti SET qta_evasa = qta_evasa - '.$rsp[0]['qta'].' WHERE idarticolo='.prepare($rsp[0]['idarticolo']).' AND descrizione='.prepare($rsp[0]['descrizione']).' AND idcontratto = '.prepare($idcontratto);
$dbo->query($query);
$query = 'DELETE FROM co_righe_documenti WHERE iddocumento='.prepare($id_record).' AND id='.prepare($idriga);
$dbo->query($query);
$rs_righe = $dbo->fetchArray('SELECT * FROM co_righe_documenti WHERE idcontratto='.prepare($idcontratto));
if (empty($rs_righe)) { // Se ci sono dei preventivi collegati li rimetto nello stato "In attesa di pagamento"
$dbo->query("UPDATE co_contratti SET idstato=(SELECT id FROM co_staticontratti WHERE descrizione='In lavorazione') WHERE id=".prepare($idcontratto));
// Aggiorno anche lo stato degli interventi collegati ai contratti
$dbo->query("UPDATE in_interventi SET idstatointervento = (SELECT idstatointervento FROM in_statiintervento WHERE descrizione = 'Completato') WHERE id IN (SELECT idintervento FROM co_promemoria WHERE idcontratto=".prepare($idcontratto).')');
// Ricalcolo inps, ritenuta e bollo
if ($dir == 'entrata') {
ricalcola_costiagg_fattura($id_record);
} else {
ricalcola_costiagg_fattura($id_record);
}
flash()->info(tr('Contratto rimosso!'));
}
}
break;
// Scollegamento riga generica da documento
case 'unlink_riga':
$id_riga = post('idriga');
if (!empty($id_riga)) {
$riga = $fattura->getRighe()->find($id_riga);
$riga->delete();
//rimuovi_riga_fattura($id_record, $idriga, $dir);
try {
$riga->delete();
// Ricalcolo inps, ritenuta e bollo
ricalcola_costiagg_fattura($id_record);
// Ricalcolo inps, ritenuta e bollo
ricalcola_costiagg_fattura($id_record);
flash()->info(tr('Riga rimossa!'));
flash()->info(tr('Riga rimossa!'));
} catch (InvalidArgumentException $e) {
flash()->error(tr('Alcuni serial number sono già stati utilizzati!'));
}
}
break;
@ -673,32 +501,43 @@ switch (post('op')) {
break;
// Aggiunta di un ordine in fattura
case 'add_ordine':
$ordine = \Modules\Ordini\Ordine::find(post('id_ordine'));
// Aggiunta di un documento in fattura
case 'add_documento':
$id_documento = post('id_documento');
$type = post('type');
$movimenta = true;
if ($type == 'ordine') {
$documento = \Modules\Ordini\Ordine::find($id_documento);
} elseif ($type == 'ddt') {
$documento = \Modules\DDT\DDT::find($id_documento);
$movimenta = false;
} elseif ($type == 'preventivo') {
$documento = \Modules\Preventivi\Preventivo::find($id_documento);
} elseif ($type == 'contratto') {
$documento = \Modules\Contratti\Contratto::find($id_documento);
}
// Creazione della fattura al volo
if (post('create_document') == 'on') {
$descrizione = ($dir == 'entrata') ? 'Fattura immediata di vendita' : 'Fattura immediata di acquisto';
$tipo = Tipo::where('descrizione', $descrizione)->first();
$fattura = Fattura::build($ordine->anagrafica, $tipo, post('data'), post('id_segment'));
$fattura->idpagamento = $ordine->idpagamento;
$fattura = Fattura::build($documento->anagrafica, $tipo, post('data'), post('id_segment'));
$fattura->idpagamento = $documento->idpagamento;
$fattura->id_ritenuta_contributi = post('id_ritenuta_contributi') ?: null;
$fattura->save();
$id_record = $fattura->id;
}
$id_rivalsa_inps = setting('Percentuale rivalsa');
if ($dir == 'uscita') {
$id_ritenuta_acconto = $fattura->anagrafica->id_ritenuta_acconto_acquisti;
} else {
$id_ritenuta_acconto = $fattura->anagrafica->id_ritenuta_acconto_vendite ?: setting("Percentuale ritenuta d'acconto");
}
$calcolo_ritenuta_acconto = setting("Metodologia calcolo ritenuta d'acconto predefinito");
$calcolo_ritenuta_acconto = post('calcolo_ritenuta_acconto') ?: null;
$id_ritenuta_acconto = post('id_ritenuta_acconto') ?: null;
$ritenuta_contributi = boolval(post('ritenuta_contributi'));
$id_rivalsa_inps = post('id_rivalsa_inps') ?: null;
$id_conto = post('id_conto');
$righe = $ordine->getRighe();
$righe = $documento->getRighe();
foreach ($righe as $riga) {
if (post('evadere')[$riga->id] == 'on') {
$qta = post('qta_da_evadere')[$riga->id];
@ -709,10 +548,13 @@ switch (post('op')) {
$copia->calcolo_ritenuta_acconto = $calcolo_ritenuta_acconto;
$copia->id_ritenuta_acconto = $id_ritenuta_acconto;
$copia->id_rivalsa_inps = $id_rivalsa_inps;
$copia->ritenuta_contributi = $ritenuta_contributi;
// Aggiornamento seriali dalla riga dell'ordine
if ($copia->isArticolo()) {
$copia->movimenta($copia->qta);
if ($movimenta) {
$copia->movimenta($copia->qta);
}
$serials = is_array(post('serial')[$riga->id]) ? post('serial')[$riga->id] : [];
@ -724,176 +566,27 @@ switch (post('op')) {
}
ricalcola_costiagg_fattura($id_record);
aggiorna_sedi_movimenti('documenti', $id_record);
flash()->info(tr('Ordine _NUM_ aggiunto!', [
'_NUM_' => $ordine->numero,
]));
break;
// Aggiunta di un ddt in fattura
case 'add_ddt':
$ddt = \Modules\DDT\DDT::find(post('id_ddt'));
// Creazione della fattura al volo
if (post('create_document') == 'on') {
$descrizione = ($dir == 'entrata') ? 'Fattura differita di vendita' : 'Fattura differita di acquisto';
$tipo = Tipo::where('descrizione', $descrizione)->first();
$fattura = Fattura::build($ddt->anagrafica, $tipo, post('data'), post('id_segment'));
$fattura->idpagamento = $ddt->idpagamento;
$fattura->save();
$id_record = $fattura->id;
$message = '';
if ($type == 'ordine') {
$message = tr('Ordine _NUM_ aggiunto!', [
'_NUM_' => $ordine->numero,
]);
} elseif ($type == 'ddt') {
$message = tr('DDT _NUM_ aggiunto!', [
'_NUM_' => $ordine->numero,
]);
} elseif ($type == 'preventivo') {
$message = tr('Preventivo _NUM_ aggiunto!', [
'_NUM_' => $ordine->numero,
]);
} elseif ($type == 'contratto') {
$message = tr('Contratto _NUM_ aggiunto!', [
'_NUM_' => $ordine->numero,
]);
}
$id_rivalsa_inps = setting('Percentuale rivalsa');
if ($dir == 'uscita') {
$id_ritenuta_acconto = $fattura->anagrafica->id_ritenuta_acconto_acquisti;
} else {
$id_ritenuta_acconto = $fattura->anagrafica->id_ritenuta_acconto_vendite ?: setting("Percentuale ritenuta d'acconto");
}
$calcolo_ritenuta_acconto = setting("Metodologia calcolo ritenuta d'acconto predefinito");
$id_conto = post('id_conto');
$righe = $ddt->getRighe();
foreach ($righe as $riga) {
if (post('evadere')[$riga->id] == 'on') {
$qta = post('qta_da_evadere')[$riga->id];
$copia = $riga->copiaIn($fattura, $qta);
$copia->id_conto = $id_conto;
$copia->calcolo_ritenuta_acconto = $calcolo_ritenuta_acconto;
$copia->id_ritenuta_acconto = $id_ritenuta_acconto;
$copia->id_rivalsa_inps = $id_rivalsa_inps;
// Aggiornamento seriali dalla riga dell'ordine
if ($copia->isArticolo()) {
$serials = is_array(post('serial')[$riga->id]) ? post('serial')[$riga->id] : [];
$copia->serials = $serials;
}
$copia->save();
}
}
ricalcola_costiagg_fattura($id_record);
aggiorna_sedi_movimenti('documenti', $id_record);
flash()->info(tr('DDT _NUM_ aggiunto!', [
'_NUM_' => $ddt->numero,
]));
break;
// Aggiunta di un preventivo in fattura
case 'add_preventivo':
$preventivo = \Modules\Preventivi\Preventivo::find(post('id_preventivo'));
// Creazione della fattura al volo
if (post('create_document') == 'on') {
$tipo = Tipo::where('descrizione', 'Fattura immediata di vendita')->first();
$fattura = Fattura::build($preventivo->anagrafica, $tipo, post('data'), post('id_segment'));
$fattura->idpagamento = $preventivo->idpagamento;
$fattura->save();
$id_record = $fattura->id;
}
$id_rivalsa_inps = setting('Percentuale rivalsa');
if ($dir == 'uscita') {
$id_ritenuta_acconto = $fattura->anagrafica->id_ritenuta_acconto_acquisti;
} else {
$id_ritenuta_acconto = $fattura->anagrafica->id_ritenuta_acconto_vendite ?: setting("Percentuale ritenuta d'acconto");
}
$calcolo_ritenuta_acconto = setting("Metodologia calcolo ritenuta d'acconto predefinito");
$id_conto = post('id_conto');
$righe = $preventivo->getRighe();
foreach ($righe as $riga) {
if (post('evadere')[$riga->id] == 'on') {
$qta = post('qta_da_evadere')[$riga->id];
$copia = $riga->copiaIn($fattura, $qta);
$copia->id_conto = $id_conto;
$copia->calcolo_ritenuta_acconto = $calcolo_ritenuta_acconto;
$copia->id_ritenuta_acconto = $id_ritenuta_acconto;
$copia->id_rivalsa_inps = $id_rivalsa_inps;
// Aggiornamento seriali dalla riga dell'ordine
if ($copia->isArticolo()) {
$copia->movimenta($copia->qta);
}
$copia->save();
}
}
ricalcola_costiagg_fattura($id_record);
aggiorna_sedi_movimenti('documenti', $id_record);
flash()->info(tr('Preventivo _NUM_ aggiunto!', [
'_NUM_' => $preventivo->numero,
]));
break;
// Aggiunta di un contratto in fattura
case 'add_contratto':
$contratto = \Modules\Contratti\Contratto::find(post('id_contratto'));
// Creazione della fattura al volo
if (post('create_document') == 'on') {
$tipo = Tipo::where('descrizione', 'Fattura immediata di vendita')->first();
$fattura = Fattura::build($contratto->anagrafica, $tipo, post('data'), post('id_segment'));
$fattura->idpagamento = $contratto->idpagamento;
$fattura->save();
$id_record = $fattura->id;
}
$id_rivalsa_inps = setting('Percentuale rivalsa');
if ($dir == 'uscita') {
$id_ritenuta_acconto = $fattura->anagrafica->id_ritenuta_acconto_acquisti;
} else {
$id_ritenuta_acconto = $fattura->anagrafica->id_ritenuta_acconto_vendite ?: setting("Percentuale ritenuta d'acconto");
}
$calcolo_ritenuta_acconto = setting("Metodologia calcolo ritenuta d'acconto predefinito");
$id_conto = post('id_conto');
$righe = $contratto->getRighe();
foreach ($righe as $riga) {
if (post('evadere')[$riga->id] == 'on') {
$qta = post('qta_da_evadere')[$riga->id];
$copia = $riga->copiaIn($fattura, $qta);
$copia->id_conto = $id_conto;
$copia->calcolo_ritenuta_acconto = $calcolo_ritenuta_acconto;
$copia->id_ritenuta_acconto = $id_ritenuta_acconto;
$copia->id_rivalsa_inps = $id_rivalsa_inps;
// Aggiornamento seriali dalla riga dell'ordine
if ($copia->isArticolo()) {
$copia->movimenta($copia->qta);
}
$copia->save();
}
}
ricalcola_costiagg_fattura($id_record);
aggiorna_sedi_movimenti('documenti', $id_record);
flash()->info(tr('Contratto _NUM_ aggiunto!', [
'_NUM_' => $contratto->numero,
]));
flash()->info($message);
break;

View File

@ -2,34 +2,32 @@
include_once __DIR__.'/../../core.php';
$module = Modules::get($id_module);
use Modules\Contratti\Contratto;
use Modules\Fatture\Fattura;
$documento_finale = Fattura::find($id_record);
$dir = $documento_finale->direzione;
$id_documento = get('id_documento');
if (!empty($id_documento)) {
$documento = Contratto::find($id_documento);
if (get('op')) {
$options = [
'op' => 'add_contratto',
'id_importazione' => 'id_contratto',
'final_module' => $module['name'],
'original_module' => 'Contratti',
'sql' => [
'table' => 'co_contratti',
'rows' => 'co_righe_contratti',
'id_rows' => 'idcontratto',
],
'serials' => false,
'op' => 'add_documento',
'type' => 'contratto',
'button' => tr('Aggiungi'),
'dir' => 'entrata',
'documento' => $documento,
'documento_finale' => $documento_finale,
];
$result = [
'id_record' => $id_record,
'id_documento' => get('iddocumento'),
];
echo App::load('importa.php', $result, $options, true);
echo App::load('importa.php', [], $options, true);
return;
}
$id_anagrafica = $documento_finale->idanagrafica;
$_SESSION['superselect']['idanagrafica'] = $id_anagrafica;
$_SESSION['superselect']['stato'] = 'is_fatturabile';
echo '
@ -39,12 +37,8 @@ echo '
</div>
</div>
<div class="box" id="info-box">
<div class="box-header with-border">
<h3 class="box-title">'.tr('Informazioni di importazione').'</h3>
</div>
<div class="box-body" id="righe_documento">
</div>
<div id="righe_documento">
</div>
<div class="alert alert-info" id="box-loading">
@ -56,30 +50,21 @@ echo '
<script src="'.$rootdir.'/lib/init.js"></script>
<script>
var box = $("#info-box");
var content = $("#righe_documento");
var loader = $("#box-loading");
$(document).ready(function(){
box.hide();
loader.hide();
})
});
$("#id_documento").on("change", function(){
loader.show();
box.hide();
var id = $(this).selectData() ? $(this).selectData().id : "";
content.html("<i>'.tr('Caricamento in corso').'...</i>");
content.load("'.$structure->fileurl($file).'?id_module='.$id_module.'&id_record=" + id + "&documento=fattura&op=add_ordine&iddocumento='.$id_record.'", function() {
if(content.html() != ""){
box.show();
}
content.html("");
content.load("'.$structure->fileurl($file).'?id_module='.$id_module.'&id_record='.$id_record.'&id_documento=" + id, function() {
loader.hide();
});
});
</script>';

View File

@ -2,55 +2,41 @@
include_once __DIR__.'/../../core.php';
$module = Modules::get($id_module);
use Modules\DDT\DDT;
use Modules\Fatture\Fattura;
$dir = ($module['name'] == 'Fatture di vendita') ? 'entrata' : 'uscita';
$documento_finale = Fattura::find($id_record);
$dir = $documento_finale->direzione;
$id_documento = get('id_documento');
if (!empty($id_documento)) {
$documento = DDT::find($id_documento);
if (get('op')) {
$options = [
'op' => 'add_ddt',
'id_importazione' => 'id_ddt',
'final_module' => $module['name'],
'original_module' => $module['name'] == 'Fatture di vendita' ? 'Ddt di vendita' : 'Ddt di acquisto',
'sql' => [
'table' => 'dt_ddt',
'rows' => 'dt_righe_ddt',
'id_rows' => 'idddt',
],
'serials' => [
'id_riga' => 'id_riga_ddt',
'condition' => '(id_riga_documento IS NOT NULL)',
],
'op' => 'add_documento',
'type' => 'ddt',
'serials' => true,
'button' => tr('Aggiungi'),
'dir' => $dir,
'documento' => $documento,
'documento_finale' => $documento_finale,
];
$result = [
'id_record' => $id_record,
'id_documento' => get('iddocumento'),
];
echo App::load('importa.php', $result, $options, true);
echo App::load('importa.php', [], $options, true);
return;
}
$info = $dbo->fetchOne('SELECT * FROM co_documenti WHERE id='.prepare($id_record));
$idanagrafica = $info['idanagrafica'];
$id_anagrafica = $documento_finale->idanagrafica;
echo '
<div class="row">
<div class="col-md-12">
{[ "type": "select", "label": "'.tr('Ddt').'", "name": "id_documento", "values": "query=SELECT dt_ddt.id, CONCAT(\'DDT num. \', IF(numero_esterno != \'\', numero_esterno, numero), \' del \', DATE_FORMAT(data, \'%d-%m-%Y\')) AS descrizione FROM dt_ddt WHERE idanagrafica='.prepare($idanagrafica).' AND idstatoddt IN (SELECT id FROM dt_statiddt WHERE descrizione IN(\'Bozza\', \'Evaso\', \'Parzialmente evaso\', \'Parzialmente fatturato\')) AND idtipoddt=(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) ORDER BY data DESC, numero DESC" ]}
{[ "type": "select", "label": "'.tr('Ddt').'", "name": "id_documento", "values": "query=SELECT dt_ddt.id, CONCAT(\'DDT num. \', IF(numero_esterno != \'\', numero_esterno, numero), \' del \', DATE_FORMAT(data, \'%d-%m-%Y\')) AS descrizione FROM dt_ddt WHERE idanagrafica='.prepare($id_anagrafica).' AND idstatoddt IN (SELECT id FROM dt_statiddt WHERE descrizione IN(\'Bozza\', \'Evaso\', \'Parzialmente evaso\', \'Parzialmente fatturato\')) AND idtipoddt=(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) ORDER BY data DESC, numero DESC" ]}
</div>
</div>
<div class="box" id="info-box">
<div class="box-header with-border">
<h3 class="box-title">'.tr('Informazioni di importazione').'</h3>
</div>
<div class="box-body" id="righe_documento">
</div>
<div id="righe_documento">
</div>
<div class="alert alert-info" id="box-loading">
@ -62,30 +48,21 @@ echo '
<script src="'.$rootdir.'/lib/init.js"></script>
<script>
var box = $("#info-box");
var content = $("#righe_documento");
var loader = $("#box-loading");
$(document).ready(function(){
box.hide();
loader.hide();
})
});
$("#id_documento").on("change", function(){
loader.show();
box.hide();
var id = $(this).selectData() ? $(this).selectData().id : "";
content.html("<i>'.tr('Caricamento in corso').'...</i>");
content.load("'.$structure->fileurl($file).'?id_module='.$id_module.'&id_record=" + id + "&documento=fattura&op=add_ordine&iddocumento='.$id_record.'", function() {
if(content.html() != ""){
box.show();
}
content.html("");
content.load("'.$structure->fileurl($file).'?id_module='.$id_module.'&id_record='.$id_record.'&id_documento=" + id, function() {
loader.hide();
});
});
</script>';

View File

@ -2,55 +2,41 @@
include_once __DIR__.'/../../core.php';
$module = Modules::get($id_module);
use Modules\Fatture\Fattura;
use Modules\Ordini\Ordine;
$dir = ($module['name'] == 'Fatture di vendita') ? 'entrata' : 'uscita';
$documento_finale = Fattura::find($id_record);
$dir = $documento_finale->direzione;
$id_documento = get('id_documento');
if (!empty($id_documento)) {
$documento = Ordine::find($id_documento);
if (get('op')) {
$options = [
'op' => 'add_ordine',
'id_importazione' => 'id_ordine',
'final_module' => $module['name'],
'original_module' => $module['name'] == 'Fatture di vendita' ? 'Ordini cliente' : 'Ordini fornitore',
'sql' => [
'table' => 'or_ordini',
'rows' => 'or_righe_ordini',
'id_rows' => 'idordine',
],
'serials' => [
'id_riga' => 'id_riga_ddt',
'condition' => '(id_riga_documento IS NOT NULL)',
],
'op' => 'add_documento',
'type' => 'ordine',
'serials' => true,
'button' => tr('Aggiungi'),
'dir' => $dir,
'documento' => $documento,
'documento_finale' => $documento_finale,
];
$result = [
'id_record' => $id_record,
'id_documento' => get('iddocumento'),
];
echo App::load('importa.php', $result, $options, true);
echo App::load('importa.php', [], $options, true);
return;
}
$info = $dbo->fetchOne('SELECT * FROM co_documenti WHERE id='.prepare($id_record));
$idanagrafica = $info['idanagrafica'];
$id_anagrafica = $documento_finale->idanagrafica;
echo '
<div class="row">
<div class="col-md-12">
{[ "type": "select", "label": "'.tr('Ordine').'", "name": "id_documento", "values": "query=SELECT or_ordini.id, CONCAT(IF(numero_esterno != \'\', numero_esterno, numero), \' del \', DATE_FORMAT(data, \'%d-%m-%Y\')) AS descrizione FROM or_ordini WHERE idanagrafica='.prepare($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).' LIMIT 0,1) AND or_ordini.id IN (SELECT idordine FROM or_righe_ordini WHERE or_righe_ordini.idordine = or_ordini.id AND (qta - qta_evasa) > 0) ORDER BY data DESC, numero DESC" ]}
{[ "type": "select", "label": "'.tr('Ordine').'", "name": "id_documento", "values": "query=SELECT or_ordini.id, CONCAT(IF(numero_esterno != \'\', numero_esterno, numero), \' del \', DATE_FORMAT(data, \'%d-%m-%Y\')) AS descrizione FROM or_ordini WHERE idanagrafica='.prepare($id_anagrafica).' 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).' LIMIT 0,1) AND or_ordini.id IN (SELECT idordine FROM or_righe_ordini WHERE or_righe_ordini.idordine = or_ordini.id AND (qta - qta_evasa) > 0) ORDER BY data DESC, numero DESC" ]}
</div>
</div>
<div class="box" id="info-box">
<div class="box-header with-border">
<h3 class="box-title">'.tr('Informazioni di importazione').'</h3>
</div>
<div class="box-body" id="righe_documento">
</div>
<div id="righe_documento">
</div>
<div class="alert alert-info" id="box-loading">
@ -62,30 +48,21 @@ echo '
<script src="'.$rootdir.'/lib/init.js"></script>
<script>
var box = $("#info-box");
var content = $("#righe_documento");
var loader = $("#box-loading");
$(document).ready(function(){
box.hide();
loader.hide();
})
});
$("#id_documento").on("change", function(){
loader.show();
box.hide();
var id = $(this).selectData() ? $(this).selectData().id : "";
content.html("<i>'.tr('Caricamento in corso').'...</i>");
content.load("'.$structure->fileurl($file).'?id_module='.$id_module.'&id_record=" + id + "&documento=fattura&op=add_ordine&iddocumento='.$id_record.'", function() {
if(content.html() != ""){
box.show();
}
content.html("");
content.load("'.$structure->fileurl($file).'?id_module='.$id_module.'&id_record='.$id_record.'&id_documento=" + id, function() {
loader.hide();
});
});
</script>';

View File

@ -2,34 +2,33 @@
include_once __DIR__.'/../../core.php';
$module = Modules::get($id_module);
use Modules\Fatture\Fattura;
use Modules\Preventivi\Preventivo;
$documento_finale = Fattura::find($id_record);
$dir = $documento_finale->direzione;
$id_documento = get('id_documento');
if (!empty($id_documento)) {
$documento = Preventivo::find($id_documento);
if (get('op')) {
$options = [
'op' => 'add_preventivo',
'id_importazione' => 'id_preventivo',
'final_module' => $module['name'],
'original_module' => 'Preventivi',
'sql' => [
'table' => 'co_preventivi',
'rows' => 'co_righe_preventivi',
'id_rows' => 'idpreventivo',
],
'serials' => false,
'op' => 'add_documento',
'type' => 'preventivo',
'button' => tr('Aggiungi'),
'dir' => 'entrata',
'documento' => $documento,
'documento_finale' => $documento_finale,
];
$result = [
'id_record' => $id_record,
'id_documento' => get('iddocumento'),
];
echo App::load('importa.php', $result, $options, true);
echo App::load('importa.php', [], $options, true);
return;
}
$id_anagrafica = $documento_finale->idanagrafica;
$_SESSION['superselect']['idanagrafica'] = $id_anagrafica;
echo '
<div class="row">
<div class="col-md-12">
@ -37,12 +36,8 @@ echo '
</div>
</div>
<div class="box" id="info-box">
<div class="box-header with-border">
<h3 class="box-title">'.tr('Informazioni di importazione').'</h3>
</div>
<div class="box-body" id="righe_documento">
</div>
<div id="righe_documento">
</div>
<div class="alert alert-info" id="box-loading">
@ -54,30 +49,21 @@ echo '
<script src="'.$rootdir.'/lib/init.js"></script>
<script>
var box = $("#info-box");
var content = $("#righe_documento");
var loader = $("#box-loading");
$(document).ready(function(){
box.hide();
loader.hide();
})
});
$("#id_documento").on("change", function(){
loader.show();
box.hide();
var id = $(this).selectData() ? $(this).selectData().id : "";
content.html("<i>'.tr('Caricamento in corso').'...</i>");
content.load("'.$structure->fileurl($file).'?id_module='.$id_module.'&id_record=" + id + "&documento=fattura&op=add_ordine&iddocumento='.$id_record.'", function() {
if(content.html() != ""){
box.show();
}
content.html("");
content.load("'.$structure->fileurl($file).'?id_module='.$id_module.'&id_record='.$id_record.'&id_documento=" + id, function() {
loader.hide();
});
});
</script>';

View File

@ -554,225 +554,3 @@ function add_articolo_infattura($iddocumento, $idarticolo, $descrizione, $idiva,
return $idriga;
}
/**
* Questa funzione rimuove un articolo dalla fattura data e lo riporta in magazzino nel primo lotto libero
* a partire dal lotto più vecchio
* $idarticolo integer codice dell'articolo da scollegare dalla fattura
* $iddocumento integer codice della fattura da cui scollegare l'articolo.
*/
function rimuovi_articolo_dafattura($idarticolo, $iddocumento, $idrigadocumento)
{
global $dir;
$dbo = database();
// Leggo la quantità di questo articolo in fattura
$query = 'SELECT qta, idintervento, idpreventivo, idordine, idddt, subtotale, descrizione FROM co_righe_documenti WHERE id='.prepare($idrigadocumento);
$rs = $dbo->fetchArray($query);
$idintervento = $rs[0]['idintervento'];
$idpreventivo = $rs[0]['idpreventivo'];
$idddt = $rs[0]['idddt'];
$idordine = $rs[0]['idordine'];
$qta = $rs[0]['qta'];
$subtotale = $rs[0]['subtotale'];
$descrizione = $rs[0]['descrizione'];
$lotto = $rs[0]['lotto'];
$serial = $rs[0]['serial'];
$altro = $rs[0]['altro'];
$non_rimovibili = seriali_non_rimuovibili('id_riga_documento', $idrigadocumento, $dir);
if (!empty($non_rimovibili)) {
return false;
}
// Se l'articolo è stato aggiunto in fattura perché era collegato ad un intervento o
// preventivo o ddt o ordine non devo riportarlo in magazzino quando lo tolgo dalla fattura, perché
// se lo scollegassi poi anche dall'intervento aggiungerei in magazzino la quantità 2 volte!!
if ($qta > 0) {
if (empty($idintervento) && empty($idddt)) {
// Fatture di vendita
if ($dir == 'entrata') {
add_movimento_magazzino($idarticolo, $qta, ['iddocumento' => $iddocumento]);
}
// Fatture di acquisto
else {
add_movimento_magazzino($idarticolo, -$qta, ['iddocumento' => $iddocumento]);
}
}
// TODO: possibile ambiguità tra righe molto simili tra loro
// Se l'articolo è stato inserito in fattura tramite un ddt devo sanare la qta_evasa
if (!empty($idddt)) {
$dbo->query('UPDATE dt_righe_ddt SET qta_evasa=qta_evasa-'.$qta.' WHERE qta='.prepare($qta).' AND idarticolo='.prepare($idarticolo).' AND idddt='.prepare($idddt));
}
// TODO: possibile ambiguità tra righe molto simili tra loro
// Se l'articolo è stato inserito in fattura tramite un ordine devo sanare la qta_evasa
if (!empty($idordine)) {
$dbo->query('UPDATE or_righe_ordini SET qta_evasa=qta_evasa-'.$qta.' WHERE qta='.prepare($qta).' AND idarticolo='.prepare($idarticolo).' AND idordine='.prepare($idordine));
}
}
// Elimino la riga dal documento
$dbo->query('DELETE FROM `co_righe_documenti` WHERE id='.prepare($idrigadocumento).' AND iddocumento='.prepare($iddocumento));
// Aggiorno lo stato dell'ordine
if (setting('Cambia automaticamente stato ordini fatturati') && !empty($idordine)) {
$dbo->query('UPDATE or_ordini SET idstatoordine=(SELECT id FROM or_statiordine WHERE descrizione="'.get_stato_ordine($idordine).'") WHERE id = '.prepare($idordine));
}
// Aggiorno lo stato del ddt
if (setting('Cambia automaticamente stato ddt fatturati') && !empty($idddt)) {
$dbo->query('UPDATE dt_ddt SET idstatoddt=(SELECT id FROM dt_statiddt WHERE descrizione="'.get_stato_ddt($idddt).'") WHERE id = '.prepare($idddt));
}
// Elimino i movimenti avvenuti nel magazzino per questo articolo lotto, serial, altro
$dbo->query('DELETE FROM `mg_movimenti` WHERE idarticolo = '.prepare($idarticolo).' AND iddocumento = '.prepare($iddocumento).' AND id = '.prepare($idrigadocumento));
// Elimino i seriali utilizzati dalla riga
$dbo->query('DELETE FROM `mg_prodotti` WHERE id_articolo = '.prepare($idarticolo).' AND id_riga_documento = '.prepare($idrigadocumento));
return true;
}
function rimuovi_riga_fattura($id_documento, $id_riga, $dir)
{
$dbo = database();
// Leggo la quantità di questo articolo in fattura
$riga = $dbo->fetchOne('SELECT * FROM co_righe_documenti WHERE id='.prepare($id_riga));
$non_rimovibili = seriali_non_rimuovibili('id_riga_documento', $id_riga, $dir);
if (!empty($non_rimovibili)) {
return false;
}
$serials = $dbo->fetchArray('SELECT serial FROM mg_prodotti WHERE serial IS NOT NULL AND id_riga_documento='.prepare($id_riga));
// Elimino la riga dal documento
$dbo->query('DELETE FROM `co_righe_documenti` WHERE id='.prepare($id_riga).' AND iddocumento='.prepare($id_documento));
if (empty($riga['qta'])) {
return true;
}
// Operazioni per la rimozione degli articoli
if (!empty($riga['idarticolo'])) {
// Movimentazione articoli se da interventi o ddt
if (empty($riga['idintervento']) && empty($riga['idddt'])) {
add_movimento_magazzino($riga['idarticolo'], ($dir == 'entrata') ? $riga['qta'] : -$riga['qta'], ['iddocumento' => $id_documento]);
}
// Se l'articolo è stato inserito in fattura tramite un preventivo devo sanare la qta_evasa
if (!empty($riga['idpreventivo'])) {
$dbo->query('UPDATE co_righe_preventivi SET qta_evasa=qta_evasa-'.$riga['qta'].' WHERE qta='.prepare($riga['qta']).' AND idarticolo='.prepare($riga['idarticolo']).' AND idpreventivo='.prepare($riga['idpreventivo']).' AND qta_evasa > 0 LIMIT 1');
}
// Se l'articolo è stato inserito in fattura tramite un ddt devo sanare la qta_evasa
if (!empty($riga['idddt'])) {
$dbo->query('UPDATE dt_righe_ddt SET qta_evasa=qta_evasa-'.$riga['qta'].' WHERE qta='.prepare($riga['qta']).' AND idarticolo='.prepare($riga['idarticolo']).' AND idddt='.prepare($riga['idddt']).' AND qta_evasa > 0 LIMIT 1');
}
// Se l'articolo è stato inserito in fattura tramite un ordine devo sanare la qta_evasa
elseif (!empty($riga['idordine'])) {
$dbo->query('UPDATE or_righe_ordini SET qta_evasa=qta_evasa-'.$riga['qta'].' WHERE qta='.prepare($riga['qta']).' AND idarticolo='.prepare($riga['idarticolo']).' AND idordine='.prepare($riga['idordine']).' AND qta_evasa > 0 LIMIT 1');
}
}
// Nota di credito
if (!empty($riga['ref_riga_documento'])) {
$dbo->query('UPDATE co_righe_documenti SET qta_evasa = qta_evasa+'.$riga['qta'].' WHERE id='.prepare($riga['ref_riga_documento']));
if (!empty($riga['idarticolo'])) {
$serials = array_column($serials, 'serial');
$serials = array_clean($serials);
$dbo->attach('mg_prodotti', ['id_riga_documento' => $riga['ref_riga_documento'], 'dir' => $dir, 'id_articolo' => $riga['idarticolo']], ['serial' => $serials]);
}
}
// Rimozione articoli collegati ad un preventivo importato con riga unica
if (empty($riga['idarticolo']) && $riga['idpreventivo']) {
//rimetto a magazzino gli articoli collegati al preventivo
$rsa = $dbo->fetchArray('SELECT id, idarticolo, qta FROM co_righe_preventivi WHERE idpreventivo = '.prepare($riga['idpreventivo']));
for ($i = 0; $i < sizeof($rsa); ++$i) {
if ($riga['is_preventivo']) {
if (!empty($rsa[$i]['idarticolo'])) {
add_movimento_magazzino($rsa[$i]['idarticolo'], $rsa[$i]['qta'], ['iddocumento' => $id_documento]);
}
} else {
$qta_evasa = $rsa[$i]['qta_evasa'] + $riga['qta'];
// Ripristino le quantità da evadere nel preventivo
$dbo->update('co_righe_preventivi',
[
'qta_evasa' => $qta_evasa,
],
[
'id' => $rsa[$i]['id'],
]
);
}
}
}
// Rimozione articoli collegati ad un contratto importato con riga unica
if (empty($riga['idarticolo']) && $riga['idcontratto']) {
//rimetto a magazzino gli articoli collegati al contratto
$rsa = $dbo->fetchArray('SELECT id, idarticolo, qta FROM co_righe_contratti WHERE idcontratto = '.prepare($riga['idcontratto']));
for ($i = 0; $i < sizeof($rsa); ++$i) {
if ($riga['is_contratto']) {
if (!empty($rsa[$i]['idarticolo'])) {
add_movimento_magazzino($rsa[$i]['idarticolo'], $rsa[$i]['qta'], ['iddocumento' => $id_documento]);
}
} else {
$qta_evasa = $rsa[$i]['qta_evasa'] + $riga['qta'];
// Ripristino le quantità da evadere nel contratto
$dbo->update('co_righe_contratti',
[
'qta_evasa' => $qta_evasa,
],
[
'id' => $rsa[$i]['id'],
]
);
}
}
}
//Rimozione righe generiche
if (empty($riga['idarticolo'])) {
// TODO: possibile ambiguità tra righe molto simili tra loro
// Se l'articolo è stato inserito in fattura tramite un ddt devo sanare la qta_evasa
if (!empty($riga['idddt'])) {
$dbo->query('UPDATE dt_righe_ddt SET qta_evasa=qta_evasa-'.$riga['qta'].' WHERE qta='.prepare($riga['qta']).' AND descrizione='.prepare($riga['descrizione']).' AND idddt='.prepare($riga['idddt']));
}
// TODO: possibile ambiguità tra righe molto simili tra loro
// Se l'articolo è stato inserito in fattura tramite un ordine devo sanare la qta_evasa
if (!empty($riga['idordine'])) {
$dbo->query('UPDATE or_righe_ordini SET qta_evasa=qta_evasa-'.$riga['qta'].' WHERE qta='.prepare($riga['qta']).' AND descrizione='.prepare($riga['descrizione']).' AND idordine='.prepare($riga['idordine']));
}
}
// Aggiorno lo stato dell'ordine
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']));
}
// Aggiorno lo stato del ddt
if (!empty($riga['idddt']) && setting('Cambia automaticamente stato ddt fatturati')) {
$dbo->query('UPDATE dt_ddt SET idstatoddt = (SELECT id FROM dt_statiddt WHERE descrizione = '.prepare(get_stato_ddt($riga['idddt'])).') WHERE id = '.prepare($riga['idddt']));
}
// Elimino i movimenti avvenuti nel magazzino per questo articolo lotto, serial, altro
$dbo->query('DELETE FROM `mg_movimenti` WHERE idarticolo = '.prepare($riga['idarticolo']).' AND iddocumento = '.prepare($id_documento).' AND id = '.prepare($id_riga));
// Elimino i seriali utilizzati dalla riga
$dbo->query('DELETE FROM `mg_prodotti` WHERE id_articolo = '.prepare($riga['idarticolo']).' AND id_riga_documento = '.prepare($id_riga));
return true;
}

View File

@ -37,26 +37,18 @@ foreach ($righe as $row) {
$extra = '';
$delete = 'unlink_riga';
// Articoli
if ($row->isArticolo()) {
$riga['descrizione'] = (!empty($row->articolo) ? $row->articolo->codice.' - ' : '').$riga['descrizione'];
$delete = 'unlink_articolo';
// Preventivi
if (!empty($riga['idpreventivo'])) {
$delete = 'unlink_preventivo';
}
// Contratti
elseif (!empty($riga['idcontratto'])) {
$delete = 'unlink_contratto';
}
$extra = '';
$mancanti = 0;
}
// Intervento
elseif (!empty($riga['idintervento'])) {
if (!empty($riga['idintervento'])) {
$intervento = $dbo->fetchOne('SELECT num_item,codice_cig,codice_cup,id_documento_fe FROM in_interventi WHERE id = '.prepare($riga['idintervento']));
$riga['num_item'] = $intervento['num_item'];
$riga['codice_cig'] = $intervento['codice_cig'];
@ -72,8 +64,6 @@ foreach ($righe as $row) {
$riga['codice_cig'] = $preventivo['codice_cig'];
$riga['codice_cup'] = $preventivo['codice_cup'];
$riga['id_documento_fe'] = $preventivo['id_documento_fe'];
$delete = 'unlink_preventivo';
}
// Contratti
elseif (!empty($riga['idcontratto'])) {
@ -82,8 +72,6 @@ foreach ($righe as $row) {
$riga['codice_cig'] = $contratto['codice_cig'];
$riga['codice_cup'] = $contratto['codice_cup'];
$riga['id_documento_fe'] = $contratto['id_documento_fe'];
$delete = 'unlink_contratto';
}
// Ordini (IDDOCUMENTO,CIG,CUP)
elseif (!empty($riga['idordine'])) {
@ -92,12 +80,6 @@ foreach ($righe as $row) {
$riga['codice_cig'] = $ordine['codice_cig'];
$riga['codice_cup'] = $ordine['codice_cup'];
$riga['id_documento_fe'] = $ordine['id_documento_fe'];
$delete = 'unlink_riga';
}
// Righe generiche
else {
$delete = 'unlink_riga';
}
// Individuazione dei seriali
@ -253,7 +235,7 @@ foreach ($righe as $row) {
<form action='".$rootdir.'/editor.php?id_module='.$id_module.'&id_record='.$id_record."' method='post' id='delete-form-".$riga['id']."' role='form'>
<input type='hidden' name='backto' value='record-edit'>
<input type='hidden' name='idriga' value='".$riga['id']."'>
<input type='hidden' name='op' value='unlink_riga'>";
<input type='hidden' name='op' value='".$delete."'>";
if ($row->isArticolo()) {
echo "

View File

@ -52,8 +52,13 @@ class Articolo extends Article
'_NUM_' => $numero,
]);
$partenza = $fattura->direzione == 'uscita' ? $fattura->idsede_destinazione : $fattura->idsede_partenza;
$arrivo = $fattura->direzione == 'uscita' ? $fattura->idsede_partenza : $fattura->idsede_destinazione;
$this->articolo->movimenta(-$qta, $movimento, $data, false, [
'iddocumento' => $fattura->id,
'idsede_azienda' => $partenza,
'idsede_controparte' => $arrivo,
]);
}

View File

@ -162,6 +162,17 @@ trait RelationTrait
return parent::save($options);
}
public function delete()
{
$result = parent::delete();
if (!empty($this->idintervento)) {
database()->query("UPDATE in_interventi SET idstatointervento = (SELECT idstatointervento FROM in_statiintervento WHERE descrizione = 'Completato') WHERE id=".prepare($this->idintervento));
}
return $result;
}
/**
* Effettua i conti per la Rivalsa INPS.
*/

View File

@ -441,6 +441,16 @@ class Fattura extends Document
return parent::save($options);
}
public function delete()
{
$result = parent::delete();
$this->rimuoviScadenze();
elimina_movimento($this->id);
return $result;
}
/**
* Restituisce l'elenco delle note di credito collegate.
*

View File

@ -2,6 +2,7 @@
include_once __DIR__.'/../../core.php';
use Modules\Articoli\Articolo as ArticoloOriginale;
use Modules\Anagrafiche\Anagrafica;
use Modules\Ordini\Components\Articolo;
use Modules\Ordini\Components\Descrizione;
@ -108,68 +109,35 @@ switch (post('op')) {
break;
case 'addarticolo':
if (post('idarticolo') !== null) {
$idarticolo = post('idarticolo');
$idiva = post('idiva');
$descrizione = post('descrizione');
$qta = post('qta');
$prezzo = post('prezzo');
// Calcolo dello sconto
$sconto_unitario = post('sconto');
$tipo_sconto = post('tipo_sconto');
$sconto = calcola_sconto([
'sconto' => $sconto_unitario,
'prezzo' => $prezzo,
'tipo' => $tipo_sconto,
'qta' => $qta,
]);
add_articolo_inordine($id_record, $idarticolo, $descrizione, $idiva, $qta, post('um'), $prezzo * $qta, $sconto, $sconto_unitario, $tipo_sconto);
flash()->info(tr('Articolo aggiunto!'));
case 'manage_articolo':
if (post('idriga') != null) {
$articolo = Articolo::find(post('idriga'));
} else {
$originale = ArticoloOriginale::find(post('idarticolo'));
$articolo = Articolo::build($ordine, $originale);
}
ricalcola_costiagg_ordine($id_record);
$articolo->descrizione = post('descrizione');
$articolo->um = post('um') ?: null;
$articolo->id_iva = post('idiva');
break;
$articolo->prezzo_unitario_acquisto = post('prezzo_acquisto') ?: 0;
$articolo->prezzo_unitario_vendita = post('prezzo');
$articolo->sconto_unitario = post('sconto');
$articolo->tipo_sconto = post('tipo_sconto');
case 'addriga':
// Selezione costi da intervento
$descrizione = post('descrizione');
$prezzo = post('prezzo');
$qta = post('qta');
$idiva = post('idiva');
$um = post('um');
$subtot = $prezzo * $qta;
try {
$articolo->qta = post('qta');
} catch (UnexpectedValueException $e) {
flash()->error(tr('Alcuni serial number sono già stati utilizzati!'));
}
// Calcolo dello sconto
$sconto_unitario = post('sconto');
$tipo_sconto = post('tipo_sconto');
$sconto = calcola_sconto([
'sconto' => $sconto_unitario,
'prezzo' => $prezzo,
'tipo' => $tipo_sconto,
'qta' => $qta,
]);
$articolo->save();
// Calcolo iva
$query = 'SELECT descrizione, percentuale, indetraibile FROM co_iva WHERE id='.prepare($idiva);
$rs = $dbo->fetchArray($query);
$iva = ($subtot - $sconto) / 100 * $rs[0]['percentuale'];
$iva_indetraibile = $iva / 100 * $rs[0]['indetraibile'];
$query = 'INSERT INTO or_righe_ordini(idordine, idiva, desc_iva, iva, iva_indetraibile, descrizione, subtotale, sconto, sconto_unitario, tipo_sconto, um, qta, is_descrizione, `order`) VALUES('.prepare($id_record).', '.prepare($idiva).', '.prepare($rs[0]['descrizione']).', '.prepare($iva).', '.prepare($iva_indetraibile).', '.prepare($descrizione).', '.prepare($subtot).', '.prepare($sconto).', '.prepare($sconto_unitario).', '.prepare($tipo_sconto).', '.prepare($um).', '.prepare($qta).', '.prepare(empty($qta)).', (SELECT IFNULL(MAX(`order`) + 1, 0) FROM or_righe_ordini AS t WHERE idordine='.prepare($id_record).'))';
$dbo->query($query);
// Messaggi informativi
if (!empty($idarticolo)) {
flash()->info(tr('Articolo aggiunto!'));
} elseif (!empty($qta)) {
flash()->info(tr('Riga aggiunta!'));
if (post('idriga') != null) {
flash()->info(tr('Articolo modificato!'));
} else {
flash()->info(tr('Riga descrittiva aggiunta!'));
flash()->info(tr('Articolo aggiunto!'));
}
// Ricalcolo inps, ritenuta e bollo
@ -177,6 +145,82 @@ switch (post('op')) {
break;
case 'manage_sconto':
if (post('idriga') != null) {
$sconto = Sconto::find(post('idriga'));
} else {
$sconto = Sconto::build($ordine);
}
$sconto->descrizione = post('descrizione');
$sconto->id_iva = post('idiva');
$sconto->sconto_unitario = post('sconto_unitario');
$sconto->tipo_sconto = 'UNT';
$sconto->save();
if (post('idriga') != null) {
flash()->info(tr('Sconto/maggiorazione modificato!'));
} else {
flash()->info(tr('Sconto/maggiorazione aggiunto!'));
}
// Ricalcolo inps, ritenuta e bollo
ricalcola_costiagg_ordine($id_record);
break;
case 'manage_riga':
if (post('idriga') != null) {
$riga = Riga::find(post('idriga'));
} else {
$riga = Riga::build($ordine);
}
$riga->descrizione = post('descrizione');
$riga->um = post('um') ?: null;
$riga->id_iva = post('idiva');
$riga->prezzo_unitario_acquisto = post('prezzo_acquisto') ?: 0;
$riga->prezzo_unitario_vendita = post('prezzo');
$riga->sconto_unitario = post('sconto');
$riga->tipo_sconto = post('tipo_sconto');
$riga->qta = post('qta');
$riga->save();
if (post('idriga') != null) {
flash()->info(tr('Riga modificata!'));
} else {
flash()->info(tr('Riga aggiunta!'));
}
// Ricalcolo inps, ritenuta e bollo
ricalcola_costiagg_ordine($id_record);
break;
case 'manage_descrizione':
if (post('idriga') != null) {
$riga = Descrizione::find(post('idriga'));
} else {
$riga = Descrizione::build($ordine);
}
$riga->descrizione = post('descrizione');
$riga->save();
if (post('idriga') != null) {
flash()->info(tr('Riga descrittiva modificata!'));
} else {
flash()->info(tr('Riga descrittiva aggiunta!'));
}
break;
// Scollegamento articolo da ordine
case 'unlink_articolo':
$idarticolo = post('idarticolo');
@ -223,92 +267,6 @@ switch (post('op')) {
break;
case 'manage_sconto':
if (post('idriga') != null) {
$sconto = Sconto::find(post('idriga'));
} else {
$sconto = Sconto::build($ordine);
}
$sconto->descrizione = post('descrizione');
$sconto->id_iva = post('idiva');
$sconto->sconto_unitario = post('sconto_unitario');
$sconto->tipo_sconto = 'UNT';
$sconto->save();
if (post('idriga') != null) {
flash()->info(tr('Sconto/maggiorazione modificato!'));
} else {
flash()->info(tr('Sconto/maggiorazione aggiunto!'));
}
// Ricalcolo inps, ritenuta e bollo
ricalcola_costiagg_ordine($id_record);
break;
// Modifica riga
case 'editriga':
if (post('idriga') !== null) {
$idriga = post('idriga');
$descrizione = post('descrizione');
$prezzo = post('prezzo');
$qta = post('qta');
$idiva = post('idiva');
$um = post('um');
$subtot = $prezzo * $qta;
// Calcolo dello sconto
$sconto_unitario = post('sconto');
$tipo_sconto = post('tipo_sconto');
$sconto = calcola_sconto([
'sconto' => $sconto_unitario,
'prezzo' => $prezzo,
'tipo' => $tipo_sconto,
'qta' => $qta,
]);
// Lettura idarticolo dalla riga documento
$rs = $dbo->fetchArray('SELECT idordine, idarticolo, qta, abilita_serial, is_descrizione FROM or_righe_ordini WHERE id='.prepare($idriga));
$idarticolo = $rs[0]['idarticolo'];
$old_qta = $rs[0]['qta'];
$idordine = $rs[0]['idordine'];
$abilita_serial = $rs[0]['abilita_serial'];
$is_descrizione = $rs[0]['is_descrizione'];
// Controllo per gestire i serial
if (!empty($idarticolo)) {
if (!controlla_seriali('id_riga_ordine', $idriga, $old_qta, $qta, $dir)) {
flash()->error(tr('Alcuni serial number sono già stati utilizzati!'));
return;
}
}
// Calcolo iva
$query = 'SELECT * FROM co_iva WHERE id='.prepare($idiva);
$rs = $dbo->fetchArray($query);
$iva = ($subtot - $sconto) / 100 * $rs[0]['percentuale'];
$iva_indetraibile = $iva / 100 * $rs[0]['indetraibile'];
$desc_iva = $rs[0]['descrizione'];
if ($is_descrizione == 0) {
// Modifica riga generica sul documento
$query = 'UPDATE or_righe_ordini SET idiva='.prepare($idiva).', desc_iva='.prepare($rs[0]['descrizione']).', iva='.prepare($iva).', iva_indetraibile='.prepare($iva_indetraibile).', descrizione='.prepare($descrizione).', subtotale='.prepare($subtot).', sconto='.prepare($sconto).', sconto_unitario='.prepare($sconto_unitario).', tipo_sconto='.prepare($tipo_sconto).', um='.prepare($um).', qta='.prepare($qta).' WHERE id='.prepare($idriga);
} else {
$query = 'UPDATE or_righe_ordini SET descrizione='.prepare($descrizione).' WHERE id='.prepare($idriga);
}
if ($dbo->query($query)) {
flash()->info(tr('Riga modificata!'));
// Ricalcolo inps, ritenuta e bollo
ricalcola_costiagg_ordine($id_record);
}
}
break;
// eliminazione ordine
case 'delete':
// Se ci sono degli articoli collegati (ma non collegati a preventivi o interventi) li rimetto nel magazzino
@ -358,7 +316,7 @@ switch (post('op')) {
// Aggiunta di un preventivo in ordine
case 'add_preventivo':
$preventivo = \Modules\Preventivi\Preventivo::find(post('id_preventivo'));
$preventivo = \Modules\Preventivi\Preventivo::find(post('id_documento'));
// Creazione della fattura al volo
if (post('create_document') == 'on') {

View File

@ -2,38 +2,28 @@
include_once __DIR__.'/../../core.php';
$module = Modules::get($id_module);
use Modules\Ordini\Ordine;
$documento = Ordine::find($id_record);
$module = Modules::get($documento->module);
if (get('documento') == 'fattura') {
$final_module = $module['name'] == 'Ordini cliente' ? 'Fatture di vendita' : 'Fatture di acquisto';
$op = 'add_documento';
} else {
$final_module = $module['name'] == 'Ordini cliente' ? 'Ddt di vendita' : 'Ddt di acquisto';
$op = 'add_ordine';
}
$dir = $module['name'] == 'Ordini cliente' ? 'entrata' : 'uscita';
$options = [
'op' => 'add_ordine',
'id_importazione' => 'id_ordine',
'final_module' => $final_module,
'original_module' => $module['name'],
'sql' => [
'table' => 'or_ordini',
'rows' => 'or_righe_ordini',
'id_rows' => 'idordine',
],
'serials' => [
'id_riga' => 'id_riga_ordine',
'condition' => '(id_riga_ddt IS NOT NULL OR id_riga_documento IS NOT NULL)',
],
'op' => $op,
'type' => 'ordine',
'module' => $final_module,
'button' => tr('Aggiungi'),
'dir' => $dir,
'create_document' => true,
'serials' => true,
'documento' => $documento,
];
$result = [
'id_record' => $id_record,
'id_documento' => get('iddocumento'),
];
echo App::load('importa.php', $result, $options, true);
echo App::load('importa.php', [], $options, true);

View File

@ -10,7 +10,7 @@ $dir = $documento->direzione;
// Impostazioni per la gestione
$options = [
'op' => 'addriga',
'op' => 'manage_riga',
'action' => 'add',
'dir' => $documento->direzione,
'idanagrafica' => $documento['idanagrafica'],
@ -36,6 +36,8 @@ $result['idiva'] = $iva[0]['idiva'] ?: setting('Iva predefinita');
$file = 'riga';
if (get('is_descrizione') !== null) {
$file = 'descrizione';
$options['op'] = 'manage_descrizione';
} elseif (get('is_articolo') !== null) {
$file = 'articolo';
@ -47,7 +49,7 @@ if (get('is_descrizione') !== null) {
$result['tipo_sconto'] = 'PRC';
}
$options['op'] = 'addarticolo';
$options['op'] = 'manage_articolo';
} elseif (get('is_sconto') !== null) {
$file = 'sconto';

View File

@ -9,7 +9,7 @@ $documento = Ordine::find($id_record);
// Impostazioni per la gestione
$options = [
'op' => 'editriga',
'op' => 'manage_riga',
'action' => 'edit',
'dir' => $documento->direzione,
'idanagrafica' => $documento['idanagrafica'],
@ -27,8 +27,12 @@ $result['prezzo'] = $riga->prezzo_unitario_vendita;
$file = 'riga';
if ($riga->isDescrizione()) {
$file = 'descrizione';
$options['op'] = 'manage_descrizione';
} elseif ($riga->isArticolo()) {
$file = 'articolo';
$options['op'] = 'manage_articolo';
} elseif ($riga->isSconto()) {
$file = 'sconto';

View File

@ -128,9 +128,9 @@ class Ordine extends Document
*
* @param Description $trigger
*/
public function controllo(Description $trigger)
public function fixStato(Description $trigger)
{
parent::controllo($trigger);
parent::fixStato($trigger);
if (setting('Cambia automaticamente stato ordini fatturati')) {
$righe = $this->getRighe();
@ -139,10 +139,12 @@ class Ordine extends Document
$qta = $righe->sum('qta');
$parziale = $qta != $qta_evasa;
$stato_attuale = $this->stato;
// Impostazione del nuovo stato
if ($qta_evasa == 0) {
$descrizione = 'Bozza';
} elseif ($trigger->parent instanceof DDT) {
} elseif (!in_array($stato_attuale->descrizione, ['Parzialmente fatturato', 'Fatturato']) && $trigger->parent instanceof DDT) {
$descrizione = $parziale ? 'Parzialmente evaso' : 'Evaso';
} else {
$descrizione = $parziale ? 'Parzialmente fatturato' : 'Fatturato';

View File

@ -2,26 +2,26 @@
include_once __DIR__.'/../../core.php';
$module = Modules::get($id_module);
use Modules\Preventivi\Preventivo;
$documento = Preventivo::find($id_record);
if (get('documento') == 'fattura') {
$final_module = 'Fatture di vendita';
$op = 'add_documento';
} else {
$final_module = 'Ordini cliente';
$op = 'add_preventivo';
}
$options = [
'op' => 'add_preventivo',
'id_importazione' => 'id_preventivo',
'final_module' => get('documento') == 'fattura' ? 'Fatture di vendita' : 'Ordini cliente',
'original_module' => $module['name'],
'sql' => [
'table' => 'co_preventivi',
'rows' => 'co_righe_preventivi',
'id_rows' => 'idpreventivo',
],
'op' => $op,
'type' => 'preventivo',
'module' => $final_module,
'button' => tr('Aggiungi'),
'dir' => 'entrata',
'create_document' => true,
'documento' => $documento,
];
$result = [
'id_record' => $id_record,
'id_documento' => get('iddocumento'),
];
echo App::load('importa.php', $result, $options, true);
echo App::load('importa.php', [], $options, true);

View File

@ -163,9 +163,9 @@ class Preventivo extends Document
*
* @param Description $trigger
*/
public function controllo(Description $trigger)
public function fixStato(Description $trigger)
{
parent::controllo($trigger);
parent::fixStato($trigger);
$righe = $this->getRighe();
@ -173,11 +173,13 @@ class Preventivo extends Document
$qta = $righe->sum('qta');
$parziale = $qta != $qta_evasa;
$stato_attuale = $this->stato;
// Impostazione del nuovo stato
if ($qta_evasa == 0) {
$descrizione = 'In lavorazione';
$descrizione_intervento = 'Completato';
} elseif ($trigger->parent instanceof Ordine) {
} elseif (!in_array($stato_attuale->descrizione, ['Parzialmente fatturato', 'Fatturato']) && $trigger->parent instanceof Ordine) {
$descrizione = $this->stato->descrizione;
$descrizione_intervento = 'Completato';
} else {

View File

@ -28,10 +28,14 @@ ALTER TABLE `dt_righe_ddt` ADD `original_id` int(11), ADD `original_type` varcha
ALTER TABLE `co_righe_contratti` ADD `abilita_serial` tinyint(1) NOT NULL DEFAULT '0';
ALTER TABLE `co_righe_preventivi` ADD `abilita_serial` tinyint(1) NOT NULL DEFAULT '0';
-- Collegamento Articoli
--
-- Attenzione: da testare per il corretto aggiornamento dei dati.
--
--
-- Fatture
--
-- Collegamento Articoli
UPDATE `co_righe_documenti` INNER JOIN `or_righe_ordini` ON `co_righe_documenti`.`idordine` = `or_righe_ordini`.`idordine` AND `co_righe_documenti`.`descrizione` = `or_righe_ordini`.`descrizione` AND `co_righe_documenti`.`idarticolo` = `or_righe_ordini`.`idarticolo` SET `co_righe_documenti`.`original_id` = `or_righe_ordini`.`id`, `co_righe_documenti`.`original_type` = 'Modules\\Ordini\\Components\\Articolo' WHERE `co_righe_documenti`.`idarticolo` != 0;
UPDATE `co_righe_documenti` INNER JOIN `dt_righe_ddt` ON `co_righe_documenti`.`idddt` = `dt_righe_ddt`.`idddt` AND `co_righe_documenti`.`descrizione` = `dt_righe_ddt`.`descrizione` AND `co_righe_documenti`.`idarticolo` = `dt_righe_ddt`.`idarticolo` SET `co_righe_documenti`.`original_id` = `dt_righe_ddt`.`id`, `co_righe_documenti`.`original_type` = 'Modules\\Ddt\\Components\\Articolo' WHERE `co_righe_documenti`.`idarticolo` != 0;
@ -67,6 +71,36 @@ UPDATE `co_righe_documenti` INNER JOIN `co_righe_contratti` ON `co_righe_documen
UPDATE `co_righe_documenti` INNER JOIN `co_righe_preventivi` ON `co_righe_documenti`.`idpreventivo` = `co_righe_preventivi`.`idpreventivo` AND `co_righe_documenti`.`descrizione` = `co_righe_preventivi`.`descrizione` AND `co_righe_documenti`.`idarticolo` = `co_righe_preventivi`.`idarticolo` SET `co_righe_documenti`.`original_id` = `co_righe_preventivi`.`id`, `co_righe_documenti`.`original_type` = 'Modules\\Preventivi\\Components\\Riga' WHERE `co_righe_documenti`.`original_id` IS NULL;
--
-- DDT
--
-- Collegamento Articoli
UPDATE `dt_righe_ddt` INNER JOIN `or_righe_ordini` ON `dt_righe_ddt`.`idordine` = `or_righe_ordini`.`idordine` AND `dt_righe_ddt`.`descrizione` = `or_righe_ordini`.`descrizione` AND `dt_righe_ddt`.`idarticolo` = `or_righe_ordini`.`idarticolo` SET `dt_righe_ddt`.`original_id` = `or_righe_ordini`.`id`, `dt_righe_ddt`.`original_type` = 'Modules\\Ordini\\Components\\Articolo' WHERE `dt_righe_ddt`.`idarticolo` != 0;
-- Collegamento Sconti
UPDATE `dt_righe_ddt` INNER JOIN `or_righe_ordini` ON `dt_righe_ddt`.`idordine` = `or_righe_ordini`.`idordine` AND `dt_righe_ddt`.`descrizione` = `or_righe_ordini`.`descrizione` AND `dt_righe_ddt`.`idarticolo` = `or_righe_ordini`.`idarticolo` SET `dt_righe_ddt`.`original_id` = `or_righe_ordini`.`id`, `dt_righe_ddt`.`original_type` = 'Modules\\Ordini\\Components\\Sconto' WHERE `dt_righe_ddt`.`is_sconto` != 0;
-- Collegamento Descrizioni
UPDATE `dt_righe_ddt` INNER JOIN `or_righe_ordini` ON `dt_righe_ddt`.`idordine` = `or_righe_ordini`.`idordine` AND `dt_righe_ddt`.`descrizione` = `or_righe_ordini`.`descrizione` AND `dt_righe_ddt`.`idarticolo` = `or_righe_ordini`.`idarticolo` SET `dt_righe_ddt`.`original_id` = `or_righe_ordini`.`id`, `dt_righe_ddt`.`original_type` = 'Modules\\Ordini\\Components\\Descrizione' WHERE `dt_righe_ddt`.`is_descrizione` != 0;
-- Collegamento Righe
UPDATE `dt_righe_ddt` INNER JOIN `or_righe_ordini` ON `dt_righe_ddt`.`idordine` = `or_righe_ordini`.`idordine` AND `dt_righe_ddt`.`descrizione` = `or_righe_ordini`.`descrizione` AND `dt_righe_ddt`.`idarticolo` = `or_righe_ordini`.`idarticolo` SET `dt_righe_ddt`.`original_id` = `or_righe_ordini`.`id`, `dt_righe_ddt`.`original_type` = 'Modules\\Ordini\\Components\\Riga' WHERE `dt_righe_ddt`.`original_id` IS NULL;
--
-- Ordini
--
-- Collegamento Articoli
UPDATE `or_righe_ordini` INNER JOIN `co_righe_preventivi` ON `or_righe_ordini`.`idpreventivo` = `co_righe_preventivi`.`idpreventivo` AND `or_righe_ordini`.`descrizione` = `co_righe_preventivi`.`descrizione` AND `or_righe_ordini`.`idarticolo` = `co_righe_preventivi`.`idarticolo` SET `or_righe_ordini`.`original_id` = `co_righe_preventivi`.`id`, `or_righe_ordini`.`original_type` = 'Modules\\Preventivi\\Components\\Articolo' WHERE `or_righe_ordini`.`idarticolo` != 0;
-- Collegamento Sconti
UPDATE `or_righe_ordini` INNER JOIN `co_righe_preventivi` ON `or_righe_ordini`.`idpreventivo` = `co_righe_preventivi`.`idpreventivo` AND `or_righe_ordini`.`descrizione` = `co_righe_preventivi`.`descrizione` AND `or_righe_ordini`.`idarticolo` = `co_righe_preventivi`.`idarticolo` SET `or_righe_ordini`.`original_id` = `co_righe_preventivi`.`id`, `or_righe_ordini`.`original_type` = 'Modules\\Preventivi\\Components\\Sconto' WHERE `or_righe_ordini`.`is_sconto` != 0;
-- Collegamento Descrizioni
UPDATE `or_righe_ordini` INNER JOIN `co_righe_preventivi` ON `or_righe_ordini`.`idpreventivo` = `co_righe_preventivi`.`idpreventivo` AND `or_righe_ordini`.`descrizione` = `co_righe_preventivi`.`descrizione` AND `or_righe_ordini`.`idarticolo` = `co_righe_preventivi`.`idarticolo` SET `or_righe_ordini`.`original_id` = `co_righe_preventivi`.`id`, `or_righe_ordini`.`original_type` = 'Modules\\Preventivi\\Components\\Descrizione' WHERE `or_righe_ordini`.`is_descrizione` != 0;
-- Collegamento Righe
UPDATE `or_righe_ordini` INNER JOIN `co_righe_preventivi` ON `or_righe_ordini`.`idpreventivo` = `co_righe_preventivi`.`idpreventivo` AND `or_righe_ordini`.`descrizione` = `co_righe_preventivi`.`descrizione` AND `or_righe_ordini`.`idarticolo` = `co_righe_preventivi`.`idarticolo` SET `or_righe_ordini`.`original_id` = `co_righe_preventivi`.`id`, `or_righe_ordini`.`original_type` = 'Modules\\Preventivi\\Components\\Riga' WHERE `or_righe_ordini`.`original_id` IS NULL;
-- Aggiunta foto utente
ALTER TABLE `zz_users` ADD `image_file_id` int(11);
UPDATE `zz_modules` SET `enabled` = 1 WHERE `name` = 'Utenti e permessi';
@ -122,3 +156,16 @@ INSERT INTO `zz_segments` (`id`, `id_module`, `name`, `clause`, `position`, `pat
-- Aggiunto codice cig e codice cup per ddt
ALTER TABLE `dt_ddt` ADD `codice_cig` VARCHAR(15), ADD `codice_cup` VARCHAR(15) AFTER `codice_cig`, ADD `id_documento_fe` VARCHAR(20) AFTER `codice_cup`,ADD `num_item` VARCHAR(15) AFTER `id_documento_fe`;
-- Fix quantità per descrizioni
UPDATE `co_righe_documenti` SET `qta` = 1 WHERE `is_descrizione` = 1;
UPDATE `dt_righe_ddt` SET `qta` = 1 WHERE `is_descrizione` = 1;
UPDATE `co_righe_preventivi` SET `qta` = 1 WHERE `is_descrizione` = 1;
UPDATE `co_righe_contratti` SET `qta` = 1 WHERE `is_descrizione` = 1;
UPDATE `or_righe_ordini` SET `qta` = 1 WHERE `is_descrizione` = 1;
UPDATE `mg_articoli_interventi` SET `qta` = 1 WHERE `is_descrizione` = 1;
-- Aggiunta generale di prezzo_unitario_acquisto
ALTER TABLE `dt_righe_ddt` ADD `prezzo_unitario_acquisto` DECIMAL(12,4) NOT NULL AFTER `descrizione`;
ALTER TABLE `or_righe_ordini` ADD `prezzo_unitario_acquisto` DECIMAL(12,4) NOT NULL AFTER `descrizione`;
ALTER TABLE `co_righe_contratti` ADD `prezzo_unitario_acquisto` DECIMAL(12,4) NOT NULL AFTER `descrizione`;