From afdef4db9ab98da3e56f396303eedc99cb529e6c Mon Sep 17 00:00:00 2001 From: Alessandro Bonazzi Date: Sun, 31 Jan 2021 13:53:51 +0100 Subject: [PATCH] Patch level : 12.0 1030 Files correlati : ve0.exe ve1.exe ve6.exe ve5.exe f34.trr f34.dir Commento : MIgliorato il meccanismo di autoevasione degli ordini nel caso di cambio di un codice e di cancellazione di una riga. Modificata la contabilizzazione del reverse charge per getire il reverse charge parziale Aggiunto il campo reverse charge sulle rige documento Interno La lettura di un documento controlla se il documento ha una causale di reverse charge e non ha il flag su nessuna riga in questo caso lo imposta su tutte le righe. Questo dovrebbe evitare conversioni sui documenti vecchi. --- src/ve/f34.dir | 2 +- src/ve/f34.trr | 3 +- src/ve/ve0300b.dat | 1 + src/ve/velib.h | 11 ++- src/ve/velib02.cpp | 9 +- src/ve/velib03.cpp | 220 ++++++++++++++++++++++++++++++++++++++++---- src/ve/velib03a.cpp | 11 +-- src/ve/velib04.cpp | 6 +- src/ve/velib04b.cpp | 83 ++++++++++------- src/ve/velib06.cpp | 53 +++++++++-- src/ve/velib06a.cpp | 16 +++- src/ve/verig.h | 4 +- src/ve/verig.uml | 27 +++++- 13 files changed, 361 insertions(+), 85 deletions(-) diff --git a/src/ve/f34.dir b/src/ve/f34.dir index 9b28ef699..da6160d80 100755 --- a/src/ve/f34.dir +++ b/src/ve/f34.dir @@ -1,3 +1,3 @@ 34 0 -$rdoc|||618|0|Righe documenti||| +$rdoc|||619|0|Righe documenti||| diff --git a/src/ve/f34.trr b/src/ve/f34.trr index bec2858be..a29f7d83e 100755 --- a/src/ve/f34.trr +++ b/src/ve/f34.trr @@ -1,5 +1,5 @@ 34 -70 +71 CODNUM|1|4|0|Codice Numeriazione ANNO|2|4|0|Anno PROVV|1|1|0|Tipo numerazione

rovvisoria efinitiva @@ -65,6 +65,7 @@ CODAGG1|1|20|0|Codice aggiuntivo 1 CODAGG2|1|20|0|Codice aggiuntivo 2 PRIORITY|3|7|0|Prioritā MSP TIPODET|1|1|0|Tipo detraibilitā +REVCHARGE|8|1|0|Flag reverse charge RG1|11|10|0|Campo memo per formule e campi virtuali DATAINIATT|5|8|0|Data inizio attivitā DATAFINATT|5|8|0|Data fine attivitā diff --git a/src/ve/ve0300b.dat b/src/ve/ve0300b.dat index b3235e80a..13051d4fa 100755 --- a/src/ve/ve0300b.dat +++ b/src/ve/ve0300b.dat @@ -84,4 +84,5 @@ CCON(8)|2|4|CONAI\nSottoc.9|4 PCON(9)|3|1305|CONAI\nPeso un.9|13 CCON(10)|2|4|CONAI\nSottoc.10|4 PCON(10)|3|1305|CONAI\nPeso un.10|13 +REVCHARGE|4||Reverse charge|14 diff --git a/src/ve/velib.h b/src/ve/velib.h index 948ef1135..0223039aa 100755 --- a/src/ve/velib.h +++ b/src/ve/velib.h @@ -829,6 +829,9 @@ class TDocumento : public TMultiple_rectype // velib03 TAssoc_array _conaiqta; // Per ogni sottocategoria CONAI mi calcola la qta TArray _qta_evasa_auto; + TBit_array _row_auto_cod_changed; + bool _auto_cod_modify_pend; + TAssoc_array _qta_evasa_auto_changed; protected: virtual TRectype * new_body_record(int logicnum = 0) @@ -902,7 +905,7 @@ public: const TRiga_documento* get_row_id(long id) const; int id2rownum(long id) const; - TRiga_documento& insert_row(int row, const char *tipo = NULL); + TRiga_documento& insert_row(int nrow, const char *tipo = NULL); TRiga_documento& new_row(const char *tipo = NULL); virtual int read(TBaseisamfile& f, word op = _isequal, word lockop = _nolock); virtual int readat(TBaseisamfile& file, TRecnotype nrec, word lockop = _nolock); @@ -1015,8 +1018,8 @@ public: void auto_evasione(const int nrow = -1); void qta_evasa_auto_pack(const int nrow) { _qta_evasa_auto.destroy(nrow, true); } - int find_nrow(const char * tiporiga, const char * codice, int from = 1) const; - TRiga_documento & find_row(const char * tiporiga, const char * codice); + int find_nrow(const char * tiporiga, const char * codice, bool reverse = false, int from = -1) const; + TRiga_documento & find_row(const char * tiporiga, const char * codice, bool reverse = false); TDocumento (); TDocumento (const TDocumento& d); @@ -1158,7 +1161,7 @@ protected: void configura_sheet(TSheet_field& sheet); static TMask* ss_getmask(int numriga, TMask& fullmask); - int insert_anal_fields(TMask& m, int page, int lf, int& y, short& dlg, short& dlgd, bool required); + int insert_anal_fields(TMask& m, int page, int lf, int& y, short& dlg, short& dlgd, bool required, const short contsep_id = -1); void insert_anal_page(); void set_or_def(short id, const TString& val); diff --git a/src/ve/velib02.cpp b/src/ve/velib02.cpp index 90a83e49f..b9bc5950d 100755 --- a/src/ve/velib02.cpp +++ b/src/ve/velib02.cpp @@ -375,7 +375,7 @@ void TRiga_documento::update_orders(real qta, TToken_string & tipi, TToken_strin { const bool storno = qta < ZERO; const TString4 tiporiga = tipo().codice(); - const TString40 codart = codice(); + const TString40 codart = get(RDOC_CODART); real qta_da_evadere = storno ? -qta : qta; if (codart.full()) @@ -409,7 +409,7 @@ void TRiga_documento::update_orders(real qta, TToken_string & tipi, TToken_strin { bool to_delete = true; - for (int nrow = docs[i].find_nrow(tiporiga, codart); to_delete && nrow > 0; nrow = docs[i].find_nrow(tiporiga, codart, nrow + 1)) + for (int nrow = docs[i].find_nrow(tiporiga, codart, storno); to_delete && nrow > 0; nrow = docs[i].find_nrow(tiporiga, codart, storno, nrow)) to_delete &= docs[i][nrow].is_evasa(); if (to_delete) docs.destroy(i, false); @@ -432,11 +432,11 @@ void TRiga_documento::update_orders(real qta, TToken_string & tipi, TToken_strin { TDocumento & d = docs[i]; - for (int nrow = d.find_nrow(tiporiga, codart); (qta_da_evadere > ZERO) && nrow > 0; nrow = d.find_nrow(tiporiga, codart, nrow + 1)) + for (int nrow = d.find_nrow(tiporiga, codart, storno); (qta_da_evadere > ZERO) && nrow > 0; nrow = d.find_nrow(tiporiga, codart, storno, nrow)) { TRiga_documento & rdoc = d[nrow]; - if (!rdoc.is_evasa()) + if (!rdoc.is_evasa() || storno) { TToken_string rdoc_key = rdoc.get_rdoc_key(); real qta_evasa = qta_da_evadere; @@ -861,6 +861,7 @@ real TRiga_documento::importo(bool scontato, bool lordo, int ndec) const real TRiga_documento::iva(int ndec) const { real zanicchi; + if (!is_sconto()) { if (is_omaggio()) diff --git a/src/ve/velib03.cpp b/src/ve/velib03.cpp index 2b551d370..2615c0eb7 100755 --- a/src/ve/velib03.cpp +++ b/src/ve/velib03.cpp @@ -257,6 +257,7 @@ HIDDEN TAssoc_array _docs_to_agg; void TDocumento::init() { + _auto_cod_modify_pend = false; add_file(LF_RIGHEDOC, RDOC_NRIGA); set_memo_fld("G1"); @@ -809,14 +810,14 @@ void TDocumento::copy_contents(const TDocumento& src, bool copy_header) } } -TRiga_documento& TDocumento::insert_row(int row, const char *tipo) +TRiga_documento& TDocumento::insert_row(int nrow, const char *tipo) { - TRiga_documento& r = (TRiga_documento&)TMultiple_rectype::insert_row(row); + TRiga_documento& r = (TRiga_documento&)TMultiple_rectype::insert_row(nrow); if (tipo && *tipo) r.set_tipo(tipo); if (this->tipo().auto_evasione()) // this per spiegare che non č il parametro tipo - _qta_evasa_auto.insert(ZERO, row); // inserisce la riga nuova nell'array + update_row_auto_qta(nrow, (real &) ZERO, true, true); return r; } @@ -878,12 +879,36 @@ void TDocumento::on_read(int err, word lockop) _old_agente = get(DOC_CODAG); _old_agente1 = get(DOC_CODAGVIS); } - _qta_evasa_auto.destroy(); - if (get(DOC_TIPODOC).full() && tipo().auto_evasione()) + + if (get(DOC_TIPODOC).full() && tipo().auto_evasione() && !_auto_cod_modify_pend) { + _qta_evasa_auto.destroy(); + _row_auto_cod_changed.reset(); + _qta_evasa_auto_changed.destroy(); FOR_EACH_SELF_PHYSICAL_RDOC(i, rdoc) update_row_auto_qta(i, rdoc->quantita(), false); } + if (get(DOC_TIPODOC).full() && tipo().causale().full()) + { + const TCausale & caus = cached_causale(tipo().causale()); + + if (caus.reverse_charge_pubb()) + { + bool no_reverse = true; + + FOR_EACH_SELF_PHYSICAL_RDOC(i, rdoc) + if (no_reverse && !rdoc->tipo().is_descrizione() && + rdoc->get(RDOC_CODIVA).full()) + no_reverse &= !rdoc->get_bool(RDOC_REVCHARGE); + if (no_reverse) + { + FOR_EACH_SELF_PHYSICAL_RDOC(i1, rdoc) + if (!rdoc->tipo().is_descrizione() && + rdoc->get(RDOC_CODIVA).full()) + rdoc->put(RDOC_REVCHARGE, true); + } + } + } } int TDocumento::read(TBaseisamfile& f, word op, word lockop) @@ -1532,7 +1557,30 @@ int TDocumento::write_rewrite(TBaseisamfile & f, bool re) const const TString80 codcms(get(DOC_CODCMS)); const TString80 fascms(get(DOC_FASCMS)); const TString80 codcos(get(DOC_CODCOSTO)); - + + /* if (get(DOC_TIPODOC).full() && tipo().causale().full()) + { + const TCausale & caus = cached_causale(tipo().causale()); + + if (caus.reverse_charge_pubb()) + { + bool no_reverse = true; + + FOR_EACH_SELF_PHYSICAL_RDOC(i, rdoc) + if (no_reverse && !rdoc->tipo().is_descrizione() && + rdoc->get(RDOC_CODIVA).full()) + no_reverse &= !rdoc->get_bool(RDOC_REVCHARGE); + if (no_reverse) + { + FOR_EACH_SELF_PHYSICAL_RDOC(i1, rdoc) + if (!rdoc->tipo().is_descrizione() && + rdoc->get(RDOC_CODIVA).full()) + rdoc->put(RDOC_REVCHARGE, true); + } + } + } + */ + for (int i = physical_rows(); i > 0; i--) { TRiga_documento& r = myself.row(i); @@ -1693,7 +1741,6 @@ int TDocumento::remove(TBaseisamfile& f) const if (_has_provv && tipo().provvigioni()) myself.update_provvigioni(true); myself.plafond().remove(myself); - // if (tipo().auto_evasione()) myself.auto_evasione(); } return TMultiple_rectype::remove(f); @@ -2850,6 +2897,9 @@ TDocumento& TDocumento::copy(const TDocumento & d) } _occas = d.occas(); _qta_evasa_auto = d._qta_evasa_auto; + _auto_cod_modify_pend = d._auto_cod_modify_pend; + _row_auto_cod_changed = d._row_auto_cod_changed; + _qta_evasa_auto_changed = d._qta_evasa_auto_changed; return *this; } @@ -3569,6 +3619,7 @@ void TDocumento::update_row_auto_qta(int nrow, real & qta, bool plus, bool inser if (insert) { _qta_evasa_auto.insert(ZERO, nrow); + _row_auto_cod_changed.insert(nrow); qta_evasa = (real *)_qta_evasa_auto.objptr(nrow); } else @@ -3577,6 +3628,8 @@ void TDocumento::update_row_auto_qta(int nrow, real & qta, bool plus, bool inser if (qta_evasa == nullptr) _qta_evasa_auto.add(qta_evasa = new real, nrow); + if (_row_auto_cod_changed[nrow]) + *qta_evasa = ZERO; *qta_evasa += (plus ? qta : -qta); } if (qta_evasa != nullptr && *qta_evasa == ZERO) @@ -3603,32 +3656,165 @@ void TDocumento::auto_evasione(const int nrow) rdoc->update_orders((real &)_qta_evasa_auto[i], tipi, stati, stato_aperto, stato_evaso); _qta_evasa_auto.destroy(i); } + _row_auto_cod_changed.reset(); + if (_auto_cod_modify_pend) + { + _auto_cod_modify_pend = false; + FOR_EACH_ASSOC_OBJECT(_qta_evasa_auto_changed, o, k, obj) + { + real & qta = (real &)*obj; + + if (qta != ZERO) + { + const bool storno = qta < ZERO; + const TString key(k); + const TString4 tiporiga = key.left(2); + real qta_da_evadere = storno ? -qta : qta; + const TString40 codart(key.mid(2)); + + if (codart.full()) + { + const int year = get_date(DOC_DATADOC).year(); + const TDate dadata(1, 1, year - 5); + const TDate adata(31, 12, year); + TLista_documenti docs; + TString_array evaded; + TArray evaded_qta; + TString_array to_delete; + + int ndocs = docs.read('D', get_char(DOC_TIPOCF), get_long(DOC_CODCF), + year, tipi, stati, dadata, adata); + + for (int i = 0; i < ndocs; i++) + if (docs[i].find_nrow(tiporiga, codart) < 0) + docs.destroy(i, false); + else + if (!storno) + { + bool to_delete = true; + + for (int nrow = docs[i].find_nrow(tiporiga, codart, storno); to_delete && nrow > 0; nrow = docs[i].find_nrow(tiporiga, codart, storno, nrow)) + to_delete &= docs[i][nrow].is_evasa(); + if (to_delete) + docs.destroy(i, false); + } + docs.pack(); + ndocs = docs.items(); + for (int i = storno ? ndocs - 1 : 0; (qta_da_evadere > ZERO) && (storno ? i >= 0 : i < ndocs); storno ? i-- : i++) + { + TDocumento & d = docs[i]; + + for (int nrow = d.find_nrow(tiporiga, codart, storno); (qta_da_evadere > ZERO) && nrow > 0; nrow = d.find_nrow(tiporiga, codart, storno, nrow)) + { + TRiga_documento & rdoc = d[nrow]; + + if (!rdoc.is_evasa()) + { + TToken_string rdoc_key = rdoc.get_rdoc_key(); + real qta_evasa = qta_da_evadere; + bool riga_evasa = false; + + if (storno) + { + const real & evaso = rdoc.qtaevasa(); + + if (qta_evasa > evaso) + { + qta_evasa = evaso; + to_delete.add(rdoc_key); + } + rdoc.sub(RDOC_QTAEVASA, qta_evasa); + } + else + { + const real & residuo = rdoc.qtaresidua(); + + if (residuo <= qta_da_evadere) + { + if (i < ndocs - 1) + qta_evasa = residuo; + riga_evasa = true; + } + rdoc.add(RDOC_QTAEVASA, qta_evasa); + } + rdoc.put(RDOC_RIGAEVASA, riga_evasa); + qta_da_evadere -= qta_evasa; + } + } + } + for (int i = 0; i < ndocs; i++) + if (docs[i].is_evaso()) + docs[i].stato(stato_evaso); + else + if (docs[i].stato() == stato_evaso) + docs[i].stato(stato_aperto); + docs.rewrite(); + } + } + } + _qta_evasa_auto_changed.destroy(); + } } else { TRiga_documento & rdoc = row(nrow); + const TString & codart = rdoc.get(RDOC_CODART); - if (rdoc.is_evadibile() && _qta_evasa_auto.objptr(nrow) != nullptr) + if (codart.full()) { - rdoc.update_orders((real &)_qta_evasa_auto[nrow], tipi, stati, stato_aperto, stato_evaso); - _qta_evasa_auto.destroy(nrow); - message_box(TR("Sono stati evasi ordini legati a questo documento.\nE' necessario registrarlo")); + real * qta = (real *)_qta_evasa_auto_changed.objptr(codart); + real qta_da_stornare = (real &)_qta_evasa_auto[nrow]; + + if (qta == nullptr) + { + TString key = rdoc.tipo().codice(); + + key.rpad(2); + key << codart; + _qta_evasa_auto_changed.add(key, qta = new real); + } + *qta += qta_da_stornare; + _row_auto_cod_changed.set(nrow, true); + _auto_cod_modify_pend = true; } + + rdoc.zero(RDOC_DACODNUM); + rdoc.zero(RDOC_DAANNO); + rdoc.zero(RDOC_DAPROVV); + rdoc.zero(RDOC_DANDOC); + rdoc.zero(RDOC_DAIDRIGA); + rdoc.zero(RDOC_ORIGINAL_ROWS); + rdoc.zero(RDOC_ORIGINAL_QTAROWS); } } } -int TDocumento::find_nrow(const char * tiporiga, const char * codice, int from) const +int TDocumento::find_nrow(const char * tiporiga, const char * codice, bool reverse, int from) const { - FOR_EACH_SELF_RDOC(i, rdoc) - if ((i >= from) && (rdoc->tipo().codice() == tiporiga) && (rdoc->codice() == codice)) - return i; + if (reverse) + { + if (from < 0) + from = physical_rows(); + from--; + FOR_EACH_SELF_RDOC_BACK(i, rdoc) + if ((i <= from) && (rdoc->tipo().codice() == tiporiga) && (rdoc->codice() == codice)) + return i; + } + else + { + if (from < 0) + from = 0; + from++; + FOR_EACH_SELF_RDOC(i, rdoc) + if ((i >= from) && (rdoc->tipo().codice() == tiporiga) && (rdoc->codice() == codice)) + return i; + } return -1; } -TRiga_documento & TDocumento::find_row(const char * tiporiga, const char * codice) +TRiga_documento & TDocumento::find_row(const char * tiporiga, const char * codice, bool reverse) { - const int i = find_nrow(tiporiga, codice); + const int i = find_nrow(tiporiga, codice, reverse); if (i > 0) return row(i); diff --git a/src/ve/velib03a.cpp b/src/ve/velib03a.cpp index 4f77aa7b9..fa04c8ba6 100755 --- a/src/ve/velib03a.cpp +++ b/src/ve/velib03a.cpp @@ -616,11 +616,11 @@ int TExpr_documento::parse_user_func(const char * name, int nparms) const if (strcmp(name, "NRATE") == 0) return nparms == 0 ? _nrate : -1; if (strcmp(name, "QTACONAI") == 0) - return nparms >= 1 && nparms < 4 ? _qtaconai : -1; + return nparms >= 0 && nparms < 4 ? _qtaconai : -1; if (strcmp(name, "PESOCONAI") == 0) - return nparms >= 1 && nparms < 4 ? _pesoconai : -1; + return nparms >= 0 && nparms < 4 ? _pesoconai : -1; if (strcmp(name, "VALCONAI") == 0) - return nparms >= 1 && nparms < 4 ? _valconai : -1; + return nparms >= 0 && nparms < 4 ? _valconai : -1; return -1; } @@ -1074,7 +1074,7 @@ void TExpr_documento::evaluate_user_func(int index, int nparms, TEval_stack & st { const int ndec = (nparms > 2) ? (int)stack.pop_real().integer() : 5; const int tipo_calcolo = (nparms > 1) ? (int)stack.pop_real().integer() : 0; - const TString cat = stack.pop_string(); + const TString cat = (nparms > 0) ? stack.pop_string() : EMPTY_STRING; stack.push(ZERO); @@ -1106,7 +1106,6 @@ void TExpr_documento::evaluate_user_func(int index, int nparms, TEval_stack & st if (tipo_calcolo == 0) val *= ((CENTO - perc_esenz) / CENTO); else - val *= (perc_esenz / CENTO); } val.round(ndec); @@ -1119,7 +1118,7 @@ void TExpr_documento::evaluate_user_func(int index, int nparms, TEval_stack & st { const int ndec = (nparms > 2) ? (int)stack.pop_real().integer() : 5; const int tipo_calcolo = (nparms > 1) ? (int)stack.pop_real().integer() : 0; - const TString cat = stack.pop_string(); + const TString cat = (nparms > 0) ? stack.pop_string() : EMPTY_STRING; TString_array sottocat_found; stack.push(ZERO); diff --git a/src/ve/velib04.cpp b/src/ve/velib04.cpp index 7c4b7f6b2..41b4bf8b9 100755 --- a/src/ve/velib04.cpp +++ b/src/ve/velib04.cpp @@ -59,7 +59,7 @@ int TLista_documenti::read(char provv, char tipocf, long clifo, int anno, CHECKD(tipocf == ' ' || clifo > 0L, "Codice cliente non valido", clifo); CHECKD(anno > 2000, "Anno non valido: ", anno); CHECK(!tipidoc.empty_items(), "Lista dei tipi documento vuota"); - CHECK(statidoc.items() == tipidoc.items(), "La lista degli stati documento non corrisponde alla lista dei tipi documento"); + CHECK(!statidoc.empty_items(), "Lista degli stati documento vuota"); const int key = (tipocf == ' ' && clifo == 0L) ? 1:2; TRelation doc(LF_DOC); @@ -149,11 +149,11 @@ int TLista_documenti::read(char provv, char tipocf, long clifo, int anno, { const TString & tipo = tipidoc.get(i); - if (tipo.blank() || tipo == "*" || tipodoc == tipo) + if (tipo.blank() || tipodoc == tipo) { const TString & stato = statidoc.get(i); - if (stato.blank() || tipo == "*" || statodoc == stato) + if (stato.blank() || statodoc == stato) { match = true; break; diff --git a/src/ve/velib04b.cpp b/src/ve/velib04b.cpp index 96a5139d6..d7cef426a 100755 --- a/src/ve/velib04b.cpp +++ b/src/ve/velib04b.cpp @@ -714,10 +714,11 @@ error_type TIVA_array::add(const TRiga_documento& r, const TBill& conto, const i // speciale per lo storno, proveniente da configurazione const TString4 tipodet = r.get(RDOC_TIPODET); + const bool revcharge = r.get_bool(RDOC_REVCHARGE); + TString80 key; - TString80 key; - key.format("%d|%-4s|%c|%3d|%3d|%6ld|%s", - ord,(const char*)cod,c.tipo(),c.gruppo(),c.conto(),c.sottoconto(), (const char*)tipodet); + key.format("%d|%-4s|%c|%3d|%3d|%6ld|%s|%s", + ord,(const char*)cod,c.tipo(),c.gruppo(),c.conto(),c.sottoconto(), (const char*)tipodet, revcharge ? "X" : ""); // Nel caso di documenti a zero tiene distinte IVA positiva e negativa if (r.doc().totale_doc().is_zero()) @@ -745,6 +746,7 @@ error_type TIVA_array::add(const TRiga_documento& r, const TBill& conto, const i iva->add(RMI_IMPONIBILE, impon); iva->put(RMI_TIPODET, tipodet); + iva->put(RMI_REVCHARGE, revcharge); iva->add(RMI_IMPOSTA, imposta); if (ord != 5) { @@ -1204,7 +1206,7 @@ error_type TContabilizzazione::compile_head_mov(TDocumento& doc) } // Codice registro IVA - const TRegistro& registro = _caus->reg(); + TRegistro& registro = (TRegistro &) _caus->reg(); const bool iva_mov = registro.ok(); long ult_prot = registro.protocol(); @@ -1219,12 +1221,8 @@ error_type TContabilizzazione::compile_head_mov(TDocumento& doc) { if (_nump_iva) // Reperisce l'ultimo numero di protocollo dal registro IVA { - const bool upd_prot = ini_get_bool(CONFIG_DITTA, "ve", "UpdateProtocol", true); - TRegistro reg(registro); - - if (upd_prot) - ult_prot = reg.protocol(); - ult_prot++; + registro.reread(); + ult_prot = registro.protocol() + 1; if (ult_prot <= 0) { _error = ultprot_error; @@ -2823,13 +2821,16 @@ error_type TContabilizzazione::write_scadenze(TDocumento& doc, bool recontabiliz TPagamento& pag = doc.pagamento(); const TCurrency_documento totspese(doc.spese(), doc); TCurrency_documento totimposte(doc.imposta(true), doc); - + bool acquisto_revcharge = _caus->iva() == iva_acquisti && _caus->reverse_charge_pubb() ; real imposte; + for (int j = _movimento->iva_items()-1; j >= 0; j--) - imposte += _movimento->iva(j).get_real(RMI_IMPOSTA) * (swapped ? -UNO : UNO); + if (!acquisto_revcharge || !_movimento->iva(j).get_bool(RDOC_REVCHARGE)) + imposte += _movimento->iva(j).get_real(RMI_IMPOSTA) * (swapped ? -UNO : UNO); if (_caus->iva() == iva_acquisti) // Ricalcola precisamente il totale imposte - { + { real ti = imposte; + if (in_valuta) cambio.eur2val(ti); totimposte.set_num(ti); @@ -3226,16 +3227,12 @@ error_type TContabilizzazione::write_all(TDocumento& doc, TMovimentoPN_VE & movi } if (_nump_iva) // Reperisce l'ultimo numero di protocollo dal registro IVA { - const bool upd_prot = ini_get_bool(CONFIG_DITTA, "ve", "UpdateProtocol", true); - // TRegistro& registro = _caus->reg(); - TRegistro registro(_caus->reg()); - TRegistro reg(registro); +// non serve const bool upd_prot = ini_get_bool(CONFIG_DITTA, "ve", "UpdateProtocol", true); + TRegistro & reg = (TRegistro &) _caus->reg(); const int ult_prot = head.get_int(MOV_PROTIVA); - if (upd_prot) - reg.update(ult_prot, doc.data()); - else - registro.update(ult_prot, doc.data()); + reg.reread(); + reg.update(ult_prot, doc.data()); } // Aggiorno subito i saldi if (_caus->soloiva()) @@ -4427,14 +4424,30 @@ error_type TContabilizzazione::write_regolarizzazione(const TDocumento& doc, TMo head.put(MOV_NUMREG,nr); TSaldo_agg saldo; + if (!do_insert) { mov.read(_isequal, _lock); aggiorna_saldi(saldo, mov, false); protiva = head.get_long(MOV_PROTIVA); } - if (protiva <= 0) - protiva = caus.reg().protocol()+1; + else + { + if (_nump_iva) // Reperisce l'ultimo numero di protocollo dal registro IVA + { + TRegistro ® = (TRegistro & )caus.reg(); + + reg.reread(); + protiva = reg.protocol() + 1; + if (protiva <= 0) + { + _error = ultprot_error; + return _error; + } + } + else + protiva = doc.numero(); + } head.put(MOV_DATAREG, datareg); head.put(MOV_DATACOMP, _movimento->curr().get(MOV_DATACOMP)); @@ -4478,17 +4491,21 @@ error_type TContabilizzazione::write_regolarizzazione(const TDocumento& doc, TMo for (int ri = 0; ri < _movimento->iva_items(); ri++) { const TRectype& rmoviva = _movimento->iva(ri); - const real imponibile = rmoviva.get(RMI_IMPONIBILE); - const real imposta = rmoviva.get(RMI_IMPOSTA); - - TRectype& rmi = mov.iva(ri); - rmi.put(RMI_IMPONIBILE, imponibile); - rmi.put(RMI_IMPOSTA, imposta); - rmi.put(RMI_CODIVA, rmoviva.get(RMI_CODIVA)); - TBill zio; caus.bill(2, zio); - zio.put(rmi); + const bool revcharge = rmoviva.get(RMI_REVCHARGE); - totdoc += imponibile + imposta; // Incrementa totdoc + if (revcharge) + { + const real imponibile = rmoviva.get(RMI_IMPONIBILE); + const real imposta = rmoviva.get(RMI_IMPOSTA); + + TRectype& rmi = mov.iva(ri); + rmi.put(RMI_IMPONIBILE, imponibile); + rmi.put(RMI_IMPOSTA, imposta); + rmi.put(RMI_CODIVA, rmoviva.get(RMI_CODIVA)); + TBill zio; caus.bill(2, zio); + zio.put(rmi); + totdoc += imponibile + imposta; // Incrementa totdoc + } } head.put(MOV_TOTDOC, totdoc); // Non usare DOC_TOTDOC! Unico modo per gestire correttamente fatture e note di credito diff --git a/src/ve/velib06.cpp b/src/ve/velib06.cpp index ab5931823..91f47961d 100755 --- a/src/ve/velib06.cpp +++ b/src/ve/velib06.cpp @@ -25,6 +25,7 @@ #include "../cg/cfban.h" #include "../ca/cfcms.h" +#include "../ca/commesse.h" #include "condv.h" #include "rcondv.h" #include "sconti.h" @@ -484,7 +485,8 @@ TDocumento_mask::~TDocumento_mask() } int TDocumento_mask::insert_anal_fields(TMask& m, int page, int lf, int& y, - short& dlg, short& dlgd, bool required) + short& dlg, short& dlgd, bool required, + const short contsep_id) { const int h = ca_create_fields(m, page, lf, 2, y, dlg, dlgd); @@ -512,14 +514,47 @@ int TDocumento_mask::insert_anal_fields(TMask& m, int page, int lf, int& y, case LF_FASI : fieldname = DOC_FASCMS; break; default : fieldname = DOC_CODCOSTO; break; } + TFieldref* f = (TFieldref*)fld.field(); - f->set_name(fieldname); - - fld.check_type(required ? CHECK_REQUIRED : CHECK_NORMAL); - TEdit_field& dfld = m.efield(dlgd+i); + f->set_name(fieldname); + fld.check_type(required ? CHECK_REQUIRED : CHECK_NORMAL); + if (logic == LF_COMMESSE) + { + bool contsep_fld_exist = contsep_id >= 0; + + if (contsep_fld_exist) + contsep_fld_exist = main_mask ? m.id2pos(contsep_id) >= 0 : sfield(F_SHEET).mask().id2pos(contsep_id) >= 0; + if (contsep_fld_exist && main_app().has_module(NPAUT, CHK_DONGLE)) + { + TBrowse * b = fld.browse(); + + if (b != nullptr) + { + TCursor * c = b->cursor(); + + if (c != nullptr) + { + TString filter = c->filter(); + const bool add = filter.full(); + + if (add) + { + filter.insert("("); + filter << ")&&("; + } + filter << "(" << COMMESSE_CONTSEP << "==\"\")||(" << COMMESSE_CONTSEP << "==#" << (main_mask ? contsep_id : -contsep_id) << ")"; + if (add) + filter << ")"; + c->setfilter(filter); + } + } + } + } + + TEdit_field& dfld = m.efield(dlgd+i); + dfld.set_field(EMPTY_STRING); // Toglie campi che fan saltare gli output! - if (main_mask) { TSheet_field& sf = sfield(F_SHEET); @@ -594,7 +629,7 @@ void TDocumento_mask::insert_anal_page() else { const bool cms_req = false; // ca_in_testa && ini.get_bool("CmsRequired"); // Ora gestisco il REQUIRED da codcms_handler - insert_anal_fields(*this, newpage, LF_COMMESSE, y, dlg, dlgd, cms_req); + insert_anal_fields(*this, newpage, LF_COMMESSE, y, dlg, dlgd, cms_req, F_CONTSEP); } set_field_handler(_cms_end, codcms_handler); } @@ -623,7 +658,7 @@ void TDocumento_mask::insert_anal_page() if (use_fsc && fasinfo.parent() == LF_COMMESSE) insert_anal_fields(*this, newpage, LF_FASI, y, dlg, dlgd, true); else - insert_anal_fields(*this, newpage, LF_COMMESSE, y, dlg, dlgd, true); + insert_anal_fields(*this, newpage, LF_COMMESSE, y, dlg, dlgd, true, F_CONTSEP); if (use_fsc && fasinfo.parent() <= 0) insert_anal_fields(*this, newpage, LF_FASI, y, dlg, dlgd, false); add_button(dlg+1, newpage, TR("Generazione righe consegnate"), 2, y++, 32); @@ -1715,7 +1750,7 @@ TVariable_mask* TDocumento_mask::riga_mask(int numriga) insert_anal_fields(*m, page, LF_FASI, y, dlg, dlgd, false); else { - insert_anal_fields(*m, page, LF_COMMESSE, y, dlg, dlgd, false); + insert_anal_fields(*m, page, LF_COMMESSE, y, dlg, dlgd, false, F_CONTSEP); } m->set_handler(_cms_end_sh, cms_mag_handler); } diff --git a/src/ve/velib06a.cpp b/src/ve/velib06a.cpp index 0d348e2a8..80c7db390 100755 --- a/src/ve/velib06a.cpp +++ b/src/ve/velib06a.cpp @@ -596,6 +596,7 @@ HIDDEN real curr_fc = UNO; bool iva_handler( TMask_field& f, KEY key ) { TDocumento_mask & mask = (TDocumento_mask &) f.mask().get_sheet()->mask(); + TMask & row_mask = f.mask(); if (key == 0 || (key == K_ENTER && f.empty())) { @@ -615,7 +616,6 @@ bool iva_handler( TMask_field& f, KEY key ) if (key == K_ENTER && /*f.focusdirty() &&*/ f.empty()) { - TMask & row_mask = f.mask(); const int r = row_mask.get_sheet()->selected() + 1; const TRiga_documento& riga = mask.doc()[r]; @@ -640,8 +640,20 @@ bool iva_handler( TMask_field& f, KEY key ) if (required) return f.error_box(TR("Il codice IVA č obbligatorio.")); } - } + if (f.running_check(key)) + { + TCodiceIVA i(f.get()); + + row_mask.set(FR_REVCHARGE, i.reverse_charge_attivo() ? "X" : ""); + } + if (f.initial_check(key)) + { + const int r = row_mask.get_sheet()->selected() + 1; + const TCausale & caus = cached_causale(mask.doc()[r].doc().tipo().causale()); + + f.mask().enable(FR_REVCHARGE, caus.reverse_charge_pubb()); + } if (key == K_ENTER) { TVariable_sheet_field * sf = (TVariable_sheet_field *)f.mask().get_sheet(); diff --git a/src/ve/verig.h b/src/ve/verig.h index c13ab00e3..624d08f78 100755 --- a/src/ve/verig.h +++ b/src/ve/verig.h @@ -131,8 +131,10 @@ #define FR_PCON10 186 #define FR_CMAX (FR_PCON10-FR_CCON01+1)/2 +#define FR_REVCHARGE 187 + // Ultimo campo fittizio -#define FR_END 187 +#define FR_END 188 #define MAX_COLUMNS FR_END-FR_LORDO #define FR_DESMAG 270 diff --git a/src/ve/verig.uml b/src/ve/verig.uml index f0766221e..c828eef92 100755 --- a/src/ve/verig.uml +++ b/src/ve/verig.uml @@ -1339,8 +1339,8 @@ ENDIF INPUT S0 FR_DESIVA DISPLAY "Descrizione@50" S0 DISPLAY "Codice@20" CODTAB - OUTPUT FR_CODIVA CODTAB - OUTPUT FR_DESIVA S0 + OUTPUT FR_CODIVA CODTAB + OUTPUT FR_DESIVA S0 IFDEF(FL_DESIVA) FLAGS FL_DESIVA ENDIF @@ -1350,9 +1350,28 @@ ENDIF END ENDIF +IFDEF(X_CODIVA) + DEFINE Y_REVCHARGE Y_CODIVA+1 + DEFINE X_TIPODET X_CODIVA+20 +ENDIF + +BOOLEAN FR_REVCHARGE +BEGIN +IFDEF(X_CODIVA) + PROMPT X_CODIVA Y_REVCHARGE "Reverse charge" + ELSE + PROMPT 2 16 "Reverse charge" +ENDIF + FIELD REVCHARGE +END + STRING FR_TIPODET 1 BEGIN - PROMPT 2 16 "Indetraib. " +IFDEF(X_CODIVA) + PROMPT X_TIPODET Y_REVCHARGE "Indetraib. " +ELSE + PROMPT 20 16 "Indetraib. " +ENDIF USE %DET INPUT CODTAB FR_TIPODET DISPLAY "Codice" CODTAB @@ -1360,9 +1379,9 @@ BEGIN DISPLAY "Descrizione@50" S0 OUTPUT FR_TIPODET CODTAB CHECKTYPE NORMAL + FIELD TIPODET FLAGS "U" END - ENDIF IFDEF(FLD_ADDIVA)