#include "abpcon.h" #include #include #include #include #include #include #include #include #include #include "../cg/cglib01.h" #include "../cg/cglib02.h" #include "ab0.h" #include "ab0400.h" /////////////////////////////////////////////////////////// // TRicl_mask /////////////////////////////////////////////////////////// class TRicl_mask : public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TRicl_mask() : TAutomask("ab0400a") { } virtual ~TRicl_mask() { } }; bool TRicl_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { const short id = o.dlg(); switch (id) { case F_ESER: case F_PDB: if (e == fe_modify) { TMask & m = o.mask(); const TString16 codpdb = m.get(F_PDB); const int eser = m.get_int(F_ESER); if (eser == 0 || codpdb.empty()) { m.set(F_DAL, ""); m.set(F_AL, ""); } else { TEsercizi_contabili es; es.update(); const int anno = es.esercizio(eser).inizio().year(); const TRectype & pdb = cache().get("%PDB", codpdb); TDate dal(pdb.get_int("I0"), pdb.get_int("I1"), anno); TDate al(pdb.get_int("I2"), pdb.get_int("I3"), anno); if (al < dal) al.addyear(1); m.set(F_DAL, dal); m.set(F_AL, al); } } break; default: break; } return TRUE; } enum TCalc_type { _ivdircee = 1, _ricl } ; class TRiga_calcolo : public TObject { int _gruppo; int _conto; long _sottoconto; int _indbil; real _saldo_iniziale; real _prog_dare; real _prog_avere; virtual TObject* dup() const { return new TRiga_calcolo(*this);} public: void set_conto(int g, int c, long s, int i) { _gruppo = g; _conto = c; _sottoconto = s; _indbil = i;} void set_saldi(const real & si, const real & pd, const real & pa) { _saldo_iniziale = si; _prog_dare = pd; _prog_avere = pa;} const int gruppo() const { return _gruppo;} const int conto() const { return _conto;} const long sottoconto() const { return _sottoconto;} const int indicatore_bilancio() const { return _indbil;} real saldo_iniziale() const { return _saldo_iniziale;} real prog_dare() const { return _prog_dare;} real prog_avere() const { return _prog_avere;} real saldo() const { return _saldo_iniziale + _prog_dare - _prog_avere;} bool sezione_opposta() const; TRiga_calcolo& copy(const TRiga_calcolo& c); TRiga_calcolo(const TRiga_calcolo& c); TRiga_calcolo() {} virtual ~TRiga_calcolo() {} }; bool TRiga_calcolo::sezione_opposta() const { bool reverse = FALSE; const real s = saldo(); if (s != ZERO) { char sezione = s > ZERO ? 'D' : 'A'; if (_indbil == 1 || _indbil == 3) reverse = sezione == 'A'; else if (_indbil == 2 || _indbil == 4) reverse = sezione == 'D'; } return reverse; } TRiga_calcolo & TRiga_calcolo::copy(const TRiga_calcolo & c) { _gruppo = c._gruppo; _conto = c._conto; _sottoconto = c._sottoconto; _indbil = c._indbil; _saldo_iniziale = c._saldo_iniziale; _prog_dare = c._prog_dare; _prog_avere = c._prog_avere; return *this; } TRiga_calcolo::TRiga_calcolo(const TRiga_calcolo & c) { copy(c); } class TRiga_output : public TObject { TString _code; real _saldo_iniziale; real _prog_dare; real _prog_avere; virtual TObject* dup() const { return new TRiga_output(*this);} public: TRiga_output & operator +=(const TRiga_calcolo & c); const TString & code() const { return _code;} real saldo_iniziale() const { return _saldo_iniziale;} real prog_dare() const { return _prog_dare;} real prog_avere() const { return _prog_avere;} real saldo() const { return _saldo_iniziale + _prog_dare - _prog_avere;} char sezione_saldo() const { return saldo() > 0 ? 'D' : 'A';} TRiga_output& copy(const TRiga_output& o); TRiga_output(const TRiga_output& o); TRiga_output(const char * code) : _code(code) {} virtual ~TRiga_output() {} }; TRiga_output & TRiga_output::operator += (const TRiga_calcolo & c) { _saldo_iniziale += c.saldo_iniziale(); _prog_dare += c.prog_dare(); _prog_avere += c.prog_avere(); return *this; } TRiga_output & TRiga_output::copy(const TRiga_output & o) { _code = o._code; _saldo_iniziale = o._saldo_iniziale; _prog_dare = o._prog_dare; _prog_avere = o._prog_avere; return *this; } TRiga_output::TRiga_output(const TRiga_output& o) { copy(o); } enum TFile_type { _textfile, _csvfile, _dbffile } ; class TRicl_saldi : public TSkeleton_application { TRicl_mask *_mask; TFilename _output_file; TCalc_type _calc_type; int _codes; TDate _dal; TDate _al; bool _provv; TString _codpdb; TArray _risultati; TAssoc_array _output; TString_array _output_keys; bool _clear; ofstream * _file; TExternisamfile * _dbf; #ifdef DBG protected: FILE * _log; void open_log(); void write_log(const char * line); void close_log(); #endif public: virtual bool create(); virtual bool destroy(); void mask2parms(const TMask & m); void calculate(); void transform(); void get_code(const TRectype & rec, bool cee, bool reverse, TString & code); void map(int gruppo, int conto, long sottoconto, bool reverse, TString & code); void output(); virtual void main_loop(); TFile_type open_output(); void output_line(TFile_type t, const char * key, TRiga_output & r); void close_output(TFile_type t); TRicl_saldi() {} virtual ~TRicl_saldi() {} }; #ifdef DBG void TRicl_saldi::open_log() { TFilename log("ab0400.log"); _log = fopen(log,"a"); if (_log == NULL) fatal_box(FR("Non posso aprire il file di log della conversione(%s)"), (const char *) log); } void TRicl_saldi::write_log(const char * line) { fprintf(_log,"%s\n", line); } void TRicl_saldi::close_log() { fclose(_log); } #endif bool TRicl_saldi::create() { open_files(LF_TAB, LF_TABCOM, LF_ABPCON, LF_ABSALDI, LF_SALDI, LF_RMOV, LF_MOV, LF_PCON, 0); _mask = new TRicl_mask(); return TSkeleton_application::create(); } bool TRicl_saldi::destroy() { delete _mask; return TSkeleton_application::destroy(); } void TRicl_saldi::mask2parms(const TMask & m) { _calc_type = (TCalc_type) m.get_int(F_TIPO); _codes = m.get_int(F_ESER); _dal = m.get(F_DAL); _al = m.get(F_AL); if (_dal.ok() && !_al.ok()) { const TDate oggi(TODAY); if (oggi > _dal) _al = oggi; else { _al.set_year(_dal.year()); _al.set_month(12); _al.set_day(31); } } _provv = m.get_bool(F_PROVV); _output_file = m.get(F_OUTPUT); _codpdb = m.get(F_PDB); _clear = m.get_bool(F_CLEAR); #ifdef DBG TString line ; write_log("---------------------------------------------------"); line = TR("Tipo di calcolo : "); line << (_calc_type ? TR("IV Direttiva CEE") : TR("Analisi")); write_log(line); line = TR("Esercizio : "); line << _codes; write_log(line); line = TR("Codice periodo : "); line << _codpdb; write_log(line); line = TR("Dal : "); line << _dal.string(); write_log(line); line = TR("Al : "); line << _al.string(); write_log(line); line = TR("Movimenti provv.: "); line << (_provv ? "Si" : "No"); write_log(line); line = TR("Output : "); line << ((const char *) _output_file) << " da ricreare : " << (_clear ? "Si" : "No"); write_log(line); write_log(""); #endif } void TRicl_saldi::calculate() { TRelation relpcon(LF_PCON); const TRectype & pcon = relpcon.curr(); TCursor cur(&relpcon, "CONTO!=0"); int gruppo; int conto; long sottoconto; int indbil; TSaldo sal; TRiga_calcolo r; const bool saldi_attuali = !_dal.ok() && !_al.ok(); const TRecnotype items = cur.items(); cur.freeze(); TProgind p(items, TR("Ricalcolo saldi"), FALSE); for (cur = 0L; !p.iscancelled() && cur.pos() < items; ++cur) { gruppo = pcon.get_int(PCN_GRUPPO); conto = pcon.get_int(PCN_CONTO); sottoconto = pcon.get_long(PCN_SOTTOCONTO); if (sottoconto == 0L) indbil = pcon.get_int(PCN_INDBIL); else { if (saldi_attuali) sal.ultima_immissione_bilancio(_codes, gruppo, conto, sottoconto, indbil, _provv ? 2 :1, FALSE); else sal.valore_al(gruppo, conto, sottoconto, _dal, _al, indbil, _provv); r.set_conto(gruppo, conto, sottoconto, indbil); r.set_saldi(sal.saldoini(), sal.prgdare(), sal.prgavere()); #ifdef DBG TString line ; line.format(FR("Conto %03d.%03d.%06ld - "), gruppo, conto, sottoconto); line << TR("Saldo iniziale ") << sal.saldoini().stringa(18, 3); line << TR(" Prog.Dare ") << sal.prgdare().stringa(18, 3); line << TR(" Prog.Avere ") << sal.prgavere().stringa(18, 3); line << TR(" Saldo ") << sal.saldo().stringa(18, 3); write_log(line); #endif _risultati.add(r); } } } void TRicl_saldi::get_code(const TRectype &rec, bool cee, bool reverse, TString & code) { if (cee) { bool opp = reverse && rec.get_int(PCN_SEZIVDOPP) != 0; code = rec.get(opp ? PCN_SEZIVDOPP : PCN_SEZIVD); if (code == "0") code.cut(0); else { code << rec.get(opp ? PCN_LETTIVDOPP : PCN_LETTIVD); code << format("%4s", (const char *) rec.get(opp ? PCN_NUMRIVDOPP : PCN_NUMRIVD)); const int numrivd = rec.get_int(opp ? PCN_NUMIVDOPP : PCN_NUMIVD); if (numrivd != 0) code << format("%02d", numrivd); code.trim(); } } else code = rec.get(PCN_CODCBL); } void TRicl_saldi::map(int gruppo, int conto, long sottoconto, bool reverse, TString & code) { const bool cee =_calc_type == _ivdircee; code.format("%d|%d|%ld", gruppo, conto, sottoconto); const TRectype & recs = cache().get(LF_PCON, code); get_code(recs, cee, reverse, code); if (code.empty()) { code.format("%d|%d", gruppo, conto); const TRectype & recc = cache().get(LF_PCON, code); get_code(recc, cee, reverse, code); if (code.empty()) { code.format("%d", gruppo); const TRectype & recg = cache().get(LF_PCON, code); get_code(recg, cee, reverse, code); } } } void TRicl_saldi::transform() { const int items = _risultati.items(); TString80 key; for (int i = 0; i < items; i++) { const TRiga_calcolo & c = (const TRiga_calcolo &) _risultati[i]; const int gruppo = c.gruppo(); const int conto = c.conto(); const long sottoconto = c.sottoconto(); const bool reverse = c.sezione_opposta(); map(gruppo, conto, sottoconto, reverse, key); if (key.not_empty()) { TRiga_output * r = (TRiga_output *)_output.objptr(key); if (r == NULL) { r = new TRiga_output(key); _output.add(key, r); } *r += c; } } } TFile_type TRicl_saldi::open_output() { TString16 ext = _output_file.ext(); TFile_type t; if (ext == "dbf") t = _dbffile; else if (ext == "csv") t = _csvfile; else t = _textfile; if (t == _dbffile) _dbf = _clear ? new TExternisamfile(_output_file, "ab0400.trr") : new TExternisamfile(_output_file); else _file = new ofstream(_output_file, _clear ? ios::trunc : ios::app); return t; } void TRicl_saldi::output_line(TFile_type t, const char * key, TRiga_output & r) { TString descr; if (_calc_type == _ivdircee) descr = cache().get("%IVD", key, "S0"); else descr = cache().get(LF_ABPCON, key, ABPC_DESCRIZ); real si = r.saldo_iniziale(); char fsi = 'D'; real s = r.saldo(); char fs = 'D'; real pd = r.prog_dare(); real pa = r.prog_avere(); if (si < ZERO) { si = -si; fsi = 'A'; } if (s < ZERO) { s = -s; fs = 'A'; } #ifdef DBG TString line ; line.format(FR("Chiave %s"), key); line << TR("Saldo iniziale ") << si.stringa(18, 3) << " " << fsi; line << TR(" Prog.Dare ") << pd.stringa(18, 3); line << TR(" Prog.Avere ") << pa.stringa(18, 3); line << TR(" Saldo ") << s.stringa(18, 3) << " " << fs; write_log(line); #endif if (t == _dbffile) { TRectype & r = _dbf->curr(); r.put("ANNOES", _codes); r.put("KEY", key); r.put("DESCR", descr); r.put("SALDOI", si); r.put("FLAGSI", fsi); r.put("PDARE", pd); r.put("PAVERE", pa); r.put("SALDO", s); r.put("FLAGS", fs); r.put("DATAI", _dal); r.put("DATAF", _al); r.put("CODPDB", _codpdb); if (_dbf->write(r) != NOERR) _dbf->rewrite(r); } else if (t == _csvfile) { *_file << _codes << ";"; *_file << "\""<< key << "\";"; *_file << "\"" << descr << "\";"; *_file << si.string() << ";"; *_file << fsi << ";"; *_file << pd.string() << ";"; *_file << pa.string() << ";"; *_file << s.string() << ";"; *_file << fs << ";"; *_file << _dal << ";"; *_file << _al << ";"; *_file << _codpdb << "\n"; } else { *_file << _codes << "\t"; *_file << key << "\t"; *_file << descr << "\t"; *_file << si.string() << "\t"; *_file << fsi << "\t"; *_file << pd.string() << "\t"; *_file << pa.string() << "\t"; *_file << s.string() << "\t"; *_file << fs << "\t"; *_file << _dal << "\t"; *_file << _al << "\t"; *_file << _codpdb << "\n"; } } void TRicl_saldi::close_output(TFile_type t) { if (t == _dbffile) { delete _dbf; _dbf = NULL; } else { delete _file; _file = NULL; } } void TRicl_saldi::output() { _output_keys.destroy(); _output.get_keys(_output_keys); _output_keys.sort(); const int items = _output_keys.items(); TFile_type t = open_output(); for (int i = 0; i < items; i++) { TString & key = _output_keys.row(i); TRiga_output & r = (TRiga_output &) _output[key]; output_line(t, key, r); } close_output(t); } void TRicl_saldi::main_loop() { while (_mask->run() != K_QUIT) { #ifdef DBG open_log(); #endif mask2parms(*_mask); calculate(); transform(); output(); #ifdef DBG close_log(); #endif } } int ab0400 (int argc, char* argv[]) { TRicl_saldi main_app; main_app.run(argc, argv, "Riclassifica saldi"); return TRUE; }