#include #include #include #include "movana.h" #include "pconana.h" #include "rmovana.h" #include "../cg/cglib01.h" #include "ca3.h" #include "calib01.h" #include "calib02.h" #include "ca3300.h" //////////////////////////////////////////////////////// // MASCHERA //////////////////////////////////////////////////////// class TPrint_bilancio_ca_mask : public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); const TString& get_report_class() const; bool test_compatible_report(); bool esistono_riclassificazioni() const; void create_sheet(); int create_sheet_fields(int lf, int& y, short& dlg, bool required); public: TPrint_bilancio_ca_mask(); virtual ~TPrint_bilancio_ca_mask() {} }; const TString& TPrint_bilancio_ca_mask::get_report_class() const { TString& lib = get_tmp_string(); lib = "ca3300"; const char stp = get(F_TIPOSTAMPA)[0]; // Raffronto o No? const char bil = get(F_BILANCIO)[0]; // Verifica o sezioni Contrapposte if (bil == 'V') lib << (stp == 'R' ? 'a' : 'b'); // Verifica else lib << (stp == 'R' ? 'c' : 'd'); // Sezioni contrapposte return lib; } bool TPrint_bilancio_ca_mask::test_compatible_report() { const TString& cls = get_report_class(); const TString& name = get(F_REPORT); bool ok = name.not_empty(); if (ok) { TReport rep; ok = rep.load(name); if (ok) { const TString& classe = rep.get_class(); ok = classe == cls; } } if (!ok) { set(F_REPORT, cls); TFilename path = cls; path.ext("rep"); ok = path.custom_path(); } return ok; } bool TPrint_bilancio_ca_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_BILANCIO: case F_TIPOSTAMPA: if (e == fe_init || e == fe_modify) test_compatible_report(); break; case F_REPORT: if (e == fe_button) { const TString8 lib = get_report_class(); TFilename path = o.get(); if (select_custom_file(path, "rep", lib)) { path = path.name(); path.ext(""); o.set(path); } } else if (e == fe_close) { if (!test_compatible_report()) return error_box("Impossibile trovare un report compatibile"); } break; case F_PRE1: case F_PRE2: case F_PRE3: if ((e == fe_init || e == fe_modify) && o.active()) { const int k = o.dlg()-F_PRE1; set(F_PAN1_INI + k, o.get(), 0x2); disable(F_PAN1_INI + k); disable(F_PANDES1_INI + k); set(F_PAN1_FIN + k, o.get(), 0x2); disable(F_PAN1_FIN + k); disable(F_PANDES1_FIN + k); } break; default: break; } return true; } int TPrint_bilancio_ca_mask::create_sheet_fields(int lf, int& y, short& dlg, bool required) { TSheet_field& sf = sfield(F_RIGHE); TMask& sm = sf.sheet_mask(); const int h = ca_create_fields(sm, 0, lf, 1, y, dlg, dlg+50); for (int i = 0; i < h; i++) { TEdit_field& fld = sm.efield(dlg+i); int logic = lf; if (logic == LF_FASI) { const TMultilevel_code_info& fasinfo = ca_multilevel_code_info(LF_FASI); if (fasinfo.parent() != 0) { const TMultilevel_code_info& parinfo = ca_multilevel_code_info(fasinfo.parent()); if (i < parinfo.levels()) logic = fasinfo.parent(); } } const char* fieldname = NULL; switch(logic) { case LF_CDC : fieldname = RMOVANA_CODCCOSTO; break; case LF_COMMESSE: fieldname = RMOVANA_CODCMS; break; case LF_FASI : fieldname = RMOVANA_CODFASE; break; default : fieldname = RMOVANA_CODCONTO; break; } TFieldref* f = (TFieldref*)fld.field(); f->set_name(fieldname); fld.check_type(required ? CHECK_REQUIRED : CHECK_NORMAL); TEdit_field& dfld = sm.efield(dlg+50+i); dfld.set_field(EMPTY_STRING); // Toglie campi che fan saltare gli output! } y += h+1; dlg += h; return h; } void TPrint_bilancio_ca_mask::create_sheet() { TSheet_field& sf = sfield(F_RIGHE); TMask& sm = sf.sheet_mask(); sm.hide(-1); const TMultilevel_code_info& fasinfo = ca_multilevel_code_info(LF_FASI); TConfig_anal ini; const bool fsc_req = ini.get_bool("FscRequired"); int y = 1; short dlg = S_CDC1 + 100; // id del primo campo da generare for (int i = 0; i < 2; i++) { const TString& level = ini.get("Level", NULL, i+1); // Legge il livello 1 o 2 if (level == "CDC") // Crea centro di costo { if (fasinfo.parent() == LF_CDC) create_sheet_fields(LF_FASI, y, dlg, fsc_req); else { const bool cdc_req = ini.get_bool("CdcRequired"); create_sheet_fields(LF_CDC, y, dlg, cdc_req); } } else if (level == "CMS") // Crea commessa { if (fasinfo.parent() == LF_COMMESSE) create_sheet_fields(LF_FASI, y, dlg, fsc_req); else { const bool cms_req = ini.get_bool("CmsRequired"); create_sheet_fields(LF_COMMESSE, y, dlg, cms_req); } } } if (fasinfo.levels() > 0 && fasinfo.parent() <= 0) create_sheet_fields(LF_FASI, y, dlg, fsc_req); for (short id = S_CDC12+100; id >= S_CDC1+100; id--) { const int pos = sm.id2pos(id); if (pos >= 0) { TMask_field& f = sm.fld(pos); const int size = f.size(); const TString& prompt = f.prompt(); sf.set_column_header(id, prompt); sf.set_column_justify(id, f.is_kind_of(CLASS_REAL_FIELD)); sf.set_column_width(id, (max(3+size, prompt.len()+1)) * CHARX); } else sf.delete_column(id); } } bool TPrint_bilancio_ca_mask::esistono_riclassificazioni() const { TLocalisamfile ric(LF_PANAPDC); return ric.first() == NOERR; } TPrint_bilancio_ca_mask::TPrint_bilancio_ca_mask() :TAutomask("ca3300") { TConfig_anal cfg; const bool use_pdcc = cfg.get_bool("UsePdcc"); const TMultilevel_code_info& pconana_info = ca_multilevel_code_info(LF_PCONANA); const int pconana_levels = pconana_info.levels(); int pconana_prefix = cfg.get_int("PdcPrefix"); if (pconana_prefix >= pconana_levels) pconana_prefix = pconana_levels-1; disable(F_PIANO); set(F_PIANO, use_pdcc ? "C" : "A"); // Controllo se voglio (e posso) usare il conto analitico come prefisso di quello contabile const int pref = cfg.get_int("PdcPrefix"); if (use_pdcc && pref > 0) { const TMultilevel_code_info& info = ca_multilevel_code_info(LF_PCONANA); const int levels = info.levels(); if (levels >= 2 && pref < levels && esistono_riclassificazioni()) { enable(F_PIANO); ca_create_fields(*this, 1, LF_PCONANA, 2, 2, F_PRE1, F_PREDES1, 0x0, PCONANA_CODCONTO); // Nascondi i campi che non fanno parte del prefisso for (int i = 0; i < levels; i++) { if (i < pref) { field(F_PRE1 + i).check_type(CHECK_REQUIRED); field(F_PRE1 + i).set_group(6); field(F_PREDES1 + i).set_group(6); } else { field(F_PRE1 + i).hide(); field(F_PREDES1 + i).hide(); } } } } for (int g = 5; g <= 6; g++) { const int logicnum = g == 5 ? LF_PCON : LF_PCONANA; const short da_dlg = g == 5 ? F_PDC1_INI : F_PAN1_INI; const short da_des = g == 5 ? F_PDCDES1_INI : F_PANDES1_INI; const short a_dlg = g == 5 ? F_PDC1_FIN : F_PAN1_FIN; const short a_des = g == 5 ? F_PDCDES1_FIN : F_PANDES1_FIN; const int nfields = ca_create_fields(*this, 1, logicnum, 2, 8, da_dlg, da_des, 0x0, PCONANA_CODCONTO); ca_create_fields(*this, 1, logicnum, 2, 14, a_dlg, a_des, 0x0, PCONANA_CODCONTO); for (int i = 0; i < nfields; i++) { TMask_field& daconto = field(da_dlg + i); daconto.set_group(1); daconto.set_group(4); daconto.set_group(g); daconto.check_type(CHECK_NORMAL); field(da_des+i).set_group(4); field(da_des+i).set_group(g); TMask_field& aconto = field(a_dlg + i); aconto.set_group(2); aconto.set_group(4); aconto.set_group(g); aconto.check_type(CHECK_NORMAL); field(a_des+i).set_group(4); field(a_des+i).set_group(g); } } // creazione dei campi della seconda pagina della maschera create_sheet(); set_handlers(); // Setta l'andler universale a tutti i nuovi campi } //////////////////////////////////////////////////////// // TReport_bilancio_verifica //////////////////////////////////////////////////////// class TReport_bilancio_verifica : public TAnal_report { protected: virtual bool set_recordset(const TString& sql); public: void set_filter(const TMask& msk, int row); TReport_bilancio_verifica(const char* name); }; bool TReport_bilancio_verifica::set_recordset(const TString& /* sql */) { TPconana_recordset* rset = new TPconana_recordset(); return TReport::set_recordset(rset); } void TReport_bilancio_verifica::set_filter(const TMask& m, int row) { TString da_conto, a_conto, costo, commessa, fase; const char tc = m.get(F_PIANO)[0]; // Contabile o Analitico? const short dlg_da = tc == 'C' ? F_PDC1_INI : F_PAN1_INI; const short dlg_al = tc == 'C' ? F_PDC1_FIN : F_PAN1_FIN; for (int i = 0; m.id2pos(dlg_da+i) > 0; i++) { da_conto << m.get(dlg_da+i); a_conto << m.get(dlg_al+i); } TDate dal = m.get(F_DATADA); TDate al = m.get(F_DATAA); int tipimov = 0; switch (m.get(F_TIPOSTAMPA)[0]) { case 'C': tipimov = _saldanal_consuntivo; break; // Consuntivo case 'P': tipimov = _saldanal_preventivi; break; // Preventivo e variazione preventivo default : tipimov = _saldanal_qualsiasi; break; // Tutti per raffronto } // 1 = per data limite; 2 = all'ultima immissione if (m.get_int(F_STAMPA) == 2) { const int anno = m.get_int(F_ANNO); if (anno > 0) { TEsercizi_contabili esc; dal = esc[anno].inizio(); al = esc[anno].fine(); } tipimov |= _saldanal_ultima_imm; } if (tc == 'A' && m.id2pos(F_PRE1) > 0) { tipimov |= _saldanal_riclassify; } const TMultilevel_code_info& info = ca_multilevel_code_info(tc == 'A' ? LF_PCONANA : LF_PCON); for (int s = info.levels()+1; s <= 4; s++) { section('H', s).deactivate(); section('F', s).deactivate(); } const bool movimentati = m.get_int(F_STAMPAV) == 1; const bool nonnulli = m.get_int(F_STAMPAV) == 2; TSheet_field& sf = m.sfield(F_RIGHE); TMask& sm = sf.sheet_mask(); sf.update_mask(row); TRelation rel(LF_RMOVANA); sm.autosave(rel); costo = rel.curr().get(RMOVANA_CODCCOSTO); commessa = rel.curr().get(RMOVANA_CODCMS); fase = rel.curr().get(RMOVANA_CODFASE); TPconana_recordset* rset = (TPconana_recordset*)recordset(); if (rset != NULL) rset->set_filter(tc, da_conto, a_conto, costo, commessa, fase, dal, al, tipimov, movimentati, nonnulli); } TReport_bilancio_verifica::TReport_bilancio_verifica(const char* name) { load(name); } //////////////////////////////////////////////////////// // TRecordset_sezioni_contapposte //////////////////////////////////////////////////////// class TRecordset_sezioni_contrapposte : public TRecordset { char _tipo_piano; TAnal_bill _filter; TDate _da_data, _a_data; int _tipimov; bool _movimentati, _nonnulli; TString_array _attivita, _passivita, _costi, _ricavi; TRecnotype _pos; TRecordset_column_info _info[4]; protected: TRecnotype items_ap() const; TRecnotype items_cr() const; public: virtual TRecnotype items() const; virtual bool move_to(TRecnotype pos); virtual TRecnotype current_row() const { return _pos; } virtual void requery(); virtual unsigned int columns() const; virtual const TRecordset_column_info& column_info(unsigned int column) const; virtual const TVariant& get(unsigned int column) const; virtual const TVariant& get(const char* field) const; void set_filter(char piano, const char* costo, const char* commessa, const char* fase, const TDate& dal, const TDate& al, word tipimov, bool movimentati, bool nonnulli); TRecordset_sezioni_contrapposte(char tipo_piano) : _tipo_piano(tipo_piano) { } }; TRecnotype TRecordset_sezioni_contrapposte::items_ap() const { return max(_attivita.items(), _passivita.items()); } TRecnotype TRecordset_sezioni_contrapposte::items_cr() const { return max(_costi.items(), _ricavi.items()); } TRecnotype TRecordset_sezioni_contrapposte::items() const { return items_ap() + items_cr(); } bool TRecordset_sezioni_contrapposte::move_to(TRecnotype pos) { _pos = pos; return _pos < items(); } void TRecordset_sezioni_contrapposte::set_filter(char piano, const char* costo, const char* commessa, const char* fase, const TDate& dal, const TDate& al, word tipimov, bool movimentati, bool nonnulli) { _tipo_piano = piano; _da_data = dal; _a_data = al; _tipimov = tipimov; _movimentati = movimentati; _nonnulli = nonnulli; _filter.reset(); _filter.set_costo(costo); _filter.set_commessa(commessa); _filter.set_fase(fase); } void TRecordset_sezioni_contrapposte::requery() { TPconana_recordset pconana(_tipo_piano); pconana.set_filter(_tipo_piano, NULL, NULL, _filter.costo(), _filter.commessa(), _filter.fase(), _da_data, _a_data, _tipimov, _movimentati, _nonnulli); int indicatore_bilancio = 1; for (TRecnotype i = 0; pconana.move_to(i); i++) { const int ib = pconana.get(PCONANA_INDBIL).as_int(); if (ib >= 1 && ib <= 4) indicatore_bilancio = ib; const TString& conto = pconana.get(PCONANA_CODCONTO).as_string(); switch (indicatore_bilancio) { case 1: _attivita.add(conto); break; case 2: _passivita.add(conto); break; case 3: _costi.add(conto); break; case 4: _ricavi.add(conto); break; default: break; } } move_to(0); } unsigned int TRecordset_sezioni_contrapposte::columns() const { return 4; } const TRecordset_column_info& TRecordset_sezioni_contrapposte::column_info(unsigned int column) const { return _info[column]; } const TVariant& TRecordset_sezioni_contrapposte::get(unsigned int column) const { return NULL_VARIANT; } const TVariant& TRecordset_sezioni_contrapposte::get(const char* field) const { return NULL_VARIANT; } //////////////////////////////////////////////////////// // TReport_bilancio_sezioni_contapposte //////////////////////////////////////////////////////// class TReport_bilancio_sezioni_contrapposte : public TAnal_report { protected: virtual bool TReport_bilancio_sezioni_contrapposte::set_recordset(const TString& sql); public: void set_filter(const TMask& msk, int row); TReport_bilancio_sezioni_contrapposte(const char* name) { load(name); } }; bool TReport_bilancio_sezioni_contrapposte::set_recordset(const TString& /* sql */) { TRecordset_sezioni_contrapposte* rset = new TRecordset_sezioni_contrapposte('A'); return TReport::set_recordset(rset); } void TReport_bilancio_sezioni_contrapposte::set_filter(const TMask& m, int row) { TDate dal = m.get(F_DATADA); TDate al = m.get(F_DATAA); int tipimov = 0; switch (m.get(F_TIPOSTAMPA)[0]) { case 'C': tipimov = _saldanal_consuntivo; break; // Consuntivo case 'P': tipimov = _saldanal_preventivi; break; // Preventivo e variazione preventivo default : tipimov = _saldanal_qualsiasi; break; // Tutti per raffronto } // 1 = per data limite; 2 = all'ultima immissione if (m.get_int(F_STAMPA) == 2) { const int anno = m.get_int(F_ANNO); if (anno > 0) { TEsercizi_contabili esc; dal = esc[anno].inizio(); al = esc[anno].fine(); } tipimov |= _saldanal_ultima_imm; } const char tipo = m.get(F_PIANO)[0]; if (tipo == 'A' && m.id2pos(F_PRE1) > 0) { tipimov |= _saldanal_riclassify; } const bool movimentati = m.get_int(F_STAMPAV) == 1; const bool nonnulli = m.get_int(F_STAMPAV) == 2; TSheet_field& sf = m.sfield(F_RIGHE); TMask& sm = sf.sheet_mask(); sf.update_mask(row); TRelation rel(LF_RMOVANA); sm.autosave(rel); const TString80 costo = rel.curr().get(RMOVANA_CODCCOSTO); const TString80 commessa = rel.curr().get(RMOVANA_CODCMS); const TString16 fase = rel.curr().get(RMOVANA_CODFASE); TRecordset_sezioni_contrapposte* recset = new TRecordset_sezioni_contrapposte(tipo); recset->set_filter(tipo, costo, commessa, fase, dal, al, tipimov, movimentati, nonnulli); TAnal_report::set_recordset(recset); }; //////////////////////////////////////////////////////// // APPLICAZIONE //////////////////////////////////////////////////////// class TPrint_bilancio_ca : public TSkeleton_application { protected: void bilancio_a_sezioni_contrapposte(TMask& mask); void bilancio_di_verifica(TMask& msk); public: virtual void main_loop(); }; void TPrint_bilancio_ca::bilancio_a_sezioni_contrapposte(TMask& mask) { TReport_bilancio_sezioni_contrapposte rep(mask.get(F_REPORT)); TSheet_field& sf = mask.sfield(F_RIGHE); const int rows = sf.items(); TReport_book book; for (int i = 0; i < rows; i++) { rep.set_filter(mask, i); book.add(rep); } book.print_or_preview(); } void TPrint_bilancio_ca::bilancio_di_verifica(TMask& mask) { TReport_bilancio_verifica rep(mask.get(F_REPORT)); const int rows = mask.sfield(F_RIGHE).items(); TReport_book book; for (int i = 0; i < rows; i++) { rep.set_filter(mask, i); book.add(rep); } book.print_or_preview(); } void TPrint_bilancio_ca::main_loop() { TPrint_bilancio_ca_mask mask; while (mask.run() != K_QUIT) { TSheet_field& sf = mask.sfield(F_RIGHE); if (sf.empty()) sf.row(-1); // Aggiungo riga vuota if (mask.get(F_BILANCIO) == "C") bilancio_a_sezioni_contrapposte(mask); else bilancio_di_verifica(mask); } } int ca3300(int argc, char* argv[]) { TPrint_bilancio_ca a; a.run(argc, argv, TR("Stampa bilancio")); return 0; }