diff --git a/ve/batbfrd.uml b/ve/batbfrd.uml index eadf3a9cd..8bb23fb93 100755 --- a/ve/batbfrd.uml +++ b/ve/batbfrd.uml @@ -58,7 +58,7 @@ STRING F_FORMULA 70 50 BEGIN PROMPT 2 11 "Formula " FIELD S1 - CHECKTYPE REQUIRED +// CHECKTYPE REQUIRED WARNING "La formula e' obbligatoria" FLAG "U" END diff --git a/ve/velib01.cpp b/ve/velib01.cpp index bf2db5fe3..be77306b8 100755 --- a/ve/velib01.cpp +++ b/ve/velib01.cpp @@ -247,7 +247,7 @@ HIDDEN real curr_fc(1.0); HIDDEN bool iva_handler( TMask_field& f, KEY key ) { - if (key == 0 || key == K_ENTER) + if (key == 0 || (key == K_ENTER && f.get().empty())) { TDocumento_mask & mask = (TDocumento_mask &) f.mask().get_sheet()->mask(); const TString16 codiva = mask.condv().clifo().get(LF_CFVEN, "ASSFIS"); @@ -445,7 +445,7 @@ HIDDEN bool sppr_handler( TMask_field& f, KEY key ) { TMask& row_mask = f.mask(); - if (key == K_TAB && (f.focusdirty() || !row_mask.get(FR_DESCR).empty())) + if (key == K_TAB && (f.focusdirty() || row_mask.get(FR_DESCR).empty())) { const int pos = row_mask.id2pos(FR_PREZZO); @@ -566,7 +566,7 @@ real iva(real imponibile, const TIVA & iva,int ndec) return val; } -real TDocumento::spese_incasso(real & imp, int ndec, bool netto) const +real TDocumento::spese_incasso(real & imp, int ndec, TTipo_importo t) const { real imp_spese; real percentuale = get_real("PERCSPINC"); @@ -598,10 +598,8 @@ real TDocumento::spese_incasso(real & imp, int ndec, bool netto) const if (cambio == ZERO) cambio = 1.0; - imp_spese /= cambio; - imp_spese.round(ndec); - if (netto == FALSE) - { +// if (netto == FALSE) +// { static TString16 codiva; static long firm = -1; long new_firm = main_app().get_firm(); @@ -613,13 +611,20 @@ real TDocumento::spese_incasso(real & imp, int ndec, bool netto) const codiva = conf.get("SPINCODIVA", "ve"); firm = new_firm; } - imp_spese += iva(imp_spese, TRiga_documento::iva(codiva), ndec); - } + real iva_spese(iva(imp_spese, TRiga_documento::iva(codiva), ndec)); +// } + if (t == _lordo) + imp_spese += iva_spese; + else + if (t == _imposta) + imp_spese = iva_spese; + imp_spese /= cambio; + imp_spese.round(ndec); } return imp_spese; } -real TDocumento::bolli(real & imp, int ndec, bool netto) const +real TDocumento::bolli(real & imp, int ndec, TTipo_importo t) const { real tot_bolli; static TArray sca_bolli; @@ -639,13 +644,15 @@ real TDocumento::bolli(real & imp, int ndec, bool netto) const TPagamento & pag = ((TDocumento*)this)->pagamento(); const int nrate = pag.n_rate(); real old_bolli = -1.00; - real iva_bolli; + real iva_bolli; + real imp_orig = imposta(); + real sp_orig = spese(); for (int j = 0; j < 5 && tot_bolli != old_bolli; j++) { - old_bolli = tot_bolli; - const real imposte = imposta() * cambio + iva_bolli; - const real imp_spese = spese() * cambio + tot_bolli - iva_bolli; + old_bolli = tot_bolli + iva_bolli; + const real imposte = imp_orig * cambio + iva_bolli; + const real imp_spese = sp_orig * cambio + tot_bolli - iva_bolli; const real imponibile = importo - imposte - imp_spese; tot_bolli = ZERO; @@ -721,8 +728,8 @@ real TDocumento::bolli(real & imp, int ndec, bool netto) const break; } } - if (netto == FALSE) - { +// if (netto == FALSE) +// { static TString16 codiva; static long firm = -1; long new_firm = main_app().get_firm(); @@ -735,10 +742,15 @@ real TDocumento::bolli(real & imp, int ndec, bool netto) const firm = new_firm; } iva_bolli = iva(tot_bolli, TRiga_documento::iva(codiva), ndec); - tot_bolli += iva_bolli; - } - importo += (tot_bolli - old_bolli); - } +// tot_bolli += iva_bolli; +// } + importo += (tot_bolli + iva_bolli - old_bolli); + } + if (t == _lordo) + tot_bolli += iva_bolli; + else + if (t == _imposta) + tot_bolli = iva_bolli; tot_bolli /= cambio; tot_bolli.round(ndec); } @@ -750,7 +762,7 @@ real TDocumento::bolli(real & imp, int ndec, bool netto) const // Formula generica /////////////////////////////////////////////////////////// -HIDDEN enum _formula {_somma, _bolli, _bolli_int, _spinc, _prezzo, _importo, _sconto, _iva, _provv, _tipo}; +HIDDEN enum _formula {_somma, _bolli, _bolli_int, _spinc, _prezzo, _importo, _sconto, _iva, _provv, _tipo, _imponibili, _imposte}; TExpr_documento::TExpr_documento(const char* expression, TTypeexp type, TDocumento * doc, TRiga_documento * row) @@ -791,8 +803,14 @@ int TExpr_documento::parse_user_func(const char * name, int nparms) const else if (strcmp(name, "TIPO") == 0) return nparms == 0 ? _tipo : -1; - else - return -1; + else + if (strcmp(name, "IMPONIBILI") == 0) + return nparms < 3 ? _imponibili : -1; + else + if (strcmp(name, "IMPOSTE") == 0) + return nparms < 3 ? _imposte : -1; + else + return -1; } void TExpr_documento::evaluate_user_func(int index, int nparms, TEval_stack & stack, TTypeexp type) const @@ -842,7 +860,7 @@ void TExpr_documento::evaluate_user_func(int index, int nparms, TEval_stack & st real & r = stack.peek_real(); if (_doc) - r = _doc->spese_incasso(r, ndec, netto); + r = _doc->spese_incasso(r, ndec, netto ? _netto : _lordo); else r = ZERO; } @@ -862,7 +880,7 @@ void TExpr_documento::evaluate_user_func(int index, int nparms, TEval_stack & st if (_doc) { r += _doc->spese_incasso(r, ndec); - r = _doc->bolli(r, ndec, netto); + r = _doc->bolli(r, ndec, netto ? _netto : _lordo); } else r = ZERO; @@ -965,7 +983,8 @@ void TExpr_documento::evaluate_user_func(int index, int nparms, TEval_stack & st real & val = stack.peek_real(); if (_row) - val = _row->iva(ndec); +// val = _row->iva(ndec); + val = _row->imposta(); else val = ZERO; } @@ -997,6 +1016,36 @@ void TExpr_documento::evaluate_user_func(int index, int nparms, TEval_stack & st s << _row->tipo().tipo(); stack.push(s); } + break; + case _imponibili: + { + int ndec = _doc && _doc->in_valuta() ? 3 : 0; + bool spese = FALSE; + + if (nparms > 1) + ndec = (int) stack.pop_real().integer(); + if (nparms > 0) + spese = !stack.pop_real().is_zero(); + else + stack.push(ZERO); + real & val = stack.peek_real(); + val = _doc->imponibile(spese, ndec); + } + break; + case _imposte: + { + int ndec = _doc && _doc->in_valuta() ? 3 : 0; + bool spese = FALSE; + + if (nparms > 1) + ndec = (int) stack.pop_real().integer(); + if (nparms > 0) + spese = !stack.pop_real().is_zero(); + else + stack.push(ZERO); + real & val = stack.peek_real(); + val = _doc->imposta(spese, ndec); + } break; default: TExpression::evaluate_user_func(index, nparms, stack, type); @@ -1113,18 +1162,6 @@ void TTipo_documento::read_formule() _formule = profile.get("CAMPICALC", "MAIN"); _formule.add(profile.get("CALCOLI", "MAIN")); - _imponibile = profile.get("IMPONIBILE", "MAIN"); - if (_imponibile.not_empty() && _formule.find(_imponibile) < 0) - { - error_box("Campo imponibile (%s) sconosciuto nel tipo documento %s", (const char *) _imponibile, (const char *) codice()); - _imponibile.cut(0); - } - _imposta = profile.get("IMPOSTA", "MAIN"); - if (_imposta.not_empty() && _formule.find(_imposta) < 0) - { - error_box("Campo imposta (%s) sconosciuto nel tipo documento %s", (const char *) _imposta, (const char *) codice()); - _imposta.cut(0); - } _totale = profile.get("TOTALE", "MAIN"); _totale_netto = "_"; _totale_netto << _totale; @@ -1223,13 +1260,7 @@ void TTipo_riga_documento::read_formule() { error_box("Campo imponibile (%s) sconosciuto nel tipo riga %s", (const char *) _imponibile, (const char *) codice()); _imponibile.cut(0); - } - _imposta = profile.get("IMPOSTA", "MAIN"); - if (_imposta.not_empty() && _formule.find(_imposta) < 0) - { - error_box("Campo imposta (%s) sconosciuto nel tipo riga %s", (const char *) _imposta, (const char *) codice()); - _imposta.cut(0); - } + } } TFormula_documento * TTipo_riga_documento::succ_formula(bool restart) @@ -1601,13 +1632,8 @@ real TRiga_documento::imponibile() const } real TRiga_documento::imposta(bool round) const -{ - const TString16 field(tipo().imposta()); - - if (field.not_empty()) - return get_real(field); - else - return iva(round ? (doc().in_valuta() ? 3 : 0) : 20); +{ + return iva(round ? (doc().in_valuta() ? 3 : 0) : 20); } void TRiga_documento::dirty_fields(bool dirty_document) @@ -2154,15 +2180,32 @@ void TDocumento::set_fields(TAuto_variable_rectype & rec) { TString work_tot_doc(tot_doc); - work_tot_doc.insert("_"); + work_tot_doc.insert("_"); + TString netto_def(exp->string()); + + if (netto_def.find("IMPONIBILI") == -1) + { + if (netto_def.not_empty()) + netto_def << "+"; + netto_def << "IMPONIBILI()"; + } - add_field(new TDocumento_variable_field(work_tot_doc, exp)); + if (netto_def.find("IMPOSTE") == -1) + { + if (netto_def.not_empty()) + netto_def << "+"; + netto_def << "IMPOSTE()"; + } + + TExpr_documento * netto_exp = new TExpr_documento(netto_def, _numexpr, this); + + add_field(new TDocumento_variable_field(work_tot_doc, netto_exp)); - TExpr_documento * new_exp = new TExpr_documento( + TExpr_documento * tot_exp = new TExpr_documento( format("%s + _BOLLI(%s)", (const char *) work_tot_doc, (const char *) work_tot_doc), _numexpr, this); - add_field(new TDocumento_variable_field(f->name(), new_exp)); + add_field(new TDocumento_variable_field(f->name(), tot_exp)); } else add_field(new TDocumento_variable_field(f->name(), exp)); @@ -2172,36 +2215,64 @@ void TDocumento::set_fields(TAuto_variable_rectype & rec) } } -real TDocumento::imponibile() const +real TDocumento::imponibile(bool spese, int ndec) const { - const TString16 field(tipo().imponibile()); - - if (field.not_empty()) - return get_real(field); - else - { - real val; + real val; + if (ndec > 99) + ndec = in_valuta() ? 3 : 0; - for (int i = rows(); i > 0; i--) - val += ((TRiga_documento &) ((TDocumento *)this)->row(i)).imponibile(); - return val; + for (int i = rows(); i > 0; i--) + val += ((TRiga_documento &) ((TDocumento *)this)->row(i)).imponibile(); + if (spese) + { + real tot_doc = val + imposta(FALSE, ndec); + val += spese_incasso(tot_doc, ndec, _netto); + tot_doc += spese_incasso(tot_doc, ndec); + val += bolli(tot_doc, ndec, _netto); } + val.round(ndec); + return val; } -real TDocumento::imposta() const -{ - const TString16 field(tipo().imposta()); +real TDocumento::imposta(bool spese, int ndec) const +{ + TAssoc_array ive; - if (field.not_empty()) - return get_real(field); - else - { - real val; - - for (int i = rows(); i > 0; i--) - val += ((TRiga_documento &) ((TDocumento *)this)->row(i)).imposta(); - return val; + if (ndec > 99) + ndec = in_valuta() ? 3 : 0; + + for (int i = rows(); i > 0; i--) + { + TRiga_documento & r = ((TRiga_documento &) ((TDocumento *)this)->row(i)); + real iva(r.imposta(FALSE)); + const TString & cod_iva = r.get("CODIVA"); + + real * tot = (real *) ive.objptr(cod_iva); + if (tot == NULL) + ive.add(cod_iva, iva); + else + *tot += iva; } + real val; + + ive.restart(); + for (real * iva = (real *) ive.get(); iva != NULL; iva = (real *) ive.get()) + { + if (*iva < ZERO) + iva->floor(ndec); + else + iva->ceil(ndec); + val += *iva; + } + if (spese) + { + real tot_doc = val + imponibile(FALSE, ndec); + val += spese_incasso(tot_doc, ndec, _imposta); + tot_doc += spese_incasso(tot_doc, ndec); + val += bolli(tot_doc, ndec, _imposta); + } + val.round(ndec); + return val; } real TDocumento::totale_doc() const diff --git a/ve/velib01.h b/ve/velib01.h index a2a616e52..ee96dc688 100755 --- a/ve/velib01.h +++ b/ve/velib01.h @@ -328,6 +328,8 @@ public: virtual ~TRiga_documento() {} }; +enum TTipo_importo { _lordo, _netto, _imposta }; + class TDocumento : public TAuto_variable_rectype { static TAssoc_array _tipi; @@ -404,12 +406,12 @@ public: void set_fields(TAuto_variable_rectype & rec); - real spese_incasso(real & imp, int ndec, bool netto = FALSE) const ; - real bolli(real & imp, int ndec, bool netto = FALSE) const ; + real spese_incasso(real & imp, int ndec, TTipo_importo netto = _lordo) const ; + real bolli(real & imp, int ndec, TTipo_importo netto = _lordo) const ; real descrizione() const; real riferimento() const; - real imponibile() const; - real imposta() const; + real imponibile(bool spese = FALSE, int ndec = 100) const; + real imposta(bool spese = FALSE, int ndec = 100) const; real totale_doc() const; real totale_netto() const; real basesconto() const;