#include "velib.h" #include "vepriv.h" #include #ifndef __APPLICAT_H #include #endif #ifndef __VEUML_H #include "veuml.h" #endif #ifndef __TABUTIL_H #include #endif #ifndef __UTILITY_H #include #endif #ifndef __VEINI_H #include "veini.h" #endif #ifndef __MGLIB_H #include "../mg/mglib.h" #endif #ifndef __SCONTI_H #include "sconti.h" #endif #ifndef __MODAUT_H #include #endif /////////////////////////////////////////////////////////// // Movimento di magazzino /////////////////////////////////////////////////////////// class TMov_mag_doc : public TMov_mag { const TDocumento * _doc; protected: virtual const char * codmag_rauto(int r) const; public: TMov_mag_doc(const TDocumento * d) : _doc(d) {} virtual ~TMov_mag_doc() {} }; const char * TMov_mag_doc::codmag_rauto(int r) const { const int rows = _doc->physical_rows(); const long num = get_long(MOVMAG_NUMREG); for (int i = 1; r > 0 && i <= rows; i++) if ((*_doc)[i].is_articolo() && num == (*_doc)[i].get_long("MOVMAG")) r--; i--; if (i > rows) return NULL; const TString & codmag = (*_doc)[i].get("CODMAGC"); return codmag.empty() ? NULL : (const char *) codmag; } /////////////////////////////////////////////////////////// // Tipo documento /////////////////////////////////////////////////////////// TAssoc_array TTipo_documento::_formule_documento; TTipo_documento::TTipo_documento(const char* tipodoc) : TRectype(LF_TABCOM) { settab("TIP"); if (tipodoc && *tipodoc) read(tipodoc); } TTipo_documento::TTipo_documento(const TRectype& rec) : TRectype(rec) { read_formule(); } TTipo_documento::~TTipo_documento() { } int TTipo_documento::read(const char* tipodoc) { TTable t("%TIP"); put("CODTAB", tipodoc); int err = TRectype::read(t); _formule = ""; if (err == NOERR) read_formule(); else yesnofatal_box("Tipo documento errato: %s", tipodoc); return err; } void TTipo_documento::read_formule() { TFilename prof(profile_name()); prof.ext("ini"); TConfig profile(prof); _formule = profile.get("CAMPICALC", "MAIN"); _formule.add(profile.get("CALCOLI", "MAIN")); _totale = profile.get("TOTALE", "MAIN"); if (_totale.empty()) { _totale = "TOTDOC"; if (_formule.find(_totale) < 0) _formule.add("TOTDOC=IMPONIBILI()+IMPOSTE()"); } _totale_netto = "_"; _totale_netto << _totale; if (_totale.not_empty() && _formule.find(_totale) < 0) { error_box("Campo totale documento (%s) sconosciuto nel tipo documento %s", (const char *) _totale, (const char *) codice()); _totale.cut(0); } _basesconto = profile.get("BASESCONTO", "MAIN"); if (_basesconto.empty()) { _basesconto = "BASESCONTO"; if (_formule.find(_basesconto) < 0) _formule.add("BASESCONTO=SOMMA(\"IMPONIBILE()\", \"(TIPO() != 'S') && (TIPO() != 'C')\")"); } if (_basesconto.not_empty() && _formule.find(_basesconto) < 0) { error_box("Campo sconto documento (%s) sconosciuto nel tipo documento %s", (const char *) _basesconto, (const char *) codice()); _basesconto.cut(0); } _spese = profile.get("SPESE", "MAIN"); if (_spese.empty()) { _spese = "SPESE"; if (_formule.find(_spese) < 0) _formule.add("SPESE=SOMMA(\"IMPONIBILE()\", \"TIPO() != 'S'\")"); } if (_spese.not_empty() && _formule.find(_spese) < 0) { error_box("Campo spese (%s) sconosciuto nel tipo documento %s", (const char *) _spese, (const char *) codice()); _spese.cut(0); } } TFormula_documento * TTipo_documento::succ_formula(bool restart) { if (restart) _formule.restart(); const TString formula(_formule.get()); if (formula.not_empty()) { char *expr = NULL; const int p = formula.find("="); if (p > 0) { expr = (char *) (const char *) formula + p; *expr = '\0'; expr++; } TFormula_documento * o = (TFormula_documento*)_formule_documento.objptr(formula); if (o == NULL) { o = new TFormula_documento(_documento, formula, expr); _formule_documento.add(formula, o); } return o; } else return NULL; } /////////////////////////////////////////////////////////// // Documento per vendite /////////////////////////////////////////////////////////// TAssoc_array TDocumento::_tipi; TDocumento::TDocumento() : TAuto_variable_rectype(LF_DOC), _rows(LF_RIGHEDOC, "NRIGA"), _nuovo(TRUE), _condv(NULL), _rel(NULL), _sconto(NULL), _esenzione(NULL) { _tipocf = new TRecfield(*this, "TIPOCF"); _codcf = new TRecfield(*this, "CODCF"); _cod_occas = new TRecfield(*this, "OCFPI"); set_memo_fld("G1"); for (int i = 3 ; i >= 0; i--) _liv_len[i] = 0; } TDocumento::TDocumento(char provv, int anno, const char* codnum, long numdoc, TCond_vendita * condv, TRelation * rel) : TAuto_variable_rectype(LF_DOC), _rows(LF_RIGHEDOC, "NRIGA"), _nuovo(TRUE), _condv(condv), _rel(rel), _sconto(NULL), _esenzione(NULL) { _tipocf = new TRecfield(*this, "TIPOCF"); _codcf = new TRecfield(*this, "CODCF"); _cod_occas = new TRecfield(*this, "OCFPI"); set_memo_fld("G1"); if (numdoc <= 0) { numdoc = 0; set_key(*this, provv, anno, codnum, numdoc); TRiga_documento* key = new TRiga_documento(this); set_key(*key, provv, anno, codnum, numdoc); _rows.set_key(key); // ok } else read(provv, anno, codnum, numdoc); for (int i = 3 ; i >= 0; i--) _liv_len[i] = 0; } TDocumento::TDocumento(const TRectype& rec, TCond_vendita * condv, TRelation * rel) : TAuto_variable_rectype(LF_DOC), _rows(LF_RIGHEDOC, "NRIGA"), _nuovo(FALSE), _condv(condv), _rel(rel), _sconto(NULL), _esenzione(NULL) { _tipocf = new TRecfield(*this, "TIPOCF"); _codcf = new TRecfield(*this, "CODCF"); _cod_occas = new TRecfield(*this, "OCFPI"); set_memo_fld("G1"); read(rec); for (int i = 3 ; i >= 0; i--) _liv_len[i] = 0; } TDocumento::~TDocumento() { delete _tipocf; delete _codcf; delete _cod_occas; if (_sconto != NULL) delete _sconto; if (_esenzione != NULL) delete _esenzione; } real TDocumento::spese_incasso(real & imp, int ndec, TTipo_importo t) const { real imp_spese; real percentuale = get_real("PERCSPINC"); static TArray spese_inc; if (percentuale > ZERO) { if (spese_inc.objptr(_rim_dir) == NULL) { TConfig conf(CONFIG_STUDIO); for (TTipo_pag p = _rim_dir; p < _nessun_pag; p = (TTipo_pag) ((int)p + 1)) { real r(conf.get("IMPSPINC", "ve", p)); spese_inc.add(r, p); } } TPagamento & pag = ((TDocumento *)this)->pagamento(); const int nrate = pag.n_rate(); for (int i = 0; i < nrate; i++) { const TTipo_pag p = (TTipo_pag) pag.tipo_rata(i); imp_spese += (real &) spese_inc[p]; } imp_spese *= percentuale / 100.0; real cambio = get_real("CAMBIO"); if (cambio == ZERO) cambio = 1.0; static TString16 codiva; static long firm = -1; long new_firm = main_app().get_firm(); if (firm != new_firm) { TConfig conf(CONFIG_DITTA); codiva = conf.get("SPINCODIVA", "ve"); firm = new_firm; } 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, TTipo_importo t) const { real tot_bolli; static TArray sca_bolli; static TArray imp_bolli; static int nscagl; TLocalisamfile clifo(LF_CLIFO); bool estero = 2; if (get_bool("ADDBOLLI")) { real cambio = get_real("CAMBIO"); if (cambio == ZERO) cambio = 1.0; real importo = imp*cambio; TPagamento & pag = ((TDocumento*)this)->pagamento(); const int nrate = pag.n_rate(); real old_bolli = -1.00; 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 + 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; pag.set_total(imponibile, imposte, imp_spese); pag.set_rate_auto(); for (int i = 0; i < nrate; i++) { const TTipo_pag p = (TTipo_pag) pag.tipo_rata(i); real imp = pag.importo_rata(i); switch (p) { case _ric_ban: { if (sca_bolli.objptr(0) == NULL) { TConfig conf(CONFIG_STUDIO); for (nscagl = 0; nscagl < 7; nscagl++) { real s(conf.get("SPBOSCA", "ve", nscagl + 1)); real i(conf.get("SPBOIMP", "ve", nscagl + 1)); if (s == ZERO && i == ZERO) break; sca_bolli.add(s, nscagl); imp_bolli.add(i, nscagl); } } for (int i = 0; i < nscagl - 1; i++) if ((real &) sca_bolli[i] >= imp) break; if (imp_bolli.items() > 0) tot_bolli += (real &) imp_bolli[i]; } break; case _tratta: case _tratta_acc: { if (estero == 2) { clifo.put("TIPOCF", get("TIPOCF")); clifo.put("CODCF", get("CODCF")); if (clifo.read() != NOERR) clifo.zero(); const TString16 stato(clifo.get("STATOPAIV")); estero = stato.not_empty() && stato != "IT"; if (!estero) estero = clifo.get("STATOCF").not_empty() || clifo.get("COMCF")[0] == 'Z'; } real r(imp); r.ceil(-3); if (estero) r *= 0.009; else r *= 0.012; r.round(-2); tot_bolli += r; } break; case _cessione: case _paghero: case _let_cred: case _rim_dir: case _rid: case _bonfico: default: break; } } static TString16 codiva; static long firm = -1; long new_firm = main_app().get_firm(); if (firm != new_firm) { TConfig conf(CONFIG_DITTA); codiva = conf.get("SPBOCODIVA", "ve"); firm = new_firm; } iva_bolli = iva(tot_bolli, TRiga_documento::iva(codiva), ndec); 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); } return tot_bolli; } // Funzione statica utile a tutti gli utenti di LF_DOC e LF_RIGHEDOC void TDocumento::set_key(TRectype& rec, char provv, int anno, const char* codnum, long numdoc) { CHECK(provv == 'D' || provv == 'P', "Provvisorio o Definitivo?"); CHECKD(anno > 1900, "Anno non valido: ", anno); CHECK(codnum && *codnum, "Codice numerazione nullo"); CHECKD(numdoc >= 0, "Numero documento non valido ", numdoc); rec.put("PROVV", provv); rec.put("ANNO", anno); rec.put("CODNUM", codnum); rec.put("NDOC", numdoc); } // Funzione statica utile a tutti gli utenti di LF_DOC e LF_RIGHEDOC void TDocumento::copy_data(TRectype& dst, const TRectype& src) { // Memorizza tutti i campi chiave const char provv = dst.get_char("PROVV"); const int anno = dst.get_int("ANNO"); const TString16 codnum = dst.get("CODNUM"); const long numdoc = dst.get_long("NDOC"); const int nriga = dst.num() == LF_RIGHEDOC ? dst.get_int("NRIGA") : 0; // Copia tutto il record dst = src; // Ripristina tutti i campi chiave set_key(dst, provv, anno, codnum, numdoc); if (nriga > 0) dst.put("NRIGA", nriga); } void TDocumento::copy_contents(const TDocumento & src) { copy_data(head(), src.head()); destroy_rows(); const int rows = src.physical_rows(); for (int i = 0; i < rows ; i++) { const TRiga_documento & s = src[i]; TRiga_documento & r = new_row(s.tipo().codice()); copy_data(r, s); } } TRiga_documento& TDocumento::insert_row(int row, const char *tipo) { TRiga_documento * r = new TRiga_documento((const TRiga_documento &) _rows.key(), this); // ok r->set_numero(row); if (tipo) r->set_tipo(tipo); _rows.insert_row(r); // ok return *r; } TRiga_documento& TDocumento::new_row(const char *tipo) { TRiga_documento & r = (TRiga_documento&)_rows.row(-1, TRUE); // ok if (tipo) r.set_tipo(tipo); return r; } int TDocumento::read(TBaseisamfile& f, word op, word lockop) { TRiga_documento* key = new TRiga_documento(this); TRectype rec(*this); const char pr = tipo_numerazione(); const int an = anno(); const TString16 cn = numerazione(); const long nu = numero(); CHECK(nu > 0, "Numero documento nullo."); set_key(*key, pr, an, cn, nu); int err = TRectype::read(f); _cli_for.zero(); _occas.zero(); if (err != NOERR && op == _isequal) { _nuovo = TRUE; head() = rec; destroy_rows(); _rows.set_key(key); // ok } else { _nuovo = FALSE; _rows.read(key); //ok } set_riga_sconto(); if (is_fattura()) set_riga_esenzione(); return err; } int TDocumento::read(char provv, int anno, const char* codnum, long numdoc, word op, word lockop) { CHECK(numdoc > 0, "Numero documento nullo."); set_key(*this, provv, anno, codnum, numdoc); return read(op, lockop); } long TDocumento::renum(long numdoc) { if (numdoc <= 0) { const char tn = tipo_numerazione(); const int an = anno(); const TString16 nu = numerazione(); numdoc = get_next_key(tn, an, nu); } char num[16]; sprintf(num, "%ld", numdoc); renum_key("NDOC", num); // Aggiorna testata _rows.renum_key("NDOC", num); // Aggiorna righe ok return numdoc; } void TDocumento::set_riga_sconto() { const TString80 sconto(get("SCONTOPERC")); if (sconto.empty()) { if(_sconto != NULL) delete _sconto; _sconto = NULL; } else { if (_sconto == NULL) { static TString _tipo_riga_sc; if (_tipo_riga_sc.empty()) { TConfig conf(CONFIG_STUDIO); _tipo_riga_sc = conf.get("TRSCONTI", "ve"); } _sconto = new TRiga_documento(this, _tipo_riga_sc); _sconto->put("DESCR","Sconto"); } _sconto->put("SCONTO", sconto); } } void TDocumento::set_riga_esenzione() { TCli_for & c = clifor(); // const char tipo = get_char("TIPOCF"); // const long cod = get_long("CODCF"); // const TString80 occ(get("OCFPI")); // c.load(tipo, cod, occ); const TIVA codes(c.vendite().get(CFV_ASSFIS)); const TString16 v_esenzione(c.vendite().get(CFV_VSPROT)); const TString16 v_data_esenzione(c.vendite().get(CFV_VSDATAREG)); // const TString16 ufficio_IVA; ?? const TString16 n_registrazione(c.vendite().get(CFV_NSPROT)); const TString16 n_data_registrazione(c.vendite().get(CFV_NSDATAREG)); bool esente = codes.tipo().not_empty() && v_esenzione.not_empty() && v_data_esenzione.not_empty() && n_registrazione.not_empty() && n_data_registrazione.not_empty(); if (esente) { esente = FALSE; const TString16 codiva(codes.codice()); for (int i = physical_rows(); !esente && i > 0; i--) esente = codiva == row(i).get("CODIVA"); } if (!esente) { if(_esenzione != NULL) delete _esenzione; _esenzione = NULL; } else { static TString _tipo_riga_es; static real _bollo_es; if (_tipo_riga_es.empty()) { TConfig conf(CONFIG_STUDIO); _tipo_riga_es = conf.get("TRESENZ", "ve"); _bollo_es = (real)conf.get("BOLLIES", "ve"); } if (_esenzione == NULL) _esenzione = new TRiga_documento(this, _tipo_riga_es); TString d(256); d.format("Fattura non imponibile come da vostra dichiarazion"); _esenzione->put( "DESCR", d); /* rilasciata dall' ufficio IVA di %s*/ d.format("e n. %s del %s da noi annotata al n. %s il %s. Marca da bollo da Lit. %s sull' originale.", (const char *) v_esenzione, (const char *) v_data_esenzione, /*(const char *) ufficio_IVA, */(const char *) n_registrazione, (const char *) n_data_registrazione, _bollo_es.string(".")); _esenzione->put("DESCLUNGA", "X"); _esenzione->put("DESCEST", d); } } void TDocumento::dirty_fields() { for (TDocumento_variable_field * f = (TDocumento_variable_field *) first_variable_field(); f != NULL; f = (TDocumento_variable_field *) succ_variable_field()) f->set_dirty(); for (int i = rows(); i > 0; i--) { TRiga_documento & r = (TRiga_documento &) row(i); if (r.doc_dependent()) r.dirty_fields(FALSE); } } int TDocumento::write_rewrite(TBaseisamfile & f, bool re) const { const bool nuovo = _nuovo || numero() <= 0; // E' nuovo di zecca! const bool check_movmag = main_app().has_module(MGAUT, CHK_DONGLE) && tipo().mov_mag(); const TString16 statomag(tipo().stato_mov()); const bool do_movmag = get("STATO") >= statomag; if (nuovo && re) // quindi ... re = FALSE; // ... non fare la rewrite int err = NOERR; const TString80 occ_code(occas().get(OCC_CFPI)); ((TDocumento *)this)->put("OCFPI", occ_code); long num = get_long("MOVMAG"); const int rows = physical_rows(); if (check_movmag) { TMov_mag_doc mov(this); TLocalisamfile m(LF_MOVMAG); mov.zero(); if (num == 0 && do_movmag) { num = atol(mov.get_next_key()); mov.put(MOVMAG_NUMREG, num); while (mov.write(m) == _isreinsert) { num++; mov.put(MOVMAG_NUMREG, num); } ((TDocumento *)this)->put("MOVMAG", num); } if (num > 0) { mov.put(MOVMAG_NUMREG, num); while (mov.read(m, _isequal, _testandlock) == _islocked) message_box("Movimento di magazzino in uso da parte di un'altro utente"); if (do_movmag) { TRecord_array & b = mov.body(); const int mag_rows = mov.rows(); for (int i = mag_rows; i > 0; i--) { TRectype & r = b[i]; if (r.get_char(RMOVMAG_TIPORIGA) == riga_dadocumento) { b.destroy_row(i); if (b.exist(i + 1) && b[i + 1].get_char(RMOVMAG_TIPORIGA) == riga_automatica) b.destroy_row(i + 1); } } b.pack(); TDate d(get("DATADOC")); mov.put(MOVMAG_ANNOES, mov.codice_esercizio(d)); mov.put(MOVMAG_DATAREG, d); mov.put(MOVMAG_DATACOMP, d); mov.put(MOVMAG_DOCPROVV, get("PROVV")); mov.put(MOVMAG_ANNODOC, get("ANNO"));; mov.put(MOVMAG_CODNUM, get("CODNUM")); const long numdoc = get_long("NDOC"); mov.put(MOVMAG_NUMDOC, numdoc); mov.put(MOVMAG_CATVEN, get("CATVEN")); mov.put(MOVMAG_CODLIST, get("CODLIST")); mov.put(MOVMAG_CODCONT, get("CODCONT")); mov.put(MOVMAG_CODCAMP, get("CODCAMP")); mov.put(MOVMAG_CODCAUS, get("CAUSMAG")); mov.put(MOVMAG_DESCR, format("%s n.ro %ld del %s", (const char *) tipo().get("S1"), numdoc, (const char *) d.string())); mov.put(MOVMAG_TIPOCF, get("TIPOCF")); mov.put(MOVMAG_CODCF, get("CODCF")); int j = 1; for (i = 1; i <= rows; i++) { TRiga_documento & r = ((TDocumento *)this)->row(i); if (r.is_articolo()) { long r_num = r.get_long("MOVMAG"); if (r_num == 0) { r_num = num; r.put("MOVMAG", r_num); } if (r_num == num) { TRectype & rm = mov.insert_row(j++); rm.put(RMOVMAG_CODMAG, r.get("CODMAG")); rm.put(RMOVMAG_CODART, r.get("CODARTMAG")); rm.put(RMOVMAG_LIVGIAC, r.get("LIVELLO")); rm.put(RMOVMAG_UM, r.get("UMQTA")); rm.put(RMOVMAG_QUANT, r.get("QTA")); rm.put(RMOVMAG_PREZZO, r.get("PREZZO")); rm.put(RMOVMAG_CODCAUS, r.get("CAUSMAG")); rm.put(RMOVMAG_TIPORIGA, (char) riga_dadocumento); } } } mov.rewrite(m); } else { mov.remove(m); for (int i = rows; i > 0; i--) { TRiga_documento & r = ((TDocumento *) this)->row(i); long r_num = r.get_long("MOVMAG"); if (r_num == num) r.zero("MOVMAG"); } ((TDocumento *)this)->zero("MOVMAG"); } } TLocalisamfile anamag(LF_ANAMAG); TLocalisamfile codalt(LF_CODCORR); codalt.setkey(2); for (int i = rows; i > 0; i--) { TRiga_documento & r = ((TDocumento *) this)->row(i); if (!r.is_checked()) { const TString & codart = r.get("CODART"); anamag.put("CODART", codart); if (anamag.read() == NOERR) r.put("CODARTMAG", codart); else { codalt.put("CODARTALT", codart); if (codalt.read() == NOERR) r.put("CODARTMAG", codalt.get("CODART")); } r.checked(); } } } if (re) { err = _rows.write(re); if (err == NOERR) { err = TRectype::rewrite(f); if (err != NOERR) err = TRectype::write(f); } } else { if (nuovo) { TDocumento& myself = *(TDocumento*)this; if (numero() <= 0) myself.renum(); do { err = TRectype::write(f); if (err == _isreinsert) myself.renum(); } while (err == _isreinsert); myself._nuovo = FALSE; } else { err = TRectype::write(f); if (err != NOERR) err = TRectype::rewrite(f); } if (err == NOERR) err = _rows.write(re); } if (err == NOERR && clifor().occasionale() && occ_code.not_empty()) { TLocalisamfile o(LF_OCCAS); err = _occas.write(o); if (err == _isreinsert) err = _occas.rewrite(o); } return err; } // eliminare anche il mov di mag. ?????? int TDocumento::remove(TBaseisamfile& f) const { int err = _rows.remove(); if (err == NOERR) err = TRectype::remove(f); return err; } const bool TDocumento::in_valuta() const { const TString& val = valuta(); return (val.not_empty() && val != "LIT"); } TRiga_documento & TDocumento::row(int index) { const int nrows = _rows.rows(); TRiga_documento * r = NULL; if (index <= nrows) r = &((TRiga_documento &) _rows.row(index, FALSE)); else { CHECKD((index == nrows + 1 && (_sconto != NULL || _esenzione != NULL)) || (index == nrows + 2 && _sconto != NULL && _esenzione != NULL), "Riga documento non esistente ", index); if (index == nrows + 1) { r = _sconto != NULL ? _sconto : _esenzione; } if (index == nrows + 2) r = _esenzione; } return *r; } long TDocumento::get_next_key(char provv, int anno, const char* codnum) const { static long n = 0; if (n == 0) { TLocalisamfile doc(LF_DOC); TRectype& curr = doc.curr(); set_key(curr, provv, anno, codnum, 9999999L); const int err = doc.read(_isgreat); if (err != _isemptyfile) { if (err == NOERR) doc.prev(); if (curr.get_char("PROVV") == provv && curr.get_int("ANNO") == anno && curr.get("CODNUM") == codnum) n = curr.get_long("NDOC"); } } n++; return n; } const TTipo_documento& TDocumento::tipo() const { const TString16 tipodoc(get("TIPODOC")); CHECK(tipodoc.not_empty(), "Tipo documento nullo"); TTipo_documento * o = (TTipo_documento*)_tipi.objptr(tipodoc); if (o == NULL) { o = new TTipo_documento(tipodoc); _tipi.add(tipodoc, o); } return *o; } bool TDocumento::raggruppabile(const TDocumento& doc, TToken_string& campi) const { bool ok = raggruppabile() && doc.raggruppabile(); if (ok) { TString campo; for (const char* c = campi.get(0); c && ok; c = campi.get()) { campo = get(c); ok &= campo == doc.get(c); } } return ok; } void TDocumento::set_fields(TAuto_variable_rectype & rec) { if (tipo_valido()) { TTipo_documento & tipo_doc = (TTipo_documento &) tipo(); const TString16 tot_doc(tipo_doc.totale_doc()); for (const TFormula_documento * f = tipo_doc.first_formula(); f; f = tipo_doc.succ_formula()) { TExpr_documento * exp = f->expr(); if (tot_doc == f->name()) { TString work_tot_doc(tot_doc); 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()"; } 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 * 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(), tot_exp)); } else add_field(new TDocumento_variable_field(f->name(), exp)); if (exp) exp->set_doc(this); } } } real TDocumento::imponibile(bool spese, int ndec) const { 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(); 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(bool spese, int ndec) const { TAssoc_array ive; 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 { const TString16 field(tipo().totale_doc()); if (field.not_empty()) return get_real(field); else { real r = imponibile() + imposta(); r += spese_incasso(r, in_valuta() ? 3 : 0); r += bolli(r, in_valuta() ? 3 : 0); return r; } } real TDocumento::totale_netto() const { const TString16 field(tipo().totale_netto()); if (field.not_empty()) return get_real(field); else return imponibile() + imposta(); } real TDocumento::basesconto() const { const TString16 field(tipo().basesconto()); if (field.not_empty()) return get_real(field); else return ZERO; } real TDocumento::spese() const { const TString16 field(tipo().spese()); if (field.not_empty()) return get_real(field); else return ZERO; } TPagamento & TDocumento::pagamento() { const TString16 codpag(get("CODPAG")); if (codpag != _pag.code()) { _pag.set_code(codpag); _pag.read(); } return _pag; } void TDocumento::put_str(const char* fieldname, const char* val) { TString v(val); if (strcmp(fieldname, "TIPODOC") == 0 && TRectype::get("TIPODOC") != v) { TAuto_variable_rectype::put_str(fieldname, v); reset_fields(*this); set_fields(*this); } else { TAuto_variable_rectype::put_str(fieldname, v); dirty_fields(); if (strcmp(fieldname, "SCONTOPERC") == 0) set_riga_sconto(); } } void TDocumento::zero(const char * fieldname) { if (strcmp(fieldname, "TIPODOC") == 0) reset_fields(*this); TAuto_variable_rectype::zero(fieldname); dirty_fields(); } void TDocumento::zero(char c) { reset_fields(*this); TAuto_variable_rectype::zero(c); destroy_rows(); } TCli_for & TDocumento::clifor() const { const char tipo = tipocf(); const long codice = codcf(); if (_cli_for.empty() || _cli_for.tipo() != tipo || _cli_for.codice() != codice) ((TDocumento *) this)->_cli_for.read(tipo, codice); return (TCli_for &)_cli_for; } TOccasionale & TDocumento::occas() const { const TString80 occ_code(cod_occas()); if (_occas.empty() || strcmp(_occas.codice(), occ_code) != 0) { TLocalisamfile o(LF_OCCAS); ((TDocumento *) this)->_occas.zero(); ((TDocumento *) this)->_occas.put(OCC_CFPI, occ_code); TRectype oc(_occas); if (((TDocumento *) this)->_occas.read(o) != NOERR) ((TDocumento *) this)->_occas = oc; } return (TOccasionale &) _occas; } TDocumento & TDocumento::operator =(const TDocumento & d) { zero(); operator=((TRectype &)d); _rows = d._rows; set_riga_sconto(); if (is_fattura()) set_riga_esenzione(); set_relation(d._rel); set_condv(d._condv); return *this; } TRectype & TDocumento::operator =(const TRectype & r) { TRectype::operator=(r); reset_fields(*this); set_fields(*this); return *this; } TRectype & TDocumento::operator =(const char * r) { TRectype::operator=(r); reset_fields(*this); set_fields(*this); return *this; } void TDocumento::update_spese_aut(TString_array & spese_aut, bool preserve_old, TSheet_field * sh) { const bool interactive = sh != NULL; if (tipo().spese_aut()) { const int nrows = _rows.rows(); for (int i = nrows; i > 0; i--) { TRiga_documento & r = row(i); if (r.tipo().tipo() == RIGA_SPESEDOC && r.is_generata()) { if (preserve_old) return; destroy_row(i, TRUE); if (interactive) sh->destroy(i - 1); } } TString16 cod_iva_cli; const int nspese = spese_aut.items(); if (nspese > 0) { TLocalisamfile cfven(LF_CFVEN); cfven.put("TIPOCF", get("TIPOCF")); cfven.put("CODCF", get("CODCF")); if (cfven.read() == NOERR) cod_iva_cli = cfven.get("ASSFIS"); for (i = 0; i < nspese; i++) { const TString & s = spese_aut.row(i); TSpesa_prest sp(s); TString16 tipo(sp.tipo_riga()); TRiga_documento & riga = new_row(tipo); riga.put("CODART", s); riga.generata(); riga.put("DESCR", sp.descrizione()); switch (sp.tipo()) { case 'Q': { real qta = sp.qta(); if (qta == ZERO) qta = 1.0; riga.put("QTA", qta); } case 'V': { const real cambio = get_real("CAMBIO"); const TString16 valuta = get("CODVAL"); real prezzo = sp.prezzo(); sppr_calc(sp, valuta, cambio, prezzo); riga.put("PREZZO", prezzo); riga.put("UMQTA", sp.um()); } break; case 'P': default: break; } if (cod_iva_cli.empty()) riga.put("CODIVA", sp.cod_iva()); else riga.put("CODIVA", cod_iva_cli); if (interactive) { const int nrow = sh->insert(-1, FALSE); riga.autoload(*sh); sh->check_row(nrow); } } } } }