///////////////////////////////////////////////////////////////////////////// // cglib02.cpp // // Aggiornamento saldi // ///////////////////////////////////////////////////////////////////////////// #include #include #include #include #include "cglib.h" #include 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() {} }; TConto* TTab_conti::add(const TBill& c, int anno, bool scar) { TString80 key; key.format("%4d%3d%3d%6ld", anno, c.gruppo(), c.conto(), c.sottoconto()); if (scar) key << "X"; 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) { TString80 key; key.format("%4d%3d%3d%6ld", anno, c.gruppo(), c.conto(), c.sottoconto()); if (scar) key << "X"; TContoExt* tc = (TContoExt*)objptr(key); return tc; } void TTab_conti::remove(const TBill& c, int anno, bool scar) { TString80 key; key.format("%4d%3d%3d%6ld", anno, c.gruppo(), c.conto(), c.sottoconto()); if (scar) key << "X"; 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 TImporto imp(sezione, importo); _tab_conti.aggiorna_conto(TBill(gruppo, conto, sottoconto), _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"); saldi.zero(); saldi.put(SLD_ANNOES, atoi(hobj->key().left(4)) ); 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, atoi(hobj->key().left(4))); 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("Errore %d nell'aggiornamento del saldo %d %d %ld", err, tcon.gruppo(), tcon.conto(), tcon.sottoconto()); } 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; } } /////////////////////////////////////////////////////////// // 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"); } 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; } 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()) { #ifdef DBG if (_firm != 0) error_box("Questo programma carinissimo usa gli esercizi,\n" "purtroppo non tiene conto del cambio ditta!"); #endif update(); } } int TEsercizi_contabili::date2index(const TDate& d) const { check(); for (int 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 { check(); for (int 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::first() const { check(); return items() ? esc(0).codice() : 0; } int TEsercizi_contabili::last() const { check(); return items() ? esc(items()-1).codice() : 0; } 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 { const int i = esc2index(codice); return esc(i); }