campo-sirio/src/cg/cglib02.cpp
AlexBonazzi 1ba75cc8f2 Patch level : 12.0 642
Files correlati     : cg1.exe cg2.exe cg4.exe cg5.exe np0.exe
Commento            :

Aggiunto il conto utile IV direttiva ai parametri ditta (se non indicato vale 9 E 22) e gestito in stampa bilancio IV direttiva.

Impostato il valore della riga di saldaconto all importo se non indicato.

Contabilità separata letto correttamente dalla maschera il codice di contabilità separata.

Non stampava il riepigolo fatture per cassa  nella stampa definitiva.
2018-11-26 01:50:39 +01:00

1265 lines
36 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 chiusura, bool first)
{
_movimentato = false;
_rec_presente_ep = false;
_rec_presente_ec = false;
_prec = false;
real saldo_ini_prec;
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();
_saldo_iniziale = ZERO;
_saldo = ZERO;
_prg_dare = ZERO;
_prg_avere = ZERO;
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 (( cont_sep != NULL && *cont_sep == '\0') || 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
if (chiusura && movap == "C")
{
_movimentato = true;
if (sezione == 'D')
_prg_dare += importo;
else
_prg_avere += 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);
}