From f5b5873eba484d75f80fb815b4a0519577c72edd Mon Sep 17 00:00:00 2001 From: bonazzi Date: Wed, 31 Jan 2018 19:54:01 +0000 Subject: [PATCH] Patch level : 12.0 520 Files correlati : ve6.exe richieste da CRPA Non aggiornava il protocollo IVA se preso dal registro git-svn-id: svn://10.65.10.50/branches/R_10_00@24327 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- src/cg/cglib01.cpp | 2433 ++++++++++++++++++++++---------------------- src/cg/cglib01.h | 531 +++++----- 2 files changed, 1487 insertions(+), 1477 deletions(-) diff --git a/src/cg/cglib01.cpp b/src/cg/cglib01.cpp index 41e19de71..e4c02c2b9 100755 --- a/src/cg/cglib01.cpp +++ b/src/cg/cglib01.cpp @@ -1,1213 +1,1220 @@ -// Esercizi contabili e registri IVA - -#include "cglib01.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "comuni.h" - -/////////////////////////////////////////////////////////// -// Gestione Tabella esercizi -/////////////////////////////////////////////////////////// - -TArray TEsercizi_contabili::_esercizi; -long TEsercizi_contabili::_firm = 0; - -TEsercizio::TEsercizio(const TRectype& rec) -{ - _codice = rec.get_int("CODTAB"); - _inizio = rec.get("D0"); - _fine = rec.get("D1"); - _scarico = rec.get("D2"); - _chiusura = rec.get("D3"); - _chiusura_mag = rec.get("D4"); -} - -int TEsercizio::compare(const TSortable& s) const -{ - const TEsercizio& e = (const TEsercizio&)s; - int c = 0; - if (_inizio != e._inizio) - c = _inizio > e._inizio ? +1 : -1; - return c; -} - -const TDate& TEsercizio::chiusura() const -{ - if (!_chiusura.ok() && fine() < TDate(TODAY)) - { - TAssoc_array chiusure; // Lista delle causali di chiusura (solitamente una!) - TISAM_recordset caus("USE CAUS SELECT MOVAP='C'"); - for (bool ok = caus.move_first(); ok; ok = caus.move_next()) - { - const TString& codcaus = caus.get(CAU_CODCAUS).as_string(); - chiusure.add(codcaus, codcaus); - } - - const TDate presto = fine(); // Prima data utile per chiusura esercizio - TDate tardi = presto; tardi.addyear(); // Ultima data utile per chiusura esercizio - - TString query; - query = "USE MOV KEY 2"; - if (chiusure.items() == 1) - { - const TString& codcaus = *(TString*)chiusure.first_item(); - query << " SELECT CODCAUS='" << codcaus << '\''; - } - query << "\nFROM DATAREG=#PRESTO\nTO DATAREG=#TARDI"; - TISAM_recordset mov(query); - mov.set_var("#PRESTO", presto); - mov.set_var("#TARDI", tardi); - for (bool ok = mov.move_first(); ok; ok = mov.move_next()) - { - const TString& codcaus = mov.get(MOV_CODCAUS).as_string(); - if (chiusure.is_key(codcaus)) - { - const TDate datacomp = mov.get(MOV_DATACOMP).as_date(); - if (datacomp <= presto) - { - ((TDate&)_chiusura) = datacomp; // Forzatura - TTable esc("ESC"); - esc.put("CODTAB", codice()); - if (esc.read(_isequal, _lock) == NOERR) - { - esc.put("D3", datacomp); - esc.rewrite(); - } - } - break; - } - } - } - return _chiusura; -} - -TEsercizi_contabili::TEsercizi_contabili() -{ } - -void TEsercizi_contabili::update() -{ - _firm = prefix().get_codditta(); - _esercizi.destroy(); - TTable tab_esc("ESC"); - for (int err = tab_esc.first(); err == NOERR; err = tab_esc.next()) - { - TEsercizio* e = new TEsercizio(tab_esc.curr()); - _esercizi.add(e); - } - _esercizi.sort(); -} - -void TEsercizi_contabili::check() -{ - if (_firm != prefix().get_codditta()) - update(); -} - -int TEsercizi_contabili::date2index(const TDate& d) const -{ - int i = -1; - if (d.ok()) - { - check(); - for (i = items()-1; i >= 0; i--) - { - const TEsercizio& e = esc(i); - if (d >= e.inizio() && d <= e.fine()) - break; - } - } - return i; -} - -int TEsercizi_contabili::esc2index(int codice) const -{ - int i = -1; - if (codice > 0) - { - check(); - for (i = items()-1; i >= 0; i--) - { - const TEsercizio& e = esc(i); - if (codice == e.codice()) - break; - } - } - return i; -} - -int TEsercizi_contabili::date2esc(const TDate& d) const -{ - const int i = date2index(d); - return i >= 0 ? esc(i).codice() : 0; -} - -int TEsercizi_contabili::date2prevesc(const TDate& d) const -{ - const int i = date2index(d); - return i > 0 ? esc(i - 1).codice() : 0; -} - -int TEsercizi_contabili::date2nextesc(const TDate& d) const -{ - const int i = date2index(d); - return i >= 0 && i < items()-1 ? esc(i+1).codice() : 0; -} - -int TEsercizi_contabili::first() const -{ - check(); - return items() ? esc(0).codice() : 0; -} - -int TEsercizi_contabili::last() const -{ - check(); - return items() ? esc(items()-1).codice() : 0; -} - -// Certified 99% -int TEsercizi_contabili::last_mag() const -{ - check(); - int i; - - for (i = items()-1; i >= 0; i--) - { - const TEsercizio& e = esc(i); - if (e.chiusura_mag().ok()) - break; - } - return esc(i+1).codice(); -} - -int TEsercizi_contabili::pred(int codice) const -{ - const int i = esc2index(codice); - return i > 0 ? esc(i-1).codice() : 0; -} - -int TEsercizi_contabili::next(int anno) const -{ - const int i = esc2index(anno); - return i < items()-1 ? esc(i+1).codice() : 0; -} - -bool TEsercizi_contabili::exist(int codice) const -{ - const int i = esc2index(codice); - return i >= 0; -} - -const TEsercizio& TEsercizi_contabili::esercizio(int codice) const -{ - int i = esc2index(codice); - if (i < 0 && codice > 0) - { - error_box(FR("Attenzione! E' necessario aprire l'esercizio %d"), codice); - const int last_index = items()-1; - if (last_index >= 0) - { - TRectype rec(LF_TAB); rec.settab("ESC"); - const TEsercizio& last = esc(last_index); - const int last_code = last.codice(); - for (int k = last_code+1; k <= codice; k++) - { - rec.put("CODTAB", k); - TDate ini = last.inizio(); ini.set_year(ini.year()+k-last_code); - TDate fin = last.fine(); fin.set_year(fin.year()+k-last_code); - rec.put("D0", ini); - rec.put("D1", fin); - _esercizi.add(new TEsercizio(rec)); - } - } - else - { - if (codice > 2000) - { - TRectype rec(LF_TAB); rec.settab("ESC"); - rec.put("CODTAB", codice); - rec.put("D0", TDate(1,1,codice)); - rec.put("D1", TDate(31,12,codice)); - _esercizi.add(new TEsercizio(rec)); - } - } - - i = esc2index(codice); // Dovrei ritrovare l'ultimo - } - return esc(i); -} - -bool TEsercizi_contabili::code2range(int codice, TDate& dal, TDate& al) const -{ - bool ok = exist(codice); - if (ok) - { - const TEsercizio& e = esercizio(codice); - dal = e.inizio(); - al = e.fine(); - } - else - { - const int primo_esercizio = first(); - const int ultimo_esercizio = last(); - if (codice < primo_esercizio) - { - const TEsercizio& e = esercizio(primo_esercizio); - dal = e.inizio(); - al = e.fine(); - dal.addyear(primo_esercizio - codice); - al.addyear(primo_esercizio - codice); - ok = true; - } - if (codice > ultimo_esercizio) - { - const TEsercizio& e = esercizio(ultimo_esercizio); - dal = e.inizio(); - al = e.fine(); - dal.addyear(codice - ultimo_esercizio); - al.addyear(codice - ultimo_esercizio); - ok = true; - } - - if (!ok) - { - if (codice > 1900) - { - dal = TDate(1, 1, codice); - al = TDate(31, 12, codice); - ok = true; - } - else - dal = al = TDate(); - } - } - return ok; -} - -TEsercizi_contabili& esercizi() -{ - HIDDEN TEsercizi_contabili __esercizi; - return __esercizi; -} - -///////////////////////////////////////////////////////// -// Simpatici metodi jolly -///////////////////////////////////////////////////////// - -const char* iva2name(TipoIVA iva) -{ - const char* i; - switch(iva) - { - case nessuna_iva: - i = TR("Nessuna IVA"); break; - case iva_acquisti: - i = TR("IVA Acquisti"); break; - case iva_vendite: - i = TR("IVA Vendite"); break; - case iva_generica: - i = TR("IVA Generica"); break; - default: - i = TR("IVA ERRATA!"); break; - } - return i; -} - -const TString& cap2comune(const TString& cap, const TString& denom) -{ - TString80 up_denom = denom; - up_denom.upper(); - TString4 codone; - - if (cap.len() == 5 && up_denom.full()) - { - TString8 cappone = cap; - if (cappone[2] == '1') //e' un capoluogo di provincia - cappone.overwrite("00", 3, 2); - - TRelation relcom(LF_COMUNI); - TRectype& comrec = relcom.curr(); - comrec.put(COM_CAPCOM, cappone); - - TCursor comuni (&relcom, "", 3, &comrec, &comrec); - const TRecnotype items = comuni.items(); - comuni.freeze(); - double cmp = 0.69; - for (comuni = 0L; comuni.pos() < items; ++comuni) - { - TString80 denominazione = comrec.get(COM_DENCOM); - denominazione.upper(); - const double fc = xvt_str_fuzzy_compare (up_denom, denominazione); - if (fc > cmp) - { - codone = comrec.get(COM_COM); - cmp = fc; - } - } - } - if (codone.blank() && denom.full()) - { - TLocalisamfile comuni(LF_COMUNI); - comuni.setkey(2); - comuni.put(COM_DENCOM, denom); - if (comuni.read() == NOERR) - codone = comuni.get(COM_COM); - else - { - double cmp = 0.9; - comuni.zero(); - const TString4 pref = up_denom.left(4); - comuni.put(COM_DENCOM, pref); - for (int err = comuni.read(_isgteq); err == NOERR; err = comuni.next()) - { - TString80 denominazione = comuni.get(COM_DENCOM); - denominazione.upper(); - if (!denominazione.starts_with(pref)) - break; - const double fc = xvt_str_fuzzy_compare(up_denom, denominazione); - if (fc > cmp) - { - cmp = fc; - codone = comuni.get(COM_COM); - } - } - } - } - - return codone.full() ? (get_tmp_string() = codone) : EMPTY_STRING; -} - -/////////////////////////////////////////////////////////// -// Registro -/////////////////////////////////////////////////////////// - -TRegistro::TRegistro(const char* cod, int year) - : _rec(LF_TAB), _att(LF_ATTIV) -{ read(cod, year); } - -TRegistro::TRegistro(const TRegistro & reg) - : _rec(LF_TAB), _att(LF_ATTIV) -{ - const int year = atoi(reg._rec.get("CODTAB").sleft(4)); - const TString8 cod = reg._rec.get("CODTAB").smid(4); - - read(cod, year); -} - -bool TRegistro::read(const char* cod, int year) -{ - if (year <= 0) - { - const TDate oggi(TODAY); - year = oggi.year(); - } - if (cod == NULL) - cod = ""; - - TString8 chiave; chiave.format("%04d%s", year, cod); - _rec = cache().get("REG", chiave); - read_att(); - - return !_rec.empty(); -} - -bool TRegistro::force_read(const char* cod, int year) -{ - TString8 chiave; chiave.format("%04d%s", year, cod); - - cache().discard("REG", chiave); - return read(cod, year); -} - -bool TRegistro::reread() -{ - if (ok()) - { - const TString8 n(name()); - const int y = year(); - return read(n, y); - } - return false; -} - -int TRegistro::year() const -{ - const TString& anno = _rec.get("CODTAB").left(4); - return atoi(anno); -} - -const TString& TRegistro::name() const -{ - return _rec.get("CODTAB").mid(4); -} - -TRegistro& TRegistro::operator =(const TRegistro& r) -{ - _rec = r._rec; - _att = r._att; - _prorata = r._prorata; - return *this; -} - -int TRegistro::tipo() const -{ - const int t = _rec.get_int("I0"); - return t; -} - -bool TRegistro::corrispettivi() const -{ - const bool c = _rec.get_bool("B0"); - return c; -} - -TipoIVA TRegistro::iva() const -{ - TipoIVA i = (TipoIVA)tipo(); - switch (i) - { - case nessuna_iva: - case iva_vendite: - case iva_acquisti: - break; - case libro_giornale: - i = nessuna_iva; - break; - default: - error_box(FR("Il registro '%s' non e' un registro IVA o contabile: tipo %d"), - (const char*)name(), i); - i = nessuna_iva; - break; - } - return i; -} - -bool TRegistro::read_att() -{ - TString16 chiave; - chiave << prefix().get_codditta() << '|' << attivita(); - - _att = cache().get(LF_ATTIV, chiave); - // Ditta - Anno - Attivitā - Tipo Attivitā (fissata a 1) - chiave.format("%05ld", prefix().get_codditta()); - chiave << year(); // non fare << year() << attivita() - chiave << attivita() << "1"; - - _prorata.destroy(); - - const TRectype& pla = cache().get("%PLA", chiave); - if (!pla.empty()) - { - chiave.format("%d", year()); - _prorata.add(chiave, pla.get_real("R8")); - _att.put("TIPOATT", pla.get("S7")); // Aggiorna tipo attivitā - } - - return !_att.empty(); -} - -bool TRegistro::agenzia_viaggi() const -{ - return _att.get_bool("REG74TER") && (iva() == iva_vendite); -} - -const TString& TRegistro::tipo_attivita() const -{ - return _att.get("TIPOATT"); -} - -real* TRegistro::read_prorata(int anno) const -{ - TString16 chiave; // Ditta - Anno - Attivitā - Tipo Attivitā (fissata a 1) - chiave.format("%05ld", prefix().get_codditta()); - chiave << anno << attivita() << "1"; - - real* prorata = NULL; - const TRectype& pla = cache().get("%PLA", chiave); - if (!pla.empty()) - prorata = new real(pla.get("R8")); - - return prorata; -} - -real TRegistro::prorata(int annodoc) -{ - const int annoiva = year(); - if (annodoc <= 1900) annodoc = annoiva; // Test per anno documento non specificato - const int annopro = annoiva >= 1998 && annodoc < annoiva ? annodoc+1 : annoiva; - - TString16 chiave; chiave << annopro; - real* pr = (real*)_prorata.objptr(chiave); - - if (pr == NULL) - { - pr = read_prorata(annopro); - if (pr == NULL && annopro != annoiva) - pr = read_prorata(annoiva); - - if (pr == NULL) - pr = new real(ZERO); - _prorata.add(chiave, pr, true); - } - - return *pr; -} - -void TRegistro::set_prorata(int annodoc, const real& pro) -{ - const int annoiva = year(); - if (annodoc <= 2000) annodoc = annoiva; // Test per anno documento non specificato - const int annopro = annodoc < annoiva ? annodoc+1 : annoiva; - TString4 chiave; chiave << annopro; - _prorata.add(chiave, pro, true); -} - -// Certified 99% -bool TRegistro::update(long protiva, const TDate& datareg) -{ - bool updated = true; - - if (protiva > _rec.get_long("I5")) - { - _rec.put("I5", protiva); - updated = false; - } - if (datareg > _rec.get_date("D2")) - { - _rec.put("D2", datareg); - updated = false; - } - if (!updated) - { - TTable reg("REG"); - updated = reg.rewrite(_rec) == NOERR; - cache().discard(_rec); // Forza rilettura registro in cache - } - - return updated; -} - -/////////////////////////////////////////////////////////// -// Libro giornale -/////////////////////////////////////////////////////////// - -// Legge il libro giornale dell'anno specificato -bool TLibro_giornale::read(int y) -{ - bool found = false; - - if (y <= 0) - { - TEsercizi_contabili esc; - const int lastes = esc.last(); - if (lastes > 0) - y = esc[lastes].inizio().year(); - else - y = TDate(TODAY).year(); - } - - TString4 anno; anno.format("%04d", y); - TTable reg("REG"); - reg.put("CODTAB", anno); // Cerca il primo registro dell'anno - - for (int err = reg.read(_isgteq); err == NOERR; err = reg.next()) - { - if (reg.get("CODTAB").compare(anno, 4) != 0) - break; // Sono arrivato all'anno dopo - - if (reg.get_int("I0") == libro_giornale) - { - found = true; - break; - } - } - - if (!found) reg.zero(); // Memorizza record (anche vuoto) - _rec = reg.curr(); - - return found; -} - -TLibro_giornale::TLibro_giornale(int y) -{ - read(y); -} - -/////////////////////////////////////////////////////////// -// Codice IVA -/////////////////////////////////////////////////////////// - -TCodiceIVA::TCodiceIVA(const char* cod) : TRectype(LF_TABCOM) -{ - read(cod); -} - -int TCodiceIVA::tipo_indetraibilita() const -{ - int tipo = 0; - const TString& codind = indetraibilita(); // Codice indetraibilitā alfanumerico (ex. 1, 3, 9) - if (codind.full()) - { - const TRectype& det = cache().get("%DET", codind); - if (det.empty()) - tipo = atoi(codind); - else - tipo = det.get_int("I0"); - } - return tipo; // Tipo indetraibilitā: 1,3,9 -} - -bool TCodiceIVA::read(const char* cod) -{ - if (cod && *cod) - *this = cache().get("%IVA", cod); - else - zero(); - - return !empty(); -} - -void TCodiceIVA::round(real& n, int ndec, const char* codval) const -{ - switch (ndec) - { - case AUTO_DECIMALS : ndec = (codval && *codval) ? TExchange(codval).decimals(false) : 2; break; - case AUTO_PRICES_DECIMALS: ndec = TExchange(codval).decimals(true); break; - default : break; - } - if (ndec < 10) - n.round(ndec); -} - -real TCodiceIVA::imposta(const real& imponibile, int ndec, const char* codval) const -{ - real iva = imponibile * percentuale() / CENTO; - round(iva, ndec, codval); - return iva; -} - -real TCodiceIVA::scorpora(real& lordo, int ndec, const char* codval) const -{ - round(lordo, ndec, codval); // Arrotondo importo lordo - real imponibile = lordo * CENTO / (CENTO + percentuale()); - round(imponibile, ndec, codval); // Arrotondo importo netto - const real iva = lordo - imponibile; - lordo = imponibile; // lordo č un reference da aggiornare con l'imponibile! - return iva; -} - -real TCodiceIVA::lordo(const real& imponibile, int ndec, const char* codval) const -{ return imponibile + imposta(imponibile, ndec, codval); } - -/////////////////////////////////////////////////////////// -// TBill -/////////////////////////////////////////////////////////// - -TBill::~TBill() -{ - if (_descrizione) - delete _descrizione; -} - -void TBill::set_description(const char* d) -{ - if (_descrizione || (d && *d)) - { - if (_descrizione) - *_descrizione = d; - else - _descrizione = new TString(d); - } -} - -// Certified 90% -const TBill& TBill::get(TToken_string& s, int from, int mode) -{ - const char* first = s.get(from); - if (mode & 0x1) - { - _tipo = first ? char(toupper(*first)) : ' '; - first = s.get(); - } - else - _tipo = ' '; - - if (strchr(" CF", _tipo) == NULL) - { -#ifdef DBG - error_box(FR("Tipo conto errato: '%c'"), _tipo); -#endif - _tipo = ' '; - } - - _gruppo = first ? atoi(first) : 0; - _conto = s.get_int(); - _sottoconto = s.get_long(); - if (mode & 0x2) - set_description(s.get()); - - _tipo_cr = -1; - _sezione = ' '; - - return *this; -} - -const TBill& TBill::copy(const TBill& bill) -{ - _tipo = bill._tipo; - _gruppo = bill._gruppo; - _conto = bill._conto; - _sottoconto = bill._sottoconto; - set_description(bill.descrizione()); - _tipo_cr = bill._tipo_cr; - _sospeso = bill._sospeso; - _sezione = bill._sezione; - return *this; -} - -// Certified 100% -const TBill& TBill::set(int g, int c, long s, char t, const char* d, int r) -{ - _tipo = (t > ' ') ? char(toupper(t)) : ' '; - _gruppo = g; - _conto = c; - _sottoconto = s; - set_description(d); - _tipo_cr = r; - return *this; -} - -const TBill& TBill::add_to(TToken_string& ts, int from, int mode) -{ - if (mode & 0x4) - { - const int cr = tipo_cr(); - if (cr > 0) ts.add(cr, from++); else ts.add(" ", from++); - } - - if (mode & 0x1) - ts.add(_tipo, from++); - - if (_gruppo > 0) ts.add(_gruppo, from++); else ts.add(" ", from++); - if (_conto > 0) ts.add(_conto, from++); else ts.add(" ", from++); - if (_sottoconto > 0L) ts.add(_sottoconto, from++); else ts.add(" ", from++); - - if (mode & 0x2) - ts.add(descrizione(), from++); - - return *this; -} - - -const char* TBill::field_name(int n, const TRectype& r, bool contro) const -{ - CHECKD(n >= 0 && n <= 3, "Invalid bill field ", n); - - const char* f = NULL; - if (contro) - { - CHECKD(r.num() == LF_RMOV || r.num() == LF_PAGSCA, "Record non valido per contropartita: ", r.num()); - switch(n) - { - case 0: f = RMV_GRUPPOC; break; - case 1: f = RMV_CONTOC; break; - case 2: f = RMV_SOTTOCONTOC; break; - default:f = RMV_TIPOCC; break; - } - } - else - { - switch(n) - { - case 0: f = RMV_GRUPPO; break; - case 1: f = RMV_CONTO; break; - case 2: - if (r.num() == LF_CLIFO) - f = CLI_CODCF; - else - f = RMV_SOTTOCONTO; - break; - default: - switch(r.num()) - { - case LF_CLIFO : f = CLI_TIPOCF; break; - case LF_RCAUSALI: f = RCA_TIPOCF; break; - default : f = RMV_TIPOC; break; - } - break; - } - } - return f; -} - -void TBill::put(TRectype& r, bool c) const -{ - r.put(field_name(0, r, c), gruppo()); - r.put(field_name(1, r, c), conto()); - r.put(field_name(2, r, c), sottoconto()); - r.put(field_name(3, r, c), tipo()); -} - -bool TBill::get(const TRectype& r, bool c) -{ - char t = ' '; - if (r.type(field_name(3, r, c)) != _nullfld) - t = r.get_char(field_name(3, r, c)); - - set(r.get_int(field_name(0, r, c)), - r.get_int(field_name(1, r, c)), - r.get_long(field_name(2, r, c)), - t); - - set_description(NULL); - _tipo_cr = -1; - _sezione = ' '; - - if (r.num() == LF_RMOVIVA) - tipo_cr(r.get_int(RMI_TIPOCR)); - - return ok(); -} - -void TBill::set(TMask& m, short g, short c, short s, short t, short d) const -{ - if (g > 0) - m.set(g, gruppo()); - if (c > 0) - m.set(c, conto()); - if (s > 0) - m.set(s, sottoconto()); - if (t > 0) - { - char typ[2] = { tipo(), '\0' }; - m.set(t, typ); - } - if (d > 0) - m.set(d, descrizione()); -} - -void TBill::get(const TMask& m, short g, short c, short s, short t, short d) -{ - const int gr = m.get_int(g); - const int co = m.get_int(c); - const long so = s > 0 ? m.get_long(s) : 0L; - char ti = ' '; - if (t) - ti = m.get(t)[0]; - TString80 de; - if (d) - de = m.get(d); - set(gr, co, so, ti, de); -} - -// Certified 100% -bool TBill::ok() const -{ - return _gruppo != 0 && _conto != 0 && _sottoconto != 0L; -} - -// Certified 99% -int TBill::compare(const TSortable& s) const -{ - CHECK(class_name()==s.class_name(), "Can't compare TBill with TObject"); - const TBill& c = (const TBill&)s; - - int res = _gruppo - c._gruppo; - if (res) return res; - - res = _conto - c._conto; - if (res) return res; - - const long lres = _sottoconto - c._sottoconto; - if (lres < 0L) res = -1; else - if (lres > 0L) res = +1; - - return res; -} - -// Certified 95% -bool TBill::find() -{ - bool ok = false; - - if ((_tipo != 'C' && _tipo != 'F') || _sottoconto == 0L) - { - TRectype pcon(LF_PCON); - ok = read(pcon); - if (!ok && _sottoconto != 0L) - { - const long sotto = _sottoconto; - _sottoconto = 0L; - if (read(pcon)) - _tipo = char(toupper(pcon.get_char(PCN_TMCF))); - _sottoconto = sotto; - } - } - - if ((_tipo == 'C' || _tipo == 'F') && _sottoconto != 0L) - { - TString16 key; - key.format("%c|%ld", _tipo, _sottoconto); - const TRectype& clifo = cache().get(LF_CLIFO, key); - ok = !clifo.empty(); - if (ok) - { - set_description(clifo.get(CLI_RAGSOC)); - if (_tipo_cr < 0) - { - _tipo_cr = 0; - _sezione = ' '; - } - _sospeso = clifo.get_bool(CLI_SOSPESO); - - const char tipoa = clifo.get_char(CLI_TIPOPERS); - if (tipoa == 'F') // Se persona fisica allora aggiusta la ragione sociale - { - TString nome(descrizione().mid(30)); - if (nome.full()) - { - _descrizione->cut(30); - _descrizione->trim(); nome.trim(); - *_descrizione << ' ' << nome; - } - } - if (_gruppo == 0 || _conto == 0) - { - _gruppo = clifo.get_int(CLI_GRUPPO); - _conto = clifo.get_int(CLI_CONTO); - } - } - } - return ok; -} - - -bool TBill::read(TRectype &r) -{ - bool ok = false; - - if (tipo() <= ' ' || sottoconto() <= 0) - { - const char* key = string(); - const TRectype& pcon = cache().get(LF_PCON, key); - if (!pcon.empty()) - { - r = pcon; - ok = true; - } - } - if (ok) - { - _tipo_cr = r.get_int(PCN_TIPOSPRIC); - _sezione = r.get_char(PCN_SEZSALDI); - set_description(r.get(PCN_DESCR)); - _sospeso = r.get_bool(PCN_SOSPESO); - } - else - r.zero(); - - return ok; -} - -int TBill::tipo_att() -{ - int tipo_att = 1; - if (tipo() <= ' ' && ok()) - { - TBill bill(gruppo(), conto()); - TRectype rec(LF_PCON); bill.read(rec); - const TIndbil ib = (TIndbil)rec.get_int(PCN_INDBIL); - if (ib == ib_passivita || ib == ib_ricavi) - { - read(rec); - const int ricser = rec.get_int(PCN_RICSER); // 0 = Altre attivita 1 = Servizi - tipo_att = (ricser == 1) ? 1 : 2; - } - } - return tipo_att; -} - -// Certified 99% -const TString& TBill::descrizione() const -{ - TBill& myself = (TBill&)*this; - // Se il conto e' valido (c'e' almeno il gruppo) cerca la sua descrizione su file - if ((_descrizione == NULL || _descrizione->blank()) && - (gruppo() != 0 || (tipo() > ' ' && codclifo()>0))) - { - if (!myself.find()) - myself.set_description(TR("Sconosciuto")); - } - - return _descrizione ? *_descrizione : (const TString&) EMPTY_STRING; -} - -int TBill::tipo_cr() const -{ - if (_tipo_cr < 0) - { - TBill& myself = (TBill&)*this; - myself.find(); - } - return _tipo_cr; -} - -int TBill::indicatore_bilancio() const -{ - TString8 str; - str.format("%d|%d", gruppo(), conto()); - const int ib = atoi(cache().get(LF_PCON, str, PCN_INDBIL)); - if (ib <= 0) - { - TString msg = str; - msg.replace('|', '.'); - msg.insert(TR("Impossibile stabilire l'indicatore di bilancio del conto ")); - NFCHECK(msg); - } - return ib; -} - - -bool TBill::sospeso() const -{ - if (_tipo_cr < 0) tipo_cr(); // trick to load _sospeso - return _sospeso; -} - -char TBill::sezione() const -{ - if (_sezione == ' ') tipo_cr(); // trick to load _sezione - return _sezione; -} - -// Certified 100% -const char* TBill::string(int mode) const -{ - TString& s = get_tmp_string(); - - if (mode & 0x8) - { - if (_sottoconto != 0) - s.format("%03d%03d%06ld", _gruppo, _conto, _sottoconto); else - if (_conto != 0) - s.format("%03d%03d", _gruppo, _conto); else - if (_gruppo != 0) - s.format("%03d", _gruppo); - return s; - } - - if (mode & 0x4) - { - const int cr = tipo_cr(); - if (cr > 0) s << cr << '|'; - else s << " |"; - } - - if (mode & 0x1) - s << _tipo << '|'; - - if (_gruppo > 0) s << _gruppo << '|'; - else s << " |"; - - if (_conto > 0) s << _conto << '|'; - else s << " |"; - - if (_sottoconto > 0L) s << _sottoconto; - else s << ' '; - - if (mode & 0x2) - s << '|' << descrizione(); - - return s; -} - -bool TBill::required_cdc() const -{ - TString16 key; - for (int i = 2; i >= 0; i--) - { - key.format("%d|%d|%ld", gruppo(), i > 0 ? conto() : 0, i > 1 ? sottoconto() : 0); - const TRectype& sottoc = cache().get(LF_PCON, key); - if (sottoc.get_bool(PCN_CMSNEEDED)) - return true; - } - return false; -} - -bool TBill::default_cdc(TString& cdc, TString& fas) const -{ - bool ok = tipo() <= ' ' && sottoconto() > 0; - if (ok) - { - TString16 key; - for (int i = 2; i >= 0; i--) - { - key.format("%d|%d|%ld", gruppo(), i > 0 ? conto() : 0, i > 1 ? sottoconto() : 0); - const TRectype& pcon = cache().get(LF_PCON, key); - if (!pcon.empty()) - { - cdc = pcon.get(PCN_CODCMS); - fas = pcon.get(PCN_FASCMS); - if (cdc.not_empty() || fas.not_empty()) - break; - } - } - } - return ok && (cdc.not_empty() || fas.not_empty()); -} - -bool TBill::is_analitico() const -{ - TString16 key; - - for (int i = 2; i >= 0; i--) - { - key.format("%d|%d|%ld", gruppo(), i > 0 ? conto() : 0, i > 1 ? sottoconto() : 0); - const TRectype& picone = cache().get(LF_PCON, key); - if (picone.get_bool(PCN_ANALITICA)) - return true; - } - return false; -} - -const char* num2str(const TString& s) -{ - TString& str = get_tmp_string(20); - - str = s; - str.trim(); - if (str.len() > 2) - { - str = s.left(2); - const int sub = atoi(s.mid(2, 2)); - switch (sub) - { - case 2: str << " bis"; break; - case 3: str << " ter";break; - case 4: str << " quater"; break; - case 5: str << " quinquies"; break; - case 6: str << " sexies"; break; - default: break; - } - const TString& sotsub = s.mid(4); - if (sotsub.full()) - str << ' ' << sotsub; - } - return (const char*)str; -} - +// Esercizi contabili e registri IVA + +#include "cglib01.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "comuni.h" + +/////////////////////////////////////////////////////////// +// Gestione Tabella esercizi +/////////////////////////////////////////////////////////// + +TArray TEsercizi_contabili::_esercizi; +long TEsercizi_contabili::_firm = 0; + +TEsercizio::TEsercizio(const TRectype& rec) +{ + _codice = rec.get_int("CODTAB"); + _inizio = rec.get("D0"); + _fine = rec.get("D1"); + _scarico = rec.get("D2"); + _chiusura = rec.get("D3"); + _chiusura_mag = rec.get("D4"); +} + +int TEsercizio::compare(const TSortable& s) const +{ + const TEsercizio& e = (const TEsercizio&)s; + int c = 0; + if (_inizio != e._inizio) + c = _inizio > e._inizio ? +1 : -1; + return c; +} + +const TDate& TEsercizio::chiusura() const +{ + if (!_chiusura.ok() && fine() < TDate(TODAY)) + { + TAssoc_array chiusure; // Lista delle causali di chiusura (solitamente una!) + TISAM_recordset caus("USE CAUS SELECT MOVAP='C'"); + for (bool ok = caus.move_first(); ok; ok = caus.move_next()) + { + const TString& codcaus = caus.get(CAU_CODCAUS).as_string(); + chiusure.add(codcaus, codcaus); + } + + const TDate presto = fine(); // Prima data utile per chiusura esercizio + TDate tardi = presto; tardi.addyear(); // Ultima data utile per chiusura esercizio + + TString query; + query = "USE MOV KEY 2"; + if (chiusure.items() == 1) + { + const TString& codcaus = *(TString*)chiusure.first_item(); + query << " SELECT CODCAUS='" << codcaus << '\''; + } + query << "\nFROM DATAREG=#PRESTO\nTO DATAREG=#TARDI"; + TISAM_recordset mov(query); + mov.set_var("#PRESTO", presto); + mov.set_var("#TARDI", tardi); + for (bool ok = mov.move_first(); ok; ok = mov.move_next()) + { + const TString& codcaus = mov.get(MOV_CODCAUS).as_string(); + if (chiusure.is_key(codcaus)) + { + const TDate datacomp = mov.get(MOV_DATACOMP).as_date(); + if (datacomp <= presto) + { + ((TDate&)_chiusura) = datacomp; // Forzatura + TTable esc("ESC"); + esc.put("CODTAB", codice()); + if (esc.read(_isequal, _lock) == NOERR) + { + esc.put("D3", datacomp); + esc.rewrite(); + } + } + break; + } + } + } + return _chiusura; +} + +TEsercizi_contabili::TEsercizi_contabili() +{ } + +void TEsercizi_contabili::update() +{ + _firm = prefix().get_codditta(); + _esercizi.destroy(); + TTable tab_esc("ESC"); + for (int err = tab_esc.first(); err == NOERR; err = tab_esc.next()) + { + TEsercizio* e = new TEsercizio(tab_esc.curr()); + _esercizi.add(e); + } + _esercizi.sort(); +} + +void TEsercizi_contabili::check() +{ + if (_firm != prefix().get_codditta()) + update(); +} + +int TEsercizi_contabili::date2index(const TDate& d) const +{ + int i = -1; + if (d.ok()) + { + check(); + for (i = items()-1; i >= 0; i--) + { + const TEsercizio& e = esc(i); + if (d >= e.inizio() && d <= e.fine()) + break; + } + } + return i; +} + +int TEsercizi_contabili::esc2index(int codice) const +{ + int i = -1; + if (codice > 0) + { + check(); + for (i = items()-1; i >= 0; i--) + { + const TEsercizio& e = esc(i); + if (codice == e.codice()) + break; + } + } + return i; +} + +int TEsercizi_contabili::date2esc(const TDate& d) const +{ + const int i = date2index(d); + return i >= 0 ? esc(i).codice() : 0; +} + +int TEsercizi_contabili::date2prevesc(const TDate& d) const +{ + const int i = date2index(d); + return i > 0 ? esc(i - 1).codice() : 0; +} + +int TEsercizi_contabili::date2nextesc(const TDate& d) const +{ + const int i = date2index(d); + return i >= 0 && i < items()-1 ? esc(i+1).codice() : 0; +} + +int TEsercizi_contabili::first() const +{ + check(); + return items() ? esc(0).codice() : 0; +} + +int TEsercizi_contabili::last() const +{ + check(); + return items() ? esc(items()-1).codice() : 0; +} + +// Certified 99% +int TEsercizi_contabili::last_mag() const +{ + check(); + int i; + + for (i = items()-1; i >= 0; i--) + { + const TEsercizio& e = esc(i); + if (e.chiusura_mag().ok()) + break; + } + return esc(i+1).codice(); +} + +int TEsercizi_contabili::pred(int codice) const +{ + const int i = esc2index(codice); + return i > 0 ? esc(i-1).codice() : 0; +} + +int TEsercizi_contabili::next(int anno) const +{ + const int i = esc2index(anno); + return i < items()-1 ? esc(i+1).codice() : 0; +} + +bool TEsercizi_contabili::exist(int codice) const +{ + const int i = esc2index(codice); + return i >= 0; +} + +const TEsercizio& TEsercizi_contabili::esercizio(int codice) const +{ + int i = esc2index(codice); + if (i < 0 && codice > 0) + { + error_box(FR("Attenzione! E' necessario aprire l'esercizio %d"), codice); + const int last_index = items()-1; + if (last_index >= 0) + { + TRectype rec(LF_TAB); rec.settab("ESC"); + const TEsercizio& last = esc(last_index); + const int last_code = last.codice(); + for (int k = last_code+1; k <= codice; k++) + { + rec.put("CODTAB", k); + TDate ini = last.inizio(); ini.set_year(ini.year()+k-last_code); + TDate fin = last.fine(); fin.set_year(fin.year()+k-last_code); + rec.put("D0", ini); + rec.put("D1", fin); + _esercizi.add(new TEsercizio(rec)); + } + } + else + { + if (codice > 2000) + { + TRectype rec(LF_TAB); rec.settab("ESC"); + rec.put("CODTAB", codice); + rec.put("D0", TDate(1,1,codice)); + rec.put("D1", TDate(31,12,codice)); + _esercizi.add(new TEsercizio(rec)); + } + } + + i = esc2index(codice); // Dovrei ritrovare l'ultimo + } + return esc(i); +} + +bool TEsercizi_contabili::code2range(int codice, TDate& dal, TDate& al) const +{ + bool ok = exist(codice); + if (ok) + { + const TEsercizio& e = esercizio(codice); + dal = e.inizio(); + al = e.fine(); + } + else + { + const int primo_esercizio = first(); + const int ultimo_esercizio = last(); + if (codice < primo_esercizio) + { + const TEsercizio& e = esercizio(primo_esercizio); + dal = e.inizio(); + al = e.fine(); + dal.addyear(primo_esercizio - codice); + al.addyear(primo_esercizio - codice); + ok = true; + } + if (codice > ultimo_esercizio) + { + const TEsercizio& e = esercizio(ultimo_esercizio); + dal = e.inizio(); + al = e.fine(); + dal.addyear(codice - ultimo_esercizio); + al.addyear(codice - ultimo_esercizio); + ok = true; + } + + if (!ok) + { + if (codice > 1900) + { + dal = TDate(1, 1, codice); + al = TDate(31, 12, codice); + ok = true; + } + else + dal = al = TDate(); + } + } + return ok; +} + +TEsercizi_contabili& esercizi() +{ + HIDDEN TEsercizi_contabili __esercizi; + return __esercizi; +} + +///////////////////////////////////////////////////////// +// Simpatici metodi jolly +///////////////////////////////////////////////////////// + +const char* iva2name(TipoIVA iva) +{ + const char* i; + switch(iva) + { + case nessuna_iva: + i = TR("Nessuna IVA"); break; + case iva_acquisti: + i = TR("IVA Acquisti"); break; + case iva_vendite: + i = TR("IVA Vendite"); break; + case iva_generica: + i = TR("IVA Generica"); break; + default: + i = TR("IVA ERRATA!"); break; + } + return i; +} + +const TString& cap2comune(const TString& cap, const TString& denom) +{ + TString80 up_denom = denom; + up_denom.upper(); + TString4 codone; + + if (cap.len() == 5 && up_denom.full()) + { + TString8 cappone = cap; + if (cappone[2] == '1') //e' un capoluogo di provincia + cappone.overwrite("00", 3, 2); + + TRelation relcom(LF_COMUNI); + TRectype& comrec = relcom.curr(); + comrec.put(COM_CAPCOM, cappone); + + TCursor comuni (&relcom, "", 3, &comrec, &comrec); + const TRecnotype items = comuni.items(); + comuni.freeze(); + double cmp = 0.69; + for (comuni = 0L; comuni.pos() < items; ++comuni) + { + TString80 denominazione = comrec.get(COM_DENCOM); + denominazione.upper(); + const double fc = xvt_str_fuzzy_compare (up_denom, denominazione); + if (fc > cmp) + { + codone = comrec.get(COM_COM); + cmp = fc; + } + } + } + if (codone.blank() && denom.full()) + { + TLocalisamfile comuni(LF_COMUNI); + comuni.setkey(2); + comuni.put(COM_DENCOM, denom); + if (comuni.read() == NOERR) + codone = comuni.get(COM_COM); + else + { + double cmp = 0.9; + comuni.zero(); + const TString4 pref = up_denom.left(4); + comuni.put(COM_DENCOM, pref); + for (int err = comuni.read(_isgteq); err == NOERR; err = comuni.next()) + { + TString80 denominazione = comuni.get(COM_DENCOM); + denominazione.upper(); + if (!denominazione.starts_with(pref)) + break; + const double fc = xvt_str_fuzzy_compare(up_denom, denominazione); + if (fc > cmp) + { + cmp = fc; + codone = comuni.get(COM_COM); + } + } + } + } + + return codone.full() ? (get_tmp_string() = codone) : EMPTY_STRING; +} + +/////////////////////////////////////////////////////////// +// Registro +/////////////////////////////////////////////////////////// + +TRegistro::TRegistro(const char* cod, int year) + : _rec(LF_TAB), _att(LF_ATTIV) +{ read(cod, year); } + +TRegistro::TRegistro(const TRegistro & reg) + : _rec(LF_TAB), _att(LF_ATTIV) +{ + const int year = atoi(reg._rec.get("CODTAB").sleft(4)); + const TString8 cod = reg._rec.get("CODTAB").smid(4); + + read(cod, year); +} + +bool TRegistro::read(const char* cod, int year) +{ + if (year <= 0) + { + const TDate oggi(TODAY); + year = oggi.year(); + } + if (cod == NULL) + cod = ""; + + TString8 chiave; chiave.format("%04d%s", year, cod); + _rec = cache().get("REG", chiave); + read_att(); + + return !_rec.empty(); +} + +bool TRegistro::force_read(const char* cod, int year) +{ + TString8 chiave; chiave.format("%04d%s", year, cod); + + cache().discard("REG", chiave); + return read(cod, year); +} + +bool TRegistro::reread() +{ + if (ok()) + { + const TString8 n(name()); + const int y = year(); + return read(n, y); + } + return false; +} + +int TRegistro::year() const +{ + const TString& anno = _rec.get("CODTAB").left(4); + return atoi(anno); +} + +const TString& TRegistro::name() const +{ + return _rec.get("CODTAB").mid(4); +} + +TRegistro& TRegistro::operator =(const TRegistro& r) +{ + _rec = r._rec; + _att = r._att; + _prorata = r._prorata; + return *this; +} + +int TRegistro::tipo() const +{ + const int t = _rec.get_int("I0"); + return t; +} + +bool TRegistro::corrispettivi() const +{ + const bool c = _rec.get_bool("B0"); + return c; +} + +TipoIVA TRegistro::iva() const +{ + TipoIVA i = (TipoIVA)tipo(); + switch (i) + { + case nessuna_iva: + case iva_vendite: + case iva_acquisti: + break; + case libro_giornale: + i = nessuna_iva; + break; + default: + error_box(FR("Il registro '%s' non e' un registro IVA o contabile: tipo %d"), + (const char*)name(), i); + i = nessuna_iva; + break; + } + return i; +} + +bool TRegistro::read_att() +{ + TString16 chiave; + chiave << prefix().get_codditta() << '|' << attivita(); + + _att = cache().get(LF_ATTIV, chiave); + // Ditta - Anno - Attivitā - Tipo Attivitā (fissata a 1) + chiave.format("%05ld", prefix().get_codditta()); + chiave << year(); // non fare << year() << attivita() + chiave << attivita() << "1"; + + _prorata.destroy(); + + const TRectype& pla = cache().get("%PLA", chiave); + if (!pla.empty()) + { + chiave.format("%d", year()); + _prorata.add(chiave, pla.get_real("R8")); + _att.put("TIPOATT", pla.get("S7")); // Aggiorna tipo attivitā + } + + return !_att.empty(); +} + +bool TRegistro::agenzia_viaggi() const +{ + return _att.get_bool("REG74TER") && (iva() == iva_vendite); +} + +const TString& TRegistro::tipo_attivita() const +{ + return _att.get("TIPOATT"); +} + +real* TRegistro::read_prorata(int anno) const +{ + TString16 chiave; // Ditta - Anno - Attivitā - Tipo Attivitā (fissata a 1) + chiave.format("%05ld", prefix().get_codditta()); + chiave << anno << attivita() << "1"; + + real* prorata = NULL; + const TRectype& pla = cache().get("%PLA", chiave); + if (!pla.empty()) + prorata = new real(pla.get("R8")); + + return prorata; +} + +real TRegistro::prorata(int annodoc) +{ + const int annoiva = year(); + if (annodoc <= 1900) annodoc = annoiva; // Test per anno documento non specificato + const int annopro = annoiva >= 1998 && annodoc < annoiva ? annodoc+1 : annoiva; + + TString16 chiave; chiave << annopro; + real* pr = (real*)_prorata.objptr(chiave); + + if (pr == NULL) + { + pr = read_prorata(annopro); + if (pr == NULL && annopro != annoiva) + pr = read_prorata(annoiva); + + if (pr == NULL) + pr = new real(ZERO); + _prorata.add(chiave, pr, true); + } + + return *pr; +} + +void TRegistro::set_prorata(int annodoc, const real& pro) +{ + const int annoiva = year(); + if (annodoc <= 2000) annodoc = annoiva; // Test per anno documento non specificato + const int annopro = annodoc < annoiva ? annodoc+1 : annoiva; + TString4 chiave; chiave << annopro; + _prorata.add(chiave, pro, true); +} + +// Certified 99% +bool TRegistro::update(long protiva, const TDate& datareg) +{ + bool updated = true; + + if (protiva > _rec.get_long("I5")) + { + _rec.put("I5", protiva); + updated = false; + } + if (datareg > _rec.get_date("D2")) + { + _rec.put("D2", datareg); + updated = false; + } + if (!updated) + { + TTable reg("REG"); + + updated = reg.rewrite(_rec) == NOERR; + cache().discard("REG", _rec.get("CODTAB")); // Forza rilettura registro in cache + } + + return updated; +} + +/////////////////////////////////////////////////////////// +// Libro giornale +/////////////////////////////////////////////////////////// + +// Legge il libro giornale dell'anno specificato +bool TLibro_giornale::read(int y) +{ + bool found = false; + + if (y <= 0) + { + TEsercizi_contabili esc; + const int lastes = esc.last(); + if (lastes > 0) + y = esc[lastes].inizio().year(); + else + y = TDate(TODAY).year(); + } + + TString4 anno; anno.format("%04d", y); + TTable reg("REG"); + reg.put("CODTAB", anno); // Cerca il primo registro dell'anno + + for (int err = reg.read(_isgteq); err == NOERR; err = reg.next()) + { + if (reg.get("CODTAB").compare(anno, 4) != 0) + break; // Sono arrivato all'anno dopo + + if (reg.get_int("I0") == libro_giornale) + { + found = true; + break; + } + } + + if (!found) reg.zero(); // Memorizza record (anche vuoto) + _rec = reg.curr(); + + return found; +} + +TLibro_giornale::TLibro_giornale(int y) +{ + read(y); +} + +/////////////////////////////////////////////////////////// +// Codice IVA +/////////////////////////////////////////////////////////// + +TCodiceIVA::TCodiceIVA(const char* cod) : TRectype(LF_TABCOM) +{ + read(cod); +} + +int TCodiceIVA::tipo_indetraibilita() const +{ + int tipo = 0; + const TString& codind = indetraibilita(); // Codice indetraibilitā alfanumerico (ex. 1, 3, 9) + if (codind.full()) + { + const TRectype& det = cache().get("%DET", codind); + if (det.empty()) + tipo = atoi(codind); + else + tipo = det.get_int("I0"); + } + return tipo; // Tipo indetraibilitā: 1,3,9 +} + +bool TCodiceIVA::read(const char* cod) +{ + if (cod && *cod) + *this = cache().get("%IVA", cod); + else + zero(); + + return !empty(); +} + +void TCodiceIVA::round(real& n, int ndec, const char* codval) const +{ + switch (ndec) + { + case AUTO_DECIMALS : ndec = (codval && *codval) ? TExchange(codval).decimals(false) : 2; break; + case AUTO_PRICES_DECIMALS: ndec = TExchange(codval).decimals(true); break; + default : break; + } + if (ndec < 10) + n.round(ndec); +} + +real TCodiceIVA::imposta(const real& imponibile, int ndec, const char* codval) const +{ + real iva = imponibile * percentuale() / CENTO; + round(iva, ndec, codval); + return iva; +} + +real TCodiceIVA::scorpora(real& lordo, int ndec, const char* codval) const +{ + round(lordo, ndec, codval); // Arrotondo importo lordo + real imponibile = lordo * CENTO / (CENTO + percentuale()); + round(imponibile, ndec, codval); // Arrotondo importo netto + const real iva = lordo - imponibile; + lordo = imponibile; // lordo č un reference da aggiornare con l'imponibile! + return iva; +} + +real TCodiceIVA::lordo(const real& imponibile, int ndec, const char* codval) const +{ return imponibile + imposta(imponibile, ndec, codval); } + +bool TCodiceIVA::reverse_charge() const +{ + const int rsi = regime_speciale(); + return rsi == 13 || rsi == 50 || rsi == 51; // Reverse charge! +} + +/////////////////////////////////////////////////////////// +// TBill +/////////////////////////////////////////////////////////// + +TBill::~TBill() +{ + if (_descrizione) + delete _descrizione; +} + +void TBill::set_description(const char* d) +{ + if (_descrizione || (d && *d)) + { + if (_descrizione) + *_descrizione = d; + else + _descrizione = new TString(d); + } +} + +// Certified 90% +const TBill& TBill::get(TToken_string& s, int from, int mode) +{ + const char* first = s.get(from); + if (mode & 0x1) + { + _tipo = first ? char(toupper(*first)) : ' '; + first = s.get(); + } + else + _tipo = ' '; + + if (strchr(" CF", _tipo) == NULL) + { +#ifdef DBG + error_box(FR("Tipo conto errato: '%c'"), _tipo); +#endif + _tipo = ' '; + } + + _gruppo = first ? atoi(first) : 0; + _conto = s.get_int(); + _sottoconto = s.get_long(); + if (mode & 0x2) + set_description(s.get()); + + _tipo_cr = -1; + _sezione = ' '; + + return *this; +} + +const TBill& TBill::copy(const TBill& bill) +{ + _tipo = bill._tipo; + _gruppo = bill._gruppo; + _conto = bill._conto; + _sottoconto = bill._sottoconto; + set_description(bill.descrizione()); + _tipo_cr = bill._tipo_cr; + _sospeso = bill._sospeso; + _sezione = bill._sezione; + return *this; +} + +// Certified 100% +const TBill& TBill::set(int g, int c, long s, char t, const char* d, int r) +{ + _tipo = (t > ' ') ? char(toupper(t)) : ' '; + _gruppo = g; + _conto = c; + _sottoconto = s; + set_description(d); + _tipo_cr = r; + return *this; +} + +const TBill& TBill::add_to(TToken_string& ts, int from, int mode) +{ + if (mode & 0x4) + { + const int cr = tipo_cr(); + if (cr > 0) ts.add(cr, from++); else ts.add(" ", from++); + } + + if (mode & 0x1) + ts.add(_tipo, from++); + + if (_gruppo > 0) ts.add(_gruppo, from++); else ts.add(" ", from++); + if (_conto > 0) ts.add(_conto, from++); else ts.add(" ", from++); + if (_sottoconto > 0L) ts.add(_sottoconto, from++); else ts.add(" ", from++); + + if (mode & 0x2) + ts.add(descrizione(), from++); + + return *this; +} + + +const char* TBill::field_name(int n, const TRectype& r, bool contro) const +{ + CHECKD(n >= 0 && n <= 3, "Invalid bill field ", n); + + const char* f = NULL; + if (contro) + { + CHECKD(r.num() == LF_RMOV || r.num() == LF_PAGSCA, "Record non valido per contropartita: ", r.num()); + switch(n) + { + case 0: f = RMV_GRUPPOC; break; + case 1: f = RMV_CONTOC; break; + case 2: f = RMV_SOTTOCONTOC; break; + default:f = RMV_TIPOCC; break; + } + } + else + { + switch(n) + { + case 0: f = RMV_GRUPPO; break; + case 1: f = RMV_CONTO; break; + case 2: + if (r.num() == LF_CLIFO) + f = CLI_CODCF; + else + f = RMV_SOTTOCONTO; + break; + default: + switch(r.num()) + { + case LF_CLIFO : f = CLI_TIPOCF; break; + case LF_RCAUSALI: f = RCA_TIPOCF; break; + default : f = RMV_TIPOC; break; + } + break; + } + } + return f; +} + +void TBill::put(TRectype& r, bool c) const +{ + r.put(field_name(0, r, c), gruppo()); + r.put(field_name(1, r, c), conto()); + r.put(field_name(2, r, c), sottoconto()); + r.put(field_name(3, r, c), tipo()); +} + +bool TBill::get(const TRectype& r, bool c) +{ + char t = ' '; + if (r.type(field_name(3, r, c)) != _nullfld) + t = r.get_char(field_name(3, r, c)); + + set(r.get_int(field_name(0, r, c)), + r.get_int(field_name(1, r, c)), + r.get_long(field_name(2, r, c)), + t); + + set_description(NULL); + _tipo_cr = -1; + _sezione = ' '; + + if (r.num() == LF_RMOVIVA) + tipo_cr(r.get_int(RMI_TIPOCR)); + + return ok(); +} + +void TBill::set(TMask& m, short g, short c, short s, short t, short d) const +{ + if (g > 0) + m.set(g, gruppo()); + if (c > 0) + m.set(c, conto()); + if (s > 0) + m.set(s, sottoconto()); + if (t > 0) + { + char typ[2] = { tipo(), '\0' }; + m.set(t, typ); + } + if (d > 0) + m.set(d, descrizione()); +} + +void TBill::get(const TMask& m, short g, short c, short s, short t, short d) +{ + const int gr = m.get_int(g); + const int co = m.get_int(c); + const long so = s > 0 ? m.get_long(s) : 0L; + char ti = ' '; + if (t) + ti = m.get(t)[0]; + TString80 de; + if (d) + de = m.get(d); + set(gr, co, so, ti, de); +} + +// Certified 100% +bool TBill::ok() const +{ + return _gruppo != 0 && _conto != 0 && _sottoconto != 0L; +} + +// Certified 99% +int TBill::compare(const TSortable& s) const +{ + CHECK(class_name()==s.class_name(), "Can't compare TBill with TObject"); + const TBill& c = (const TBill&)s; + + int res = _gruppo - c._gruppo; + if (res) return res; + + res = _conto - c._conto; + if (res) return res; + + const long lres = _sottoconto - c._sottoconto; + if (lres < 0L) res = -1; else + if (lres > 0L) res = +1; + + return res; +} + +// Certified 95% +bool TBill::find() +{ + bool ok = false; + + if ((_tipo != 'C' && _tipo != 'F') || _sottoconto == 0L) + { + TRectype pcon(LF_PCON); + ok = read(pcon); + if (!ok && _sottoconto != 0L) + { + const long sotto = _sottoconto; + _sottoconto = 0L; + if (read(pcon)) + _tipo = char(toupper(pcon.get_char(PCN_TMCF))); + _sottoconto = sotto; + } + } + + if ((_tipo == 'C' || _tipo == 'F') && _sottoconto != 0L) + { + TString16 key; + key.format("%c|%ld", _tipo, _sottoconto); + const TRectype& clifo = cache().get(LF_CLIFO, key); + ok = !clifo.empty(); + if (ok) + { + set_description(clifo.get(CLI_RAGSOC)); + if (_tipo_cr < 0) + { + _tipo_cr = 0; + _sezione = ' '; + } + _sospeso = clifo.get_bool(CLI_SOSPESO); + + const char tipoa = clifo.get_char(CLI_TIPOPERS); + if (tipoa == 'F') // Se persona fisica allora aggiusta la ragione sociale + { + TString nome(descrizione().mid(30)); + if (nome.full()) + { + _descrizione->cut(30); + _descrizione->trim(); nome.trim(); + *_descrizione << ' ' << nome; + } + } + if (_gruppo == 0 || _conto == 0) + { + _gruppo = clifo.get_int(CLI_GRUPPO); + _conto = clifo.get_int(CLI_CONTO); + } + } + } + return ok; +} + + +bool TBill::read(TRectype &r) +{ + bool ok = false; + + if (tipo() <= ' ' || sottoconto() <= 0) + { + const char* key = string(); + const TRectype& pcon = cache().get(LF_PCON, key); + if (!pcon.empty()) + { + r = pcon; + ok = true; + } + } + if (ok) + { + _tipo_cr = r.get_int(PCN_TIPOSPRIC); + _sezione = r.get_char(PCN_SEZSALDI); + set_description(r.get(PCN_DESCR)); + _sospeso = r.get_bool(PCN_SOSPESO); + } + else + r.zero(); + + return ok; +} + +int TBill::tipo_att() +{ + int tipo_att = 1; + if (tipo() <= ' ' && ok()) + { + TBill bill(gruppo(), conto()); + TRectype rec(LF_PCON); bill.read(rec); + const TIndbil ib = (TIndbil)rec.get_int(PCN_INDBIL); + if (ib == ib_passivita || ib == ib_ricavi) + { + read(rec); + const int ricser = rec.get_int(PCN_RICSER); // 0 = Altre attivita 1 = Servizi + tipo_att = (ricser == 1) ? 1 : 2; + } + } + return tipo_att; +} + +// Certified 99% +const TString& TBill::descrizione() const +{ + TBill& myself = (TBill&)*this; + // Se il conto e' valido (c'e' almeno il gruppo) cerca la sua descrizione su file + if ((_descrizione == NULL || _descrizione->blank()) && + (gruppo() != 0 || (tipo() > ' ' && codclifo()>0))) + { + if (!myself.find()) + myself.set_description(TR("Sconosciuto")); + } + + return _descrizione ? *_descrizione : (const TString&) EMPTY_STRING; +} + +int TBill::tipo_cr() const +{ + if (_tipo_cr < 0) + { + TBill& myself = (TBill&)*this; + myself.find(); + } + return _tipo_cr; +} + +int TBill::indicatore_bilancio() const +{ + TString8 str; + str.format("%d|%d", gruppo(), conto()); + const int ib = atoi(cache().get(LF_PCON, str, PCN_INDBIL)); + if (ib <= 0) + { + TString msg = str; + msg.replace('|', '.'); + msg.insert(TR("Impossibile stabilire l'indicatore di bilancio del conto ")); + NFCHECK(msg); + } + return ib; +} + + +bool TBill::sospeso() const +{ + if (_tipo_cr < 0) tipo_cr(); // trick to load _sospeso + return _sospeso; +} + +char TBill::sezione() const +{ + if (_sezione == ' ') tipo_cr(); // trick to load _sezione + return _sezione; +} + +// Certified 100% +const char* TBill::string(int mode) const +{ + TString& s = get_tmp_string(); + + if (mode & 0x8) + { + if (_sottoconto != 0) + s.format("%03d%03d%06ld", _gruppo, _conto, _sottoconto); else + if (_conto != 0) + s.format("%03d%03d", _gruppo, _conto); else + if (_gruppo != 0) + s.format("%03d", _gruppo); + return s; + } + + if (mode & 0x4) + { + const int cr = tipo_cr(); + if (cr > 0) s << cr << '|'; + else s << " |"; + } + + if (mode & 0x1) + s << _tipo << '|'; + + if (_gruppo > 0) s << _gruppo << '|'; + else s << " |"; + + if (_conto > 0) s << _conto << '|'; + else s << " |"; + + if (_sottoconto > 0L) s << _sottoconto; + else s << ' '; + + if (mode & 0x2) + s << '|' << descrizione(); + + return s; +} + +bool TBill::required_cdc() const +{ + TString16 key; + for (int i = 2; i >= 0; i--) + { + key.format("%d|%d|%ld", gruppo(), i > 0 ? conto() : 0, i > 1 ? sottoconto() : 0); + const TRectype& sottoc = cache().get(LF_PCON, key); + if (sottoc.get_bool(PCN_CMSNEEDED)) + return true; + } + return false; +} + +bool TBill::default_cdc(TString& cdc, TString& fas) const +{ + bool ok = tipo() <= ' ' && sottoconto() > 0; + if (ok) + { + TString16 key; + for (int i = 2; i >= 0; i--) + { + key.format("%d|%d|%ld", gruppo(), i > 0 ? conto() : 0, i > 1 ? sottoconto() : 0); + const TRectype& pcon = cache().get(LF_PCON, key); + if (!pcon.empty()) + { + cdc = pcon.get(PCN_CODCMS); + fas = pcon.get(PCN_FASCMS); + if (cdc.not_empty() || fas.not_empty()) + break; + } + } + } + return ok && (cdc.not_empty() || fas.not_empty()); +} + +bool TBill::is_analitico() const +{ + TString16 key; + + for (int i = 2; i >= 0; i--) + { + key.format("%d|%d|%ld", gruppo(), i > 0 ? conto() : 0, i > 1 ? sottoconto() : 0); + const TRectype& picone = cache().get(LF_PCON, key); + if (picone.get_bool(PCN_ANALITICA)) + return true; + } + return false; +} + +const char* num2str(const TString& s) +{ + TString& str = get_tmp_string(20); + + str = s; + str.trim(); + if (str.len() > 2) + { + str = s.left(2); + const int sub = atoi(s.mid(2, 2)); + switch (sub) + { + case 2: str << " bis"; break; + case 3: str << " ter";break; + case 4: str << " quater"; break; + case 5: str << " quinquies"; break; + case 6: str << " sexies"; break; + default: break; + } + const TString& sotsub = s.mid(4); + if (sotsub.full()) + str << ' ' << sotsub; + } + return (const char*)str; +} + diff --git a/src/cg/cglib01.h b/src/cg/cglib01.h index bcbff6025..93821a829 100755 --- a/src/cg/cglib01.h +++ b/src/cg/cglib01.h @@ -1,264 +1,267 @@ -#ifndef __CGLIB01_H -#define __CGLIB01_H - -#ifndef __ISAM_H -#include -#endif - -// Gestione esercizi contabili, registri e libro giornale - -class TEsercizio : public TSortable -{ - int _codice; - TDate _inizio, _fine, _scarico, _chiusura, _chiusura_mag; - -protected: // TSortable - virtual int compare(const TSortable& s) const; - -public: - int codice() const { return _codice; } - const TDate& inizio() const { return _inizio; } - const TDate& fine() const { return _fine; } - const TDate& scarico() const { return _scarico; } - const TDate& chiusura() const; - const TDate& chiusura_mag() const { return _chiusura_mag; } - - TEsercizio(const TRectype& rec); - virtual ~TEsercizio() {} -}; - -class TEsercizi_contabili : public TObject -{ - static TArray _esercizi; - static long _firm; - -protected: - static void check(); - - const TEsercizio& esc(int i) const - { return (const TEsercizio&)_esercizi[i]; } - - int date2index(const TDate& d) const; - int esc2index(int codice) const; - int items() const { return _esercizi.items(); } - -public: - static void update(); - - const TEsercizio& esercizio(int codice) const; - const TEsercizio& operator [](int codice) const { return esercizio(codice); } - const TEsercizio& esercizio(const TDate& date) const { return esercizio(date2esc(date)); } - - int date2esc(const TDate& date) const; - int date2prevesc(const TDate& date) const; - int date2nextesc(const TDate& date) const; - int pred(int codice) const; - int next(int codice) const; - int first() const; - int last() const; - int last_mag() const; - bool exist(int codice) const; - bool code2range(int codice, TDate& dal, TDate& al) const; - - TEsercizi_contabili(); - virtual ~TEsercizi_contabili() {} -}; - -TEsercizi_contabili& esercizi(); - -enum TipoIVA -{ - iva_errata = -1, - nessuna_iva = 0, - iva_vendite = 1, - iva_acquisti = 2, - libro_giornale = 5, - iva_generica = 9 -}; - -const char* iva2name(TipoIVA i); -const TString& cap2comune(const TString& cap, const TString& denom); - -class TMask_field; - -class TRegistro : public TObject -{ - bool read_att(); - -protected: - TRectype _rec, _att; - TAssoc_array _prorata; - - real* read_prorata(int anno) const; - -public: - bool read(const char* code, int year); - bool force_read(const char* code, int year); - bool reread(); - TRegistro& operator =(const TRegistro& r); - - virtual bool ok() const { return !_rec.empty(); } - - int tipo() const; - TipoIVA iva() const; - bool corrispettivi() const; - bool sospeso() const { return _rec.get_bool("B1");} - const TString& name() const; - int year() const; - TDate last_reg() const { return _rec.get_date("D2"); } - TDate last_print() const { return _rec.get_date("D3"); } - long mese_stampa_ultima_liq() const { return _rec.get_long("I4"); } - long protocol() const { return _rec.get_long("I5"); } - const TString& attivita() const { return _rec.get("S8"); } - - - bool agenzia_viaggi() const; - const TString& tipo_attivita() const; - bool attivita_mista() const { const char a = tipo_attivita()[0]; return a == 'E'; } - - void set_prorata(int annodoc, const real& pro); - real prorata(int annodoc); -#ifdef PRORATA100 - bool prorata100(int annodoc) { return prorata(annodoc) >= CENTO; } -#endif - bool update(long uprotiva, const TDate& lastreg); - - TRegistro(const char* code = "", int year = 0); - TRegistro(const TRegistro & reg); - virtual ~TRegistro() {} -}; - -class TLibro_giornale : public TRegistro -{ -public: - bool read(int year); - TDate global_last_print() const; - - TLibro_giornale(int year = 0); - virtual ~TLibro_giornale() {} -}; - -class TCodiceIVA : public TRectype -{ -protected: - void copy(const TRectype & iva) { TRectype::operator =(iva); } - void round(real& n, int ndec, const char* codval) const; - -public: // TObject - virtual bool ok() const { return !empty(); } - TCodiceIVA& operator =(const TCodiceIVA & iva) { copy(iva) ; return *this;} - TObject* dup() const { return new TCodiceIVA(*this); } - bool read(const char* codice); - const TString& codice() const { return get("CODTAB"); } - const TString& descrizione() const { return get("S0"); } - const real percentuale() const { return get_real("R0"); } - const TString& tipo() const { return get("S1"); } - const TString& indetraibilita() const { return get("S4"); } // Codice indetraibilitā alfanumerico (ex. 1, 3, 9) - int tipo_indetraibilita() const; // Tipo indetraibilitā: 1,3,9 - bool senza_imposta() { return percentuale() == ZERO;} - - int allegato(char tipocf) const { return get_int(tipocf == 'F' ? "S8" : "S7"); } - bool has_plafond() const { return get_int("S3") > 0; } - - real imposta(const real& imponibile, int ndec = AUTO_DECIMALS, const char * codval = "") const; // Calcola l'imposta sull'imponibile l'imposta e la ritorna - real scorpora(real& imponibile, int ndec = AUTO_DECIMALS, const char * codval = "") const; // Scorpora dall'imponibile l'imposta e la ritorna - real lordo(const real& imponibile, int ndec = AUTO_DECIMALS, const char * codval = "") const; // Calcola il lordo dell'imponibile l'imposta e la ritorna - - TCodiceIVA(const char* codice = NULL); - TCodiceIVA(const TRectype & rec) : TRectype(rec) {} - TCodiceIVA(const TCodiceIVA & iva) : TRectype(iva) {} - virtual ~TCodiceIVA() {} -}; - -#ifndef __MASK_H -class TMask; -#endif - -class TBill : public TSortable -{ - char _tipo; // ' ' = Conto, 'C' = Cliente, 'F' = 'Fornitore' - int _gruppo, _conto; - long _sottoconto; // Sottoconto, codice cliente o fornitore - TString* _descrizione; // Vuota fino alla chiamata di describe - int _tipo_cr; // Tipo costo/ricavo - char _sezione; - bool _sospeso; - -protected: - void set_description(const char* d); - const TBill& copy(const TBill& b); - const char* field_name(int n, const TRectype& rec, bool contro) const; - -public: // TObject - virtual int compare(const TSortable& s) const; - virtual const char* class_name() const { return "Conto"; } - virtual bool ok() const; // Gruppo, Conto e Sottoconto non nulli - -public: - TBill(int g = 0, int c = 0, long s = 0L, char t = ' ', const char* d = NULL, int r = -1) - : _tipo(t), _gruppo(g), _conto(c), _sottoconto(s), _descrizione(NULL), - _sezione(' '), _sospeso(false) - { set(g,c,s,t,d,r);} - - TBill(TToken_string& tgcsd, int from, int mode = 0) - : _descrizione(NULL), _sezione(' '), _sospeso(false) - { get(tgcsd, from, mode); } - - TBill(const TRectype& rec, bool contro = false) - : _descrizione(NULL), _sezione(' '), _sospeso(false) - { get(rec, contro); } - - TBill(const TBill& b) - : _descrizione(NULL) - { copy(b); } - - virtual ~TBill(); - - const TBill& set(int g = 0, int c = 0, long s = 0L, char t = ' ', - const char* d = NULL, int r = -1); - - const TBill& get(TToken_string& ts, int from, int mode = 0); - const TBill& add_to(TToken_string& ts, int from, int mode = 0); - const TBill& operator=(const TBill& b) { return copy(b); } - - bool empty() const { return _gruppo==0 && _conto==0 && _sottoconto == 0; } - - char tipo() const { return _tipo; } - int gruppo() const { return _gruppo; } - int conto() const { return _conto; } - long sottoconto() const { return _sottoconto; } - long codclifo() const { return _sottoconto; } - long& codclifo() { return _sottoconto; } - - bool find(); - const TString& descrizione() const; - int tipo_cr() const; - void tipo_cr(int tcr) { _tipo_cr = tcr; } - int indicatore_bilancio() const; - - int tipo_att(); - bool read(TRectype& r); - bool sospeso() const; - char sezione() const; - - void put(TRectype& r, bool contro = false) const; - bool get(const TRectype& r, bool contro = false); - - void set(TMask& m, short g, short c, short s, short t = 0, short d = 0) const; - void get(const TMask& m, short g, short c, short s, short t = 0, short d = 0); - - const char* string(int mode = 0) const; - - bool required_cdc() const; - bool default_cdc(TString& cdc, TString& fas) const; - bool is_analitico() const; -}; - -enum TIndbil { ib_null, ib_attivita, ib_passivita, ib_costi, ib_ricavi, ib_conti_ordine }; - -enum tipo_movimento { tm_nessuno = 0, tm_fattura = 1, tm_nota_credito = 2, - tm_pagamento = 3, tm_insoluto = 5, tm_pagamento_insoluto = 6 }; - -const char* num2str(const TString & s); - -#endif +#ifndef __CGLIB01_H +#define __CGLIB01_H + +#ifndef __ISAM_H +#include +#endif + +// Gestione esercizi contabili, registri e libro giornale + +class TEsercizio : public TSortable +{ + int _codice; + TDate _inizio, _fine, _scarico, _chiusura, _chiusura_mag; + +protected: // TSortable + virtual int compare(const TSortable& s) const; + +public: + int codice() const { return _codice; } + const TDate& inizio() const { return _inizio; } + const TDate& fine() const { return _fine; } + const TDate& scarico() const { return _scarico; } + const TDate& chiusura() const; + const TDate& chiusura_mag() const { return _chiusura_mag; } + + TEsercizio(const TRectype& rec); + virtual ~TEsercizio() {} +}; + +class TEsercizi_contabili : public TObject +{ + static TArray _esercizi; + static long _firm; + +protected: + static void check(); + + const TEsercizio& esc(int i) const + { return (const TEsercizio&)_esercizi[i]; } + + int date2index(const TDate& d) const; + int esc2index(int codice) const; + int items() const { return _esercizi.items(); } + +public: + static void update(); + + const TEsercizio& esercizio(int codice) const; + const TEsercizio& operator [](int codice) const { return esercizio(codice); } + const TEsercizio& esercizio(const TDate& date) const { return esercizio(date2esc(date)); } + + int date2esc(const TDate& date) const; + int date2prevesc(const TDate& date) const; + int date2nextesc(const TDate& date) const; + int pred(int codice) const; + int next(int codice) const; + int first() const; + int last() const; + int last_mag() const; + bool exist(int codice) const; + bool code2range(int codice, TDate& dal, TDate& al) const; + + TEsercizi_contabili(); + virtual ~TEsercizi_contabili() {} +}; + +TEsercizi_contabili& esercizi(); + +enum TipoIVA +{ + iva_errata = -1, + nessuna_iva = 0, + iva_vendite = 1, + iva_acquisti = 2, + libro_giornale = 5, + iva_generica = 9 +}; + +const char* iva2name(TipoIVA i); +const TString& cap2comune(const TString& cap, const TString& denom); + +class TMask_field; + +class TRegistro : public TObject +{ + bool read_att(); + +protected: + TRectype _rec, _att; + TAssoc_array _prorata; + + real* read_prorata(int anno) const; + +public: + bool read(const char* code, int year); + bool force_read(const char* code, int year); + bool reread(); + TRegistro& operator =(const TRegistro& r); + + virtual bool ok() const { return !_rec.empty(); } + + int tipo() const; + TipoIVA iva() const; + bool corrispettivi() const; + bool sospeso() const { return _rec.get_bool("B1");} + const TString& name() const; + int year() const; + TDate last_reg() const { return _rec.get_date("D2"); } + TDate last_print() const { return _rec.get_date("D3"); } + long mese_stampa_ultima_liq() const { return _rec.get_long("I4"); } + long protocol() const { return _rec.get_long("I5"); } + const TString& attivita() const { return _rec.get("S8"); } + + + bool agenzia_viaggi() const; + const TString& tipo_attivita() const; + bool attivita_mista() const { const char a = tipo_attivita()[0]; return a == 'E'; } + + void set_prorata(int annodoc, const real& pro); + real prorata(int annodoc); +#ifdef PRORATA100 + bool prorata100(int annodoc) { return prorata(annodoc) >= CENTO; } +#endif + bool update(long uprotiva, const TDate& lastreg); + + TRegistro(const char* code = "", int year = 0); + TRegistro(const TRegistro & reg); + virtual ~TRegistro() {} +}; + +class TLibro_giornale : public TRegistro +{ +public: + bool read(int year); + TDate global_last_print() const; + + TLibro_giornale(int year = 0); + virtual ~TLibro_giornale() {} +}; + +class TCodiceIVA : public TRectype +{ +protected: + void copy(const TRectype & iva) { TRectype::operator =(iva); } + void round(real& n, int ndec, const char* codval) const; + +public: // TObject + virtual bool ok() const { return !empty(); } + TCodiceIVA& operator =(const TCodiceIVA & iva) { copy(iva) ; return *this;} + TObject* dup() const { return new TCodiceIVA(*this); } + bool read(const char* codice); + const TString& codice() const { return get("CODTAB"); } + const TString& descrizione() const { return get("S0"); } + const real percentuale() const { return get_real("R0"); } + const TString& tipo() const { return get("S1"); } + const TString& indetraibilita() const { return get("S4"); } // Codice indetraibilitā alfanumerico (ex. 1, 3, 9) + int tipo_indetraibilita() const; // Tipo indetraibilitā: 1,3,9 + bool senza_imposta() { return percentuale() == ZERO;} + + int allegato(char tipocf) const { return get_int(tipocf == 'F' ? "S8" : "S7"); } + bool has_plafond() const { return get_int("S3") > 0; } + + real imposta(const real& imponibile, int ndec = AUTO_DECIMALS, const char * codval = "") const; // Calcola l'imposta sull'imponibile l'imposta e la ritorna + real scorpora(real& imponibile, int ndec = AUTO_DECIMALS, const char * codval = "") const; // Scorpora dall'imponibile l'imposta e la ritorna + real lordo(const real& imponibile, int ndec = AUTO_DECIMALS, const char * codval = "") const; // Calcola il lordo dell'imponibile l'imposta e la ritorna + + bool reverse_charge() const; + int regime_speciale() const { return get_int("I5");} + + TCodiceIVA(const char* codice = NULL); + TCodiceIVA(const TRectype & rec) : TRectype(rec) {} + TCodiceIVA(const TCodiceIVA & iva) : TRectype(iva) {} + virtual ~TCodiceIVA() {} +}; + +#ifndef __MASK_H +class TMask; +#endif + +class TBill : public TSortable +{ + char _tipo; // ' ' = Conto, 'C' = Cliente, 'F' = 'Fornitore' + int _gruppo, _conto; + long _sottoconto; // Sottoconto, codice cliente o fornitore + TString* _descrizione; // Vuota fino alla chiamata di describe + int _tipo_cr; // Tipo costo/ricavo + char _sezione; + bool _sospeso; + +protected: + void set_description(const char* d); + const TBill& copy(const TBill& b); + const char* field_name(int n, const TRectype& rec, bool contro) const; + +public: // TObject + virtual int compare(const TSortable& s) const; + virtual const char* class_name() const { return "Conto"; } + virtual bool ok() const; // Gruppo, Conto e Sottoconto non nulli + +public: + TBill(int g = 0, int c = 0, long s = 0L, char t = ' ', const char* d = NULL, int r = -1) + : _tipo(t), _gruppo(g), _conto(c), _sottoconto(s), _descrizione(NULL), + _sezione(' '), _sospeso(false) + { set(g,c,s,t,d,r);} + + TBill(TToken_string& tgcsd, int from, int mode = 0) + : _descrizione(NULL), _sezione(' '), _sospeso(false) + { get(tgcsd, from, mode); } + + TBill(const TRectype& rec, bool contro = false) + : _descrizione(NULL), _sezione(' '), _sospeso(false) + { get(rec, contro); } + + TBill(const TBill& b) + : _descrizione(NULL) + { copy(b); } + + virtual ~TBill(); + + const TBill& set(int g = 0, int c = 0, long s = 0L, char t = ' ', + const char* d = NULL, int r = -1); + + const TBill& get(TToken_string& ts, int from, int mode = 0); + const TBill& add_to(TToken_string& ts, int from, int mode = 0); + const TBill& operator=(const TBill& b) { return copy(b); } + + bool empty() const { return _gruppo==0 && _conto==0 && _sottoconto == 0; } + + char tipo() const { return _tipo; } + int gruppo() const { return _gruppo; } + int conto() const { return _conto; } + long sottoconto() const { return _sottoconto; } + long codclifo() const { return _sottoconto; } + long& codclifo() { return _sottoconto; } + + bool find(); + const TString& descrizione() const; + int tipo_cr() const; + void tipo_cr(int tcr) { _tipo_cr = tcr; } + int indicatore_bilancio() const; + + int tipo_att(); + bool read(TRectype& r); + bool sospeso() const; + char sezione() const; + + void put(TRectype& r, bool contro = false) const; + bool get(const TRectype& r, bool contro = false); + + void set(TMask& m, short g, short c, short s, short t = 0, short d = 0) const; + void get(const TMask& m, short g, short c, short s, short t = 0, short d = 0); + + const char* string(int mode = 0) const; + + bool required_cdc() const; + bool default_cdc(TString& cdc, TString& fas) const; + bool is_analitico() const; +}; + +enum TIndbil { ib_null, ib_attivita, ib_passivita, ib_costi, ib_ricavi, ib_conti_ordine }; + +enum tipo_movimento { tm_nessuno = 0, tm_fattura = 1, tm_nota_credito = 2, + tm_pagamento = 3, tm_insoluto = 5, tm_pagamento_insoluto = 6 }; + +const char* num2str(const TString & s); + +#endif