#include #include #include #include #include "condv.h" #include "rcondv.h" #include "ve2500a.h" /////////////////////////////////////////////////////////////// // MASCHERA /////////////////////////////////////////////////////////////// class TGestione_listini_semplice_mask: public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); void crea_listino_da_anagrafica(); void copia_listino(); public: int find_art(TSheet_field& s, const char tipo, const TString& art, const int tranne = -1) const; int guess_art(TSheet_field& s, const char tipo, const TString& art) const; TGestione_listini_semplice_mask(); }; TGestione_listini_semplice_mask::TGestione_listini_semplice_mask() : TAutomask("ve2500a") { //in base alla cervellotica configurazione impostata dall'utonto abilita/disabilita campi const bool gesliscv = ini_get_bool(CONFIG_DITTA, "ve", "GESLISCV"); enable(F_L_CATVEN, gesliscv); enable(F_L_DESVEN, gesliscv); //attenzione!!! il campo CATVEN è in chiave 1! per disabilitarlo ci vuole questo trucco! if (!gesliscv) efield(F_L_CATVEN).reset_key(1); } //metodo per la ricerca al volo di un articolo (serve per posizionare il cursore sullo sheet in tempo reale.. //..mentre si digita il codice articolo nel campo di ricerca int TGestione_listini_semplice_mask::guess_art(TSheet_field& s, const char tipo, const TString& art) const { return 0; } //metodo che restituisce l'indice della riga dello sheet che contiene //la coppia tipo-articolo desiderata (-1 se non lo trova) int TGestione_listini_semplice_mask::find_art(TSheet_field& s, const char tipo, const TString& art, const int tranne) const { int r = -1; //scorro le righe dello sheet partendo dall'ultima //tranne serve per evitare una riga specifica;di default è posto =-1 perchè non si usa for (r = s.items() - 1; r >= 0; r--) { if (r != tranne) { const char* tiporiga = s.row(r).get(0); const char* codart = s.row(r).get(1); if (tipo == tiporiga[0] && art == codart) break; } } return r; } void TGestione_listini_semplice_mask::crea_listino_da_anagrafica() { } void TGestione_listini_semplice_mask::copia_listino() { } bool TGestione_listini_semplice_mask::on_field_event(TOperable_field &o, TField_event e, long jolly) { switch(o.dlg()) { case F_L_CODRIGA_A: case F_L_CODRIGA_G: case F_L_CODRIGA_S: case F_L_CODRIGA_R: if (e == fe_modify) { const char tiporiga = get(F_L_TIPORIGA)[0]; const TString& codriga = o.get(); TSheet_field& sf_righe = sfield(F_L_RIGHE); const long riga = find_art(sf_righe, tiporiga, codriga); if (riga >= 0) sf_righe.select(riga, true); } break; //se abilita la gestione scaglioni nello sheet devono comparire le colonne NSCAGL e QLIM case F_L_GESTSCAGL: if (e == fe_init || e == fe_modify) { TSheet_field& sf_righe = sfield(F_L_RIGHE); const bool gest_scagl = o.get().full(); sf_righe.enable_column(F_NSCAGL, gest_scagl); sf_righe.enable_column(F_QLIM, gest_scagl); sf_righe.force_update(); } break; //stesso giochetto per UM case F_L_GESTUM: if (e == fe_init || e == fe_modify) { TSheet_field& sf_righe = sfield(F_L_RIGHE); const bool gest_um = o.get().full(); sf_righe.enable_column(F_UM, gest_um); sf_righe.force_update(); } break; //e anche per i campi omaggio case F_L_GESTSCO: if (e == fe_init || e == fe_modify) { TSheet_field& sf_righe = sfield(F_L_RIGHE); const bool gest_sco = o.get().full(); sf_righe.enable_column(F_ADDIVA, gest_sco); sf_righe.enable_column(F_CODIVA, gest_sco); sf_righe.enable_column(F_QOM, gest_sco); sf_righe.enable_column(F_QBASE, gest_sco); sf_righe.enable_column(F_CODARTOM, gest_sco); sf_righe.enable_column(F_UMOM, gest_sco); sf_righe.enable_column(F_PROMAGGIO, gest_sco); sf_righe.force_update(); } break; //controllo della unicità del tiporiga+codriga nello sheet case F_L_RIGHE: if (e == se_notify_modify) { TSheet_field& sf_righe = sfield(F_L_RIGHE); TToken_string& riga = sf_righe.row(jolly); const char tipo = riga.get_char(0); const TString& art = riga.get(1); const long found_riga = find_art(sf_righe, tipo, art, jolly); if (found_riga >= 0) return error_box(TR("Non è possibile inserire lo stesso articolo più di una volta!")); } break; case DLG_CREA: if (e == fe_button) { crea_listino_da_anagrafica(); } break; case DLG_COPIA: { copia_listino(); } break; default: break; } return true; } /////////////////////////////////////////////////////////////// // APPLICAZIONE /////////////////////////////////////////////////////////////// class TGestione_listini_semplice : public TRelation_application { TGestione_listini_semplice_mask *_mask; TRelation* _rel; private: void save_rows(); TString build_query() const; protected: virtual bool user_create(); virtual bool user_destroy(); virtual TMask *get_mask(int) { return _mask; } virtual bool changing_mask(int) { return false; } // virtual void init_query_mode(TMask& m); // virtual void init_insert_mode(TMask& m); // virtual void init_modify_mode(TMask& m); virtual bool protected_record(TRectype& rec); virtual int read(TMask& m); // virtual bool remove(); virtual int write(const TMask& m); virtual int rewrite(const TMask& m); public: virtual TRelation *get_relation() const { return _rel; } TGestione_listini_semplice() { _rel = NULL; _mask = NULL;} virtual ~TGestione_listini_semplice() {} }; void TGestione_listini_semplice::save_rows() { //attenzione!!! fatto questo casino per poter usare la find_art() che è un metodo della maschera listini const TGestione_listini_semplice_mask& m = *_mask; //instanzio un TISAM_recordset sulle righe listino e un localisamfile TISAM_recordset righelist(build_query()); righelist.set_var("#CATVEN", m.get(F_L_CATVEN)); righelist.set_var("#COD", m.get(F_L_COD)); const long righelist_items = righelist.items(); TLocalisamfile& file = righelist.cursor()->file(); //sheet righe listino da salvare! (righe panda?) TSheet_field& righe = m.sfield(F_L_RIGHE); //scorro tutte le righe listino ed elimino tutte quelle che non ci sono più sullo sheet (modifiche utonto) for (bool ok = righelist.move_first(); ok; ok = righelist.move_next()) { const char tiporiga = righelist.get("TIPORIGA").as_string()[0]; const TString& art = righelist.get("CODRIGA").as_string(); if (m.find_art(righe, tiporiga, art) < 0) file.remove(); } //procede al salvataggio di testata e righe //----------------------------------------- //per prima cosa servono i dati di testata utili per riempire la chiave di riga listino const TString& catven = m.get(F_L_CATVEN); const TString& cod = m.get(F_L_COD); //recupero la maschera di riga TMask& msk = righe.sheet_mask(); //per ogni riga dello sheet FOR_EACH_SHEET_ROW(righe, r, row) { file.zero(); file.put(RCONDV_TIPO, "L"); file.put(RCONDV_CATVEN, catven); file.put(RCONDV_COD, cod); //per ogni campo della maschera setta all'interno del record corrente di file //il valore di quei campi che hanno un field FOR_EACH_MASK_FIELD(msk, i, f) { const TFieldref* fr = f->field(); if (fr != NULL && f->dlg() < 200) { const int pos = righe.cid2index(f->dlg()); fr->write(row->get(pos), file.curr()); } } //se è in inserimento deve fare un write, se in modifica la rewrite if (m.insert_mode()) file.write_rewrite(); else file.rewrite_write(); } } bool TGestione_listini_semplice::protected_record(TRectype& rec) { //non deve consentire l'eliminazione di un listino se ha dei figli da mantenere! TString query; query << "USE CONDV\n"; query << "SELECT (FATHCATVEN=#CATVEN)&&(FATHCOD=#COD)\n"; query << "FROM TIPO=L\n"; query << "TO TIPO=L\n"; TISAM_recordset figli(query); figli.set_var("#CATVEN", rec.get(CONDV_CATVEN)); figli.set_var("#COD", rec.get(CONDV_COD)); return figli.items() > 0; } TString TGestione_listini_semplice::build_query() const { TString query; query << "USE RCONDV\n"; query << "FROM TIPO=L CATVEN=#CATVEN COD=#COD\n"; query << "TO TIPO=L CATVEN=#CATVEN COD=#COD\n"; return query; } int TGestione_listini_semplice::read(TMask& m) { //eseguo la read() standard int err = TRelation_application::read(m); //se la read va a buon fine if (err == NOERR) { //instanzio un TISAM_recordset sulle righe listino (RCONDV) TISAM_recordset righelist(build_query()); righelist.set_var("#CATVEN", m.get(F_L_CATVEN)); righelist.set_var("#COD", m.get(F_L_COD)); const long righelist_items = righelist.items(); const TRectype& rec = righelist.cursor()->curr(); //recupero sheet e realtiva mashera di riga TSheet_field& sf_righe = m.sfield(F_L_RIGHE); TMask& msk = sf_righe.sheet_mask(); sf_righe.destroy(); //per ogni riga dello sheet int pos = -1; for (bool ok = righelist.move_first(); ok; ok = righelist.move_next()) { ++pos; TToken_string& row = sf_righe.row(-1); //per ogni campo della maschera setta all'interno del record corrente di file //il valore di quei campi che hanno un field FOR_EACH_MASK_FIELD(msk,i,f) { const TFieldref* fr = f->field(); if (fr != NULL) row.add(fr->read(rec),sf_righe.cid2index(f->dlg())); } //forzo una check_row sf_righe.check_row(sf_righe.items()-1, 3); } } return err; } int TGestione_listini_semplice::rewrite(const TMask& m) { int err = TRelation_application::rewrite(m); if(err == NOERR) save_rows(); return err; } int TGestione_listini_semplice::write(const TMask& m) { int err = TRelation_application::write(m); if(err == NOERR) save_rows(); return err; } bool TGestione_listini_semplice::user_create() { _rel = new TRelation(LF_CONDV); //attenzione!! questo è il parametro per avere la lunghezza del numero riga TSheet_field::set_line_number_width(5); _mask = new TGestione_listini_semplice_mask; return true; } bool TGestione_listini_semplice::user_destroy() { delete _mask; delete _rel; return true; } int ve2500(int argc, char* argv[]) { TGestione_listini_semplice a; a.run(argc, argv, "Gestione listini"); return 0; }