campo-sirio/cg/cglib02.cpp
guy e9f6cac415 Corretta gestione ini in banche clifo
git-svn-id: svn://10.65.10.50/branches/R_10_00@22933 c028cbd2-c16b-5b4b-a496-9718f37d4682
2014-05-14 08:25:17 +00:00

1261 lines
35 KiB
C++
Executable File

/////////////////////////////////////////////////////////////////////////////
// cglib02.cpp
//
// Aggiornamento saldi
//
/////////////////////////////////////////////////////////////////////////////
#include "cglib01.h"
#include "cglib02.h"
#include <diction.h>
#include <progind.h>
#include <relation.h>
#include <causali.h>
#include <mov.h>
#include <pconti.h>
#include <rmov.h>
#include <saldi.h>
///////////////////////////////////////////////////////////
// TSaldi_list
///////////////////////////////////////////////////////////
//
// Cerca l'esercizio precedente di EseCorr
// Se EseCorr e' già 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 già 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 realtà 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 possibilità 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::aggiorna(const TRectype& rmov, bool somma, bool scaricato)
{
const real imp = rmov.get(RMV_IMPORTO);
if (!imp.is_zero())
{
const char sez = rmov.get_char(RMV_SEZIONE);
const TImporto importo(sez, imp);
const TBill bill(rmov);
const long numreg = rmov.get_long(RMV_NUMREG);
if (numreg > _num_ulmov)
{
_num_ulmov = numreg;
_data_ulmov = rmov.get_date(RMV_DATAREG);
_anno_es = rmov.get_int(RMV_ANNOES);
}
aggiorna(bill, importo, somma, 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)
{
TFast_isamfile saldi(LF_SALDI);
set_anno_es(year);
saldi.zero();
if (anno_es() != 0)
saldi.put(SLD_ANNOES, anno_es());
const 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' già 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);
const 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();
const int annoes = atoi(hobj->key().left(4));
CHECK(tcon.ok() && annoes > 2000, "Tentativo di saldare un conto incompleto");
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.is_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);
}