#include #include #include #include #include #include #include #include #include #include "../mg/anamag.h" #include "ha3.h" #include "ha3900a.h" ////////////////////////////////////////////// // Albero ////////////////////////////////////////////// //Albero per la gestione delle macchine di un cliente class TCoffee_tree : public TBidirectional_tree { TString8 _curr_node; long _codcf; TString8 _codart; TString16 _matricola; TISAM_recordset _recset; public: virtual bool goto_root(); virtual bool goto_firstson() { return false; } virtual bool goto_rbrother(); virtual bool goto_node(const TString &id); virtual bool could_have_son() const { return false; } virtual bool has_son() const { return false; } virtual bool has_rbrother() const; virtual TObject* curr_node() const { return (TObject*)&_curr_node; } virtual void node2id(const TObject* obj, TString& id) const { id = *(TString*)obj; } virtual bool has_root() const; virtual bool has_father() const { return false; } virtual bool has_lbrother() const; virtual bool goto_father() { return false; } virtual bool goto_lbrother(); virtual bool get_description(TString& desc) const; virtual TFieldtypes get_var(const TString& name, TVariant& var) const; virtual TImage* image(bool selected) const { return get_res_icon(10232); } public: bool set_clifo(long codcf); bool select_attr(const TString& codart, const TString& matricola); const long get_codcf() const; const TString& get_codart() const; const TString& get_matricola() const; TCoffee_tree() : _codcf(0), _recset("USE &ATT") { set_clifo(0L); } }; bool TCoffee_tree::has_root() const { return _recset.items() > 0L; } bool TCoffee_tree::goto_root() { const bool ok = _recset.move_first(); if (ok) _curr_node = "0"; else _curr_node.cut(0); return ok; } bool TCoffee_tree::has_rbrother() const { const long pos = atol(_curr_node); return pos < _recset.items() - 1; } bool TCoffee_tree::goto_rbrother() { const long pos = atol(_curr_node) + 1; const bool ok = _recset.move_to(pos); if (ok) _curr_node.format("%ld", pos); return ok; } bool TCoffee_tree::has_lbrother() const { return atol(_curr_node) > 0L; } bool TCoffee_tree::goto_lbrother() { const long pos = atol(_curr_node) - 1; const bool ok = pos >= 0 && _recset.move_to(pos); if (ok) _curr_node.format("%ld", pos); return ok; } bool TCoffee_tree::goto_node(const TString &id) { const long pos = atol(id); const bool ok = _recset.move_to(pos); if (ok) _curr_node = id; return ok; } bool TCoffee_tree::get_description(TString& desc) const { desc = _recset.get("CODTAB").as_string(); return desc.full(); } TFieldtypes TCoffee_tree::get_var(const TString& name, TVariant& var) const { //se il campo richiesto è la descrizione ci vuole quella dell'articolo, non dell'attrezzatura.. //..che risulta vuota if (name == "S0") { TString8 codart = _recset.get("CODTAB[1,5]").as_string(); codart.trim(); var = cache().get(LF_ANAMAG, codart, ANAMAG_DESCR); } else var = _recset.get(name); return var.type(); } const TString& TCoffee_tree::get_codart() const { return _codart; } const TString& TCoffee_tree::get_matricola() const { return _matricola; } const long TCoffee_tree::get_codcf() const { return _codcf; } bool TCoffee_tree::set_clifo(long codcf) { _codcf = codcf; TString query; query << "USE &ATT\nSELECT I0=" << codcf; _recset.set(query); return goto_root(); } bool TCoffee_tree::select_attr(const TString& codart, const TString& matricola) { bool found = false; for (bool ok = _recset.move_first(); ok; ok = _recset.move_next()) { TString8 curr_codart = _recset.get("CODTAB[1,5]").as_string(); curr_codart.trim(); if (curr_codart == codart) { _codart = codart; TString16 curr_matricola = _recset.get("CODTAB[16,30]").as_string(); curr_matricola.trim(); if (curr_matricola == matricola) { _curr_node.format("%ld", _recset.current_row()); found = true; _matricola = matricola; break; } } } return found; } ////////////////////////////////////////////// // Maschera ////////////////////////////////////////////// class TGestione_attrezzature_mask : public TAutomask { bool _sheet_dirty; protected: void fill_sheet_storico(const TString& codattr); bool write(); void save_if_dirty(); virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TGestione_attrezzature_mask(); }; //metodo che riempie il primo sheet delle attrezzature in base ai filtri su cliente/attrezztura void TGestione_attrezzature_mask::fill_sheet_storico(const TString& codattr) { //riempie lo sheet dello storico in base all'attrezzatura scelta nell'albero TString query; query << "USE &HIS"; query << "\nFROM CODTAB=#CODATTR"; query << "\nTO CODTAB=#CODATTR"; TISAM_recordset recset(query); recset.set_var("#CODATTR", codattr); const long recset_items = recset.items(); TSheet_field& sf_righe = sfield(F_STORICO); sf_righe.destroy(); //maschera di sheet TMask& msk = sf_righe.sheet_mask(); //record del recordset con i valori da mettere sulla riga sheet const TRectype& rec = recset.cursor()->curr(); //new style (seza _pos_campo!) for (bool ok = recset.move_first(); ok; ok = recset.move_next()) { TToken_string& row = sf_righe.row(-1); //riga sheet da riempire //per ogni campo della maschera di sheet setta.. //..il valore di quei campi che hanno un field FOR_EACH_MASK_FIELD(msk, i, f) { const short id = f->dlg(); if (id >= 101 && id < 200) { const TFieldref* fr = f->field(); if (fr != NULL) row.add(fr->read(rec), id - 101); } } } //mostra e aggiorna lo sheet sf_righe.show(); sf_righe.force_update(); } //metodo di salvataggio dei record dello sheet bool TGestione_attrezzature_mask::write() { TTreelist_field& tf = (TTreelist_field&)field(F_ATTREZZATURE); TCoffee_tree* ct = (TCoffee_tree*)tf.tree(); if (ct == NULL) return false; const TString& codart = ct->get_codart(); const TString& matricola = ct->get_matricola(); TSheet_field& sf_righe = sfield(F_STORICO); //maschera di riga dello sheet TMask& sm = sf_righe.sheet_mask(); //tabella di modulo con lo storico interventi TModule_table his("&HIS"); TRectype& rec_his = his.curr(); //codice articolo + matricola (prima parte del CODTAB del record di tabmod) TString80 codtab; codtab.format("%-15s%-15s", (const char*)codart, (const char*)matricola); //contatore delle righe che vengono salvate int righe_tot = 0; //giro su tutte le righe dello sheet FOR_EACH_SHEET_ROW(sf_righe, r, riga) { short id = 101; //giro su tutti i campi della riga (che è una sporca token_string) //per prima cosa mette la chiave del record che è così fatta: // codart=codtab[1,5] - matricola=codtab[16,30] - nriga=codtab[31,35] TString80 curr_codtab; curr_codtab.format("%05d", r + 1); curr_codtab.insert(codtab); //azzera il record senno' nei campi vuoti ci metterebbe quelli del record precedente //deve azzerare la tabella, senno' perde il codice modulo HA ed il codice tabella HIS his.zero(); rec_his.put("CODTAB", curr_codtab); FOR_EACH_TOKEN(*riga, str) { const TMask_field& mf = sm.field(id); const TFieldref* fr = mf.field(); //solo i campi della maschera di riga che hanno un FIELD vengono salvati, gli altri si arrangino! if (fr != NULL) { fr->write(str, rec_his); } id ++; } his.rewrite_write(); righe_tot ++; } //compatta le righe dello storico, eliminando quelle in esubero TString query; query << "USE &HIS"; query << "\nFROM CODTAB=#DACODTAB"; TISAM_recordset recset(query); TString80 dacodtab; dacodtab.format("%05d", righe_tot + 1); dacodtab.insert(codtab); recset.set_var("#DACODTAB", dacodtab); //accoppa tutte le righe in esubero dalla tabella &HIS for (bool ok = recset.move_first(); ok; ok = recset.move_next()) recset.cursor()->relation()->remove(); //una volta che ha salvato lo sheet deve risultare immacolato! _sheet_dirty = false; return true; } void TGestione_attrezzature_mask::save_if_dirty() { if (_sheet_dirty && yesno_box(TR("Salvare le modifiche ?"))) write(); } bool TGestione_attrezzature_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { //campi case F_CODCF: if (e == fe_modify) { //albero magico: selezionando un cliente riempie l'albero con tutte le attrezzature del cliente TTreelist_field& tf = (TTreelist_field&)field(F_ATTREZZATURE); TCoffee_tree* ct = (TCoffee_tree*)tf.tree(); if (ct != NULL) { ct->set_clifo(atol(o.get())); tf.win().force_update(); } } break; case F_COD_MATR: if (e == fe_modify) { //albero magico: selezionando un'attrezzatura, si posiziona direttamente sulla giusta posizione nell'albero.. //..(il cliente viene riempito dalla maschera) TTreelist_field& tf = (TTreelist_field&)field(F_ATTREZZATURE); TCoffee_tree* ct = (TCoffee_tree*)tf.tree(); if (ct != NULL) { ct->set_clifo(get_long(F_CODCF)); const TString& codart = get(F_COD_ART); const TString& matricola = get(F_COD_MATR); if (ct->select_attr(codart, matricola)) { tf.select_current(); send_key(K_SPACE, F_ATTREZZATURE, &o); } } } break; case F_ATTREZZATURE: if (e == fe_modify) { TTreelist_field& tf = (TTreelist_field&)field(F_ATTREZZATURE); TCoffee_tree* ct = (TCoffee_tree*)tf.tree(); if (ct != NULL) { TString80 codattr; ct->get_description(codattr); //riempie i campi di intestazione maschera set(F_COD_ART, codattr.left(5)); set(F_COD_MATR, codattr.mid(15,15)); //chiede di salvare le modifiche al cambio attrezzatura save_if_dirty(); //riempie lo sheet fill_sheet_storico(codattr); } } break; case F_STORICO: if (e == se_query_modify || e == se_notify_del) { _sheet_dirty = true; } break; //bottoni case DLG_SAVEREC: if (e == fe_button && check_fields()) { write(); } break; case DLG_CANCEL: if (e == fe_button && jolly == 0) //il jolly=0 significa che si riferisce alla maschera principale!.. { //..se non ci fosse azzererebbe tutto anche quando si fa annulla sulla maschera di riga! //nel caso l'utonto clicchi su ANNULLA dopo aver fatto modifiche sara' meglio chiedere conferma se le vuole mantenere save_if_dirty(); //azzera i campi della maschera reset(); TTreelist_field& tf = (TTreelist_field&)field(F_ATTREZZATURE); TCoffee_tree* ct = (TCoffee_tree*)tf.tree(); if (ct != NULL) { ct->set_clifo(0L); tf.win().force_update(); } return false; } break; case DLG_QUIT: if (e == fe_button) { //nel caso l'utonto clicchi su FINE dopo aver fatto modifiche sara' meglio chiedere conferma se le vuole mantenere save_if_dirty(); } break; default: break; } return true; } TGestione_attrezzature_mask::TGestione_attrezzature_mask() : TAutomask("ha3900a") { //assegna l'albero del caffe' al campo di tipo albero sulla maschera TTreelist_field& tf = (TTreelist_field&)field(F_ATTREZZATURE); TCoffee_tree* ct = new TCoffee_tree; tf.set_tree(ct); //inizializza lo "sporcatore" dello sheet _sheet_dirty = false; } ////////////////////////////////////////////// // Applicazione ////////////////////////////////////////////// class TGestione_attrezzature : public TSkeleton_application { virtual void main_loop(); }; void TGestione_attrezzature::main_loop() { TGestione_attrezzature_mask mask; while (mask.run() == K_ENTER) { } } int ha3900(int argc, char* argv[]) { TGestione_attrezzature app; app.run(argc, argv, TR("Gestione storico attrezzature")); return 0; }