#include #include #include #include #include "lvlib.h" #include "lv0.h" #include "lv0500a.h" #include "lvpasplan.h" #include "lvperisop.h" //////////////// // MASCHERA // //////////////// class TPass_plan_contr_mask : public TAutomask { private: void proponi_orario(); protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TPass_plan_contr_mask(); }; void TPass_plan_contr_mask::proponi_orario() { TSheet_field& sheet = sfield(F_PASPLAN); TToken_string& rigamodificata = sheet.row(sheet.items()-1); rigamodificata.add("00:00",sheet.cid2index(F_S_ORA)); return; } bool TPass_plan_contr_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_PASPLAN: switch (e) { case se_notify_add: proponi_orario(); break; default: break; } break; default: break; } return true; } TPass_plan_contr_mask::TPass_plan_contr_mask() :TAutomask("lv0500a") {} //////////////////// // Applicazione // //////////////////// class TPass_plan_contr : public TRelation_application { TPass_plan_contr_mask* _mask; TRelation* _rel; long _codcli; long _codcont; private: void fill_pasplan(const long codcli, const long codcont); //riempie i passaggi planning per contratto int find_pass(TSheet_field& s,const int ggcons, const int coditi) const; //controlla se esiste una passaggio int write_pasplan(TSheet_field& pasplan, const long codcli, const long codcont); //scrive i passaggi planning per contratto int remove_pasplan(const long codcli, const long codcont); //cancella i passaggi planning per contratto protected: virtual void init_query_mode(TMask& m); virtual bool user_create(); virtual bool user_destroy(); virtual int read(TMask& m); virtual int write(const TMask& m); virtual int rewrite(const TMask& m); virtual bool remove(); virtual TMask* get_mask(int mode) { return _mask; } virtual bool changing_mask(int mode) { return false; } public: virtual TRelation* get_relation() const {return (TRelation*)_rel;} }; /////////////////////////////////////////// //// FUNZIONI PER READ //// /////////////////////////////////////////// //FILL_PASPLAN: questa funzione riempie lo sheet dei passaggi contratto per planning, se ne sono stati già inseriti... //...per la coppia cliente - contratto selezionata, se no propone un insieme di righe vuote,... //...una per ogni giorno della settimana void TPass_plan_contr::fill_pasplan(const long codcli,const long codcont) { //preparo il recordset su LVPASPLAN TISAM_recordset pplan("USE LVPASPLAN\n FROM CODCF=#CODCF CODCONT=#CODCONT\nTO CODCF=#CODCF CODCONT=#CODCONT"); pplan.set_var("#CODCF",codcli); pplan.set_var("#CODCONT",codcont); TProgind pi(pplan.items(), TR("Elaborazione dati passaggi per contratto in corso..."), true, true); TSheet_field& sheet = _mask->sfield(F_PASPLAN); TMask& sheetmask = sheet.sheet_mask(); TRelation& rel = *pplan.cursor()->relation(); //accesso al file delle righe sheet.destroy(); if (pplan.items()>0) { for (bool ok = pplan.move_first(); ok; ok = pplan.move_next()) { if (!pi.addstatus(1)) break; TToken_string& row = sheet.row(-1); //crea una nuova riga dello sheet //scandisco nella maschera tutti i campi che hanno un field FOR_EACH_MASK_FIELD(sheetmask,i,f) { const TFieldref* fr = f->field(); //leggo il valore dalla relation if (fr != NULL) row.add(fr->read(rel),sheet.cid2index(f->dlg())); //metto il valore letto nella posizione corretta nella TToken_string } sheet.check_row(sheet.items()-1); //fa fare alla maschera la decodifica dei codici e aggiorna la TToken_string } } else { //questo ciclo crea le sette righe vuote TString ora = "00:00"; for (int i = 1; i<=7; ++i) { TToken_string& row = sheet.row(-1); //crea una nuova riga dello sheet row.add(i,sheet.cid2index(F_S_GGCONS)); //aggiunge al posto giusto il numero del giorno della settimana row.add(ora,sheet.cid2index(F_S_ORA)); //propone l'ora di arrivo in automatico sheet.check_row(sheet.items()-1); //forza la maschera a fare la decodifica dei codici } } sheet.force_update(); //forza l'update dello sheet, in modo da rendere visibili i cambiamneti fatti return; } //READ: ridefinizione metodo read() delle TRelation int TPass_plan_contr::read(TMask& m) { //i due campi di testata DEVONO essere pieni tutte e due /*if (m.field(F_CODCF).empty() || m.field(F_CODCONT).empty()) return !NOERR;*/ //recupero i dati della testata const long codcli = _rel->curr().get_long("CODCF"); const long codcont = _rel->curr().get_long("CODCONT"); fill_pasplan(codcli,codcont); TSheet_field& ps = m.sfield(F_PERSOSP); ps.record()->read(*ps.putkey(*_rel)); ps.autoload(*_rel); return NOERR; } /////////////////////////////////////////// //// FUNZIONI PER WRITE E REWRITE //// /////////////////////////////////////////// //FIND_PASS: questa funziona controlla se una coppia giorno di consegna - itinerario che esiste sul file, //esiste ancora sullo sheet (se non esiste è stato cancellato) int TPass_plan_contr::find_pass(TSheet_field& s,const int ggcons, const int coditi) const { int r=-1; //per ogni riga dello sheet, leggi giorno di consegna e itinerario, //e se esiste interrompi restituendo un valore positivo, //se no arriva fino in fondo e resituisci -1 for (r=s.items()-1;r>=0;r--) { const int gc = s.row(r).get_int(s.cid2index(F_S_GGCONS)); const int ci = s.row(r).get_int(s.cid2index(F_S_ITI)); if (ggcons == gc && coditi == ci) break; } return r; } //WRITE_PASPLAN: questa funzione scrive i dati sul file 164 (LVPASPLAN) int TPass_plan_contr::write_pasplan(TSheet_field& pasplan, const long codcli, const long codcont) { //instanzio un TISAM_recordset TISAM_recordset pplan("USE LVPASPLAN\n FROM CODCF=#CODCF CODCONT=#CODCONT\nTO CODCF=#CODCF CODCONT=#CODCONT"); pplan.set_var("#CODCF",codcli); pplan.set_var("#CODCONT",codcont); int err = NOERR; //instanzio un TLocalisamfile TLocalisamfile& file = pplan.cursor()->file(); //per ogni riga del recordset for (bool ok=pplan.move_first(); ok; ok=pplan.move_next()) { //leggo il giorno di consegna e il codice itinerario const int ggcons = pplan.get(LVPASPLAN_GGCONS).as_int(); const int coditi = pplan.get(LVPASPLAN_CODITI).as_int(); //tutte le righe del TISAM_recordset che NON SONO nel TRecord_array vanno eliminate dal file if (find_pass(pasplan,ggcons,coditi) < 0) file.remove(); } //Maschera di sheet TMask& msk = pasplan.sheet_mask(); //per ogni riga dello sheet FOR_EACH_SHEET_ROW(pasplan,r,row) { if (row->get_int(pasplan.cid2index(F_S_ITI)) == 0) continue; else { file.zero(); //putto nel file codcli e codcont (sempre gli stessi) file.put(LVPASPLAN_CODCF,codcli); file.put(LVPASPLAN_CODCONT,codcont); //per ogno campo della maschera di sheet FOR_EACH_MASK_FIELD(msk,i,f) { //prendo il FIELD a cui si riferiscono const TFieldref*fr = f->field(); //se efftivamente il campo ha un field di riferimento if (fr!= NULL) { const int pos=pasplan.cid2index(f->dlg()); //salvo la sua posizione all'inetrno dello sheet fr->write(row->get(pos),file.curr()); //scrivo il valore che sto leggendo nel record corrente del file } } //setto le informazioni di creazione e/o aggiornamento del record if (_mask->edit_mode()) lv_set_update_info(file.curr()); else lv_set_creation_info(file.curr()); err = file.rewrite_write(); //o faccio la rewrite, o faccio la write } } //se la scrittura è andata a buon fine, genero i passaggi planning per contratto... //...dalla data odierna alla data dell'ultimo passaggio previsto già generato if (err == NOERR) { //la scrittura automatica dei giri viene fatta solo se è settato l'apposito flag... //...nella configurazione di modulo TConfig* configlv = new TConfig(CONFIG_DITTA,"lv"); if (configlv->get("Autgiri") == "X") { //richiamo il programma lv2100.cpp per generare i giri in autmatico dalla data odierna... //...alla data dell'ultimo giro già generato TFilename fname; fname.tempdir(); fname.add("autogiri.ini"); TConfig ini(fname,"main"); ini.set("transaction", "update"); ini.set_paragraph("167"); ini.set("CODCF", codcli); ini.set_paragraph("main"); TString str; str << "lv2 -0 -i" << fname; TExternal_app app(str); app.run(); fname.fremove(); } } return err; } //WRITE: ridefinizione metodo write delle TRelation int TPass_plan_contr::write(const TMask& m) { if (_mask->field(F_CODCF).empty() || _mask->field(F_CODCONT).empty()) return _isnocurkey; const long codcli = _mask->get_long(F_CODCF); const long codcont = _mask->get_long(F_CODCONT); int err_1 = NOERR; //variabili per lavorare sugli sheet TSheet_field& pasplan = _mask->sfield(F_PASPLAN); if (pasplan.items() > 0) err_1 = write_pasplan(pasplan,codcli,codcont); TSheet_field& ps = m.sfield(F_PERSOSP); ps.autosave(*get_relation()); ps.record()->write(false); return err_1; } //ridefinizione metodo rewrite delle TRelation int TPass_plan_contr::rewrite(const TMask& m) { if (_mask->field(F_CODCF).empty() || _mask->field(F_CODCONT).empty()) return _isnocurkey; const long codcli = _mask->get_long(F_CODCF); const long codcont = _mask->get_long(F_CODCONT); int err_1 = NOERR; //variabili per lavorare sugli sheet TSheet_field& pasplan = _mask->sfield(F_PASPLAN); if (pasplan.items() >= 0) err_1 = write_pasplan(pasplan,codcli,codcont); TSheet_field& ps = m.sfield(F_PERSOSP); ps.autosave(*_rel); ps.record()->write(true); return err_1; } /////////////////////////////////////////// //// FUNZIONI PER REMOVE //// /////////////////////////////////////////// //REMOVE_PASPLAN: elimina tutte le righe dei passaggi per la coppia cliente - contratto selezionata int TPass_plan_contr::remove_pasplan(const long codcli, const long codcont) { //instanzio un TISAM_recordset TISAM_recordset pplan("USE LVPASPLAN\n FROM CODCF=#CODCF CODCONT=#CODCONT\nTO CODCF=#CODCF CODCONT=#CODCONT"); pplan.set_var("#CODCF", codcli); pplan.set_var("#CODCONT", codcont); int tmp = pplan.items(); int err = NOERR; //instanzio un TLocalisamfile TLocalisamfile& file = pplan.cursor()->file(); //per ogni riga del recordset for (bool ok=pplan.move_first(); ok && err == NOERR; ok=pplan.move_next()) err = file.remove(); return err; } //REMOVE: ridefinizione del metodo remove delle TRelation bool TPass_plan_contr::remove() { TSheet_field& ps = _mask->sfield(F_PERSOSP); ps.autosave(*_rel); ps.record()->remove(); //valori recuperati dalla testata const long codcli = _rel->curr().get_long(LVPASPLAN_CODCF); const long codcont = _rel->curr().get_long(LVPASPLAN_CODCONT); return remove_pasplan(codcli,codcont) == NOERR; } /////////////////////////////////////////// //// METODI PRIVATI //// /////////////////////////////////////////// //questa funzione forza i campi F_CODCF e F_CODCONT quando... //...vengono passati come parametri al programma void TPass_plan_contr::init_query_mode(TMask& m) { if (_codcli > 0) { m.set(F_CODCF,_codcli); m.set(F_CODCONT,_codcont,0x2); if (find(0)) modify_mode(); } } //costruttore bool TPass_plan_contr::user_create() { _rel = new TRelation(LF_LVCONDV); _mask = new TPass_plan_contr_mask; //se gli sono stati passati più parametri, allora setto le variabili globali _codcli e _codcont... //...con i parametri desiderati, se no li setto a zero if (argc() > 2) { _codcli = atol(argv(2)); _codcont = atol(argv(3)); } else { _codcli = 0; _codcont = 0; } return true; } //distruttore bool TPass_plan_contr::user_destroy() { delete _mask; return true; } int lv0500(int argc, char* argv[]) { TPass_plan_contr a; a.run(argc, argv, TR("Archivi Lavanderie")); return 0; }