#include #include #include #include #include #include "calib01.h" #include "calibmsk.h" #include "../cg/cg2103.h" #include "movana.h" #include "rmovana.h" #include "rip.h" #include "rrip.h" #include "saldana.h" /////////////////////////////////////////////////////////// // TConfig_anal /////////////////////////////////////////////////////////// class TConfig_anal : public TConfig { bool _has_ca; public: virtual const TString& get(const char* var, const char* section = NULL, int index = -1, const char* def = ""); TConfig_anal(); }; TConfig_anal::TConfig_anal() : TConfig(CONFIG_DITTA, "ca"), _has_ca(dongle().active(CAAUT)) { } const TString& TConfig_anal::get(const char* var, const char* section, int index, const char* def) { if (_has_ca) return TConfig::get(var, section, index, def); //se il valore della variabile sul .ini e' vuoto controlla se e' possibile assegnarlo di default TString& tmp = get_tmp_string(); if (var == "AttFasi") tmp = "X"; else if (var == "FathFasi") tmp = "CMS"; else if (var == "Level(1)") tmp = "CMS"; else if (var == "Cms(1)") tmp = "LLLLLLLLLLLLLLLLLLLL"; else if (var == "CmsDes(1)") tmp = "Commessa"; else if (var == "Fsc(1)") tmp = "LLLLLLLLLL"; else if (var == "FscDes(1)") tmp == "Fase"; else if (var == "EdMask") tmp = "ca0300a"; else if (var == "UsePdcc") tmp = "X"; return tmp; } TConfig& ca_config() { static TConfig_anal* cfg = NULL; if (cfg == NULL) cfg = new TConfig_anal; return *cfg; } /////////////////////////////////////////////////////////// // TMultilevel_code_info /////////////////////////////////////////////////////////// int TMultilevel_code_info::levels() const { return _picture.items(); } const TString& TMultilevel_code_info::picture(int level) const { if (level < 0 || level >= levels()) return EMPTY_STRING; return _picture.row(level); } bool TMultilevel_code_info::is_required(int level) const { bool yes = level <= 0; return yes; } bool TMultilevel_code_info::is_numeric_picture(int level) const { const TString& pic = picture(level); if (pic.blank()) return false; for (int i = 0; pic[i]; i++) if (pic[i] != '0' && pic[i] != '9') return false; return true; } int TMultilevel_code_info::len(int level) const { return picture(level).len(); } int TMultilevel_code_info::total_len(int level) const { const int max_lev = levels(); if (level < 0) // -1 = fino al penultimo level = max_lev+level-1; int l = 0; for (int i = 0; i <= level && i < max_lev; i++) l += picture(i).len(); return l; } const TString& TMultilevel_code_info::prompt(int level) const { if (level < 0 || level >= _prompt.items()) return EMPTY_STRING; return _prompt.row(level); } const TFieldref& TMultilevel_code_info::fieldref(int level, int key) const { const TArray& a = key <= 1 ? _key1_fields : _key2_fields; const TFieldref& fr = (const TFieldref&)a[level]; return fr; } const char* TMultilevel_code_info::get_key_fieldname(int k) const { const RecDes& rd = prefix().get_recdes(_logicnum); CHECKD(k > 0 && k <= rd.NKeys, "Invalid key ", k); const KeyDes& ky = rd.Ky[k-1]; int idx = 0; if (k == 1 && (_logicnum == LF_TAB || _logicnum == LF_TABCOM || _logicnum == LF_FASI)) idx = 1; const int pos = ky.FieldSeq[idx] % MaxFields; return rd.Fd[pos].Name; } bool TMultilevel_code_info::get_cfg_vars(TString& key, TString& des) const { switch (_logicnum) { case LF_PCONANA : key = "Pdci"; des = "PdciDes"; break; case LF_CDC : key = "CdC"; des = "CdCDes"; break; case LF_COMMESSE: key = "Cms"; des = "CmsDes"; break; case LF_FASI : key = "Fsc"; des = "FscDes"; break; default: break; } return key.not_empty(); } void TMultilevel_code_info::add_fieldref(int k, int from, int to) { TArray& a = k == 1 ? _key1_fields : _key2_fields; TString80 str = get_key_fieldname(k); if (from > 0) str << '[' << from << ',' << to << ']'; TFieldref* fr = new TFieldref(str, _logicnum); a.add(fr); } TMultilevel_code_info::TMultilevel_code_info(int logicnum) : _logicnum(logicnum), _parentnum(0) { if (_logicnum == LF_PCON) { _key1_fields.add(new TFieldref(PCN_GRUPPO, LF_PCON)); _picture.add("999"); _prompt.add(TR("Gruppo")); _key1_fields.add(new TFieldref(PCN_CONTO, LF_PCON)); _picture.add("999"); _prompt.add(TR("Conto")); _key1_fields.add(new TFieldref(PCN_SOTTOCONTO, LF_PCON)); _picture.add("999999"); _prompt.add(TR("Sottoconto")); _key2_fields.add(new TFieldref(PCN_DESCR, LF_PCON)); } else { TConfig& cfg = ca_config(); if (logicnum == LF_FASI) { const TString& father = cfg.get("FathFasi"); if (father == "CMS") _parentnum = LF_COMMESSE; else if (father == "CDC") _parentnum = LF_CDC; if (_parentnum != 0) { const TMultilevel_code_info& info = ca_multilevel_code_info(_parentnum); for (int i = 0; i < info.levels(); i++) { _prompt.add(info.prompt(i)); _picture.add(info.picture(i)); TFieldref fr = info.fieldref(i); fr.set_name("CODCMSFAS"); _key1_fields.add(fr); } } } TString16 keyvar, desvar; get_cfg_vars(keyvar, desvar); int from = 1, to = 1; for (int level = 1; ; level++) { const TString& prompt = cfg.get(desvar, NULL, level); if (prompt.blank()) break; _prompt.add(prompt); const TString& picture = cfg.get(keyvar, NULL, level); _picture.add(picture); const int keylen = picture.len(); to = from+keylen-1; add_fieldref(1, from, to); from = to+1; } add_fieldref(2, 0, 0); } const TRectype rec(logicnum); rec.get_relapp(_editor); } const TMultilevel_code_info& ca_multilevel_code_info(int logicnum) { static TArray* cache = NULL; if (cache == NULL) cache = new TArray; TMultilevel_code_info* info = (TMultilevel_code_info*)cache->objptr(logicnum); if (info == NULL) { info = new TMultilevel_code_info(logicnum); cache->add(info, logicnum); } return *info; } bool ca_test_multilevel_field(TEdit_field& fld, int level) { const int logic = fld.browse()->cursor()->curr().num(); const TMultilevel_code_info& info = ca_multilevel_code_info(logic); const TString& pic = info.picture(level); const TString& val = fld.get(); bool ok = val.len() <= pic.len(); for (int i = 0; val[i] && ok; i++) { const char v = val[i]; const char p = pic[i]; switch (p) { case 'A': ok = (v >= '0' && v <= '9') || (v >= 'A' && v <= 'Z'); break; case '0': ok = (v >= '0' && v <= '9'); break; case '9': ok = (v == ' ') || (v >= '0' && v <= '9'); break; default : break; } } if (!ok) { TString msg; msg << TR("Il codice non rispetta il formato impostato nella configurazione") << '\n' << val << " <> " << pic; return fld.error_box(msg); } return ok; } /////////////////////////////////////////////////////////// // Utilities /////////////////////////////////////////////////////////// static void ca_append_select_clause(ostream& out, int level, int logic) { TString str; if (logic == LF_PCON) { switch (level) { case 0: str = "CONTO==\"\""; break; case 1: str = "SOTTOCONTO==\"\""; break; default: break; } } else { const TMultilevel_code_info& mci = ca_multilevel_code_info(logic); const TFieldref& key = mci.fieldref(level); str << "STR("; if (level > 1) str << "(NUM(LEN(" << key.name() << "))>" << key.from() << ')'; // SE LEN(CODCONTO)>=4 if (level < mci.levels()) { if (level > 1) str << "&&"; str << "(NUM(LEN(" << key.name() << "))<=" << key.to() << ')'; // SE LEN(CODCONTO)<=7 } str << ')'; } if (str.not_empty()) out << " SE " << str << '\n'; } static void ca_append_run_clause(ostream& out, int logicnum) { const TString& app = ca_multilevel_code_info(logicnum).editor(); if (app.not_empty()) out << "AD RU " << app << '\n'; } static void init_tmp_filename(TFilename& name) { name.tempdir(); name.add("tmp.msk"); } void ca_create_browse1(TEdit_field& kfld, int level, int logic, short key_id, short des_id) { const TMultilevel_code_info& main_info = ca_multilevel_code_info(logic); if (logic == LF_FASI) { const int par = main_info.parent(); if (par > 0) { const TMultilevel_code_info& parinfo = ca_multilevel_code_info(par); if (level < parinfo.levels()) logic = par; } } const TMultilevel_code_info& mci = ca_multilevel_code_info(logic); TFilename tmp; init_tmp_filename(tmp); ofstream out(tmp); out << "US " << logic << '\n'; ca_append_select_clause(out, level, logic); ca_append_run_clause(out, logic); for (int i = 0; i <= level; i++) { const TString& picture = mci.picture(i); const TString& prompt = mci.prompt(i); const TFieldref& field = mci.fieldref(i); const int length = field.to() - field.from(); out << "IN " << field << ' ' << (key_id+i) << '\n'; out << "DI \"" << prompt; if (length > prompt.len()) out << '@' << length; out << "\" " << field << '\n'; out << "OU " << (key_id+i) << ' ' << field << '\n'; } const TFieldref& field = mci.fieldref(0, 2); out << "DI \"" << TR("Descrizione") << "@50\" " << field << '\n'; out << "OU " << (des_id+level) << ' ' << field << '\n'; out << "CH NO" << '\n'; out << "FI " << main_info.fieldref(level) << '\n'; out << "EN" << '\n'; out.close(); TScanner scan(tmp); while (scan.pop() != "EN") kfld.parse_item(scan); xvt_fsys_removefile(tmp); } void ca_create_browse2(TEdit_field& kfld, int level, int logic, short key_id, short des_id) { const TMultilevel_code_info& main_info = ca_multilevel_code_info(logic); if (logic == LF_FASI) { const int par = main_info.parent(); if (par > 0) { const TMultilevel_code_info& parinfo = ca_multilevel_code_info(par); if (level < parinfo.levels()) logic = par; } } const TMultilevel_code_info& mci = ca_multilevel_code_info(logic); const TFieldref& field = mci.fieldref(0, 2); TString str2; str2 << field; TFilename tmp; init_tmp_filename(tmp); ofstream out(tmp); out << "US " << logic << " KE 2" << '\n'; ca_append_select_clause(out, level, logic); ca_append_run_clause(out, logic); out << "IN " << str2 << ' ' << kfld.dlg() << '\n'; out << "DI \"" << TR("Descrizione") << "@50\" " << str2 << '\n'; out << "OU " << kfld.dlg() << ' ' << str2 << '\n'; for (int i = 0; i <= level; i++) { const TString& picture = mci.picture(i); const TString& prompt = mci.prompt(i); const TFieldref& field = mci.fieldref(i); const int length = field.to() - field.from(); out << "DI \"" << prompt; if (length > prompt.len()) { out << '@' << length; if (mci.is_numeric_picture(i)) out << 'R'; } out << "\" " << field << '\n'; out << "OU " << (key_id+i) << ' ' << field << '\n'; } out << "CH NO" << '\n'; if (level == main_info.levels()-1) out << "FI " << main_info.fieldref(0, 2) << '\n'; out << "EN" << '\n'; out.close(); TScanner scan(tmp); while (scan.pop() != "EN") kfld.parse_item(scan); xvt_fsys_removefile(tmp); } int ca_create_fields(TMask& msk, int page, int logicnum, int x, int y, short key_id, short des_id, unsigned int mode, const char* fieldname) { TWait_cursor hourglass; const TMultilevel_code_info& mci = ca_multilevel_code_info(logicnum); int maxkeylen = 0, maxdeslen = 0; for (int level = 0; level < mci.levels(); level++) { const TString& prompt = mci.prompt(level); const TString& picture = mci.picture(level); const int keylen = picture.len(); const int deslen = prompt.len(); if (keylen > maxkeylen) maxkeylen = keylen; if (deslen > maxdeslen) maxdeslen = deslen; } maxdeslen++; const int tab0 = x; const int tab1 = tab0 + maxdeslen + maxkeylen + 4; if (key_id > 0 && (mode == 0 || (mode & 0x1) != 0)) { for (int i = 0; i < mci.levels(); i++) { const short kid = key_id+i; const TString& picture = mci.picture(i); TString80 prompt = mci.prompt(i); prompt.left_just(maxdeslen); const char* flags = picture[0] == '0' || picture[0] == '9' ? "BUZ" : "BU"; TEdit_field* kfld = NULL; if (mci.is_numeric_picture(i)) // Numeric kfld = &msk.add_number(kid, page, prompt, tab0, y+i, picture.len(), flags); else kfld = &msk.add_string(kid, page, prompt, tab0, y+i, picture.len(), flags); ca_create_browse1(*kfld, i, logicnum, key_id, des_id); if ((mode & 0x1) != 0 && fieldname == NULL) kfld->set_key(1); // Ho specificato un nome di campo speciale if (fieldname && *fieldname) { const TFieldref& fr = *kfld->field(); TString80 str; str.format("%s[%d,%d]", fieldname, fr.from()+1, fr.to()); kfld->set_field(str); } } } if (des_id > 0 && (mode == 0 || (mode & 0x2) != 0)) { for (int i = 0; i < mci.levels(); i++) { const short did = des_id+i; TEdit_field& dfld = msk.add_string(did, page, "", tab1, y+i, 50, "B", 72+tab0-tab1); ca_create_browse2(dfld, i, logicnum, key_id, des_id); if ((mode & 0x2) != 0 && fieldname == NULL) dfld.set_key(2); else dfld.set_field(""); } } return mci.levels(); } /////////////////////////////////////////////////////////// // TAnal_tree /////////////////////////////////////////////////////////// struct TAnal_tree_pos : public TObject { TRecnotype _recno; TToken_string _key; void as_string(TString& id) const; int level() const { return _key.items(); } void reset(); }; void TAnal_tree_pos::as_string(TString& id) const { id.format("%ld|%s", _recno, (const char*)_key); } void TAnal_tree_pos::reset() { _recno = 0; _key.cut(0); } class TAnal_tree : public TBidirectional_tree { TLocalisamfile* _file; TAnal_tree_pos _curr; protected: virtual void node2id(const TObject* node, TString& id) const; virtual bool goto_firstson(); virtual bool goto_rbrother(); virtual bool goto_node(const TString &id); virtual TObject* curr_node() const; virtual bool goto_father(); virtual bool goto_lbrother(); virtual bool get_description(TString& desc) const; protected: void update_curr(); int level_of(const TToken_string& key) const; int level_of_file() const; const TToken_string& curr_of_file() const; int curr_level() const; int max_level() const; const TToken_string& father_of(const TToken_string& key) const; const TToken_string& father_of_file() const; bool repos() const; public: virtual bool goto_root(); TAnal_tree(int logicnum); virtual ~TAnal_tree(); }; /////////////////////////////////////////////////////////// // TAnal_msk /////////////////////////////////////////////////////////// #define F_TREE 99 short TSimple_anal_msk::get_field_id(int n, int k) const { short id = 0; if (n >= 0 && n < fieldrefs(1)) { if (k == 1) id = F_KEY1+n; else id = F_DES1+n; } return id; } bool TSimple_anal_msk::test_key_field(short id) { TEdit_field& fld = efield(id); const int level = id - F_KEY1; return ca_test_multilevel_field(fld, level); } bool TSimple_anal_msk::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_TREE: if (e == fe_select) { if (edit_mode() && !dirty()) set_mode(MODE_QUERY); if (query_mode()) { const TTree_field& fld = (const TTree_field&)o; const TTree& tree = *fld.tree(); TToken_string curr; tree.curr_id(curr); for (int i = 0; ; i++) { const short id = get_field_id(i); if (id <= 0) break; const char* tok = curr.get(i+1); TEdit_field& e = efield(id); e.set(tok); e.show(); } stop_run(K_AUTO_ENTER); } else beep(0); } break; case F_KEY1: case F_KEY2: case F_KEY3: case F_KEY4: if ((jolly == 0) &&(e == fe_modify || e == fe_close)) return test_key_field(o.dlg()); break; default: break; } return true; } int TSimple_anal_msk::compute_offset() const { int delta = 0; RCT rct; xvt_vobj_get_client_rect(TASK_WIN, &rct); if (rct.right > 720) delta = (rct.right - 720) / 2 / CHARX; return delta; } void TSimple_anal_msk::read(const char* name) { const int delta = compute_offset(); if (delta > 0) { TFilename outname; init_tmp_filename(outname); TFilename inpname = name; inpname.ext("msk"); inpname.custom_path(); ofstream out(outname); TString line; int status = 0; TScanner inp(inpname); while (!inp.eof()) { line = inp.line(); switch (status) { case 0: if (line.starts_with("PA")) status = 1; // Ho trovato la prima pagina break; case 1: if (line.starts_with("PR")) // Ho trovato un prompt sulla prima pagina { TToken_string l(line, ' '); int x = l.get_int(1); if (x >= 0) { x += delta; l.add(x, 1); line = l; } } else if (line.starts_with("PA")) // Ho finito la prima pagina { status = 2; } break; default: break; } out << line << endl; } out.close(); read_mask(outname, 0, 0); xvt_fsys_removefile(outname); set_source_file(name); } else read_mask(name, 0, 0); create_key_fields(); create_tree_field(); } short TSimple_anal_msk::create_tree_field() { short id = 0; const int delta = compute_offset(); if (delta > 0) { id = F_TREE; add_tree(id, 0, 0, 1, (delta-1)*2, -1); TAnal_tree* t = new TAnal_tree(get_logicnum()); tfield(id).set_tree(t); t->goto_root(); t->expand(); } set_handlers(); return id; } void TSimple_anal_msk::update_tree_field() { const int pos = id2pos(F_TREE); if (pos >= 0) { TTree_field& t = tfield(F_TREE); t.win().force_update(); } } int TSimple_anal_msk::fieldrefs(int k) const { int n = 1; if (k == 1) { const TMultilevel_code_info& mci = ca_multilevel_code_info(get_logicnum()); n = mci.levels(); } return n; } const TFieldref& TSimple_anal_msk::fieldref(int n, int k) const { const TMultilevel_code_info& mci = ca_multilevel_code_info(get_logicnum()); return mci.fieldref(n, k); } const TToken_string& TSimple_anal_msk::get_key_value(const TRectype& rec, int c) const { TToken_string& val = get_tmp_string(); const int tot = fieldrefs(c); for (int i = 0; i < tot; i++) { const TFieldref& field = fieldref(i, c); val.add(field.read(rec)); } return val; } const TToken_string& TSimple_anal_msk::get_key_value(int c) const { TToken_string& val = get_tmp_string(); for (TEditable_field* f = get_key_field(c, true); f != NULL; f = get_key_field(c, false)) { val.add(f->get()); } return val; } int TSimple_anal_msk::create_key_fields() { const int logic = get_logicnum(); const short kid = get_field_id(0, 1); const short did = get_field_id(0, 2); const int x = compute_offset()+3; const int y = 1; const int n = ca_create_fields(*this, 0, logic, x, y, kid, did, 0x1); const int m = ca_create_fields(*this, 0, logic, x, y, kid, did, 0x2); first_focus(kid); return n; } /////////////////////////////////////////////////////////// // TAnal_tree /////////////////////////////////////////////////////////// const TToken_string& TAnal_tree::curr_of_file() const { const TMultilevel_code_info& mci = ca_multilevel_code_info(_file->num()); const TRectype& rec = _file->curr(); TToken_string& k = get_tmp_string(); for (int i = 0; i < mci.levels(); i++) { const TFieldref& fld = mci.fieldref(i); k.add(fld.read(rec)); } for (int j = k.len()-1; j >= 0; j--) { if (k[j] == ' ' || k[j] == k.separator()) k.cut(j); else break; } return k; } int TAnal_tree::level_of(const TToken_string& k) const { return k.items(); } int TAnal_tree::level_of_file() const { const TToken_string& str = curr_of_file(); return level_of(str); } int TAnal_tree::curr_level() const { return level_of(_curr._key); } int TAnal_tree::max_level() const { const TMultilevel_code_info& mci = ca_multilevel_code_info(_file->num()); return mci.levels(); } const TToken_string& TAnal_tree::father_of(const TToken_string& key) const { const int pos = key.rfind(key.separator()); if (pos <= 0) return EMPTY_STRING; TToken_string& k = get_tmp_string(); k = key.left(pos); return k; } const TToken_string& TAnal_tree::father_of_file() const { const TToken_string& k = curr_of_file(); return father_of(k); } void TAnal_tree::update_curr() { _curr._key = curr_of_file(); if (_curr._key.not_empty()) _curr._recno = _file->recno(); else _curr.reset(); } bool TAnal_tree::repos() const { bool ok = false; if (_curr.level() > 0) { if (_file->recno() != _curr._recno) ok = ((TLocalisamfile*)_file)->readat(_curr._recno) == NOERR; else ok = true; } return ok; } void TAnal_tree::node2id(const TObject* node, TString& id) const { const TAnal_tree_pos* pos = (const TAnal_tree_pos*)node; pos->as_string(id); } bool TAnal_tree::goto_root() { const bool ok = _file->first() == NOERR; if (ok) update_curr(); else _curr.reset(); return ok; } bool TAnal_tree::goto_firstson() { bool ok = _curr.level() < max_level() && repos(); if (ok) { ok = _file->next() == NOERR; if (ok) { ok = father_of_file() == _curr._key; if (ok) update_curr(); } } return ok; } bool TAnal_tree::goto_rbrother() { bool ok = false; if (repos()) { const TToken_string curr_father = father_of(_curr._key); while (_file->next() == NOERR) { const int lev = level_of_file(); if (lev > _curr.level()) continue; const TToken_string& next_father = father_of_file(); ok = next_father == curr_father; break; } if (ok) update_curr(); } return ok; } bool TAnal_tree::goto_node(const TString &id) { const TRecnotype rec = atol(id); const int err = _file->readat(rec); if (err == NOERR) update_curr(); return err == NOERR; } bool TAnal_tree::goto_father() { const int lev = _curr.level(); bool ok = lev > 1; if (ok) { TRectype& rec = _file->curr(); rec.zero(); const TMultilevel_code_info& mci = ca_multilevel_code_info(_file->num()); for (int i = 0; i < lev-1; i++) { const char* val = _curr._key.get(i); const TFieldref& fld = mci.fieldref(i); fld.write(val, rec); } ok = _file->read() == NOERR; if (ok) update_curr(); } return ok; } bool TAnal_tree::goto_lbrother() { bool ok = false; if (repos()) { const TString curr_father = father_of(_curr._key); while (_file->prev() == NOERR) { const int lev = level_of_file(); if (lev > _curr.level()) continue; const TString& next_father = father_of_file(); ok = next_father == curr_father; break; } if (ok) update_curr(); } return ok; } TObject* TAnal_tree::curr_node() const { return (TObject*)&_curr; } bool TAnal_tree::get_description(TString& desc) const { const bool ok = repos(); if (ok) { const int lev = _curr.level(); if (lev > 0) { const TMultilevel_code_info& mci = ca_multilevel_code_info(_file->num()); const TFieldref& fld1 = mci.fieldref(lev-1, 1); const TFieldref& fld2 = mci.fieldref(0, 2); const TRectype& rec = _file->curr(); desc = fld1.read(rec); desc << ' ' << fld2.read(rec); } } return ok; } TAnal_tree::TAnal_tree(int logicnum) { _file = new TLocalisamfile(logicnum); } TAnal_tree::~TAnal_tree() { delete _file; } /////////////////////////////////////////////////////////// // TAnal_app /////////////////////////////////////////////////////////// void TAnal_app::init_key_fields(TSimple_anal_msk & m) const { int maxlev = 0; for (maxlev = 0; maxlev < 4; maxlev++) { const short id = m.get_field_id(maxlev, 1); if (id <= 0 || m.id2pos(id) < 0) break; m.disable(id); const short did = m.get_field_id(maxlev, 2); m.disable(did); } for (int i = maxlev-1; i >= 0; i--) { const short id = m.get_field_id(i, 1); TEdit_field& e = m.efield(id); const short did = m.get_field_id(i, 2); TEdit_field& d = m.efield(did); if (e.empty()) { e.hide(); d.hide(); } else { e.show(); e.check(STARTING_CHECK); TString80 key2; key2 << m.fieldref(0, 2); d.set_field(key2); d.show(); d.enable(); m.first_focus(d.dlg()); d.enable_check(false); break; } } } TRelation* TAnal_app::create_relation() const { return new TRelation(_msk->get_logicnum()); } bool TAnal_app::user_create() { _msk = create_mask(); _rel = create_relation(); return true; } void TAnal_app::init_query_mode(TMask& mask) { TSimple_anal_msk& m = (TSimple_anal_msk&)mask; for (int i = 0; ; i++) { const short id = m.get_field_id(i, 1); if (id <= 0 || m.id2pos(id) < 0) break; TEdit_field& e = m.efield(id); e.show(); e.enable(); const short did = m.get_field_id(i, 2); TEdit_field& d = m.efield(did); d.show(); d.enable(); d.enable_check(); d.set_field(""); } m.first_focus(m.get_field_id(0, 1)); } void TAnal_app::init_modify_mode(TMask& mask) { init_key_fields((TSimple_anal_msk &)mask); } void TAnal_app::init_insert_mode(TMask& mask) { init_key_fields((TSimple_anal_msk &)mask); } int TAnal_app::write(const TMask& m) { _msk->update_tree_field(); return TRelation_application::write(m); } int TAnal_app::rewrite(const TMask& m) { _msk->update_tree_field(); return TRelation_application::rewrite(m); } bool TAnal_app::user_destroy() { if (_msk != NULL) delete _msk; if (_rel != NULL) delete _rel; return true; } /////////////////////////////////////////////////////////// // TAnal_mov /////////////////////////////////////////////////////////// TImporto& TAnal_mov::saldo(const TRectype& row) { TToken_string key; key.add(get(MOVANA_TIPOMOV)); key.add(get(MOVANA_ANNOES)); key.add(row.get(RMOVANA_CODCCOSTO)); key.add(row.get(RMOVANA_CODCMS)); key.add(row.get(RMOVANA_CODFASE)); key.add(row.get(RMOVANA_CODCONTO)); TImporto* imp = (TImporto*)_saldi.objptr(key); if (imp == NULL) { imp = new TImporto; _saldi.add(key, imp); } return *imp; } void TAnal_mov::load_saldi(bool reset) { if (reset) _saldi.destroy(); const int dec = TCurrency::get_firm_dec(); const TRecord_array& a = body(LF_RMOVANA); for (int i = a.last_row(); i > 0; i--) { const TRectype& row = a[i]; const TImporto imp(row.get_char(RMOVANA_SEZIONE), row.get_real(RMOVANA_IMPORTO)); TImporto& sld = saldo(row); if (reset) sld -= imp; else sld += imp; sld.valore().round(dec); } } void TAnal_mov::update_saldi(bool kill) { if (!kill) load_saldi(false); save_saldi(); if (kill) _saldi.destroy(); else load_saldi(true); } bool TAnal_mov::save_saldi() { TLocalisamfile saldi(LF_SALDANA); FOR_EACH_ASSOC_OBJECT(_saldi, h, k, o) { const TImporto& imp = *(const TImporto*)o; if (!imp.is_zero()) { TToken_string key = k; const char tipo = key.get_char(0); saldi.put(SALDANA_ANNO, key.get()); saldi.put(SALDANA_COSTO, key.get()); saldi.put(SALDANA_COMMESSA, key.get()); saldi.put(SALDANA_FASE, key.get()); saldi.put(SALDANA_CONTO, key.get()); int err = saldi.read(_isequal, _testandlock); if (err != NOERR) { saldi.zero(); saldi.put(SALDANA_ANNO, key.get(1)); saldi.put(SALDANA_COSTO, key.get()); saldi.put(SALDANA_COMMESSA, key.get()); saldi.put(SALDANA_FASE, key.get()); saldi.put(SALDANA_CONTO, key.get()); err = saldi.write(); } if (err == NOERR) { const char* fld_sez = NULL; const char* fld_val = NULL; switch (tipo) { case 'P': fld_sez = SALDANA_SEZIONEP; fld_val = SALDANA_SALDOP; break; case 'V': fld_sez = SALDANA_SEZIONEV; fld_val = SALDANA_SALDOV; break; default : fld_sez = SALDANA_SEZIONE; fld_val = SALDANA_SALDO; break; } TImporto saldo(saldi.get_char(fld_sez), saldi.get_real(fld_val)); saldo += imp; saldo.normalize(); saldi.put(fld_sez, saldo.sezione()); saldi.put(fld_val, saldo.valore()); err = saldi.rewrite(); } if (err != NOERR) return error_box(FR("Impossibile aggiornare i saldi: errore %d"), err); } } return true; } int TAnal_mov::readat(TBaseisamfile& f, TRecnotype nrec, word lockop) { const int err = TMultiple_rectype::readat(f, nrec, lockop); load_saldi(true); return err; } int TAnal_mov::read(TBaseisamfile& f, word op, word lockop) { const int err = TMultiple_rectype::read(f, op, lockop); load_saldi(true); return err; } // Riporta su tutte le righe la data di competenza e l'esercizio dellla testata void TAnal_mov::update_datacomp() const { body().renum_key(RMOVANA_ANNOES, get(MOVANA_ANNOES)); body().renum_key(RMOVANA_DATACOMP, get(MOVANA_DATACOMP)); } int TAnal_mov::write(TBaseisamfile& f) const { update_datacomp(); const int err = TMultiple_rectype::write(f); if (err == NOERR) ((TAnal_mov*)this)->update_saldi(false); return err; } int TAnal_mov::rewrite(TBaseisamfile& f) const { update_datacomp(); const int err = TMultiple_rectype::rewrite(f); if (err == NOERR) ((TAnal_mov*)this)->update_saldi(false); return err; } int TAnal_mov::remove(TBaseisamfile& f) const { const int err = TMultiple_rectype::remove(f); if (err == NOERR) ((TAnal_mov*)this)->update_saldi(true); return err; } int TAnal_mov::read(long numreg, word lock) { put(MOVANA_NUMREG, numreg); const int err = TMultiple_rectype::read(_isequal, lock); load_saldi(true); return err; } TAnal_mov::TAnal_mov(long numreg) : TMultiple_rectype(LF_MOVANA) { add_file(LF_RMOVANA, RMOVANA_NUMRIG); if (numreg > 0) read(numreg); } /////////////////////////////////////////////////////////// // TAnal_rip /////////////////////////////////////////////////////////// TAnal_rip::TAnal_rip() : TMultiple_rectype(LF_RIP) { add_file(LF_RRIP, RRIP_NRIGA); } /////////////////////////////////////////////////////////// // TCache_ripartizioni /////////////////////////////////////////////////////////// TObject* TCache_ripartizioni::key2obj(const char* key) { TToken_string parametro(key); TLocalisamfile rip(LF_RIP); const int nkey = parametro.get_int(0); rip.setkey(nkey); rip.put(RIP_TIPO, "B"); switch (nkey) { case 3: //chiave 3 (tipo+gr/co/stc) rip.put(RIP_GRUPPO, parametro.get(1)); rip.put(RIP_CONTO, parametro.get()); rip.put(RIP_SOTTOCONTO, parametro.get()); break; case 4: //chiave 4 (tipo+codcosto+codcms) rip.put(RIP_CODCOSTO, parametro.get(1)); rip.put(RIP_CODCMS, parametro.get()); break; default: break; } TString80 chiave; if (rip.read() == NOERR) chiave << "B|" << rip.get(RIP_CODICE); TRecord_array* rows = new TRecord_array(chiave, LF_RRIP); return (TObject*)rows; } const TRecord_array& TCache_ripartizioni::righe(const char* costo, const char* commessa) { TToken_string parametro; parametro << "4|" << costo << '|' << commessa; //per chiave 4 return *(const TRecord_array*)objptr(parametro); } const TRecord_array& TCache_ripartizioni::righe(const int gruppo, const int conto, const long sottoconto) { TToken_string parametro; parametro << "3|" << gruppo << '|' << conto << '|' << sottoconto; //per chiave 3 return *(const TRecord_array*)objptr(parametro); } const TRecord_array& TCache_ripartizioni::righe(const TBill& bill) { return righe(bill.gruppo(), bill.conto(), bill.sottoconto()); }