diff --git a/lv/lv0100.cpp b/lv/lv0100.cpp index a6ea0b8e6..aa7ed9997 100755 --- a/lv/lv0100.cpp +++ b/lv/lv0100.cpp @@ -30,6 +30,7 @@ class TLV_table_app : public TTable_module_application { protected: // TRelation_application virtual TMask* user_create_mask(); + virtual bool get_next_key(TToken_string& key); public: }; @@ -45,6 +46,24 @@ TMask* TLV_table_app::user_create_mask() return TTable_module_application::user_create_mask(); } +// Cerca di generare automaticamente la prossima chiave numerica di una tabella +bool TLV_table_app::get_next_key(TToken_string& key) +{ + // Controlla se il campo COTDAB e' numerico + TMask& msk = curr_mask(); + TMask_field* keyfield = msk.find_by_fieldname("CODTAB"); + if (keyfield != NULL && keyfield->is_kind_of(CLASS_REAL_FIELD)) + { + long num = 1; + TLocalisamfile& tab = get_relation()->lfile(); + if (tab.last() == NOERR) // Cerca l'eventuale ultimo record della tabella + num += tab.get_long("CODTAB"); + // Costrusci la chiave formattata alla giusta lunghezza del campo, es: "101|0003" + key.format("%d|%0*ld", keyfield->dlg(), keyfield->size(), num); + } + return key.full(); // Ritorna true se la procedura e' riuscita +} + int lv0100(int argc, char* argv[]) { TLV_table_app a; diff --git a/lv/lv0500.cpp b/lv/lv0500.cpp index 9539651d1..60933ffa6 100755 --- a/lv/lv0500.cpp +++ b/lv/lv0500.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -18,7 +19,6 @@ class TPass_plan_contr_mask : public TAutomask { private: void proponi_orario(); - void nuovo_persosp(); protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); @@ -35,40 +35,6 @@ void TPass_plan_contr_mask::proponi_orario() return; } -//questa funzione viene richiamata ogni volta che si aggiunge una riga allo sheet dei periodi di sospensione... -//...e propone il codice del periodo in automatico -void TPass_plan_contr_mask::nuovo_persosp() -{ - //recupero il codcf e il codcont dalla maschera - const long codcli = get_long(F_CODCF); - const long codcont = get_long(F_CODCONT); - int codper; //codice periodo di sospensione - - //variabili per lavorare sullo sheet - TSheet_field& sheet = sfield(F_PERSOSP); - TToken_string& rigamodificata = sheet.row(sheet.items()-1); - - //se è la prima riga che inserisco, cerco l'ultimo CODPER per la coppia... - //...cliente - contratto sulla tabella, e lo incremento di 1 - if (sheet.items()==1) - { - TISAM_recordset psosp("USE LVPERISOSP\n FROM CODCF=#CODCF CODCONT=#CODCONT\nTO CODCF=#CODCF CODCONT=#CODCONT"); - psosp.set_var("#CODCF",codcli); - psosp.set_var("#CODCONT",codcont); - - psosp.move_last(); - codper = psosp.get("LVPERISOSP_CODPER").as_int()+1; - } - else //se esistono già altre righe, prendo il codice dalla riga precedente, e lo incremento di 1 - { - TToken_string& rigaprecedente = sheet.row(sheet.items()-2); - codper = rigaprecedente.get_int(sheet.cid2index(F_S_CODPER))+1; - } - rigamodificata.add(codper,sheet.cid2index(F_S_CODPER)); //metto in codper nella posizione giusta sulla TToken_string - - return; -} - bool TPass_plan_contr_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) @@ -78,17 +44,10 @@ bool TPass_plan_contr_mask::on_field_event(TOperable_field& o, TField_event e, l { case se_notify_add: proponi_orario(); + break; default: break; } - case F_PERSOSP: - switch (e) - { - case se_notify_add: //se si aggiunge una riga nuova allo sheet - nuovo_persosp(); - break; - default: - break; - } + break; default: break; } @@ -111,16 +70,9 @@ class TPass_plan_contr : public TRelation_application private: void fill_pasplan(const long codcli, const long codcont); //riempie i passaggi planning per contratto - void fill_persosp(const long codcli, const long codcont); //riempie i periodi di sospensione - int find_pass(TSheet_field& s,const int ggcons, const int coditi) const; //controlla se esiste una passaggio - int find_sosp(TSheet_field& s,const int codper) const; //controlla se esiste un periodo di sospensione - int write_pasplan(TSheet_field& pasplan, const long codcli, const long codcont); //scrive i passaggi planning per contratto - int write_persosp(TSheet_field& persosp, const long codcli, const long codcont); //scrive i periodi di sospensione - - int remove_pasplan(TSheet_field& pasplan, const long codcli, const long codcont); //cancella i passaggi planning per contratto - int remove_persosp(TSheet_field& persosp, const long codcli, const long codcont); //cancella i periodi di sospensionE + int remove_pasplan(const long codcli, const long codcont); //cancella i passaggi planning per contratto protected: virtual void init_query_mode(TMask& m); @@ -194,56 +146,21 @@ void TPass_plan_contr::fill_pasplan(const long codcli,const long codcont) return; } -//FILL_PERSOSP: questa funzione riempie lo sheet dei periodi di sospensione, recuperando eventualmente i dati già inseriti... -//...nella tabella dei periodi di sospensione (LVPERISOSP) per la coppia cliente - contratto selezionata -void TPass_plan_contr::fill_persosp(const long codcli,const long codcont) -{ - //preparo il recordset su LVPERISOSP - TISAM_recordset psosp("USE LVPERISOSP\n FROM CODCF=#CODCF CODCONT=#CODCONT\nTO CODCF=#CODCF CODCONT=#CODCONT"); - psosp.set_var("#CODCF",codcli); - psosp.set_var("#CODCONT",codcont); - - TProgind pi(psosp.items(), TR("Elaborazione dati periodi di sospensione in corso..."), true, true); - - TSheet_field& sheet = _mask->sfield(F_PERSOSP); - TMask& sheetmask = sheet.sheet_mask(); - TRelation& rel = *psosp.cursor()->relation(); //accesso al file delle righe - - sheet.destroy(); - - for (bool ok = psosp.move_first(); ok; ok = psosp.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 - } - 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 (_mask->field(F_CODCF).empty() || _mask->field(F_CODCONT).empty()) + if (m.field(F_CODCF).empty() || m.field(F_CODCONT).empty()) return !NOERR; //recupero i dati della testata - const long codcli = _mask->get_long(F_CODCF); - const long codcont = _mask->get_long(F_CODCONT); - + const long codcli = m.get_long(F_CODCF); + const long codcont = m.get_long(F_CODCONT); fill_pasplan(codcli,codcont); - fill_persosp(codcli,codcont); + + TSheet_field& ps = m.sfield(F_PERSOSP); + ps.record()->read(*ps.putkey(*_rel)); + ps.autoload(*_rel); return NOERR; } @@ -272,24 +189,6 @@ int TPass_plan_contr::find_pass(TSheet_field& s,const int ggcons, const int codi return r; } -//FIND_SOSP: questa funziona controlla se un periodo di sospensione che esiste sul file, -//esiste ancora sullo sheet (se non esiste è stato cancellato) -int TPass_plan_contr::find_sosp(TSheet_field& s,const int codper) const -{ - int r=-1; - - //per ogni riga dello sheet, leggi codice del periodo di sospensione, - //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 cp = s.row(r).get_int(s.cid2index(F_S_CODPER)); - - if (codper == cp) - 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) @@ -352,123 +251,50 @@ int TPass_plan_contr::write_pasplan(TSheet_field& pasplan, const long codcli, co return err; } -//WRITE_PERSOSP: questa funzione scrive i dati sul file 165 (LVPERISOSP) -int TPass_plan_contr::write_persosp(TSheet_field& persosp, const long codcli, const long codcont) -{ - if (_mask->field(F_CODCF).empty() || _mask->field(F_CODCONT).empty()) - return !NOERR; - - //instanzio un TISAM_recordset - TISAM_recordset psosp("USE LVPERISOSP\n FROM CODCF=#CODCF CODCONT=#CODCONT\nTO CODCF=#CODCF CODCONT=#CODCONT"); - psosp.set_var("#CODCF",codcli); - psosp.set_var("#CODCONT",codcont); - - int err = NOERR; - - //instanzio un TLocalisamfile - TLocalisamfile& file = psosp.cursor()->file(); - - //per ogni riga del recordset - for (bool ok=psosp.move_first(); ok; ok=psosp.move_next()) - { - //leggo il codice del periodo di sospensione - const int sosp = psosp.get(LVPERISOSP_CODPER).as_int(); - - //tutte le righe del TISAM_recordset che NON SONO nel TRecord_array vanno eliminate dal file - if (find_sosp(persosp,sosp) < 0) - file.remove(); - } - - //creo un TRectype - TRectype& rec = file.curr(); - - //Maschera di sheet - TMask& msk = persosp.sheet_mask(); - - //per ogni riga dello sheet - FOR_EACH_SHEET_ROW(persosp,r,row) - { - //azzero il record - rec.zero(); - //putto nel record codcli e codcont (sempre gli stessi) - rec.put(LVPERISOSP_CODCF,codcli); - rec.put(LVPERISOSP_CODCONT,codcont); - - //per ogni campo della mashera 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 char* field = fr->name(); //salvo il nome del campo - const int pos = persosp.cid2index(f->dlg()); //salvo la sua posizione all'inetrno dello sheet - rec.put(field,row->get(pos)); //putto il suo valore nel record che sto costruendo - } - } - - //setto le informazioni di creazione e/o aggiornamento del record - if (_mask->edit_mode()) - lv_set_update_info(rec); - else - lv_set_creation_info(rec); - - err = file.rewrite_write(); //o faccio la rewrite, o faccio la write - } - - 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 !NOERR; + return _isnocurkey; const long codcli = _mask->get_long(F_CODCF); const long codcont = _mask->get_long(F_CODCONT); - int err_1; - int err_2; + int err_1 = NOERR; //variabili per lavorare sugli sheet TSheet_field& pasplan = _mask->sfield(F_PASPLAN); - TSheet_field& persosp = _mask->sfield(F_PERSOSP); - if (pasplan.items() > 0) - err_1 = write_pasplan(pasplan,codcli,codcont); - - if (persosp.items() > 0) - err_2 = write_persosp(persosp,codcli,codcont); + err_1 = write_pasplan(pasplan,codcli,codcont); - return err_1 && err_2; + 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 !NOERR; + return _isnocurkey; const long codcli = _mask->get_long(F_CODCF); const long codcont = _mask->get_long(F_CODCONT); - int err_1; - int err_2; + int err_1 = NOERR; //variabili per lavorare sugli sheet TSheet_field& pasplan = _mask->sfield(F_PASPLAN); - TSheet_field& persosp = _mask->sfield(F_PERSOSP); - if (pasplan.items() > 0) err_1 = write_pasplan(pasplan,codcli,codcont); - - if (persosp.items() > 0) - err_2 = write_persosp(persosp,codcli,codcont); - return err_1 && err_2; + TSheet_field& ps = m.sfield(F_PERSOSP); + ps.autosave(*_rel); + ps.record()->write(true); + + return err_1; } /////////////////////////////////////////// @@ -476,7 +302,7 @@ int TPass_plan_contr::rewrite(const TMask& m) /////////////////////////////////////////// //REMOVE_PASPLAN: elimina tutte le righe dei passaggi per la coppia cliente - contratto selezionata -int TPass_plan_contr::remove_pasplan(TSheet_field& pasplan, const long codcli, const long codcont) +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"); @@ -489,54 +315,23 @@ int TPass_plan_contr::remove_pasplan(TSheet_field& pasplan, const long codcli, c //instanzio un TLocalisamfile TLocalisamfile& file = pplan.cursor()->file(); - //per ogni riga del recordset - for (bool ok=pplan.move_first(); ok; ok=pplan.move_next()) - { + for (bool ok=pplan.move_first(); ok && err == NOERR; ok=pplan.move_next()) err = file.remove(); - } - return err; -} - -//REMOVE_PERSOSP: elimina tutte le righe dei periodi di sospensione per la coppia cliente - contratto selezionata -int TPass_plan_contr::remove_persosp(TSheet_field& persosp, const long codcli, const long codcont) -{ - //instanzio un TISAM_recordset - TISAM_recordset psosp("USE LVPERISOSP\n FROM CODCF=#CODCF CODCONT=#CODCONT\nTO CODCF=#CODCF CODCONT=#CODCONT"); - psosp.set_var("#CODCF",codcli); - psosp.set_var("#CODCONT",codcont); - - int err = NOERR; - - //instanzio un TLocalisamfile - TLocalisamfile& file = psosp.cursor()->file(); - - //per ogni riga del recordset - for (bool ok=psosp.move_first(); ok; ok=psosp.move_next()) - { - err = file.remove(); - } return err; } //REMOVE: ridefinizione del metodo remove delle TRelation bool TPass_plan_contr::remove() { - if (_mask->field(F_CODCF).empty() || _mask->field(F_CODCONT).empty()) - return !NOERR; + TSheet_field& ps = _mask->sfield(F_PERSOSP); + ps.autosave(*_rel); + ps.record()->remove(); //valori recuperati dalla testata - const long codcli = _mask->get_long(F_CODCF); - const long codcont = _mask->get_long(F_CODCONT); - - //variabili per lavorare sugli sheet - TSheet_field& pasplan = _mask->sfield(F_PASPLAN); - TSheet_field& persosp = _mask->sfield(F_PERSOSP); - - int err_1 = remove_pasplan(pasplan,codcli,codcont); - int err_2 = remove_persosp(persosp,codcli,codcont); - - return err_1 && err_2; + const long codcli = _rel->curr().get_long(LVPASPLAN_CODCF); + const long codcont = _rel->curr().get_long(LVPASPLAN_CODCONT); + return remove_pasplan(codcli,codcont) == NOERR; } /////////////////////////////////////////// diff --git a/lv/lv0500a.h b/lv/lv0500a.h index d1eea3480..c83188a4d 100755 --- a/lv/lv0500a.h +++ b/lv/lv0500a.h @@ -25,18 +25,17 @@ #define F_S_DATAUA 997 #define F_S_ORAUA 998 //campi sheet dei periodi di sospensione -#define F_S_CODPER 101 -#define F_S_TPSOSP 102 +#define F_S_TPSOSP 101 #define F_S_DTPSOSP 999 -#define F_S_DADATA 103 -#define F_S_ADATA 104 -#define F_S_FLFAT 105 -#define F_S_IMPFAT 106 -#define F_S_PERFAT 107 -#define F_S_NOTEPS 108 +#define F_S_DADATA 102 +#define F_S_ADATA 103 +#define F_S_FLFAT 104 +#define F_S_IMPFAT 105 +#define F_S_PERFAT 106 +#define F_S_NOTEPS 107 #define F_S_UTENTEC 993 #define F_S_DATAC 994 #define F_S_ORAC 995 #define F_S_UTENTEUA 996 #define F_S_DATAUA 997 -#define F_S_ORAUA 998 \ No newline at end of file +#define F_S_ORAUA 998 diff --git a/lv/lv0500a.uml b/lv/lv0500a.uml index a5968e8a5..ad3bc2a33 100755 --- a/lv/lv0500a.uml +++ b/lv/lv0500a.uml @@ -66,29 +66,33 @@ END SPREADSHEET F_PASPLAN 0 7 BEGIN - PROMPT 0 5 "Passaggi planning per contratto" - ITEM "Num." - ITEM "Giorno" - ITEM "Itinerario" - ITEM "Ordine\nfermata" - ITEM "Ora\nprevista" - ITEM "Mod. pass." - ITEM "Frequenza\nconsegne" - ITEM "Giro\nstagionale" - ITEM "Note@50" + PROMPT 0 5 "Passaggi planning per contratto" + ITEM "Num." + ITEM "Giorno" + ITEM "Itinerario" + ITEM "Ordine\nfermata" + ITEM "Ora\nprevista" + ITEM "Mod. pass." + ITEM "Frequenza\nconsegne" + ITEM "Giro\nstagionale" + ITEM "Note@50" END SPREADSHEET F_PERSOSP 0 7 BEGIN - PROMPT 0 13 "Periodi di sospensione" - ITEM "Codice" - ITEM "Tipo\nsospensione" - ITEM "Data\ninizio" - ITEM "Data\nfine" - ITEM "Fattura" - ITEM "Importo da\nfatturare" - ITEM "Percentuale da\nfatturare" - ITEM "Note@50" + PROMPT 0 13 "Periodi di sospensione" + ITEM "Tipo" + ITEM "Data\ninizio" + ITEM "Data\nfine" + ITEM "Fattura" + ITEM "Importo da\nfatturare" + ITEM "Percentuale da\nfatturare" + ITEM "Note@50" + + USE LF_LVPERISOSP KEY CODPER + INPUT CODCF F_CODCF + INPUT CODCONT F_CODCONT + FLAGS "A" END ENDPAGE @@ -282,13 +286,6 @@ BEGIN PROMPT 1 0 "@bDati periodo di sospensione" END -NUMBER F_S_CODPER 6 -BEGIN - PROMPT 2 1 "Codice " - FLAGS "ZDR" - FIELD CODPER -END - STRING F_S_TPSOSP 3 BEGIN PROMPT 2 2 "Tipo "