campo-sirio/lv/lv0400.cpp

804 lines
26 KiB
C++
Raw Normal View History

#include <automask.h>
#include <defmask.h>
#include <execp.h>
#include <progind.h>
#include <relapp.h>
#include "lv0400.h"
#include "lvlib.h"
#include "../cg/cglib01.h"
#include "../mg/clifogiac.h"
//LV_NEW_CONTRACT: metodo generale utilizzato sia nella maschera che nell'applicazione
//che restituisce il primo codcont libero
long lv_new_contract(long cliente, int indsped)
{
//leggo dalla configurazione se la numerazione dei contratti
//<2F> sequenziale per ditta o per cliente
TConfig ini(CONFIG_DITTA, "lv");
const bool unicont=ini.get_bool("UniCont");
long codcont=0;
if (unicont) //se la numerazione <20> per ditta, cerco in tutto LVCONDV il codcont pi<70> grande
{
TISAM_recordset recset ("USE LVCONDV");
for (bool ok=recset.move_first(); ok; ok=recset.move_next())
{
const long codice=recset.get("CODCONT").as_int();
if (codice>codcont)
codcont=codice;
}
}
else //altrimenti cerco il codcont pi<70> grande di un determinato cliente
{
TString query;
query<<"USE LVCONDV\n"
<<"FROM CODCF=#CLIENTE\n"
<<"TO CODCF=#CLIENTE\n";
TISAM_recordset recset (query);
recset.set_var("#CLIENTE",cliente);
if (recset.move_last())
codcont=recset.get("CODCONT").as_int();
}
codcont++;
return codcont;
}
//////////////////////////////
//// TCONTRATTI_MSK ////
//////////////////////////////
//classe TContratti_msk
class TContratti_msk: public TAutomask
{
long _post_contr;
TString80 _artrig;
protected:
bool on_art_select();
virtual void on_idle();
virtual bool on_field_event(TOperable_field& o,TField_event e,long jolly);
public:
TContratti_msk();
};
//ON_ART_SELECT: metodo che riempie i campi delle dotazioni e del consegnato sullo sheet e sulla maschera
//e riporta i dati dello sheet nel dettaglio sulla maschera (sotto lo sheet)
bool TContratti_msk::on_art_select()
{
//dallo sheet identifico la riga selezionata e estraggo i dati di interesse
TSheet_field& ss = sfield(F_RIGHE);
TToken_string& row = ss.row(ss.selected());
const TString80 codart(row.get(ss.cid2index(S_CODART)));
const long codcf = get_long(F_CODCF);
const int indsped = get_int(F_INDSPED);
//instanzio un TArticolo_lavanderie per poter recuperare i dati di interesse
TArticolo_lavanderie& artrec = cached_article_laundry(codart, 'C', codcf, indsped);
//setto datasc a oggi e fisso l'anno esercizio
TDate datasc(TODAY);
const int annoes = esercizi().date2esc(datasc);
//estraggo l'indice dal record corrispondente su LF_CLIFOGIAC
int index = artrec.find_clifomag(annoes);
//recupero la maschera di riga
TMask& rowmask = ss.sheet_mask();
//se esiste il record su LF_CLIFOGIAC, recupero l'unit<69> di misura dalla riga dello sheet selezionata
//e setto i campi delle dotazioni e dei consegnati ai valori corretti riportati alla giusta unit<69> di misura
if (index > 0)
{
const TString4 umcont(row.get(ss.cid2index(S_UM))); //unit<69> di misura
//calcolo dotazione iniziale, scritta sia sulla maschera che sullo sheet
const real dotin = artrec.convert_to_um(artrec.clifomag(annoes)[index].get_real(CLIFOGIAC_DOTIN),umcont);
rowmask.set(S_DOTIN, dotin);
row.add(dotin.stringa(), ss.cid2index(S_DOTIN));
//calcolo dotazione odierna, scritta sia sulla maschera che sullo sheet
const real dotod = artrec.convert_to_um(artrec.clifomag(annoes)[index].get_real(CLIFOGIAC_DOTOD),umcont);
rowmask.set(S_DOTOD, dotod);
row.add(dotod.stringa(), ss.cid2index(S_DOTOD));
//calcolo dotazione temporanea, scritta sia sulla maschera che sullo sheet
const real dottmp = artrec.convert_to_um(artrec.clifomag(annoes)[index].get_real(CLIFOGIAC_DOTTM),umcont);
rowmask.set(S_DOTTMP, dottmp);
row.add(dottmp.stringa(), ss.cid2index(S_DOTTMP));
//calcolo consegnato anno, scritto sia sulla maschera che sullo sheet
const real consyear = artrec.convert_to_um(artrec.clifomag(annoes)[index].get_real("CONSANNO"),umcont);
rowmask.set(S_CONSANNO, consyear);
row.add(consyear.stringa(), ss.cid2index(S_CONSANNO));
//calcolo consegnato mese, scritto sia sulla maschera che sullo sheet
const real consmonth = artrec.convert_to_um(artrec.clifomag(annoes)[index].get_real("CONSMESE"),umcont);
rowmask.set(S_CONSMESE, consmonth);
row.add(consmonth.stringa(), ss.cid2index(S_CONSMESE));
}
//instanzio una cache sull'anagrafica di magazzino
//per leggere il valore di PPCONF corretto e sempre aggiornato
const TRectype& anamag = cache().get(LF_ANAMAG, codart);
rowmask.set(S_PPCONF, anamag.get_int(ANAMAG_PPCONF));
row.add(anamag.get(ANAMAG_PPCONF), ss.cid2index(S_PPCONF));
//ciclo i dati di interesse della riga selezionata nel dettaglio
//sulla maschera principale
for (short id = F_CODART; id <= F_CODART + 35; id++)
{
const int pos = id2pos(id);
if (pos > 0)
fld(pos).set(row.get(ss.cid2index(id - 400)));
}
if (field(F_PPCONF).empty())
{
set(F_CALCCONS, "0");
set(F_ARROT, "");
disable(F_CALCCONS);
disable(F_ARROT);
}
else
{
enable(F_CALCCONS);
enable(F_ARROT);
set(F_ARROT, "X");
TToken_string row = ss.row(ss.selected());
row.add("X", ss.cid2index(S_ARROT));
ss.force_update();
}
return true;
}
//ON_IDLE: ridefinizione del metodo on_idle() delle TAutomask per settare il focus
//nel posto desiderato
void TContratti_msk::on_idle()
{
if (_post_contr > 0)
{
set(F_CODCONT, _post_contr);
_post_contr = 0;
efield(F_CODCONT).set_focus();
}
TAutomask::on_idle();
}
//ON_FIELD_EVENT: definizione del metodo che setta i comportamenti dei vari campi della mashera
bool TContratti_msk::on_field_event(TOperable_field& o,TField_event e,long jolly)
{
switch(o.dlg())
{
case F_CODCF:
//se sono in query_mode e se il campo risulta pieno e modificato,
//e il codcont vuoto, allora riempio in automatico l'indirizzo di spedizione
//e propongo il contratto valido nella giornata di oggi
if (query_mode())
{
if (e == fe_modify && !o.empty() && efield(F_CODCONT).empty())
{
const long codcf = atol(o.get());
const int indsped = get_int(F_INDSPED);
const TDate oggi(TODAY);
_post_contr = lv_find_contract(codcf, indsped, oggi);
}
}
break;
case DLG_PLANNING:
//se viene premuto il bottone "Giri", lancia lv0500 (generatore automatico dei giri)
if (e == fe_button && edit_mode())
{
TRelation_application& app = (TRelation_application&) main_app();
app.get_relation()->read(_isequal,_unlock);
TString str;
str << "lv0 -4 " << get(F_CODCF) << " " << get(F_CODCONT);
TExternal_app planning(str);
planning.run();
app.get_relation()->read(_isequal,_lock);
}
break;
case S_CODART:
if (!o.empty()) //se il campo risulta pieno
{
if (e == fe_modify) //e se risulta modificato
{
const TString& codart = o.get();
TSheet_field& ss = sfield(F_RIGHE);
TMask& m = o.mask(); // maschera di riga!
//se ho scritto un articolo diverso da quello che esisteva prima
//e se si desidera veramente modificarlo, allora permetto la modifica
//e forzo l'updatre della riga, altrimenti riscrivo l'articolo che c'era prima
//e lascio tutto invariato
if (_artrig.full() && codart != _artrig)
{
if (!yesno_box("Si desidera veramente modificare l'articolo %s",(const char*) _artrig))
{
m.set(S_CODART,_artrig);
TToken_string& row=ss.row(ss.selected());
row.add(_artrig, 0);
ss.force_update(ss.selected());
}
else
_artrig = codart;
}
//se all'articolo <20> associata un'unit<69> di misura, la propongo
//in automatico e richiamo il metodo ON_ART_SELECT(); altrimenti lo richiamo
//solo se <20> arrivato un fe_init al campo
TArticolo art(codart);
if (art.um().rows() > 0)
{
const TString& um = art.um()[1].get(UMART_UM);
m.set(S_UM,um);
TToken_string& row = ss.row(ss.selected());
row.add(o.get(),ss.cid2index(S_CODART));
row.add(um,S_UM);
on_art_select();
}
}
else
if (e == fe_init)
on_art_select();
}
break;
case F_RIGHE:
//se lo sheet ha ricevuto un se_enter, allora aggiorno i campi del dettaglio sulla mashera principale
if (e == se_enter)
{
TSheet_field& ss = (TSheet_field&)o;
TToken_string& row = ss.row(ss.selected());
for (short id = F_CODART; id <= F_CODART+35; id++)
{
const int pos=id2pos(id);
if (pos>0)
{
fld(pos).set(row.get(ss.cid2index(id-400)));
fld(pos).set_dirty(false);
}
}
//questo pezzo serve per gestire enable e disable dei campi in modo corretto
//senza massage in maschera, sia sullo sheet che sul dettaglio
if (field(F_PPCONF).empty())
{
set(F_CALCCONS, "0");
set(F_ARROT, "");
disable(F_CALCCONS);
disable(F_ARROT);
}
else
{
enable(F_CALCCONS);
enable(F_ARROT);
set(F_ARROT, "X");
row.add("X", ss.cid2index(S_ARROT));
ss.force_update();
}
_artrig=row.get(0); //salvo nella variabile globale il codart della riga selezionata
}
//se ho cancellato una riga dello sheet, chiedo conferma che sia effettivamente quello che si vuole fare
if (e == se_query_del)
{
TSheet_field& ss = (TSheet_field&)o;
TToken_string& row = ss.row(ss.selected());
const TString codart = row.get(ss.cid2index(S_CODART));
if (!yesno_box("Si desidera veramente cancellare l'articolo %s",(const char*) codart))
return false;
}
break;
case DLG_NEWREC:
if (e == fe_button)
{
//se sono in edit_mode, forzo l'uscita dal contratto attuale
if (edit_mode())
{
send_key(K_ESC, 0);
return false;
}
//se sono in query_mode e esiste gi<67> un cliente selzionato, allora richiamo il metodo LV_NEW_CONTRACT()
//e calcolo il primo codcont libero proponendolo in automatico
if (query_mode())
{
const long codcf = get_long(F_CODCF);
if (codcf > 0)
{
const int indsped = get_int(F_INDSPED);
const long codcont = lv_new_contract(codcf, indsped);
if (codcont > 0)
set(F_CODCONT, codcont);
}
}
}
break;
default:
//se sto modificando un campo con indice > 500 e diverso da F_CAUSLAVDESCRIG
//allora forzo l'update dello sheet sulla riga selezionata
if (e == fe_modify && is_running() && o.dlg() > 500/*&& o.dlg() != F_CAUSLAVDESCRIG*/)
{
TSheet_field& ss = sfield(F_RIGHE);
const int sel = ss.selected();
if (sel >= 0)
{
const short rowid = o.dlg() - 400;
const int index = ss.cid2index(rowid);
ss.sheet_mask().set(rowid,o.get());
ss.row(sel).add(o.get(),index);
ss.force_update(sel);
}
}
break;
}
return true;
}
//Costruttore; nasconde o mostra il campo F_INDSPED a seconda di cosa <20> scritto in configurazione
TContratti_msk::TContratti_msk():TAutomask("lv0400a"), _post_contr(0)
{
TConfig* configlv = new TConfig(CONFIG_DITTA,"lv");
char indir = configlv->get_char("Useindsp");
if (indir != 'X')
field(F_INDSPED).hide();
}
//////////////////////////////
//// TCONTRATTI_APP ////
//////////////////////////////
//classe TContratti_app
class TContratti_app: public TRelation_application
{
TContratti_msk* _msk;
TRelation* _rel;
private:
void save_rows(const TMask& m);
TString build_query(const TMask& m) const;
int find_art(TSheet_field& s,const TString& art) const;
protected:
virtual TMask* get_mask (int mode) {return _msk; }
virtual TRelation* get_relation() const {return _rel;}
virtual bool user_create();
virtual bool user_destroy();
virtual void on_config_change(); //METODO VUOTO
virtual bool get_next_key(TToken_string& key); //METODO MAI UTILIZZATO?
virtual int read(TMask& m);
virtual int write(const TMask& m);
virtual int rewrite(const TMask& m);
virtual bool protected_record(TRectype & rec); //METODO MAI UTILIZZATO?
virtual bool remove();
virtual void init_query_mode(TMask& m);
virtual void init_insert_mode(TMask& m);
virtual void init_modify_mode(TMask& m);
bool elimina_planning(const long& codcont, const long& codcf) const;
bool kill_planning (TISAM_recordset& selrighe) const;
};
//SAVE_ROWS: questo metodo salva effettivamente le righe vislualizzate sullo sheet sul file
//LF_LVRCONDV e aggiorna e/o aggiunge record su LF_CLIFOGIAC
void TContratti_app::save_rows(const TMask& m)
{
//instanzio un TISAM_recordset sulle righe contratto
TISAM_recordset righeset(build_query(m));
//instazio un TLocalisamfile partendo dal recordset che ho appena creato
//(cio<69> su LF_LVRCONDV)
TLocalisamfile& file = righeset.cursor()->file();
//recupero lo sheet
TSheet_field& righe = m.sfield(F_RIGHE);
//scorro tutte le righe contratto e elimino tutte quelle che non ci sono pi<70> sullo sheet
for (bool ok = righeset.move_first(); ok; ok = righeset.move_next())
{
const TString& art = righeset.get("CODART").as_string();
if (find_art(righe, art) < 0)
file.remove();
}
//instanzio un TLocalisamfile su LF_CLIFOGIAC
TLocalisamfile magcli(LF_CLIFOGIAC);
//setto alcune variabili di interesse
const TDate oggi(TODAY);
const int year = oggi.year();
const long clifo = m.get_long(F_CODCF);
const int indsp = m.get_int(F_INDSPED);
//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("CODCF",clifo);
file.put("CODCONT",m.get(F_CODCONT));
//per ogni campo della maschera scrivi 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)
{
const int pos = righe.cid2index(f->dlg());
fr->write(row->get(pos), file.curr());
}
}
//leggo il codart
const TString80 codart=row->get(0);
//se il codart <20> pieno
if (codart.full())
{
//scrivo o aggiorno il record sul file
file.rewrite_write();
//gestione LF_CLIFOGIAC
bool found = false;
magcli.zero();
//se sono in dicembre, allora leggo i dati dell'anno successivo
if (oggi.month() == 12)
{
magcli.put(CLIFOGIAC_ANNOES, year+1);
magcli.put(CLIFOGIAC_TIPOCF, 'C');
magcli.put(CLIFOGIAC_CODCF, clifo);
magcli.put(CLIFOGIAC_INDSPED, indsp);
magcli.put(CLIFOGIAC_CODART, codart);
found = magcli.read() == NOERR;
}
//se fallisce la read o non sono in dicembre, allora cerco nell'anno attuale (record svuotato dalla read)
if (!found)
{
magcli.zero();
magcli.put(CLIFOGIAC_ANNOES, year);
magcli.put(CLIFOGIAC_TIPOCF, 'C');
magcli.put(CLIFOGIAC_CODCF, clifo);
magcli.put(CLIFOGIAC_INDSPED, indsp);
magcli.put(CLIFOGIAC_CODART, codart);
found = magcli.read()==NOERR;
//se la read fallisce ancora, allora devo inserire tutto da capo (record svuotato dalla read)
if (!found) // FORZO LA SCRITTURA DELLA CHIAVE
{
magcli.zero();
magcli.put(CLIFOGIAC_ANNOES, year);
magcli.put(CLIFOGIAC_TIPOCF, 'C');
magcli.put(CLIFOGIAC_CODCF, clifo);
magcli.put(CLIFOGIAC_INDSPED, indsp);
magcli.put(CLIFOGIAC_CODART, codart);
}
}
//setto i valori delle dotazioni
magcli.put(CLIFOGIAC_DOTIN,row->get(righe.cid2index(S_DOTIN)));
magcli.put(CLIFOGIAC_DOTOD,row->get(righe.cid2index(S_DOTOD)));
magcli.put(CLIFOGIAC_DOTTM,row->get(righe.cid2index(S_DOTTMP)));
//scrivo o aggiorno il record corrispondente su LF_CLIFOGIAC
magcli.rewrite_write();
}
}
}
//BUILD_QUERY: metodo che crea la query sulle righe contratti
//recuperando i dati di interesse dalla maschera
TString TContratti_app:: build_query(const TMask& m) const
{
TString query="";
query << "USE LVRCONDV\n"
<< "FROM CODCF=" << m.get(F_CODCF) << " CODCONT=" << m.get(F_CODCONT) << "\n"
<< "TO CODCF=" << m.get(F_CODCF) << " CODCONT=" << m.get(F_CODCONT);
return query;
}
//FIND_ART: metodo che restituisce l'indice della riga dello sheet che contiene
//l'articolo desiderato (-1 se non lo trova)
int TContratti_app::find_art(TSheet_field& s, const TString& art) const
{
int r = -1;
//scorro le righe dello sheet partendo dall'ultima
for (r = s.items()-1 ; r>=0 ; r--)
{
const char* codart = s.row(r).get(0);
if (art == codart)
break;
}
return r;
}
//USER_CREATE: metodo che crea TRelation e TContratti_msk solo se si <20> in un esercizio valido
//e che setta i comportamenti sulle righe aggiunte agli sheet
bool TContratti_app:: user_create()
{
TDate datasc(TODAY);
if (esercizi().date2esc(datasc) == 0)
return error_box("Attenzione non esiste l'esercizio corrispondente al %s", datasc.string());
_rel=new TRelation (LF_LVCONDV);
_msk= new TContratti_msk;
TSheet_field& ss = _msk->sfield(F_RIGHE);
ss.set_auto_append();
ss.set_append(false);
return true;
}
//USER_DESTROY: metodo che distrugge le variabili globali alla fine dell'esecuzione
bool TContratti_app:: user_destroy()
{
delete _msk;
delete _rel;
return true;
}
//ON_CONFIG_CHANGE: per adesso un semplice segnaposto
void TContratti_app:: on_config_change()
{
int cazzone = 1;
}
//GET_NEXT_KEY: metodo che restituisce la chiave di ricerca sui contratti prendendo il prossimo codcont libero
bool TContratti_app:: get_next_key(TToken_string& key)
{
const long cliente=_msk->get_long(F_CODCF);
if (cliente <= 0)
return false;
key.add(F_CODCF);
key.add(cliente);
key.add(F_CODCONT);
long codcont= lv_new_contract(cliente, _msk->get_int(F_INDSPED));
key.add(codcont);
return true;
}
//READ: ridefinizione del metodo read() delle TRealtion_application
int TContratti_app:: 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 contratto
TISAM_recordset righeset(build_query(m));
const TRectype& rec = righeset.cursor()->curr();
//instanzio un TLcalisamfile su LF:CLIFOGIAC
TLocalisamfile magcli(LF_CLIFOGIAC);
//setto alcune variabili di interesse
const TDate oggi(TODAY);
const int year = oggi.year();
const long clifo = m.get_long(F_CODCF);
const int indsp = m.get_int(F_INDSPED);
//recupero sheet e realtiva mashera di riga
TSheet_field& righe = m.sfield(F_RIGHE);
TMask& msk = righe.sheet_mask();
righe.destroy();
//per ogni riga dello sheet
for (bool ok = righeset.move_first(); ok; ok = righeset.move_next())
{
TToken_string& row = righe.row(-1);
//per ogni campo della maschera scrivi 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),righe.cid2index(f->dlg()));
}
//lettura dei dati da LF_CLIFOGIAC
bool found = false;
magcli.zero();
const TString codart=row.get(0);
//se sono in dicembre, allora leggo i dati dell'anno successivo
if (oggi.month() == 12)
{
magcli.put(CLIFOGIAC_ANNOES, year+1);
magcli.put(CLIFOGIAC_TIPOCF, 'C');
magcli.put(CLIFOGIAC_CODCF, clifo);
magcli.put(CLIFOGIAC_INDSPED, indsp);
magcli.put(CLIFOGIAC_CODART, codart);
found = magcli.read() == NOERR;
}
//se fallisce la read o non sono in dicembre, allora cerco nell'anno attuale (record svuotato dalla read)
if (!found)
{
magcli.zero();
magcli.put(CLIFOGIAC_ANNOES, year);
magcli.put(CLIFOGIAC_TIPOCF, 'C');
magcli.put(CLIFOGIAC_CODCF, clifo);
magcli.put(CLIFOGIAC_INDSPED, indsp);
magcli.put(CLIFOGIAC_CODART, codart);
found = magcli.read() == NOERR;
}
//se la read riesce, leggo tutti i dati di interesse e li metto nella riga attuale dell sheet
if (found)
{
const int dotin = magcli.get_int(CLIFOGIAC_DOTIN);
const int dotod = magcli.get_int(CLIFOGIAC_DOTOD);
const int dottmp = magcli.get_int(CLIFOGIAC_DOTTM);
row.add(dotin, righe.cid2index(S_DOTIN));
row.add(dotod, righe.cid2index(S_DOTOD));
row.add(dottmp, righe.cid2index(S_DOTTMP));
}
//forzo una check_row
righe.check_row(righe.items()-1, 3);
}
//forzo l'update dello sheet
righe.force_update();
}
return err;
}
//WRITE: ridefinizione del metodo write() delle TRelation_application
int TContratti_app::write(const TMask& m)
{
//esegui la write standard
int err = TRelation_application::write(m);
//se va a buon fine esegui la save_rows() e ricorda all'utente i passaggi per planning
if(err == NOERR)
{
save_rows(m);
warning_box(TR("Ricordarsi di inserire i passaggi per planning"));
}
return err;
}
//REWRITE: ridefinizione del metodo rewrite() delle TRelation_application
int TContratti_app::rewrite(const TMask& m)
{
//esegui la write standard
int err=TRelation_application::rewrite(m);
//se va a buon fine esegui la save_rows()
if(err == NOERR)
save_rows(m);
return err;
}
//PROTECTED_RECORD: metodo che rendo un record non cancellabile
bool TContratti_app::protected_record(TRectype & rec)
{
TLaundry_contract cont(rec);
return !cont.can_be_deleted();
}
//REMOVE: ridefinizione del metodo remove() delle TRelartion_application
bool TContratti_app::remove()
{
//eseguo la remove standard
bool ok = TRelation_application::remove();
//se va a buon fine, elimino anche le righe contratto dal file specifico
if(ok)
{
TISAM_recordset righeset(build_query(*_msk));
TLocalisamfile& file=righeset.cursor()->file();
for (bool ok = righeset.move_first(); ok; ok = righeset.move_next())
{
file.remove();
}
//elimino i planning esistenti per quel cliente - contratto
elimina_planning(_msk->get_long(F_CODCONT),_msk->get_long(F_CODCF));
}
return ok;
}
//INIT_QUERY_MODE: ridefinizione del metodo init_query_mode() standard
void TContratti_app::init_query_mode(TMask& m)
{
//abilita il campo F_RAGSOC se il campo F_CODCF <20> abilitato
m.field(F_RAGSOC).enable(m.field(F_CODCF).enabled());
m.reset();
}
//INIT_MODIFY_MODE: ridefinizione del metodo init_modify_mode() standard
void TContratti_app::init_modify_mode(TMask& m)
{
//setto alcune variabili di interesse
const TDate oggi(TODAY);
const int year=oggi.year();
const long clifo=m.get_long(F_CODCF);
const int indsp=m.get_int(F_INDSPED);
//instanzio un TLocaisamfile su LF_CLIFOGIAC
TLocalisamfile magcli(LF_CLIFOGIAC);
//recupero lo sheet
TSheet_field& righe = m.sfield(F_RIGHE);
//per ogni riga dello sheet aggiorno le dotazioni su LF_CLIFOGIAC
//per tutti ????, se il record esiste gi<67>
FOR_EACH_SHEET_ROW(righe,r,row)
{
const TString80 codart=row->get(righe.cid2index(S_CODART));
// righe.disable_cell(r, righe.cid2index(S_CODART));
// righe.disable_cell(r, righe.cid2index(S_DESCR));
// righe.disable_cell(r, righe.cid2index(S_UM));
for (int y = year + oggi.month() == 12; y >= year; y--)
{
magcli.put(CLIFOGIAC_ANNOES, y);
magcli.put(CLIFOGIAC_TIPOCF, 'C');
magcli.put(CLIFOGIAC_CODCF, clifo);
magcli.put(CLIFOGIAC_INDSPED, indsp);
magcli.put(CLIFOGIAC_CODART, codart);
if (magcli.read() == NOERR)
{
row->add(magcli.get(CLIFOGIAC_DOTIN), righe.cid2index(S_DOTIN));
row->add(magcli.get(CLIFOGIAC_DOTOD), righe.cid2index(S_DOTOD));
row->add(magcli.get(CLIFOGIAC_DOTTM), righe.cid2index(S_DOTTMP));
break;
}
}
}
}
//INIT_INSERT_MODE: ridefinizione del metodo init_insert_mode() standard
void TContratti_app::init_insert_mode(TMask& m)
{
//se esiste gi<67> un contratto in essere alla data odierna per questo cliente,
//contrassegna quello attuale come "PROPOSTA"
const long codcf = m.get_long(F_CODCF);
const long indsp = m.get_int(F_INDSPED);
const TDate oggi(TODAY);
const long old_contr = lv_find_contract(codcf, indsp, oggi);
const long cur_contr = m.get_long(F_CODCONT);
if (old_contr > 0 && old_contr < cur_contr)
m.set(F_PROPOSTA, "X");
}
//ELIMINA PLANNING: metodo che prepara il recordset sui planning con le righe da eliminare
bool TContratti_app::elimina_planning(const long& codcont, const long& codcf) const
{
//creo il recordset
TISAM_recordset selrighe("USE LVRCONSPLAN KEY 3\nFROM CODCF=#CODCF CODCONT=#CODCONT \nTO CODCF=#CODCF CODCONT=#CODCONT");
//setto le variabili
selrighe.set_var("#CODCF",codcf);
selrighe.set_var("#CODCONT",codcont);
//richiamo la funzione che effettivamente fa la cancellazione delle righe interessate
kill_planning(selrighe);
return true;
}
//KILL_PLANNING: metodo che effettivamente fa la cancellazione dei planning interessati
bool TContratti_app::kill_planning (TISAM_recordset& selrighe) const
{
//se effettivamente ci sono delle righe da cancellare, allora le cancello
const int righe = selrighe.items();
if (righe > 0)
{
TProgind pi(righe, TR("Eliminazione planning in corso..."), true, true);
TLocalisamfile& rplan = selrighe.cursor()->file();
for (bool ok = selrighe.move_last(); ok; ok = selrighe.move_prev())
{
if (!pi.addstatus(1))
break;
rplan.remove();
}
}
return true;
}
int lv0400(int argc, char* argv[])
{
TContratti_app app;
app.run (argc,argv,TR("Gestione contratti"));
return 0;
}