diff --git a/ve/ve0200e.uml b/ve/ve0200e.uml index 42de7bbd8..ae8bc60d8 100755 --- a/ve/ve0200e.uml +++ b/ve/ve0200e.uml @@ -142,6 +142,12 @@ GROUP 3 //WARNING "La sequenza di ricerca per anagrafica deve indicare quattro tipi diversi" END +BOOLEAN F_SCONTO_LORDO +BEGIN + PROMPT 2 14 "Contabilizzazione merci al lordo " + FIELD CONTSCLOR +END + ENDPAGE ENDMASK diff --git a/ve/ve6.cpp b/ve/ve6.cpp index 406c18ce2..171fe5273 100755 --- a/ve/ve6.cpp +++ b/ve/ve6.cpp @@ -27,5 +27,6 @@ int main( int argc, char** argv ) error_box( usage, argv[0] ); break; } + exit(0); return rt; } diff --git a/ve/ve6100.cpp b/ve/ve6100.cpp index 1b3790933..179a8164e 100755 --- a/ve/ve6100.cpp +++ b/ve/ve6100.cpp @@ -101,6 +101,8 @@ bool TContabilizzazione_app::handle_data_range(TMask_field& f, KEY k) if (k==K_ENTER && f.dirty()) { TMask& m = f.mask(); + if (m.get_bool(F_DATA_AUTO)) + return TRUE; // Skip controls if data is automatic TDate da(m.get_date(F_DATA_INI)); TDate a(m.get_date(F_DATA_FIN)); m.field(F_DATA_REG).set_dirty(); @@ -115,6 +117,14 @@ bool TContabilizzazione_app::handle_data_range(TMask_field& f, KEY k) f.error_box("L'intervallo tra le date non puo' eccedere i 15 giorni."); return FALSE; } + if (F_DATA_FIN) + m.set(F_DATA_REG,f.get()); + } + if (f.focusdirty()) + { + TMask& m = f.mask(); + if (!m.get_bool(F_DATA_AUTO) && f.dlg() == F_DATA_FIN) + m.set(F_DATA_REG,f.get()); } return TRUE; } @@ -259,7 +269,7 @@ bool TContabilizzazione_app::create() _msk->set_handler(F_CODICE_ELAB,handle_cod_eld); _msk->set_handler(F_DATA_INI,handle_data_range); _msk->set_handler(F_DATA_FIN,handle_data_range); - _msk->set_handler(F_DATA_REG,handle_data_reg); + //_msk->set_handler(F_DATA_REG,handle_data_reg); _msk->set_handler(DLG_USER,handle_select); _num_sheet = new TArray_sheet(-1,-1,-4,-4,"Codici numerazione", "@1|Cod. numerazione|Descrizione@50"); diff --git a/ve/ve6100a.uml b/ve/ve6100a.uml index 00debb88c..54563cb91 100755 --- a/ve/ve6100a.uml +++ b/ve/ve6100a.uml @@ -49,15 +49,12 @@ BOOLEAN F_DATA_AUTO BEGIN PROMPT 42 5 "Data registrazione automatica" MESSAGE TRUE CLEAR,F_DATA_REG|"",F_DATA_REG - MESSAGE FALSE ENABLE,F_DATA_REG END DATE F_DATA_REG BEGIN PROMPT 42 6 "Data registrazione " - FLAG "A" - VALIDATE NOT_EMPTY_FUNC - WARNING "La data registrazione e' obbligatoria" + FLAG "D" END RADIOBUTTON F_SELPROT 1 32 diff --git a/ve/veconf.h b/ve/veconf.h index c62a38d4c..f9969c9f2 100755 --- a/ve/veconf.h +++ b/ve/veconf.h @@ -86,6 +86,7 @@ #define F_RICERCAAN2 107 #define F_RICERCAAN3 108 #define F_RICERCAAN4 109 +#define F_SCONTO_LORDO 110 // Campi per ve0200f.uml #define F_IMPSPINC1 101 diff --git a/ve/velib.h b/ve/velib.h index 6eef17c29..93a9a627b 100755 --- a/ve/velib.h +++ b/ve/velib.h @@ -399,6 +399,7 @@ public: real prezzo(bool scontato, bool lordo, int ndec = AUTO_DECIMALS) const ; real importo(bool scontato , bool lordo, int ndec = AUTO_DECIMALS) const ; + real sconto() const { return importo(FALSE,FALSE) - importo(TRUE,FALSE); } real iva(int ndec) const; real imponibile() const; real imposta(bool round = TRUE) const; @@ -876,11 +877,15 @@ protected: // Funzione per ricercare il conto di costo/ricavo error_type search_costo_ricavo(TBill&, const TRiga_documento&); // Funzione per aggiungere la riga iva al TAssoc_array _righe_iva - error_type add_iva_row(const TBill&, const TRiga_documento&); + error_type add_iva_row(const TBill&, const TRiga_documento&, const int); // Funzione atomica per aggiungere le righe di spese d'incasso e bolli al TAssoc_array _righe_iva void calculate_spese(real&, real&, int, bool, bool); // Funzione per aggiungere le righe di spese d'incasso e bolli al TAssoc_array _righe_iva (chiama calculate_spese()) - error_type add_spese_inbo(TDocumento&); + error_type add_spese_inbo(TDocumento&, const int); + // Aggiorna le righe di sconto importo o percentuale + error_type adjust_sconto_rows(TDocumento&); + // Controlla la corrispondenza tra limposta del documento e quelle generate + error_type adjust_iva_rows(TDocumento&); // Crea le righe iva sul movimento error_type create_iva_rows(TDocumento&); // Crea la riga di totale documento diff --git a/ve/velib04b.cpp b/ve/velib04b.cpp index 8a5e2a437..70721c3d2 100755 --- a/ve/velib04b.cpp +++ b/ve/velib04b.cpp @@ -404,34 +404,51 @@ class TIVA_element : public TObject real _imp; real _iva; real _ali; + TString _cod_iva; public: real& imp() { return _imp;} // Imponibile real& iva() { return _iva;} // Iva real& ali() { return _ali;} // Aliquota % - void zero(){ _imp = 0.0; _iva = 0.0; _ali = 0.0; } + TString& cod_iva() { return _cod_iva;} + void zero(){ _imp = 0.0; _iva = 0.0; _ali = 0.0; _cod_iva = "";} virtual TObject* dup() const { return new TIVA_element(*this); } TIVA_element& operator = (TIVA_element& a); - TIVA_element& operator += (const TRiga_documento& a); - TIVA_element() {_imp = 0.0; _iva = 0.0; _ali = 0.0;} + TIVA_element& add(const TRiga_documento& a, const bool sc, const int ndec); + TIVA_element() { zero(); } ~TIVA_element() {}; }; TIVA_element& TIVA_element::operator=(TIVA_element& a) { _imp = a.imp(); _iva = a.iva(); _ali = a.ali(); + _cod_iva = a.cod_iva(); return *this; } -TIVA_element& TIVA_element::operator+=(const TRiga_documento& a) +TIVA_element& TIVA_element::add(const TRiga_documento& a, const bool sc, const int ndec) // It's horrible, I know. { - _imp += a.imponibile(); _iva += a.imposta(); _ali = a.iva().aliquota(); + const TIVA& xx = a.iva(); + if (!sc) // Al netto dello sconto + { + _imp += a.imponibile(); + _iva += a.imposta(); + } + else + { + real imponibile = a.importo(FALSE,FALSE,ndec); // Imponibile della riga al lordo dello sconto + _imp += imponibile;// Imponibile lorda + _iva += ::iva(imponibile,xx,ndec);// imposta calcolata sull'imponibile lorda + } + _ali = xx.aliquota(); + _cod_iva = xx.codice(); return *this; } static TBill _sco_perc_bill, _sco_imp_bill, // Conti per gli sconti a percentuale ed importi (dalla configurazione) _spin_billa, _spin_billv, _spbo_billa, _spbo_billv; +static bool _contsclor; // Contabilizza sconti al netto o al lordo (sconti suddiviso per ogni contropartita) static TEsercizi_contabili _esc; // Per sapere a quale esercizio appartiene il documento static TCausale *_caus = NULL; // causale del documento corrente static TMovimentoPN_VE *_movimento = NULL; // Movimento di prima nota @@ -552,6 +569,8 @@ bool TContabilizzazione::load_parameters() so = conf.get_long("SCOIMCODCON","ve",3); _sco_imp_bill.set(gr,co,so); + _contsclor = conf.get_bool("CONTSCLOR","ve"); + gr = conf.get_int("SPINCODCONA","ve",1); co = conf.get_int("SPINCODCONA","ve",2); so = conf.get_long("SPINCODCONA","ve",3); @@ -890,13 +909,8 @@ error_type TContabilizzazione::search_costo_ricavo(TBill& conto, const TRiga_doc } break; // case 'P','S' } - case 'C': // righe sconti (TBI) (reperire l'imposta e l'imponibile normalizzare. Il conto e' nei parametri) - // quale sconto deve reperire dalla configurazione? Sconto ad importo o sconto a percentuale? - if (!r.get(RDOC_SCONTO).empty()) // se c'e' la percentuale reperisce il conto dello sconto a percentuale - conto = _sco_perc_bill; - else // altrimenti quello dello sconto ad importo - conto = _sco_imp_bill; - break; // case 'C' + case 'C': + // righe sconti: vengono considerate in adjust_sconto_rows() case 'D': // righe descrizioni (saltare) default : break; @@ -906,17 +920,20 @@ error_type TContabilizzazione::search_costo_ricavo(TBill& conto, const TRiga_doc return _error; } -error_type TContabilizzazione::add_iva_row(const TBill& conto, const TRiga_documento& r) +error_type TContabilizzazione::add_iva_row(const TBill& conto, const TRiga_documento& r, const int ndec) // Aggiunge le righe iva all'assoc_array di raggruppamento { TIVA_element el_tmp; - TString cod(r.iva().codice()); + const TIVA& tiva = r.iva(); + TString cod(tiva.codice()); const char tipo = conto.tipo(); const int gr = conto.gruppo(); const int co = conto.conto(); const long so = conto.sottoconto(); TString key; const char tipo_r = r.tipo().tipo(); + const bool sconto_lordo = tipo_r != 'C' && _contsclor && _sco_perc_bill.ok(); + bool exists; int ord=0; // Ordine con cui vengono immesse le righe IVA: // merce, omaggi, prestazioni, spese, bolli/spese d'incasso, sconti. @@ -935,16 +952,43 @@ error_type TContabilizzazione::add_iva_row(const TBill& conto, const TRiga_docum case 'S': ord = 4; break; - case 'C': - ord = 6; - break; default: break; } - key.format("%d|%-4s|%c|%3d|%3d|%6ld",ord,(const char*)cod,tipo,gr,co,so); - const bool exists = _righe_iva.is_key(key); - TIVA_element& el = (exists ? (TIVA_element&)_righe_iva[key] : el_tmp); - el += r; - _righe_iva.add(key,el,exists); + + // Le righe di sconto ad importo o percentuale vanno saltate + if (tipo_r != 'C') + { + key.format("%d|%-4s|%c|%3d|%3d|%6ld",ord,(const char*)cod,tipo,gr,co,so); + exists = _righe_iva.is_key(key); + TIVA_element& el = (exists ? (TIVA_element&)_righe_iva[key] : el_tmp); + + el.add(r,sconto_lordo,ndec); // Inserisce la riga IVA al netto o al lordo dello sconto + _righe_iva.add(key,el,exists); // Le righe di sconto le aggiorna dopo + } + + if (sconto_lordo) // Se e' settato il flag di contabilizzare anche gli sconti merce + { + real sconto = - r.sconto(); // Imponibile dello sconto (positivo, quindi si cambia di segno + if (sconto != ZERO) + { + real ivasc = ::iva(sconto,tiva,ndec);// imposta calcolata sullo sconto + key.format("6|%-4s|%c|%3d|%3d|%6ld", + (const char*)cod, + _sco_perc_bill.tipo(), + _sco_perc_bill.gruppo(), + _sco_perc_bill.conto(), + _sco_perc_bill.sottoconto()); + + el_tmp.zero(); + exists = _righe_iva.is_key(key); + TIVA_element& el_sc = (exists ? (TIVA_element&)_righe_iva[key] : el_tmp); + el_sc.ali() = tiva.aliquota(); + el_sc.cod_iva() = tiva.codice(); + el_sc.imp() += sconto; + el_sc.iva() += ivasc; + _righe_iva.add(key,el_sc,exists); // Sostituisce od aggiunge la riga relativa allo sconto + } + } return no_error; } @@ -972,12 +1016,11 @@ void TContabilizzazione::calculate_spese(real& spese, real& sp_iva, int ndec, bo _righe_iva.add(key,el,exists); } -error_type TContabilizzazione::add_spese_inbo(TDocumento& doc) +error_type TContabilizzazione::add_spese_inbo(TDocumento& doc, const int ndec) // Aggiunge le righe di spese incasso/bolli { real tot_netto, sp_incasso, sp_bolli; real iva_sp_incasso, iva_sp_bolli; - const int ndec = doc.in_valuta() ? 3 : 0; bool is_cli = doc.get(DOC_TIPOCF) == "C"; // Aggiunge le spese d'incasso tot_netto = doc.totale_netto(); @@ -994,8 +1037,102 @@ error_type TContabilizzazione::add_spese_inbo(TDocumento& doc) return _error; } -error_type TContabilizzazione::create_iva_rows(TDocumento& doc) +// Aggiorna le righe di sconto (importo o a percentuale) +error_type TContabilizzazione::adjust_sconto_rows(TDocumento& doc) { + TIVA_element el_tmp; + TAssoc_array& aa = doc.tabella_iva(); + TRiepilogo_iva * riep; + TString cod,key; // Codice IVA corrente + real sconto,iva; + const int ndec = doc.in_valuta() ? 3 : 0; + + // Scorre tutti gli elementi della tabella IVA del documento (elementi per codice iva) + for (riep = (TRiepilogo_iva*) aa.first_item(); riep != NULL; riep = (TRiepilogo_iva*) aa.succ_item()) + { + const TIVA& codiva = riep->cod_iva(); + cod = codiva.codice(); // Codice IVA + for (int i = 0; i < 2; i++) // Ciclo per sconto a percentuale (i == 0) e ad importo (i == 1) + { + //Importo sconto (sconto_perc() o sconto_imp()) + //Calcola ::iva() sullo sconto + //Somma alla riga corrispondente o la crea se non esiste gia' + //I conti per aggiustare l'iva vengono fatti in adjust_iva_rows() + const bool perc = i == 0; + TBill& conto = perc ? _sco_perc_bill : _sco_imp_bill; + sconto = perc ? riep->sconto_perc() : riep->sconto_imp(); + iva = ::iva(sconto,codiva,ndec); + if (sconto != ZERO) + { + key.format("6|%-4s|%c|%3d|%3d|%6ld",(const char*)cod, + conto.tipo(), + conto.gruppo(), + conto.conto(), + conto.sottoconto()); + const bool exists = _righe_iva.is_key(key); + // Aggiorna imponibile ed imposta all'elemento relativo + el_tmp.zero(); + TIVA_element& el = exists ? (TIVA_element&)_righe_iva[key] : el_tmp; + el.imp() += sconto; + el.iva() += iva; + el.ali() = codiva.aliquota(); + el.cod_iva() = cod; + _righe_iva.add(key,el,exists); + } + } + } + return no_error; +} + +// "Aggiusta" l'imposta sulle righe IVA secondo la tabella interna al documento +// Tratta anche i documenti in valuta. DI solito si tratta di poche lire. +error_type TContabilizzazione::adjust_iva_rows(TDocumento& doc) +{ + TAssoc_array& aa = doc.tabella_iva(); + TRiepilogo_iva * riep; + TString cod; // Codice IVA corrente + const int items = _righe_iva.items(); // Numero di righe IVA + const bool in_valuta = doc.in_valuta(); + const real cambio = doc.cambio(); + real iva_gen,imponibile; + + // Scorre tutti gli elementi della tabella IVA del documento (elementi per codice iva) + for (riep = (TRiepilogo_iva*) aa.first_item(); riep != NULL; riep = (TRiepilogo_iva*) aa.succ_item()) + { + cod = riep->cod_iva().codice(); // Codice IVA + iva_gen = riep->imposta(); + + if (in_valuta) // I documenti vanno sempre contabilizzati in lire + iva_gen *= cambio; + + if (iva_gen < ZERO) + iva_gen.floor(0); + else + iva_gen.ceil(0); + + TGeneric_distrib gd(iva_gen); // Instanzia il TGeneric_ditrib con la vera Imposta + // Adesso scorre tutte le righe IVA contabili con questo codice IVA + for (int i = 0; i < items; i++) + { + TRectype& ie = _movimento->iva(i); + if (ie.get(RMI_CODIVA) == cod) // Se il codice IVA e' uguale + gd.add(ie.get_real(RMI_IMPOSTA)); // Aggiunge al TGeneric_distrib l'imposta corrente + } + // Alla fine per performare tutto il calcolo (Thanx to TGeneric_distrib) si fanno le get + // E le si mettono nel rispettivo record IVA + + for (i = 0; i < items; i++) + { + TRectype& ie = _movimento->iva(i); + if (ie.get(RMI_CODIVA) == cod) // Se il codice IVA e' uguale + ie.put(RMI_IMPOSTA,gd.get()); // Sostituisce l'imposta con quella ricalcolata al fine di avere tutto giusto + } + } // Visto che vengono restituiti nello stesso ordine in cui sono state chiamate le rispettive TGeneric_distrib::add() + return no_error; +} + +error_type TContabilizzazione::create_iva_rows(TDocumento& doc) +{ const int items = _righe_iva.items(); const bool in_valuta = doc.in_valuta(); TRectype& head = _movimento->lfile().curr(); @@ -1027,7 +1164,7 @@ error_type TContabilizzazione::create_iva_rows(TDocumento& doc) conto.set(gr,co,so,tipo); conto.find(); imponibile = cur.imp(); - if (in_valuta) + if (in_valuta) // I documenti vanno sempre contabilizzati in lire { imponibile = cur.imp() * cambio; // imponibile in lire imponibile.round(); @@ -1125,7 +1262,7 @@ error_type TContabilizzazione::compile_rows_mov(TDocumento& doc) // Compila le righe { const int rows = doc.rows(); - + const int ndec = doc.in_valuta() ? 3 : 0; _righe_iva.destroy(); // resetta l'assoc_array delle righe di iva for (int i=1; good() && i<=rows; i++) // browse all this fucked document rows { @@ -1136,11 +1273,11 @@ error_type TContabilizzazione::compile_rows_mov(TDocumento& doc) { TBill conto; const char tipo = r.tipo().tipo(); - if (tipo != 'D') + if (tipo != 'D' && tipo != 'C') { search_costo_ricavo(conto,r); // l'errore eventuale viene settato qui dentro if (good()) - add_iva_row(conto,r); + add_iva_row(conto,r,ndec); } } else @@ -1152,11 +1289,20 @@ error_type TContabilizzazione::compile_rows_mov(TDocumento& doc) // Crea le righe per le spese d'incasso e bolli if (good()) - add_spese_inbo(doc); + add_spese_inbo(doc,ndec); + // Aggiorna le righe di sconto (sconto ad importo o percentuale) + if (good()) + adjust_sconto_rows(doc); + // Crea le righe di IVA if (good()) create_iva_rows(doc); + + // Controlla che le imposte per ogni aliquota ed eventualmente corregge le imposte stesse sulle righe + if (good()) + adjust_iva_rows(doc); + // Crea la riga di totale documento if (good()) create_total_doc_row();