#include #include #include #include #include "baeur.h" #include "baeur20.h" #include "../cg/cglib01.h" #include #include #include #include #include /////////////////////////////////////////////////////////// // Main app /////////////////////////////////////////////////////////// class TEuro02_app : public TEuro_app { public: virtual void main_loop(); }; inline TEuro02_app& app() { return (TEuro02_app&)main_app(); } /////////////////////////////////////////////////////////// // Gestione movimenti di apertura e chiusura /////////////////////////////////////////////////////////// bool TCG_mov::add(int g, int c, long s, char sez, const real& imp) { bool ok = s > 0; if (ok) { TCG_rmov* rmov = new TCG_rmov; rmov->_gruppo = g; rmov->_conto = c; rmov->_sottoconto = s; rmov->_importo.set(sez, imp); TArray::add(rmov); } #ifdef DBG else error_box("Conto non valido: %d %d %ld", g, c, s); #endif return ok; } bool TCG_mov::add(const TBill& bill, const TImporto& imp) { int g = bill.gruppo(); int c = bill.conto(); long s = bill.sottoconto(); char sez = imp.sezione(); real val = imp.valore(); return add(g, c, s, sez, val); } void TCG_mov::crea_testata(TLocalisamfile& mov, const TString& caus, const TDate& datareg, const TString& desc) const { long numreg = 1; if (mov.last() == NOERR) numreg = mov.get_long(MOV_NUMREG)+1; mov.zero(); mov.put(MOV_NUMREG, numreg); mov.put(MOV_CODCAUS, caus); mov.put(MOV_DATAREG, datareg); mov.put(MOV_DATACOMP, datareg); mov.put(MOV_DESCR, desc); mov.put(MOV_ANNOIVA, datareg.year()); TEsercizi_contabili esc; const int annoes = esc.date2esc(datareg); mov.put(MOV_ANNOES, annoes); } void TCG_mov::crea_riga(const TRectype& mov, TRectype& rmov, int r) const { rmov.zero(); rmov.put(RMV_NUMREG, mov.get(MOV_NUMREG)); rmov.put(RMV_NUMRIG, r); rmov.put(RMV_DATAREG, mov.get(MOV_DATAREG)); rmov.put(RMV_ANNOES, mov.get(MOV_ANNOES)); } void TCG_mov::update_saldo(const TRectype& mov, const TRectype& rmov, TLocalisamfile& saldi) { TBill zio; zio.get(rmov); TRectype& curr = saldi.curr(); curr.zero(); curr.put(SLD_ANNOES, mov.get(MOV_ANNOES)); curr.put(SLD_GRUPPO, zio.gruppo()); curr.put(SLD_CONTO, zio.conto()); curr.put(SLD_SOTTOCONTO, zio.sottoconto()); curr.put(SLD_FLSCA, ""); const bool found = saldi.read() == NOERR; if (!found) { curr.zero(); curr.put(SLD_ANNOES, mov.get(MOV_ANNOES)); curr.put(SLD_GRUPPO, zio.gruppo()); curr.put(SLD_CONTO, zio.conto()); curr.put(SLD_SOTTOCONTO, zio.sottoconto()); curr.put(SLD_FLSCA, ""); } const TDate sld_datareg = curr.get(SLD_DATAULMOV); const TDate mov_datareg = mov.get(MOV_DATAREG); if (mov_datareg >= sld_datareg) { curr.put(SLD_NUMULTMOV, mov.get(MOV_NUMREG)); curr.put(SLD_DATAULMOV, mov_datareg); } const TImporto importo(rmov.get_char(RMV_SEZIONE), rmov.get_real(RMV_IMPORTO)); const TString4 caus = mov.get(MOV_CODCAUS); const char movap = cache().get(LF_CAUSALI, caus, CAU_MOVAP)[0]; switch (movap) { case 'A': { TImporto saldo(curr.get_char(SLD_FLAGSALINI), curr.get_real(SLD_SALDO)); saldo += importo; saldo.normalize(); curr.put(SLD_FLAGSALINI, saldo.sezione()); curr.put(SLD_SALDO, saldo.valore()); } break; case 'C': { TImporto saldo(curr.get_char(SLD_FLAGSALFIN), curr.get_real(SLD_SALDOFIN)); saldo += importo; saldo.normalize(); curr.put(SLD_FLAGSALFIN, saldo.sezione()); curr.put(SLD_SALDOFIN, saldo.valore()); } break; default: { const char* field = importo.sezione() == 'D' ? SLD_PDARE : SLD_PAVERE; real saldo = curr.get(field); saldo += importo.valore(); curr.put(field, saldo); } break; } if (found) saldi.rewrite(); else saldi.write(); } // Salva un movimento di primanota, eventualmente spezzandolo su piu' records se necessario TImporto TCG_mov::save(const TDate& datareg, const TString& caus, const TString& desc, const TBill& contro, bool adeuro, bool convert, bool invert) { TProgind pi(items(), desc, FALSE, TRUE); // Apro comunque i file in lire per avere i tracciati TLocalisamfile lmov(LF_MOV); TLocalisamfile lrmov(LF_RMOV); TLocalisamfile lsaldi(LF_SALDI); TLocalisamfile *pmov, *prmov, *psaldi; // Apro quelli in euro se necessario if (adeuro) { pmov = new TEuroisamfile(LF_MOV, adeuro); prmov = new TEuroisamfile(LF_RMOV, adeuro); psaldi = new TEuroisamfile(LF_SALDI, adeuro); } else { pmov = &lmov; prmov = &lrmov; psaldi = &lsaldi; } TLocalisamfile& mov = *pmov; TLocalisamfile& rmov = *prmov; TLocalisamfile& saldi = *psaldi; TImporto bilancio; for (int i = 0; i < items(); i += MAX_CG_ROWS) { const int first_row = i; int last_row = i + MAX_CG_ROWS; if (last_row > items()) last_row = items(); crea_testata(mov, caus, datareg, desc); TImporto totale; int written = 0; for (int r = i; r < last_row; r++) { pi.addstatus(1); const TCG_rmov& riga = row(r); TImporto imp = riga._importo; if (convert) { real euro = imp.valore() / EURO; euro.round(2); imp.set(imp.sezione(), euro); } if (imp.is_zero()) continue; if (invert) imp.swap_section(); imp.normalize(); totale += imp; crea_riga(mov.curr(), rmov.curr(), ++written); rmov.put(RMV_SEZIONE, imp.sezione()); rmov.put(RMV_IMPORTO, imp.valore()); TBill conto(riga._gruppo, riga._conto, riga._sottoconto); if (!conto.find()) error_box("Nella riga %d del movimento %ld sarebbe utile anche il conto %d %d %ld", written, mov.get_long(MOV_NUMREG), riga._gruppo, riga._conto, riga._sottoconto); conto.put(rmov.curr(), FALSE); contro.put(rmov.curr(), TRUE); if (rmov.write() == NOERR) update_saldo(mov.curr(), rmov.curr(), saldi); } // Scrittura ultima riga di contropartita if (written > 0) { crea_riga(mov.curr(), rmov.curr(), ++written); totale.normalize(); rmov.put(RMV_SEZIONE, totale.sezione() == 'D' ? 'A' : 'D'); rmov.put(RMV_IMPORTO, totale.valore()); contro.put(rmov.curr(), FALSE); const TCG_rmov& riga = row(0); const TBill conto(riga._gruppo, riga._conto, riga._sottoconto); conto.put(rmov.curr(), TRUE); if (rmov.write() == NOERR) update_saldo(mov.curr(), rmov.curr(), saldi); // Scrittura testata mov.put(MOV_TOTDOC, totale.valore()); mov.write(); } bilancio += totale; } if (adeuro) { delete pmov; delete prmov; delete psaldi; } return bilancio; } TImporto TCG_mov::calc_bil(bool convert, bool invert) { TImporto bilancio; for (int i = items()-1; i >= 0; i--) { const TCG_rmov& riga = row(i); TImporto imp = riga._importo; if (convert) { real euro = imp.valore() / EURO; euro.round(2); imp.set(imp.sezione(), euro); } if (imp.is_zero()) continue; if (invert) imp.swap_section(); bilancio += imp; } bilancio.normalize(); return bilancio; } int TCG_movs::indbil(int g, int c) const { TString16 key; key.format("%d|%d", g, c); const TRectype& rec = cache().get(LF_PCON, key); int ib = rec.get_int(PCN_INDBIL); if (ib <= 0) { error_box("Manca l'indicatore di bilancio per il conto %d %d", g, c); ib = 1; } return ib; } TCG_mov& TCG_movs::mov(int ib) { TCG_mov* m = (TCG_mov*)objptr(ib); if (m == NULL) { m = new TCG_mov; TArray::add(m, ib); } return *m; } int TCG_movs::add(int g, int c, long s, char sez, const real& imp) { const int ib = indbil(g, c); // Determina l'inidicatore di bilancio mov(ib).add(g, c, s, sez, imp); // Somma il saldo al movimento opportuno return ib; } TImporto TCG_movs::save(const TDate& datareg, const TString& caus, const TString& desc, const TBill& contro, bool adeuro, bool convert, bool invert) { TImporto bilancio; const int lib = last(); for (int ib = 1; ib <= lib; ib++) if (objptr(ib)) bilancio += mov(ib).save(datareg, caus, desc, contro, adeuro, convert, invert); return bilancio; } /////////////////////////////////////////////////////////// // Main mask /////////////////////////////////////////////////////////// class TEuro20_mask : public TAutomask { public: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); virtual void on_firm_change(); TEuro20_mask() : TAutomask("baeur20") { } }; bool TEuro20_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { return TRUE; } void TEuro20_mask::on_firm_change() { const long firm = app().get_firm(); TDate adozione(1,1,2002); TFilename dati, datie; app().get_aree_dati(dati, datie); TString8 ditta; ditta.format("%05ldA", firm); TFilename inie = datie; inie.add(ditta); inie.add("prassid.ini"); bool adotta = FALSE, inizio = FALSE; if (inie.exist()) { set(F20_DATI, dati); set(F20_DATIE, datie); adotta = app().data_adozione_euro(firm, adozione, inizio); set(F20_ADOZIONE, adozione); if (!adotta || inizio) { disable(DLG_OK); error_box("Non è possibile utilizzare questa procedura:\n" "la ditta %ld adotta l'Euro da inizio esercizio.", firm); } else enable(DLG_OK); } else { disable(DLG_OK); error_box("Non è possibile utilizzare questa procedura:\n" "la ditta %ld non esiste nello studio in Euro.", firm); } TFilename ini = dati; ini.add(ditta); ini.add("prassid.ini"); if (ini.exist()) { TConfig prassid(ini, "cg"); set(F20_CAUS_C, prassid.get("CoCaCh"), TRUE); set(F20_CAUS_A, prassid.get("CoCaAp"), TRUE); set(F20_CONTROG_C, prassid.get("CsBiChG")); set(F20_CONTROC_C, prassid.get("CsBiChC")); set(F20_CONTROS_C, prassid.get("CsBiChS"), TRUE); set(F20_CONTROG_A, prassid.get("CsBiApG")); set(F20_CONTROC_A, prassid.get("CsBiApC")); set(F20_CONTROS_A, prassid.get("CsBiApS"), TRUE); } set(F20_DESC_C, "Chiusura conti"); set(F20_DESC_A, "Apertura conti"); TBill arrotino; if (app().load_round_bill(arrotino)) { arrotino.set(*this, F20_DIFF_G, F20_DIFF_C, F20_DIFF_S); field(F20_DIFF_S).check(STARTING_CHECK); } } /////////////////////////////////////////////////////////// // Main /////////////////////////////////////////////////////////// struct TSaldi_data : public TObject { int _anno; TCG_movs _movs; }; static bool saldi_handler(TRectype& rec, void* jolly) { TSaldi_data* sd = (TSaldi_data*)jolly; const int anno = rec.get_int(SLD_ANNOES); if (anno != sd->_anno) return FALSE; const int gruppo = rec.get_int(SLD_GRUPPO); const int conto = rec.get_int(SLD_CONTO); const long sottoconto = rec.get_long(SLD_SOTTOCONTO); if (gruppo <= 0 || conto <= 0 || sottoconto <= 0) return error_box("Il file dei saldi contiene il conto errato %d %d %ld", gruppo, conto, sottoconto); TImporto saldo, pdare, pavere; saldo.set(rec.get_char(SLD_FLAGSALINI), rec.get_real(SLD_SALDO)); pdare.set('D', rec.get_real(SLD_PDARE)); pavere.set('A', rec.get_real(SLD_PAVERE)); saldo += pdare; saldo += pavere; saldo.normalize(); if (!saldo.is_zero()) { sd->_movs.add(gruppo, conto, sottoconto, saldo.sezione(), saldo.valore()); } return FALSE; } void TEuro02_app::main_loop() { const long f = argc() > 2 ? atol(argv(2)) : -1; goto_lire(f); if (f <= 0L) set_firm(); TEuro20_mask msk; msk.on_firm_change(); // Preimposta data adozione euro ed altro if (msk.run() == K_ENTER) { TSaldi_data sd; const TDate adozione = msk.get(F20_ADOZIONE); TEsercizi_contabili esc; sd._anno = esc.date2esc(adozione); convert_file(LF_SALDI, NULL, NULL, NULL, saldi_handler, &sd); TBill contro; contro.get(msk, F20_CONTROG_C, F20_CONTROC_C, F20_CONTROS_C); sd._movs.save(adozione, msk.get(F20_CAUS_C), msk.get(F20_DESC_C), contro, FALSE, FALSE, TRUE); contro.get(msk, F20_CONTROG_A, F20_CONTROC_A, F20_CONTROS_A); TImporto bil_eur = sd._movs.save(adozione, msk.get(F20_CAUS_A), msk.get(F20_DESC_A), contro, TRUE, TRUE, FALSE); TBill arrotino; arrotino.get(msk, F20_DIFF_G, F20_DIFF_C, F20_DIFF_S); save_round_bill(arrotino); if (!bil_eur.is_zero()) { TCG_mov mov; bil_eur.swap_section(); mov.add(arrotino, bil_eur); mov.save(adozione, msk.get(F20_CAUS_A), msk.get(F20_DESC_A), contro, TRUE, FALSE, FALSE); } } } int baeur02(int argc, char* argv[]) { TEuro02_app ma; ma.run(argc, argv, "Conversione saldi infrannuale"); return 0; }