///////////////////////////////////////////////////////////////////////////// // cglib02.cpp // // Aggiornamento saldi // ///////////////////////////////////////////////////////////////////////////// #include "cglib01.h" #include "cglib02.h" #include #include #include #include #include #include #include #include /////////////////////////////////////////////////////////// // TSaldi_list /////////////////////////////////////////////////////////// // // Cerca l'esercizio precedente di EseCorr // Se EseCorr e' gia' il primo ritorna 0 // HIDDEN int EsePre(const int EseCorr) { TEsercizi_contabili esc; return esc.pred(EseCorr); } // aep e' l'esercizio precedente TSaldi_list::TSaldi_list(int gr, int co, int aec, int aep_par) { TString16 key; int aep = aep_par; destroy(); // Se non passo l'anno precedente lo devo comunque calcolare if (aep_par == 0) aep = EsePre(aec); TLocalisamfile cf(LF_SALDI); cf.setkey(2); cf.put(SLD_GRUPPO,gr); cf.put(SLD_CONTO,co); for (cf.read(_isgteq);!cf.eof();cf.next()) { if (!cf.get_bool(SLD_FLSCA)) { const int ae = cf.get_int(SLD_ANNOES); const int g = cf.get_int(SLD_GRUPPO); const int c = cf.get_int(SLD_CONTO); const long s = cf.get_long(SLD_SOTTOCONTO); if (g != gr || c != co) break; if (ae != aec && ae != aep) continue; const TRectype& r = cf.curr(); key.format("%3d%3d%6ld", g, c, s); // Se avevo chiesto anche l'es. prec. puo' darsi che l'abbia gia' trovato bool force = !aep_par; add(key, r, force); } } } TRectype* TSaldi_list::saldi() const { TObject* o = ((TAssoc_array*)this)->get(); return (TRectype*)o; } /////////////////////////////////////////////////////////// // TSaldo /////////////////////////////////////////////////////////// TSaldo::TSaldo() : _saldi(LF_SALDI), _saldoiniziale(ZERO), _saldo_iniziale(ZERO), _prg_dare(ZERO), _prg_avere(ZERO), _saldo(ZERO), _annoes(0), _indbil(0), _prec(false), _movimentato(false), _significativo(false), _rec_presente_ec(false), _rec_presente_ep(false), _causali_apertura(LF_CAUSALI, CAU_MOVAP) { for (int i = 0; i < 12; i++) { _prg_dare_mese[i] = ZERO; _prg_avere_mese[i] = ZERO; } } real TSaldo::saldofin_esprec(int annoes, int g, int c, long s, bool saldo_chiusura, bool provvis) { _significativo = false; const int annoesprec = EsePre(annoes); if (!ricerca_progr_prec(annoesprec, g, c, s)) // non ci sono esercizi prima del primo return ZERO; const char flag = _saldi.get(SLD_FLAGSALINI)[0]; const real saldo = _saldi.get_real(SLD_SALDO); const real pdare = _saldi.get_real(SLD_PDARE); const real pavere = _saldi.get_real(SLD_PAVERE); const real pdarepro = _saldi.get_real(SLD_PDAREPRO); const real paverepro = _saldi.get_real(SLD_PAVEREPRO); const char flagsf = _saldi.get_char(SLD_FLAGSALFIN); const real saldosf = _saldi.get_real(SLD_SALDOFIN); real tot = pdare-pavere; if (flag == 'D') tot += saldo; else tot -= saldo; if (saldo_chiusura) // W96SALDI del 18-07-96 { // Ho aggiunto il flag saldo_chiusura con valore di if (flagsf == 'D') // default a false, perche' il saldo finale dell' esercizio tot += saldosf; // precedente va considerato solamente nel calcolo dei else // progressivi precedenti nella stampa mastrini, tot -= saldosf; // che e' l'unico programma ad usare la funzione } // passandogli come flag saldo_chiusura il valore true. if (provvis) { tot += pdarepro; tot -= paverepro; } _significativo = !tot.is_zero(); return tot; } //richiamata nel bilancio a sez.contr per data limite //in realta' calcola il saldo finale es.prec real TSaldo::calcola_saldo_iniziale(int g,int c,long s,int indbil, bool provvis) { real saldoini; _significativo = true; _saldi.zero(); _saldi.put(SLD_GRUPPO,g); _saldi.put(SLD_CONTO,c); _saldi.put(SLD_SOTTOCONTO,s); _saldi.put(SLD_ANNOES,_annoes); _saldi.put(SLD_FLSCA,""); if (_rec_presente_ec = (_saldi.read() == NOERR)) saldoini = _saldi.get_real(SLD_SALDO); _significativo = _rec_presente_ec && saldoini != ZERO; if (saldoini != ZERO) //non va considerato!!! Vedi appunti _saldo_iniziale = ZERO; if (saldoini == ZERO) { if (indbil == 1 || indbil == 2 || indbil == 5) { _prec = true; saldoini = saldofin_esprec(_annoes, g, c, s, false, provvis); } _saldo_iniziale = saldoini; } return _saldo_iniziale; } bool TSaldo::leggi_mov(long nr) { const TRectype& mov = cache().get(LF_MOV, nr); const bool ok = !mov.empty(); if (ok) { _codcaus = mov.get(MOV_CODCAUS); _datareg = mov.get(MOV_DATAREG); _provv = mov.get(MOV_PROVVIS); // _provv.trim(); _datacomp = mov.get(MOV_DATACOMP); } else NFCHECK("Testata assente: %ld", nr); return ok; } //per bilancio scalare (ovvero a sezioni contrapposte) per data limite bool TSaldo::data_limite_bilancio(int bilancio, int g, int c, long s, const TDate& data_inf, const TDate& data_sup, int indbil, int stp_prov, const char* filter) { _saldo_iniziale = ZERO; _saldo = ZERO; _movimentato = false; _rec_presente_ep = false; _rec_presente_ec = false; _prec = false; TRelation rel(LF_RMOV); TRectype& rmov = rel.curr(); rmov.put(RMV_GRUPPO,g); rmov.put(RMV_CONTO,c); rmov.put(RMV_SOTTOCONTO,s); TCursor cur(&rel, filter, 2, &rmov, &rmov); const TRecnotype items = cur.items(); cur.freeze(); // Anche se non movimentato vado a vedere il saldo if (stp_prov != 3 && (filter == NULL || *filter == '\0')) _saldo = calcola_saldo_iniziale(g,c,s,indbil,stp_prov == 2); for (cur = 0L; cur.pos() < items; ++cur) { const long num_reg = rmov.get_long(RMV_NUMREG); if (!leggi_mov(num_reg)) // Leggo la testata continue; // Evita righe orfane! TDate data_mov; if (bilancio == DataLimite) data_mov = _datacomp; else { if (_annoes == 0) data_mov = _datareg; else data_mov = _datacomp; } if (data_mov < data_inf || data_mov > data_sup) continue; // "Se la causale del movimento e' di chiusura, // o di apertura il movimento non va considerato" if (_codcaus.not_empty()) { const TString& movap = _causali_apertura.decode(_codcaus); if (movap == "C") continue; } //bilancio normale (non comprende i provvisori) ? if (stp_prov == 1 && _provv.not_empty()) continue; //bilancio dei soli provvisori ? if (stp_prov == 3 && _provv.empty()) continue; const char sezione = rmov.get_char(RMV_SEZIONE); const real importo = rmov.get_real(RMV_IMPORTO); // I mov. di puro riferimento (= con importo = 0) vanno scartati if (importo.is_zero()) continue; _movimentato = true; if (sezione == 'D') _saldo += importo; else _saldo -= importo; } #ifdef DBG xvtil_statbar_refresh(); #endif return _movimentato; } //per bilancio di verifica all'ultima immissione bool TSaldo::ultima_immissione_verifica(int annoes,int g,int c,long s,int indbil,int stp_prov) { //Si considerano i saldi e non piu' i movimenti char sezione; real pdarepro, paverepro; bool esito = false; _saldo_iniziale = ZERO; _saldoiniziale = ZERO; _prg_dare = ZERO; _prg_avere = ZERO; _saldo = ZERO; _saldofin = ZERO; _sezsf = ' '; for (int i = 0; i < 12; i++) { _prg_dare_mese[i] = ZERO; _prg_avere_mese[i] = ZERO; } _saldi.zero(); _saldi.put(SLD_ANNOES,annoes); _saldi.put(SLD_GRUPPO,g); _saldi.put(SLD_CONTO,c); _saldi.put(SLD_SOTTOCONTO,s); _saldi.put(SLD_FLSCA, ""); if (_saldi.read() == NOERR) { // int annoe = _saldi.get_int(SLD_ANNOES); // int gruppo = _saldi.get_int(SLD_GRUPPO); // int conto = _saldi.get_int(SLD_CONTO); // long sottoconto = _saldi.get_long(SLD_SOTTOCONTO); _saldo_iniziale = _saldi.get_real(SLD_SALDO); _prg_dare = _saldi.get_real(SLD_PDARE); _prg_avere = _saldi.get_real(SLD_PAVERE); pdarepro = _saldi.get_real(SLD_PDAREPRO); paverepro = _saldi.get_real(SLD_PAVEREPRO); sezione = _saldi.get_char(SLD_FLAGSALINI); _sezsf = _saldi.get_char(SLD_FLAGSALFIN); // W96SALDI del 19-06-96 modifica richiesta _saldofin = _saldi.get_real(SLD_SALDOFIN); // da PATRIZIA if (stp_prov == 1) //bilancio normale (senza provvisori) if (_saldo_iniziale.is_zero() && _prg_dare.is_zero() && _prg_avere.is_zero()) return esito; // if (stp_prov == 0 && paverepro == ZERO) if (stp_prov == 3 && paverepro.is_zero() && pdarepro.is_zero()) // Modifica del 24-09-96 errore MI0890. { _saldo = _prg_dare = _prg_avere = ZERO; // N.B. Non e' detto che funzioni sempre!!!!!! return esito; } if (sezione == 'A') _saldo_iniziale = -_saldo_iniziale; if (_sezsf == 'A') _saldofin = -_saldofin; // W96SALDI del 19-06-96 _saldoiniziale = _saldo_iniziale; //saldo iniziale presente sul record saldi //non comprensivo del saldo finale es.precedente if (_saldo_iniziale.is_zero() && stp_prov != 3) { if (indbil == 1 || indbil == 2 || indbil == 5) _saldo_iniziale += saldofin_esprec(annoes,g,c,s, false, stp_prov == 2); } esito = true; switch (stp_prov) { case 1: _saldo = _saldo_iniziale + _prg_dare - _prg_avere + _saldofin; // W96SALDI del 19-06-96 break; case 2: _saldo = _saldo_iniziale + _prg_dare - _prg_avere + pdarepro - paverepro + _saldofin; // W96SALDI del 19-06-96 if (pdarepro != ZERO) // Modifica del 24-09-96 errore MI0890: nel caso in cui i progressivi _prg_dare = pdarepro; // pdarepro o paverepro sono compilati sono in presenza di un movimento if (paverepro != ZERO) // provvisorio, dunque li trasferisco nei progressivi che poi uso nel _prg_avere = paverepro; // CG1500 per la stampa. break; case 3: _saldo = pdarepro - paverepro; _prg_dare = pdarepro; // Idem come sopra. _prg_avere = paverepro; // N.B. Non e' detto che funzioni sempre!!!!!! break; default: break; } } return esito; } //per bilancio a sezioni contrapposte all'ultima immissione // W96SALDI in questa funzione e' stato aggiunto il parametro saldo_chiusura che di default // e' true. A cosa serve ? Serve per includere nel calcolo del saldo all' ultima immissione // anche il saldo finale compilato nei movimenti di chiusura (se non venisse considerato i conti // risulterebbero aperti); siccome alcuni programmi (esempio il bilancio IV dir. CEE) non ne // devono tenere conto, si e' data la possibilita' di usare la funzione passandogli il parametro a false. // Modifica del 09-07-96 bool TSaldo::ultima_immissione_bilancio(int annoes,int g,int c,long s,int indbil,int stp_prov,bool saldo_chiusura) { //Si considerano i saldi e non piu' i movimenti char sezione; // int gruppo, conto, annoe; // long sottoconto; real pdarepro, paverepro; bool esito = false; _saldo_iniziale = ZERO; _prg_dare = ZERO; _prg_avere = ZERO; _saldo = ZERO; _saldofin = ZERO; _sezsf = ' '; _rec_presente_ec = false; _rec_presente_ep = false; _prec = false; for (int i = 0; i < 12; i++) { _prg_dare_mese[i] = ZERO; _prg_avere_mese[i] = ZERO; } _saldi.zero(); _saldi.put(SLD_ANNOES,annoes); _saldi.put(SLD_GRUPPO,g); _saldi.put(SLD_CONTO,c); _saldi.put(SLD_SOTTOCONTO,s); _saldi.put(SLD_FLSCA, ""); if (_saldi.read() == NOERR) { // annoe = _saldi.get_int(SLD_ANNOES); // gruppo = _saldi.get_int(SLD_GRUPPO); // conto = _saldi.get_int(SLD_CONTO); // sottoconto = _saldi.get_long(SLD_SOTTOCONTO); _saldo_iniziale = _saldi.get_real(SLD_SALDO); _prg_dare = _saldi.get_real(SLD_PDARE); _prg_avere = _saldi.get_real(SLD_PAVERE); pdarepro = _saldi.get_real(SLD_PDAREPRO); paverepro = _saldi.get_real(SLD_PAVEREPRO); sezione = _saldi.get_char(SLD_FLAGSALINI); _sezsf = _saldi.get_char(SLD_FLAGSALFIN); _saldofin = _saldi.get_real(SLD_SALDOFIN); if (stp_prov == 1) //bilancio normale (senza provvisori) esito = (_saldo_iniziale != ZERO || _prg_dare != ZERO || _prg_avere != ZERO); if (stp_prov == 2) //bilancio globale (con provvisori) esito = (_saldo_iniziale != ZERO || _prg_dare != ZERO || _prg_avere != ZERO || pdarepro != ZERO || paverepro != ZERO); if (stp_prov == 3) //bilancio dei soli mov. provvisori esito = (pdarepro != ZERO || paverepro != ZERO); if (sezione == 'A') _saldo_iniziale = -_saldo_iniziale; if (saldo_chiusura) // W96SALDI modifica inserita per il discorso di inclusione oppure if (_sezsf == 'A') // no del saldo di chiusura inserita il 09-07-96 _saldofin = -_saldofin; _rec_presente_ec = esito; } if (_saldo_iniziale.is_zero() && stp_prov != 3) if (indbil == 1 || indbil == 2 || indbil == 5) { _prec = true; _saldo_iniziale += saldofin_esprec(annoes,g,c,s,false,stp_prov==2); } if (stp_prov == 1) _saldo = _saldo_iniziale + _prg_dare - _prg_avere; if (stp_prov == 2) _saldo = _saldo_iniziale + _prg_dare - _prg_avere + pdarepro - paverepro; if (stp_prov == 3) _saldo = pdarepro - paverepro; if (saldo_chiusura) // W96SALDI modifica inserita per il discorso di inclusione oppure _saldo += _saldofin; // no del saldo di chiusura inserita il 09-07-96 #ifdef __LONGDOUBLE__ _saldo.round(TCurrency::get_firm_dec()); #endif return esito; } const real& TSaldo::saldo_periodo(int g, int c, long s, const TDate& dal, const TDate& al, int indbil, bool provv) { _saldo_iniziale = ZERO; _saldo = ZERO; _prg_dare = ZERO; _prg_avere = ZERO; _movimentato = false; _rec_presente_ep = false; _rec_presente_ec = false; _prec = false; for (int i = 0; i < 12; i++) { _prg_dare_mese[i] = ZERO; _prg_avere_mese[i] = ZERO; } TEsercizi_contabili es; const int codes = es.date2esc(dal); const TDate inizio = es.esercizio(codes).inizio(); _annoes = codes; TString80 key; key.format("%04d| |%d|%d|%ld", _annoes, g, c, s); const TRectype& saldo = cache().get(LF_SALDI, key); _saldo_iniziale = saldo.get_real(SLD_SALDO); _prec = _saldo_iniziale.is_zero() && (indbil == 1 || indbil == 2 || indbil == 5); if (_prec) { _saldo_iniziale = saldofin_esprec(codes,g,c,s); } else { if (saldo.get_char(SLD_FLAGSALINI) == 'A') _saldo_iniziale = -_saldo_iniziale; } TRelation relrmov(LF_RMOV); TRectype& rmov = relrmov.curr(); rmov.put(RMV_GRUPPO,g); rmov.put(RMV_CONTO,c); rmov.put(RMV_SOTTOCONTO,s); TCursor cur(&relrmov, "", 2, &rmov, &rmov); const TRecnotype items = cur.items(); if (items > 0) { cur.freeze(); TProgind* p = NULL; if (items > 100) // E' proprio utile la progind? { TString80 prompt; prompt.format(FR("Calcolo saldo del conto %d.%d.%ld"), g, c, s); p = new TProgind(items, prompt, false); } for (cur = 0L; cur.pos() < items; ++cur) { if (p != NULL) p->addstatus(1L); const long num_reg = rmov.get_long(RMV_NUMREG); const real importo = rmov.get_real(RMV_IMPORTO); if (!importo.is_zero()) { const char sezione = rmov.get_char(RMV_SEZIONE); // "Se la causale del movimento e' di chiusura, // o di apertura il movimento non va considerato" leggi_mov(num_reg); const TString& movap = _causali_apertura.decode(_codcaus); if ((provv || _provv.empty()) && movap.blank()) { if (_datacomp >= dal && _datacomp <= al) { _movimentato = true; const int m = _datacomp.month() - 1; if (sezione == 'D') { _prg_dare += importo; _prg_dare_mese[m] += importo; } else { _prg_avere += importo; _prg_avere_mese[m] += importo; } } else if (_datacomp >= inizio && _datacomp < dal) { if (sezione == 'D') _saldo_iniziale += importo; else _saldo_iniziale -= importo; } } } } if (p != NULL) delete p; } _saldo = _saldo_iniziale + _prg_dare - _prg_avere; return _saldo; } bool TSaldo::ricerca_progr_prec (int annoesprec, int g, int c, long s) { if (annoesprec == 0) _rec_presente_ep = false; else { const int oldkey = _saldi.getkey(); _saldi.setkey(1); _saldi.zero(); _saldi.put(SLD_ANNOES,annoesprec); _saldi.put(SLD_GRUPPO,g); _saldi.put(SLD_CONTO,c); _saldi.put(SLD_SOTTOCONTO,s); _saldi.put(SLD_FLSCA, ""); _rec_presente_ep = _saldi.read() == NOERR; _saldi.setkey(oldkey); } return _rec_presente_ep; } //calcolo dei progressivi attuali (normali o eliminati) bool TSaldo::prg_saldo(int annoes, TConto& conto, real& prgdare, real& prgavere, bool scar) { _saldi.zero(); _saldi.put(SLD_GRUPPO,conto.gruppo()); _saldi.put(SLD_CONTO,conto.conto()); _saldi.put(SLD_SOTTOCONTO,conto.sottoconto()); _saldi.put(SLD_ANNOES,annoes); _saldi.put(SLD_FLSCA, scar); bool ok = _saldi.read() == NOERR; if (ok) { const char flagsalini = _saldi.get_char(SLD_FLAGSALINI); const real saldoini = _saldi.get_real(SLD_SALDO); prgdare = _saldi.get_real(SLD_PDARE); prgavere = _saldi.get_real(SLD_PAVERE); if (flagsalini == 'D') prgdare += saldoini ; else prgavere += saldoini; } return ok; } bool TSaldo::saldo_cont_sep(int g, int c, long s, const int codes, TDate al, int indbil, const char * cont_sep, int provv, bool first) { _saldo_iniziale = ZERO; _saldo = ZERO; _prg_dare = ZERO; _prg_avere = ZERO; _movimentato = false; _rec_presente_ep = false; _rec_presente_ec = false; _prec = false; TEsercizi_contabili es; _annoes = codes; const TDate inizio = es[_annoes].inizio(); TString80 key; key.format("%04d| |%d|%d|%ld", _annoes, g, c, s); const TRectype& saldo = cache().get(LF_SALDI, key); if (!al.ok()) al = es[_annoes].fine(); /* if (_prec && first) { const int codesprec = es.date2prevesc(al); _saldo_iniziale = saldo_cont_sep(g, c, s, codesprec, es[codesprec].fine(), indbil, cont_sep, provv, false); } */ TRelation relrmov(LF_RMOV); TRectype& rmov = relrmov.curr(); rmov.put(RMV_GRUPPO,g); rmov.put(RMV_CONTO,c); rmov.put(RMV_SOTTOCONTO,s); TCursor cur(&relrmov, "", 2, &rmov, &rmov); const TRecnotype items = cur.items(); if (items > 0) { cur.freeze(); TProgind* p = NULL; if (items > 100) // E' proprio utile la progind? { TString80 prompt; prompt.format(FR("Calcolo saldo del conto %d.%d.%ld"), g, c, s); p = new TProgind(items, prompt, false); } for (cur = 0L; cur.pos() < items; ++cur) { if (p != NULL) p->addstatus(1L); const long num_reg = rmov.get_long(RMV_NUMREG); const real importo = rmov.get_real(RMV_IMPORTO); if (!importo.is_zero()) { const char sezione = rmov.get_char(RMV_SEZIONE); const TRectype& mov = cache().get(LF_MOV, num_reg); const bool ok = !mov.empty(); if (ok) { if (mov.get(MOV_CONTSEP) == cont_sep) { _codcaus = mov.get(MOV_CODCAUS); _datareg = mov.get(MOV_DATAREG); _provv = mov.get(MOV_PROVVIS); _datacomp = mov.get(MOV_DATACOMP); const TString& movap = _causali_apertura.decode(_codcaus); if (provv > 1 || _provv.empty()) { if (_datacomp >= inizio && _datacomp <= al) { if (movap.blank()) { _movimentato = true; if (sezione == 'D') _prg_dare += importo; else _prg_avere += importo; } else if (movap == "A") { _movimentato = true; if (sezione == 'D') _saldo_iniziale += importo; else _saldo_iniziale -= importo; } } } } } else NFCHECK("Testata assente: %ld", num_reg); } } if (p != NULL) delete p; } _saldo = _saldo_iniziale + _prg_dare - _prg_avere; return _movimentato; } /////////////////////////////////////////////////////////// // TContoExt /////////////////////////////////////////////////////////// class TContoExt : public TConto { bool _scaricato; public: bool scaricato() const { return _scaricato; } TContoExt(int g = 0, int c = 0, long s = 0L, char t = ' ', const char* d = NULL, bool sc = false) : TConto(g, c, s, t, d), _scaricato(sc) {} TContoExt(TToken_string& tgcsd, int from, int mode = 0, bool sc = false) : TConto(tgcsd, from, mode), _scaricato(sc) {} virtual ~TContoExt() {} }; const TString& TTab_conti::build_key(const TBill& c, int anno, bool scar) const { TString& key = get_tmp_string(23); key.format("%4d%3d%3d%6ld%c", anno, c.gruppo(), c.conto(), c.sottoconto(), scar ? 'X' : '\0'); return key; } TConto* TTab_conti::add(const TBill& c, int anno, bool scar) { const TString& key = build_key(c, anno, scar); TContoExt* tc = new TContoExt(c.gruppo(), c.conto(), c.sottoconto(), c.tipo(), NULL, scar); TAssoc_array::add(key, tc); return tc; } TConto* TTab_conti::find(const TBill& c, int anno, bool scar) { const TString& key = build_key(c, anno, scar); TContoExt* tc = (TContoExt*)objptr(key); return tc; } void TTab_conti::remove(const TBill& c, int anno, bool scar) { const TString& key = build_key(c, anno, scar); TAssoc_array::remove(key); } void TTab_conti::aggiorna_conto(const TBill& tcon, int anno_es, const TImporto& importo, tiposal movap, bool provv, bool somma, bool movimentato, bool scaricato) { TContoExt* tc = (TContoExt*)find(tcon, anno_es, scaricato); if (tc == NULL) tc = (TContoExt*)add(tcon, anno_es, scaricato); const real i(somma ? importo.valore() : -importo.valore()); if (provv) { if (importo.sezione() == 'D') tc->darepro() += i; else tc->averepro() += i; } else { if (movap == apertura) { if (importo.sezione() == 'D') tc->saldo() += i; else tc->saldo() -= i; } else { if (movap == chiusura) { if (importo.sezione() == 'D') tc->saldofin() += i; else tc->saldofin() -= i; } else { if (importo.sezione() == 'D') tc->dare() += i; else tc->avere() += i; } } } // rimuovo dalla tabella il conto se dare e avere vanno a zero if (!movimentato) if (tc->dare().is_zero() && tc->avere().is_zero() && tc->saldofin().is_zero() && tc->darepro().is_zero() && tc->averepro().is_zero() && tc->saldo().is_zero()) remove(*tc, anno_es, scaricato); } /////////////////////////////////////////////////////////// // TSaldo_agg /////////////////////////////////////////////////////////// TSaldo_agg::TSaldo_agg() : _anno_es(0), _data_ulmov(""), _num_ulmov(0l), _movap(normale), _provv(false), _movimentato(false) {} void TSaldo_agg::aggiorna(const TBill& tc, const TImporto& imp, bool somma, bool scaricato) { _tab_conti.aggiorna_conto(tc, _anno_es, imp, _movap, _provv, somma, _movimentato, scaricato); } void TSaldo_agg::aggiorna(int gruppo, int conto, long sottoconto, const real& importo, char sezione, bool somma, bool scaricato) { const TBill bill(gruppo, conto, sottoconto); const TImporto imp(sezione, importo); _tab_conti.aggiorna_conto(bill, _anno_es, imp, _movap, _provv, somma, _movimentato, scaricato); } void TSaldo_agg::reset() { _tab_conti.destroy(); } /////////////////////////////////////////////////////////////////////////////// // pulizia file saldi // // Scorro il file saldi per l' anno year o per tutti gli anni se year = 0 // e azzero i progressivi. // /////////////////////////////////////////////////////////////////////////////// void TSaldo_agg::clear_saldi(int year) { TLocalisamfile saldi(LF_SALDI); set_anno_es(year); saldi.zero(); if (anno_es() != 0) saldi.put(SLD_ANNOES, anno_es()); TRectype last(saldi.curr()); for (saldi.read(_isgteq, _lock); !saldi.eof() && saldi.curr() <= last; saldi.next(_lock)) { if (!saldi.get_bool(SLD_FLSCA)) { saldi.remove(); } else { saldi.put(SLD_FLSCA, ""); saldi.write(); saldi.put(SLD_FLSCA, "X"); saldi.read(_isequal,_unlock); } } saldi.reread(_unlock); } /////////////////////////////////////////////////////////////////////////////// // Aggiornamento file saldi // // Scorro la tabella dei conti interna _tab_conti. // Per ogni conto cerco il record su saldi, se non c'e' lo creo. // Se c'e' gia' lo aggiorno nel seguente modo: // GLOP /////////////////////////////////////////////////////////////////////////////// void TSaldo_agg::registra() { real si, r; char flag_salini; TDate data_ulmov; long num_ulmov; TLocalisamfile saldi(LF_SALDI); int conti = _tab_conti.items(); _tab_conti.restart(); for (int i = 0; i < conti; i++) { THash_object* hobj = _tab_conti.get_hashobj(); TContoExt& tcon = (TContoExt&)hobj->obj(); CHECK(tcon.ok(), "Tentativo di saldare un conto incompleto"); const int annoes = atoi(hobj->key().left(4)); saldi.zero(); saldi.put(SLD_ANNOES, annoes); saldi.put(SLD_GRUPPO, tcon.gruppo()); saldi.put(SLD_CONTO, tcon.conto()); saldi.put(SLD_SOTTOCONTO, tcon.sottoconto()); saldi.put(SLD_FLSCA, tcon.scaricato()); bool update = true; if (saldi.read(_isequal, _lock) != NOERR) { saldi.zero(); saldi.put(SLD_ANNOES, annoes); saldi.put(SLD_GRUPPO, tcon.gruppo()); saldi.put(SLD_CONTO, tcon.conto()); saldi.put(SLD_SOTTOCONTO, tcon.sottoconto()); saldi.put(SLD_FLSCA, tcon.scaricato()); si = tcon.saldo(); if (si < ZERO) { flag_salini = 'A'; si = -si; } else flag_salini = 'D'; saldi.put(SLD_FLAGSALINI, flag_salini); saldi.put(SLD_SALDO, si); saldi.put(SLD_PDARE, tcon.dare()); saldi.put(SLD_PAVERE, tcon.avere()); saldi.put(SLD_PDAREPRO, tcon.darepro()); saldi.put(SLD_PAVEREPRO, tcon.averepro()); real sf = tcon.saldofin(); char flag_salfin = sf < ZERO ? 'A' : 'D'; if (flag_salfin == 'A') sf = -sf; saldi.put(SLD_FLAGSALFIN, flag_salfin); saldi.put(SLD_SALDOFIN, sf); if (_num_ulmov != 0L) saldi.put(SLD_NUMULTMOV, _num_ulmov); if (_data_ulmov.ok()) saldi.put(SLD_DATAULMOV, _data_ulmov); update = saldi.write() == _isreinsert; if (update) saldi.read(_isequal, _lock); } if (update) { num_ulmov = saldi.get_long(SLD_NUMULTMOV); data_ulmov = saldi.get_date(SLD_DATAULMOV); if ((_num_ulmov != 0L) && (_num_ulmov > num_ulmov)) saldi.put(SLD_NUMULTMOV, _num_ulmov); if ((_data_ulmov.ok()) && (_data_ulmov > data_ulmov)) saldi.put(SLD_DATAULMOV, _data_ulmov); r = tcon.saldo(); si = saldi.get_real(SLD_SALDO); flag_salini = saldi.get_char(SLD_FLAGSALINI); if (r != ZERO) { if (flag_salini == 'A') si = r - si; else si += r; if (si < ZERO) { flag_salini = 'A'; si = -si; } else flag_salini = 'D'; saldi.put(SLD_FLAGSALINI, flag_salini); saldi.put(SLD_SALDO, si); } TImporto sf('D', tcon.saldofin()); char old_flag_sf = saldi.get(SLD_FLAGSALFIN)[0]; TImporto old_sf(old_flag_sf, saldi.get_real(SLD_SALDOFIN)); sf += old_sf; sf.normalize(); saldi.put(SLD_FLAGSALFIN, sf.sezione()); saldi.put(SLD_SALDOFIN, sf.valore()); r = saldi.get_real(SLD_PDARE); r += tcon.dare(); saldi.put(SLD_PDARE, r); r = saldi.get_real(SLD_PAVERE); r += tcon.avere(); saldi.put(SLD_PAVERE, r); r = saldi.get_real(SLD_PDAREPRO); r += tcon.darepro(); saldi.put(SLD_PDAREPRO, r); r = saldi.get_real(SLD_PAVEREPRO); r += tcon.averepro(); saldi.put(SLD_PAVEREPRO, r); const int err = saldi.rewrite(); if (err != NOERR) yesnofatal_box(FR("Errore %d nell'aggiornamento del saldo %d %d %ld"), err, tcon.gruppo(), tcon.conto(), tcon.sottoconto()); } // Calcolo saldo finale per controllo segno in prima nota if (si.is_zero()) { TLocalisamfile pcon(LF_PCON); TRectype& curr = pcon.curr(); curr.put(PCN_GRUPPO, tcon.gruppo()); curr.put(PCN_CONTO, tcon.conto()); const int err = pcon.read(); if (err == NOERR) { const int indbil = curr.get_int(PCN_INDBIL); if (indbil == 1 || indbil == 2 || indbil == 5) { TSaldo saldo; si = saldo.saldofin_esprec(annoes, tcon.gruppo(), tcon.conto(), tcon.sottoconto()); if (si < ZERO) { flag_salini = 'A'; si = -si; } else flag_salini = 'D'; } } else { // Era errore fatale } } TImporto sf(flag_salini, si); const TImporto dare('D', saldi.get_real(SLD_PDARE)); const TImporto avere('A', saldi.get_real(SLD_PAVERE)); sf += dare; sf += avere; sf.normalize(+1); // Rendi sempre positivo tcon.saldo_finale() = sf; } } /////////////////////////////////////////////////////////// // TBalance /////////////////////////////////////////////////////////// TBalance::TBalance() { } TBalance::TBalance(int g, int c, long s, int esercizio, bool ignora_movap, bool provvis) { read(g, c, s, esercizio, ignora_movap, provvis); } TBalance::TBalance(const TBill& b, int esercizio, bool ignora_movap, bool provvis) { read(b, esercizio, ignora_movap, provvis); } bool TBalance::find(const TBill& b, int esercizio, TImporto& si, TImporto& da, TImporto& av, TImporto& sf, TImporto& pd, TImporto& pa) const { CHECK(b.sottoconto() > 0L, "Sottoconto mancante"); TString80 key; key.format("%d||%d|%d|%ld", esercizio, b.gruppo(), b.conto(), b.sottoconto()); const TRectype & saldi = cache().get(LF_SALDI, key); const bool ok = !saldi.empty(); if (ok) { si.set(saldi.get_char(SLD_FLAGSALINI), saldi.get_real(SLD_SALDO)); da.set('D', saldi.get_real(SLD_PDARE)); av.set('A', saldi.get_real(SLD_PAVERE)); sf.set(saldi.get_char(SLD_FLAGSALFIN), saldi.get_real(SLD_SALDOFIN)); pd.set('D', saldi.get_real(SLD_PDAREPRO)); pa.set('A', saldi.get_real(SLD_PAVEREPRO)); } else { si.set('D', ZERO); da = av = sf = pd = pa = si; } return ok; } void TBalance::read(int gruppo, int conto, long sottoconto, int esercizio, bool ignora_movap, bool provvis) { const TBill zio(gruppo, conto, sottoconto); read(zio, esercizio, ignora_movap, provvis); } int TBalance::indicatore_bilancio(const TBill& b) const { TString16 str; str.format("%d|%d", b.gruppo(), b.conto()); const int ib = atoi(cache().get(LF_PCON, str, PCN_INDBIL)); #ifdef DBG if (ib < 1 || ib > 5) { TString msg; msg << "Impossibile stabilire l'indicatore di bilancio del conto " << b.gruppo() << ' ' << b.conto(); NFCHECK(msg); } #endif return ib; } void TBalance::read(const TBill& b, int esercizio, bool ignora_movap, bool provvis) { TImporto si, sf, pd, pa, prd, pra; find(b, esercizio, si, pd, pa, sf, prd, pra); if (provvis) { pd += prd; pa += pra; } _saldo_ini = si; _progr_dare = pd; _progr_avere = pa; _saldo_fin = sf; if (_saldo_ini.is_zero()) { const int indbil = indicatore_bilancio(b); if (indbil == 1 || indbil == 2 || indbil == 5) { TEsercizi_contabili esercizi; const int precedente = esercizi.pred(esercizio); if (precedente > 0 && find(b, precedente, si, pd, pa, sf, prd, pra)) { if (provvis) { pd += prd; pa += pra; } _saldo_ini = si; _saldo_ini += pd; _saldo_ini += pa; _saldo_ini += sf; _saldo_ini.normalize(); } } } else { if (ignora_movap) _saldo_ini.set('D', ZERO); } } const TImporto& TBalance::saldo_iniziale() const { return _saldo_ini; } const real& TBalance::progressivo_dare_iniziale() const { return _saldo_ini.sezione() == 'D' ? _saldo_ini.valore() : ZERO; } const real& TBalance::progressivo_avere_iniziale() const { return _saldo_ini.sezione() == 'A' ? _saldo_ini.valore() : ZERO; } real TBalance::progressivo_dare_finale() const { real pd = progressivo_dare_iniziale(); pd += _progr_dare.valore(); if (_saldo_fin.sezione() == 'D') pd += _saldo_fin.valore(); return pd; } real TBalance::progressivo_avere_finale() const { real pa = progressivo_avere_iniziale(); pa += _progr_avere.valore(); if (_saldo_fin.sezione() == 'A') pa += _saldo_fin.valore(); return pa; } TImporto TBalance::saldo_finale(bool chiusura) const { TImporto sf(_saldo_ini); sf += _progr_dare; sf += _progr_avere; if (chiusura) sf += _saldo_fin; return sf; } TImporto TBalance::saldo_finale_chiusura() const { return saldo_finale(true); }