#include #include #include #include "ca0800a.h" const char* get_key_fieldname(int logic, int k) { const RecDes& rd = prefix().get_recdes(logic); CHECKD(k > 0 && k <= rd.NKeys, "Invalid key on file ", logic); const KeyDes& ky = rd.Ky[k-1]; const int idx = (logic == LF_TAB || logic == LF_TABCOM) ? 1 : 0; const int pos = ky.FieldSeq[idx] % MaxFields; return rd.Fd[pos].Name; } void append_select_clause(ostream& out, int level, const TArray& key1) { const TFieldref& key = (const TFieldref&)key1[level-1]; TString str; str << " SE STR("; if (level > 1) str << "(NUM(LEN(" << key.name() << "))>" << key.from() << ')'; // SE LEN(CODCONTO)>=4 if (level < key1.items()) { if (level > 1) str << "&&"; str << "(NUM(LEN(" << key.name() << "))<=" << key.to() << ')'; // SE LEN(CODCONTO)<=7 } str << ')'; out << str << endl; } void append_run_clause(ostream& out, int logicnum) { const TRectype r(logicnum); TString app; r.get_relapp(app); if (app.not_empty()) out << "AD RU " << app << endl; } void create_browse1(TEdit_field& kfld, int level, TConfig& cfg, int logic, const char* key_var, short key_id, const char* des_var, short des_id, const TArray& key1, const TArray& key2) { TFilename tmp; tmp.temp(); ofstream out(tmp); out << "US " << logic << endl; append_select_clause(out, level, key1); append_run_clause(out, logic); for (int i = 1; i <= level; i++) { const TString& picture = cfg.get(key_var, NULL, i); const TString& prompt = cfg.get(des_var, NULL, i); const TFieldref& field = (const TFieldref&)key1[i-1]; const int length = field.to() - field.from(); out << "IN " << field << ' ' << (key_id+i-1) << endl; out << "DI \"" << prompt; if (length > prompt.len()) out << '@' << length; out << "\" " << field << endl; out << "OU " << (key_id+i-1) << ' ' << field << endl; out << "FI " << field << endl; } const TFieldref& field = (const TFieldref&)key2[0]; out << "DI \"Descrizione@50\" " << field << endl; out << "OU " << (des_id+level-1) << ' ' << field << endl; out << "CH RE" << endl; out << "EN" << endl; out.close(); TScanner scan(tmp); while (scan.pop() != "EN") kfld.parse_item(scan); xvt_fsys_removefile(tmp); } void create_browse2(TEdit_field& kfld, int level, TConfig& cfg, int logic, const char* key_var, short key_id, const char* des_var, short des_id, const TArray& key1, const TArray& key2) { const TFieldref& field = (const TFieldref&)key2[0]; TString str2; str2 << field; TFilename tmp; tmp.temp(); ofstream out(tmp); out << "US " << logic << " KE 2"; append_select_clause(out, level, key1); append_run_clause(out, logic); out << "DI \"Descrizione@50\" " << str2 << endl; out << "IN " << str2 << ' ' << kfld.dlg() << endl; out << "OU " << kfld.dlg() << ' ' << str2 << endl; int from = 1, to = 1; for (int i = 1; i <= level; i++) { const TString& picture = cfg.get(key_var, NULL, i); const TString& prompt = cfg.get(des_var, NULL, i); const TFieldref& field = (const TFieldref&)key1[i-1]; const int length = field.to() - field.from(); out << "DI \"" << prompt; if (length > prompt.len()) out << '@' << length; out << "\" " << field << endl; out << "OU " << (key_id+i-1) << ' ' << field << endl; from = to+1; } out << "CH NO" << endl; out << "EN" << endl; out.close(); TScanner scan(tmp); while (scan.pop() != "EN") kfld.parse_item(scan); xvt_fsys_removefile(tmp); } int create_fields(TMask& msk, int logicnum, int x, int y, const char* key_var, short key_id, const char* des_var, short des_id) { TConfig cfg(CONFIG_DITTA, "ca"); TArray key1, key2; int maxkeylen = 0, maxdeslen = 0; int level; int from = 1, to = 1; for (level = 1; ; level++) { const TString& prompt = cfg.get(des_var, NULL, level); if (prompt.blank()) break; const TString& picture = cfg.get(key_var, NULL, level); const int keylen = picture.len(); const int deslen = prompt.len(); if (keylen > maxkeylen) maxkeylen = keylen; if (deslen > maxdeslen) maxdeslen = deslen; to = from+keylen-1; TString80 str; str = get_key_fieldname(logicnum, 1); str << '[' << from << ',' << to << ']'; key1.add(new TFieldref(str, logicnum)); from = to+1; } key2.add(new TFieldref(get_key_fieldname(logicnum, 2), logicnum)); maxdeslen++; const int tab0 = x; const int tab1 = tab0 + maxdeslen + maxkeylen + 4; for (int i = 1; i < level; i++) { const short kid = key_id+i-1; const TString& picture = cfg.get(key_var, NULL, i); TString80 prompt = cfg.get(des_var, NULL, i); prompt.left_just(maxdeslen); TEdit_field& kfld = msk.add_string(kid, 0, prompt, tab0, y+i-1, picture.len(), "BU"); create_browse1(kfld, i, cfg, logicnum, key_var, key_id, des_var, des_id, key1, key2); kfld.set_group(2); const short did = des_id+i-1; TEdit_field& dfld = msk.add_string(did, 0, "", tab1, y+i-1, 50, "B", 72+tab0-tab1); create_browse2(dfld, i, cfg, logicnum, key_var, key_id, des_var, des_id, key1, key2); dfld.set_group(2); } return level; } /////////////////////////////////////////////////////////// // TRiparti_msk /////////////////////////////////////////////////////////// class TRiparti_msk : public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); void create_sheet(); public: TRiparti_msk(); }; bool TRiparti_msk::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_TIPORIP: if (e == fe_init || e == fe_modify) { TSheet_field& sf = sfield(F_SHEET); TMask& sm = sf.sheet_mask(); const int t = atoi(o.get()); sm.show(101, t == 0); // Percentuale sm.show(201, t == 2); // Parti } if (e == fe_close && atoi(o.get()) == 0) { TSheet_field& sf = sfield(F_SHEET); real tot; FOR_EACH_SHEET_ROW(sf, i, row) tot += real(row->get(0)); tot.round(2); if (tot != CENTO) return error_box(TR("Il totale delle percentuali di riparto deve essere 100")); } break; default: break; } return true; } void TRiparti_msk::create_sheet() { TSheet_field& sf = sfield(F_SHEET); TMask& sm = sf.sheet_mask(); sm.hide(-1); TConfig ini(CONFIG_DITTA, "ca"); const bool use_pdc = ini.get_bool("UsePdcc"); create_fields(sm, LF_CDC, 1, 1, "CdC", 202, "CdCDes", 252); create_fields(sm, LF_COMMESSE, 1, 5, "Cms", 206, "CmsDes", 256); create_fields(sm, LF_CDC, 1, 9, "CdC", 210, "CdCDes", 260); if (!use_pdc) { create_fields(sm, LF_PCONANA,1, 13, "Pdci", 214, "PdciDes", 264); sm.hide(-6); } for (short id = 217; id >= 202; id--) { short dlg = id; if (use_pdc && id >= 213) dlg -= 100; const int pos = sm.id2pos(dlg); 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_width(id, (2+max(size, prompt.len())) * CHARX); } else sf.delete_column(id); } } TRiparti_msk::TRiparti_msk() : TAutomask("ca0800a") { create_fields(*this, LF_CDC, 2, 5, "CdC", F_CODCDC_1, "CdCDes", F_DESCDC_1); create_fields(*this, LF_COMMESSE, 2, 11, "Cms", F_CODCMS_1, "CmsDes", F_DESCMS_1); create_sheet(); } /////////////////////////////////////////////////////////// // TRiparti_app /////////////////////////////////////////////////////////// class TRiparti_app : public TRelation_application { TRelation* _rel; TRiparti_msk* _msk; const TString& somma_campi(TToken_string& row, int first) const; void write_rows(); void spezza_campo(const TString& str, TToken_string& row, int first) const; void read_rows(); protected: virtual bool user_create(); virtual bool user_destroy(); virtual int write(const TMask& m); virtual int rewrite(const TMask& m); virtual TRelation* get_relation() const { return _rel; } virtual TMask* get_mask(int) { return _msk; } }; const TString& TRiparti_app::somma_campi(TToken_string& row, int first) const { TSheet_field& sheet = _msk->sfield(F_SHEET); TMask& m = sheet.sheet_mask(); short id = 200 + first; if (m.id2pos(id) < 0) id -= 100; TString& str = get_tmp_string(20); for (int i = first; i < first+4; i++) { TString80 token = row.get(i); if (m.id2pos(id+i) < 0) break; const TEdit_field& fld = m.efield(id+1); token.left_just(fld.size()); str << token; } return str; } void TRiparti_app::spezza_campo(const TString& str, TToken_string& row, int first) const { TSheet_field& sheet = _msk->sfield(F_SHEET); TMask& m = sheet.sheet_mask(); short id = 200 + first; if (m.id2pos(id) < 0) id -= 100; int start = 0; for (int i = first; i < first+4; i++) { if (m.id2pos(id+i) < 0) break; const TEdit_field& fld = m.efield(id+1); const int len = fld.size(); const TString& token = str.mid(start, len); row.add(token, i); start += len; } } void TRiparti_app::write_rows() { TRectype* key = new TRectype(LF_RRIP); const char tipo = _msk->get(F_TIPO)[0]; key->put("TIPO", tipo); key->put("CODICE", _msk->get(tipo == 'B' ? F_CODICE_B : F_CODICE_I)); TRecord_array a(LF_RRIP, "NRIGA"); a.set_key(key); TSheet_field& sheet = _msk->sfield(F_SHEET); FOR_EACH_SHEET_ROW(sheet, i, row) { TRectype& rec = a.row(i+1, true); // Crea una riga nuova rec.put("RIPARTO", row->get(0)); rec.put("CODCOSTO", somma_campi(*row, 1)); rec.put("CODCMS", somma_campi(*row, 5)); rec.put("CODFASE", somma_campi(*row, 9)); rec.put("CODCONTO", somma_campi(*row,13)); } a.rewrite(); } void TRiparti_app::read_rows() { TRectype key (LF_RRIP); const char tipo = _msk->get(F_TIPO)[0]; key.put("TIPO", tipo); key.put("CODICE", _msk->get(tipo == 'B' ? F_CODICE_B : F_CODICE_I)); TRecord_array a(key, "NRIGA"); TSheet_field& sheet = _msk->sfield(F_SHEET); sheet.destroy(); for (int i = 1; i <= a.rows(); i++) { const TRectype& rec = a.row(i); TToken_string& row = sheet.row(i-1); row = rec.get("RIPARTO"); spezza_campo(rec.get("CODCOSTO"), row, 1); spezza_campo(rec.get("CODCMS"), row, 5); spezza_campo(rec.get("CODFASE"), row, 9); spezza_campo(rec.get("CODCONTO"), row,13); } } int TRiparti_app::write(const TMask& m) { const int err = TRelation_application::write(m); if (err == NOERR) write_rows(); return err; } int TRiparti_app::rewrite(const TMask& m) { const int err = TRelation_application::rewrite(m); if (err == NOERR) write_rows(); return err; } bool TRiparti_app::user_create() { _rel = new TRelation(LF_RIP); _msk = new TRiparti_msk; return true; } bool TRiparti_app::user_destroy() { delete _rel; delete _msk; return true; } int ca0800(int argc, char* argv[]) { TRiparti_app a; a.run(argc, argv, TR("Tabella di ripartizione")); return 0; }