#include #include #include #include #include "ca2.h" #include "ca2100a.h" #include "calib01.h" #include "../cg/cglib01.h" #include "movana.h" #include "rmovana.h" class TMovanal_msk : public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event fe, long jolly); virtual bool can_be_closed() const; public: TMovanal_msk(); virtual ~TMovanal_msk() { } }; bool TMovanal_msk::can_be_closed() const { return !get_bool(F_BLOCCATO); } bool TMovanal_msk::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_DATAREG: if ((e == fe_modify || e == fe_close) && !query_mode()) { const TDate datareg = o.get(); const TEsercizi_contabili ec; if (ec.date2esc(datareg) <= 0) return error_box(((TEdit_field&)o).get_warning()); if (e == fe_close && field(F_DATACOMP).empty()) set(F_DATACOMP, datareg); } break; case F_DATACOMP: if ((e == fe_modify || e == fe_close) && !query_mode()) { const TDate datareg = get(F_DATAREG); TDate datacomp = o.get(); if (!datacomp.ok()) datacomp = datareg; if (datacomp > datareg) return error_box(TR("La data di competenza non puo' superare la data di registrazione")); const TEsercizi_contabili ec; const int ae = ec.date2esc(datacomp); if (ae > 0) set(F_ANNOES, ae, 0x1); else return error_box(((TEdit_field&)o).get_warning()); const int ar = ec.date2esc(datareg); const int ap = ec.pred(ar); if (ae != ar && ae != ap) return error_box(FR("La data di competenza deve appartenere all'esercizio in corso o al precedente")); } break; case F_TOTDOC: if (e == fe_close) { const real imp = o.get(); const char sez = get(F_SEZIONE)[0]; const TImporto totdoc(sez, imp); TImporto totrig; TSheet_field& sf = sfield(F_RIGHE); FOR_EACH_SHEET_ROW(sf, i, row) { const real dare = row->get(0); const real avere = row->get(); TImporto imp; if (dare.is_zero()) imp.set('A', avere); else imp.set('D', dare); totrig += imp; } if (totrig != totdoc) return error_box(FR("Il totale delle righe e' %s %s"), totrig.valore().string(), totrig.sezione() == 'D' ? TR("Dare") : TR("Avere")); } break; default: break; } return true; } TMovanal_msk::TMovanal_msk() : TAutomask("ca2100a") { TSheet_field& sf = sfield(F_RIGHE); TMask& sm = sf.sheet_mask(); sm.hide(-1); // Nasconde tutti campi fittizi TConfig ini(CONFIG_DITTA, "ca"); const bool use_pdc = ini.get_bool("UsePdcc"); const short id_cdc = 201+sf.cid2index(S_CDC1); const short id_cms = 201+sf.cid2index(S_CMS1); const short id_fas = 201+sf.cid2index(S_FAS1); const short id_con = 201+sf.cid2index(S_CON1); ca_create_fields(sm, LF_CDC, 1, 2, id_cdc, id_cdc+50); ca_create_fields(sm, LF_COMMESSE, 1, 6, id_cms, id_cms+50); ca_create_fields(sm, LF_FASI, 1, 10, id_fas, id_fas+50); ca_create_fields(sm, use_pdc ? LF_PCON : LF_PCONANA, 1, 14, id_con, id_con+50); for (short id = id_con+3; id >= id_cdc; 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); } } } class TMovanal_app : public TRelation_application { TRelation* _rel; TMovanal_msk* _msk; protected: virtual bool user_create(); virtual bool user_destroy(); virtual TMask* get_mask(int); virtual TRelation* get_relation() const; const TString& somma_campi(TToken_string& row, int first) const; void spezza_campo(const TString& str, TToken_string& row, int first) const; int write_rows(const TMask& m); void read_rows(const TMask& m); virtual bool protected_record(TRectype& rec); virtual int write(const TMask& m); virtual int rewrite(const TMask& m); virtual int read(TMask& m); virtual void init_query_mode(TMask& m); virtual void init_insert_mode(TMask& m); virtual void init_modify_mode(TMask& m); }; TMask* TMovanal_app::get_mask(int) { return _msk; } TRelation* TMovanal_app::get_relation() const { return _rel; } const TString& TMovanal_app::somma_campi(TToken_string& row, int first) const { TSheet_field& sheet = _msk->sfield(F_RIGHE); TMask& m = sheet.sheet_mask(); const short id = 201 + first; TString& str = get_tmp_string(20); for (int i = 0; i < 4; i++) { TString80 token = row.get(first+i); if (m.id2pos(id+i) < 0) break; const TEdit_field& fld = m.efield(id+i); token.left_just(fld.size()); str << token; } return str; } int TMovanal_app::write_rows(const TMask& m) { TRecord_array a(LF_RMOVANA, RMOVANA_NUMRIG); TRectype* key = new TRectype(LF_RMOVANA); key->put(RMOVANA_NUMREG, m.get(F_NUMREG)); a.set_key(key); TSheet_field& sheet = _msk->sfield(F_RIGHE); // Calcola le posizioni dei campi multilivello generati const int pos_cdc = sheet.cid2index(S_CDC1); const int pos_cms = sheet.cid2index(S_CMS1); const int pos_fas = sheet.cid2index(S_FAS1); const int pos_con = sheet.cid2index(S_CON1); // Scandisce lo sheet e riempie il recarray FOR_EACH_SHEET_ROW(sheet, i, row) { TRectype& rec = a.row(i+1, true); // Crea una riga nuova rec.put(RMOVANA_ANNOES, m.get(F_ANNOES)); rec.put(RMOVANA_DATAREG, m.get(F_DATAREG)); rec.put(RMOVANA_DESCR, row->get(sheet.cid2index(S_DESCR))); const real dare = row->get(0), avere = row->get(); if (!avere.is_zero()) { rec.put(RMOVANA_SEZIONE, 'A'); rec.put(RMOVANA_IMPORTO, avere); } else { rec.put(RMOVANA_SEZIONE, 'D'); rec.put(RMOVANA_IMPORTO, dare); } rec.put(RMOVANA_CODCCOSTO, somma_campi(*row, pos_cdc)); rec.put(RMOVANA_CODCMS, somma_campi(*row, pos_cms)); rec.put(RMOVANA_CODFASE, somma_campi(*row, pos_fas)); rec.put(RMOVANA_CODCONTO, somma_campi(*row, pos_con)); } a.rewrite(); return NOERR; } void TMovanal_app::spezza_campo(const TString& str, TToken_string& row, int first) const { TSheet_field& sheet = _msk->sfield(F_RIGHE); TMask& m = sheet.sheet_mask(); TString80 token; const short id = 201 + first; int start = 0; for (int i = 0; i < 4; i++) { if (m.id2pos(id+i) < 0) break; const TEdit_field& fld = m.efield(id+i); const int len = fld.size(); token = str.mid(start, len); token.trim(); row.add(token, first+i); start += len; } } void TMovanal_app::read_rows(const TMask& m) { TRectype key (LF_RMOVANA); key.put(RMOVANA_NUMREG, _msk->get(F_NUMREG)); TRecord_array a(key, RMOVANA_NUMRIG); TSheet_field& sheet = m.sfield(F_RIGHE); sheet.destroy(); for (int i = 1; i <= a.rows(); i++) { const TRectype& rec = a.row(i); TToken_string& row = sheet.row(i-1); const char sez = rec.get_char(RMOVANA_SEZIONE); const real imp = rec.get(RMOVANA_IMPORTO); row.add(sez == 'D' ? imp.string() : ""); row.add(sez == 'A' ? imp.string() : ""); row.add(rec.get(RMOVANA_DESCR)); // Calcola le posizioni dei campi multilivello generati const int pos_cdc = sheet.cid2index(S_CDC1); const int pos_cms = sheet.cid2index(S_CMS1); const int pos_fas = sheet.cid2index(S_FAS1); const int pos_con = sheet.cid2index(S_CON1); spezza_campo(rec.get(RMOVANA_CODCCOSTO), row, pos_cdc); spezza_campo(rec.get(RMOVANA_CODCMS), row, pos_cms); spezza_campo(rec.get(RMOVANA_CODFASE), row, pos_fas); spezza_campo(rec.get(RMOVANA_CODCONTO), row, pos_con); } } bool TMovanal_app::protected_record(TRectype& rec) { return rec.get_bool(MOVANA_BLOCCATO); } int TMovanal_app::write(const TMask& m) { int err = m.get_bool(F_BLOCCATO) ? _islocked : NOERR; if (err == NOERR) { err = TRelation_application::write(m); if (err == NOERR) write_rows(m); } return err; } int TMovanal_app::rewrite(const TMask& m) { int err = m.get_bool(F_BLOCCATO) ? _islocked : NOERR; if (err == NOERR) { err = TRelation_application::rewrite(m); if (err == NOERR) write_rows(m); } return err; } int TMovanal_app::read(TMask& m) { int err = TRelation_application::read(m); if (err == NOERR) { read_rows(m); } return err; } void TMovanal_app::init_query_mode(TMask& m) { m.enable(F_BLOCCATO); m.enable(DLG_SAVEREC); m.enable(DLG_QUIT); } void TMovanal_app::init_insert_mode(TMask& m) { m.enable(F_BLOCCATO); m.enable(DLG_SAVEREC); } void TMovanal_app::init_modify_mode(TMask& m) { const bool unlocked = m.can_be_closed(); m.enable(F_BLOCCATO, unlocked); m.enable(DLG_SAVEREC, unlocked); m.enable(DLG_QUIT, unlocked); } bool TMovanal_app::user_create() { _rel = new TRelation(LF_MOVANA); _msk = new TMovanal_msk; return true; } bool TMovanal_app::user_destroy() { delete _msk; _msk = NULL; delete _rel; _rel = NULL; return true; } int ca2100(int argc, char* argv[]) { TMovanal_app app; app.run(argc, argv, "Movimenti analitici"); return 0; }