campo-sirio/lv/lv3100.cpp
luca83 559355aaed Patch level : 10.0 patch 290
Files correlati     : lv3
Ricompilazione Demo : [ ]
Commento            :
0001281: trasformazione righe contratto in dotazioni temporanee
Descrizione: per un cliente nuovo o generato il contratto e il planning
ho inserito una bolla con causale lavanderia "dotazione iniziale"
lui mi mette nel periodo temporaneo di inizio la data della bolla
in quello di fine la prossima consegna
dopo di che me li scrive pure sul contratto e imporvvisamente il
contratto diventa temporaneo anche se incrementa la dotazione
giusta (non quella temporanea)

0001286: documenti di Trasporto
Descrizione: i campi data delle dotazioni temporanee devono essere vuoti quando non esiste alcuna temporaneità invece sono sempre impostati


git-svn-id: svn://10.65.10.50/trunk@18779 c028cbd2-c16b-5b4b-a496-9718f37d4682
2009-04-24 13:55:05 +00:00

1199 lines
38 KiB
C++
Executable File
Raw Blame History

#include "../ve/ve0100.h"
#include "../ve/veini.h"
#include "../ve/veuml.h"
#include "../ve/veuml3.h"
#include "../ve/verig.h"
#include "../ve/vepriv.h"
#include "lvlib.h"
#include "lvcondv.h"
#include "lvrcondv.h"
#include "lvrconsplan.h"
#include "../mg/clifogiac.h"
#define FOR_EACH_DOC_ROW_BACK(d, r, row) const TRiga_documento* row = NULL; for (int r = d.rows(); r > 0 && (row = &d[r]) != NULL; r--)
//////////////////////////////////////////
//// CLASSE TGESTIONE_BOLLE_MSK ////
//////////////////////////////////////////
//Definizione della classe della maschera
class TGestione_bolle_msk : public TDocumento_mask
{
long _stcodcf;
long _stcodcont;
protected:
static void arrotonda(const TMask& msk, real& quantita);
static void dettaglio_causale(TSheet_field& ss);
//hanlder di documento:
static bool lv_data_handler(TMask_field& f, KEY k);
static bool lv_contratto_handler(TMask_field& f, KEY k);
static bool lv_bolla_handler(TMask_field& f, KEY k);
//handler di riga:
static bool lv_ritirato_handler(TMask_field& f, KEY k);
static bool lv_consegnato_handler(TMask_field& f, KEY k);
static bool lv_codart_handler(TMask_field& f, KEY k);
static bool lv_causale_handler(TMask_field& f, KEY k);
static bool lv_codmag_handler(TMask_field& f, KEY k);
static bool lv_datatmp_handler(TMask_field& f, KEY k);
static bool ss_notify(TSheet_field& ss, int r, KEY key);
virtual void on_idle();
public:
virtual void user_set_handler( short fieldid, int index);
virtual void user_set_row_handler(TMask& rm, short field, int index);
void reset_var_mask() {_stcodcf = 0; _stcodcont = 0;}
TGestione_bolle_msk(const char* tipodoc);
int _autoselect;
};
////////////////////////////////////
//// CLASSE TGIAC_PER_CLI ////
////////////////////////////////////
//Definizione della classe Giacenza per Cliente
class TGiac_per_cli : public TObject
{
private:
TAssoc_array _odierna; //TAssoc_array che conterr<72> le dotazioni odierne
TAssoc_array _temporanea; //TAssoc_array che conterr<72> le dotazioni temporanee
long _clifo; //variabile che conterr<72> il cliente selezionato
long _cont; //variabile che conterr<72> il contratto selezionato
int _year; //variabile che conterr<72> l'anno documento
long _indsped; //variabile che conterr<72> l'indirizzo di spedizione
protected:
real& giacart_od(const TString& codart); //restituisce un puntatore al valore della dot. od. salvato
real& giacart_tmp(const TString& codart); //restituisce un puntatore al valore valore della dot. temp. salvato
long giac_in_mag(const TString& codart, bool odierna) const; //restituisce il valore salvato nel magazzino
public:
bool preset(const TDocumento& doc); //precarico le variabili globali della classe
bool reset(const TDocumento& doc); //svuota i TAssoc_array e carica cli e cont
bool load_row(const TRiga_documento& rdoc); //popola i TAssoc_array
real giac_att(TRiga_documento& rdoc, bool odierna); //restituisce le quantit<69> attuali di dotazione
int write_giac(const TMask& m); //scrive i valori corretti sul file 166
TGiac_per_cli(); //costruttore
};
//GIACART_OD: metodo che restituisce un puntatore al real che contiene il valore
//della dotazione odierna per un determinato articolo
real& TGiac_per_cli::giacart_od(const TString& codart)
{
real *giac = (real*)_odierna.objptr(codart);
if (giac == NULL)
{
giac = new real(giac_in_mag(codart, true));
_odierna.add(codart,giac);
}
return *giac;
};
//GIACART_TMP: metodo che restituisce un puntatore al real che contiene il valore
//della dotazione temporanea per un determinato articolo
real& TGiac_per_cli::giacart_tmp(const TString& codart)
{
real *giac = (real*)_temporanea.objptr(codart);
if (giac == NULL)
{
giac = new real(giac_in_mag(codart, false));
_temporanea.add(codart,giac);
}
return *giac;
};
//GIAC_IN_MAG: questo metodo restituisce le quantit<69> presenti sul file 166 (clifogiac)
//restituendo il valore salvato in dotazione odierna se odierna == true,
//oppure il valore salvato in dotazione temporanea se odierna = false
long TGiac_per_cli::giac_in_mag(const TString& codart, bool odierna) const
{
//recupero i valori delle dotazioni odierne e temporanee dal magazzino del cliente
TLocalisamfile magcli(LF_CLIFOGIAC);
magcli.put(CLIFOGIAC_ANNOES, _year);
magcli.put(CLIFOGIAC_TIPOCF, 'C');
magcli.put(CLIFOGIAC_CODCF, _clifo);
magcli.put(CLIFOGIAC_INDSPED, _indsped);
magcli.put(CLIFOGIAC_CODART, codart);
//leggo il record corrispondente
if (magcli.read() == NOERR)
return magcli.get_long( odierna ? CLIFOGIAC_DOTOD : CLIFOGIAC_DOTTM);
return 0;
}
//PRESET: metodo che carica la coppia cliente - contratto
bool TGiac_per_cli::preset(const TDocumento& doc)
{
//estraggo i dati di interesse dal documento
_clifo = doc.get_long(DOC_CODCF);
_cont = doc.get_long(DOC_CODCONT);
_year = doc.get_date(DOC_DATADOC).year();
_indsped = doc.get_long(DOC_CODINDSP);
return true;
}
//RESET: metodo che distrugge i due TAssoc_array e carica la coppia cliente - contratto
bool TGiac_per_cli::reset(const TDocumento& doc)
{
preset(doc);
//distruggo i due TAssoc_array
_odierna.destroy();
_temporanea.destroy();
return true;
}
//LOAD_ROW: questo metodo popola e aggiorna i TAssoc_array
bool TGiac_per_cli::load_row(const TRiga_documento& rdoc)
{
//recupero il documento e la sua maschera a partire dalla riga documento
const TDocumento& doc = rdoc.doc();
real vardot;
real vartmp;
//se sul documento leggo o il cliente o il contratto o l'indirizzo di spedizione
//diversi da quelli che avevo salvato vuol dire che ho cambiato uno dei due,
//e quindi le giacenze non vanno pi<70> bene; in tal caso resetto i TAssoc_array e riparto
if (doc.get_long(DOC_CODCF) != _clifo || doc.get_long(DOC_CODCONT) != _cont || doc.get_long(DOC_CODINDSP) != _indsped)
reset(doc);
real& dotazione = giacart_od(rdoc.get(RDOC_CODART));
real& dotmp = giacart_tmp(rdoc.get(RDOC_CODART));
//instanzio una cache sulla tabella delle causali
TString4 causale = rdoc.get(RDOC_CODAGG1);
const TRectype& cau = cache().get("&CAU", causale);
//movimento o meno la dotazione temporanea a seconda di cosa prevede la causale
if (cau.get_bool("B0"))
{
const TCausale_magazzino & rit = cached_causale_magazzino(cau.get("S1"));
const real & ritirato = rdoc.get_real(RDOC_QTAGG1);
int st = rit.sgn(s_dottm);
int so = rit.sgn(s_dotod);
vartmp += real(st) * ritirato;
vardot += real(so) * ritirato;
}
if (cau.get_bool("B1"))
{
const TCausale_magazzino & con = cached_causale_magazzino(cau.get("S2"));
const real & consegnato = rdoc.get_real(RDOC_QTA);
int st = con.sgn(s_dottm);
int so = con.sgn(s_dotod);
vartmp += real(st) * consegnato;
vardot += real(so) * consegnato;
}
if (rdoc.get_int(RDOC_MOVMAG) != ZERO)
{
dotmp -= vartmp;
dotazione -= vardot;
}
return true;
}
//GIAC_ATT: questo metodo restituisce il valore della dotazione da scrivere a video in base ai valori
//di consegnato e ritirato; ATTENZIONE: restituisce la dotazione odierna se odierna = true,
//restituisce la dotazione temporanea se odierna = false
real TGiac_per_cli::giac_att(TRiga_documento& rdoc, bool odierna)
{
const TString& codart = rdoc.get(RDOC_CODART);
real giac = odierna ? giacart_od(codart) : giacart_tmp(codart);
real saldo;
//instanzio una cache sulla tabella delle causali
TString4 causale = rdoc.get(RDOC_CODAGG1);
const TRectype& cau = cache().get("&CAU", causale);
//movimento o meno la dotazione temporanea/odierna a seconda di cosa prevede la causale
if (cau.get_bool("B0"))
{
const TCausale_magazzino& rit = cached_causale_magazzino(cau.get("S1"));
const int s = rit.sgn(odierna ? s_dotod : s_dottm);
saldo += real(s) * rdoc.get_real(RDOC_QTAGG1);
}
if (cau.get_bool("B1"))
{
const TCausale_magazzino& con = cached_causale_magazzino(cau.get("S2"));
const int s = con.sgn(odierna ? s_dotod : s_dottm);
saldo += real(s) * rdoc.get_real(RDOC_QTA);
}
giac += saldo;
return giac;
}
int TGiac_per_cli::write_giac(const TMask& m)
{
int err = NOERR;
TGestione_bolle_msk& mask = (TGestione_bolle_msk&) m;
TDocumento& d = mask.doc();
TLocalisamfile magcli(LF_CLIFOGIAC);
FOR_EACH_DOC_ROW_BACK(d, r, row)
{
if (row->is_articolo())
{
magcli.put(CLIFOGIAC_ANNOES, _year);
magcli.put(CLIFOGIAC_TIPOCF, 'C');
magcli.put(CLIFOGIAC_CODCF, _clifo);
magcli.put(CLIFOGIAC_INDSPED, _indsped);
magcli.put(CLIFOGIAC_CODART, row->get(RDOC_CODART));
magcli.put(CLIFOGIAC_DOTOD, row->get_real("DOTOD"));
magcli.put(CLIFOGIAC_DOTTM, row->get_real("DOTMP"));
err = magcli.rewrite_write();
}
}
return err;
}
//costruttore
TGiac_per_cli::TGiac_per_cli()
{
//estraggo i dati di interesse dal documento
_clifo = 0;
_cont = 0;
_year = 0;
_indsped = 0;
}
//////////////////////////////////////////
//// CLASSE TGESTIONE_BOLLE_APP ////
//////////////////////////////////////////
// Definizione della classe dell'applicazione motore
class TGestione_bolle_app : public TMotore_application
{
TGiac_per_cli _giac;
protected:
virtual TMask* get_mask( int mode );
virtual int write( const TMask& m );
virtual int rewrite( const TMask& m );
virtual int read ( TMask& m );
virtual void init_insert_mode( TMask& m );
void elimina_vuote( const TMask& m);
public:
TGiac_per_cli& giacenza();
TGestione_bolle_app() {}
};
inline TGestione_bolle_app& gbapp() { return (TGestione_bolle_app &)main_app(); };
//////////////////////////////////////////
//// CLASSE TGESTIONE_BOLLE_MSK ////
//////////////////////////////////////////
//ARROTONDA: metodo che arrotonda la quantit<69> che gli passo se <20> previsto sul contratto
void TGestione_bolle_msk::arrotonda(const TMask& msk, real& quantita)
{
TConfig* configlv = new TConfig(CONFIG_DITTA,"lv");
int perarr = configlv->get_int("Perarr");
const TString& codart = msk.get(FR_CODART);
//instanzio una cache sulla tabella del magazzino
const TRectype& anamag = cache().get(LF_ANAMAG,codart);
//recupero i dati di interesse dall'anagrafica di magazzino
const long ppconf = anamag.get_long(ANAMAG_PPCONF);
if (ppconf > 0)
{
TDocumento_mask& dmsk = (TDocumento_mask&) msk.get_sheet()->mask();
//recupero dal documento i dati di interesse per recuperare...
//...i dati dalla riga contratto
const long codcf = dmsk.get_long(F_CODCF);
const int indsped = dmsk.get_int(F_CODINDSP);
TDate datadoc = dmsk.get_date(F_DATADOC);
if (!datadoc.ok())
datadoc = TODAY;
const TLaundry_contract cont(codcf, indsped, datadoc);
//leggo la riga del contratto per l'articolo corrente
const TRectype& rcont = cont.row(codart);
//recupero i dati di interesse dalla riga del contratto
if (rcont.get_bool(LVRCONDV_ARROT))
{
//calcolo di quanti pezzi sforo
long arr = quantita.integer() % ppconf;
//calcolo quanti pezzi in pi<70> o in meno gli devo dare e aggiorno la quantit<69>
if (arr > ppconf * perarr / 100) //arr <= ppconf*perarr/100 -> formula calcolo congualgio di Tassan
{
arr = ppconf - arr;
quantita += arr;
}
else
quantita -= arr;
}
}
}
//DETTAGLIO_CAUSALE: metodo che setta esplode la causale negli appositi campi
void TGestione_bolle_msk::dettaglio_causale(TSheet_field& ss)
{
TGestione_bolle_msk& dmsk = (TGestione_bolle_msk&) ss.mask();
TString4 causale = ss.cell(ss.selected(),ss.cid2index(FR_CODAGG1));
//instanzio una cache sulle causali
const TRectype& cau = cache().get("&CAU", causale);
//esplodo la causale
dmsk.set(F_LVCODCAU, causale);
dmsk.set(F_LVDESCAU, cau.get("S0"));
}
////////////////////////////
// HANDLER DI DOCUMENTO //
////////////////////////////
void TGestione_bolle_msk:: on_idle()
{
TDocumento_mask::on_idle();
if (_autoselect >= 0)
{
TSheet_field& s = sfield(F_SHEET);
//per ora 4 fisso perch<63> non sappiamo calcolare la colonna del ritirato
s.set_focus_cell_id(_autoselect, FR_QTAGG1);
_autoselect = -1;
dettaglio_causale(s);
}
}
//magico metodo per settare, al cambio riga dello sheet, il focus sul campo desiderato (il campo in questione <20>..
//..definito nella on_idle(); ricordarsi la set_notify() nel costruttore della maschera senno' viene eseguito l'ss_notify()..
//..standard e non questo qui ridefinito. Allah!
bool TGestione_bolle_msk::ss_notify(TSheet_field& ss, int r, KEY key)
{
TGestione_bolle_msk& dmsk = (TGestione_bolle_msk&) ss.mask();
if (key == K_TAB && dmsk._autoselect == -1)
dmsk._autoselect = ss.selected(); //riga per settare il focus
return TDocumento_mask::ss_notify(ss, r, key);
}
//LV_DATA_HANDLER: handler che si occupa di decodificare i campi data in testata
bool TGestione_bolle_msk::lv_data_handler(TMask_field& f, KEY k)
{
bool ok = true;
switch(f.dlg())
{
case F_DATADOC: ok = data_hndl( f, k ); break;
default: break;
}
TGestione_bolle_msk& dmsk = (TGestione_bolle_msk&)f.mask();
TDate oggi(TODAY);
TDate primo = oggi;
primo.set_day(1);
if (dmsk.insert_mode() && !dmsk.field(F_DATADOC).focusdirty())
dmsk.set(F_DATADOC,oggi);
else //permette la decodifica corretta della data nel caso stia guardando una bolla vecchia
{
oggi = dmsk.get_date(F_DATADOC);
primo = oggi;
primo.set_day(1);
}
//decodifica del giorno della settimana
dmsk.set(F_LVGIORNO, itow(oggi.wday()));
//settimana del mese = settimana(oggi) - settimana(primo del mese) +1
long tmp = oggi.week() - primo.week() + 1;
TString4 settimana;
settimana << tmp;
dmsk.set(F_LVSETTIMANA, settimana);
return ok;
}
//LV_CONTRATTO_HANDLER: handler che si occupa di riempire il campo contratto in testata
bool TGestione_bolle_msk::lv_contratto_handler(TMask_field& f, KEY k)
{
TGestione_bolle_msk& dmsk = (TGestione_bolle_msk&)f.mask();
const long codcf = dmsk.get_long(F_CODCF);
const int indsped = dmsk.get_int(F_CODINDSP);
TDate datadoc = dmsk.get_date(F_DATADOC);
if (!datadoc.ok())
datadoc = TODAY;
const int anno = datadoc.year();
if (codcf <= 0)
return true;
long codcont = lv_find_contract(codcf,indsped,datadoc);
if (codcont <= 0)
{
warning_box(TR("Non ci sono contratti in essere alla data indicata"));
return true;
}
else
{
TString16 tmp;
tmp << codcont;
dmsk.set(F_LVCODCONT, tmp);
}
TDocumento& doc = dmsk.doc();
doc.put(DOC_CODCONT, codcont);
return true;
}
//LV_BOLLA_HANDLER: handler di bolla, carica le righe contratto sulle bolle, preparando la struttura del documento
bool TGestione_bolle_msk::lv_bolla_handler(TMask_field& f, KEY k)
{
bool ok = true;
switch(f.dlg())
{
case F_CODCF: ok = TDocumento_mask::clifo_handler( f, k ); break;
default: break;
}
TGestione_bolle_msk& dmsk = (TGestione_bolle_msk&)f.mask();
TSheet_field& sheet = dmsk.sfield(F_SHEET);
if (ok && k == K_TAB && ((dmsk.insert_mode() && f.to_check(k, true)) || f.focusdirty()))
{
f.set_focusdirty(false);
TDocumento& doc = dmsk.doc();
int nrighe = sheet.items();
const long codcf = dmsk.get_long(F_CODCF);
const int indsped = dmsk.get_int(F_CODINDSP);
TDate datadoc = dmsk.get_date(F_DATADOC);
if (!datadoc.ok())
datadoc = TODAY;
const int anno = datadoc.year();
if (codcf <= 0)
return true;
const long codcont = lv_find_contract(codcf,indsped,datadoc);
if (codcont <= 0)
{
warning_box(TR("Non ci sono contratti in essere alla data indicata"));
return true;
}
else
{
doc.put(DOC_CODCF, codcf);
doc.put(DOC_DATADOC, datadoc);
doc.put(DOC_CODINDSP, indsped);
doc.put(DOC_CODCONT, codcont);
}
if (dmsk._stcodcf == codcf && dmsk._stcodcont == codcont && nrighe > 0)
return true;
dmsk.mask2doc();
dmsk._stcodcf = codcf;
dmsk._stcodcont = codcont;
//elimino tutte le righe del documento
doc.destroy_rows();
//tipo riga
const TString& tprig = dmsk.get(F_LBTIPORIGA);
//instanzio una cache sulla tabella dei contratti
const TLaundry_contract tcont(codcf, codcont);
//estraggo i dati di interesse dalla cache
const int tplis = tcont.get_int(LVCONDV_TIPOLIS); //tipo listino
//instanzio un recordset sulle righe del contratto considerato
TISAM_recordset rcont("USE LVRCONDV\nFROM CODCF=#CODCF CODCONT=#CODCONT\nTO CODCF=#CODCF CODCONT=#CODCONT");
rcont.set_var("#CODCF",codcf);
rcont.set_var("#CODCONT",codcont);
//leggo dalla configurazione i codici magazzino e deposito standard
TConfig* configlv = new TConfig(CONFIG_DITTA,"lv");
TString8 codmag;
codmag << configlv->get("CODMAG") << configlv->get("CODMAGC");
//per ogni riga estraggo l'articolo, il relativo prezzo e l'eventaule sconto da applicare,
//...riportati in bolla solo se necessario
for (bool ok = rcont.move_first(); ok; ok = rcont.move_next())
{
//creo una nuova riga documento
TRiga_documento& rdoc = doc.new_row(tprig);
//recupero i dati di interesse dalla riga del contratto e li inserisco sullo sheet
const TString80 codart = rcont.get(LVRCONDV_CODART).as_string();
TString4 causale = rcont.get(LVRCONDV_CAUSLAV).as_string();
if (causale.blank() || atoi(causale) == 0)
{
TConfig* configlv = new TConfig(CONFIG_DITTA,"lv");
causale = configlv->get("CAUSLAV");
}
//instanzio una cache sulle anagrafice di magazzino
const TRectype& anamag = cache().get(LF_ANAMAG,codart);
rdoc.put(RDOC_CODART,codart);
rdoc.put(RDOC_CODARTMAG,codart);
rdoc.put(RDOC_CHECKED,'X');
rdoc.put(RDOC_DESCR,anamag.get(ANAMAG_DESCR));
rdoc.put(RDOC_UMQTA,rcont.get(LVRCONDV_UM).as_string());
rdoc.put(RDOC_CODAGG1,causale);
rdoc.put(RDOC_CODIVA,anamag.get(ANAMAG_CODIVA));
rdoc.put(RDOC_CODMAG, codmag);
rdoc.put(RDOC_CODMAGC, codmag);
//gestione campi dotazione odierna e dotazione temporanea
TGiac_per_cli& giac = gbapp().giacenza();
giac.preset(doc);
real dotod = giac.giac_att(rdoc, true);
rdoc.put("DOTOD", dotod);
real dotmp = giac.giac_att(rdoc, false);
rdoc.put("DOTMP", dotmp);
//elaborazione per il prezzo: o lo prendo dalle righe contratto, o dall'anagrafica magazzino
const TString& sconto = rcont.get(LVRCONDV_SCONTPERC).as_string();
rdoc.put(RDOC_SCONTO, sconto);
//controllo da dove devo prendere il prezzo
real prezzo;
if (tplis == 0)
prezzo = rcont.get(LVRCONDV_PREZZO).as_real();
else
prezzo = anamag.get_real(ANAMAG_COSTSTD);
rdoc.put(RDOC_PREZZO, prezzo);
}
dmsk.doc2mask(false);
FOR_EACH_MASK_FIELD(dmsk, i, f)
{
if (f->has_check())
f->check(STARTING_CHECK);
if (f->is_edit())
f->on_hit();
}
dmsk._autoselect = 0;
}
return ok;
}
///////////////////////
// HANDLER DI RIGA //
///////////////////////
//LV_RITIRATO_HANDLER: handler sul campo ritirato, che copia nel campo consegnato
//lo stesso valore eventualmente arrotondato e aggiorna il campo "dotazione odierna" (sempre)
//e il campo "dotazione temporanea" (se la causale <20> giusta)
bool TGestione_bolle_msk::lv_ritirato_handler(TMask_field& f, KEY k)
{
if (f.to_check(k) && !f.empty())
{
TMask& msk = f.mask();
real ritirato = f.get();
real dotod = msk.get_real(FR_JOLLY1);
if (ritirato > dotod && f.dirty())
warning_box(TR("ATTENZIONE: stai ritirando un quantitativo maggiore della dotazione!"));
TSheet_field* sheet = msk.get_sheet();
TDocumento_mask& dmask = (TDocumento_mask&)sheet->mask();
TDocumento& doc = dmask.doc();
TRiga_documento& rdoc = dmask.doc()[sheet->selected()+1];
rdoc.put(RDOC_QTAGG1,ritirato);
if (msk.field(FR_QTA).enabled() && rdoc.get(RDOC_QTA).empty())
{
real consegnato = ritirato;
arrotonda(msk, consegnato);
msk.set(FR_QTA, consegnato, 0x3);
return true;
}
//gestione campi dotazione odierna e dotazione temporanea
TGiac_per_cli& giac = gbapp().giacenza();
dotod = giac.giac_att(rdoc, true);
msk.set(FR_JOLLY1, dotod);
rdoc.put("DOTOD", dotod);
//scrivo la dotazione temporanea solo se esistono le date di dotazione temporanea e questa non <20> scaduta
if (rdoc.get_date("DADATATMP").ok() && rdoc.get_date("ADATATMP").ok() && rdoc.get_date("ADATATMP") >= doc.get_date(DOC_DATADOC))
{
real dotmp = giac.giac_att(rdoc, false);
msk.set(FR_JOLLY2, dotmp);
rdoc.put("DOTMP", dotmp);
}
}
return true;
}
//LV_CONSEGNATO_HANDLER: per adesso <20> solo un segna - posto
bool TGestione_bolle_msk::lv_consegnato_handler(TMask_field& f, KEY k)
{
bool ok = true;
switch(f.dlg())
{
case FR_QTA: ok = qta_handler( f, k ); break;
default: break;
}
if (f.to_check(k))
{
TMask& msk = f.mask();
real consegnato = f.get();
//gestione campi dotazione odierna e dotazione temporanea
TSheet_field* sheet = msk.get_sheet();
TDocumento_mask& dmask = (TDocumento_mask&)sheet->mask();
TDocumento& doc = dmask.doc();
TRiga_documento& rdoc = dmask.doc()[sheet->selected()+1];
rdoc.put(RDOC_QTA, consegnato);
TGiac_per_cli& giac = gbapp().giacenza();
real dotod = giac.giac_att(rdoc, true);
msk.set(FR_JOLLY1, dotod);
rdoc.put("DOTOD", dotod);
//scrivo la dotazione temporanea solo se esistono le date di dotazione temporanea e questa non <20> scaduta
if (rdoc.get_date("DADATATMP").ok() && rdoc.get_date("ADATATMP").ok() && rdoc.get_date("ADATATMP") >= doc.get_date(DOC_DATADOC))
{
real dotmp = giac.giac_att(rdoc, false);
msk.set(FR_JOLLY2, dotmp);
rdoc.put("DOTMP", dotmp);
}
}
return ok;
}
//LV_CODART_HANDLER: handler sul campo codice articolo, che carica la causale relativa all'articolo
//e controlla se l'articolo che si sta inserendo fa parte della dotazione del cliente
bool TGestione_bolle_msk::lv_codart_handler(TMask_field& f, KEY k)
{
bool ok = true;
switch(f.dlg())
{
case FR_CODART: ok = codart_handler( f, k ); break;
default: break;
}
if (ok && (k == K_ENTER || k == K_TAB))
{
TMask& msk = f.mask();
const TString& codart = msk.get(FR_CODART);
if (codart.full())
{
TGestione_bolle_msk& dmsk = (TGestione_bolle_msk&) msk.get_sheet()->mask();
TSheet_field* sheet = msk.get_sheet();
TRiga_documento& rdoc = dmsk.doc()[sheet->selected()+1];
rdoc.put(RDOC_CODART, codart);
//recupero dal documento i dati di interesse per recuperare...
//...i dati dalla riga contratto
const long codcf = dmsk.get_long(F_CODCF);
const int indsped = dmsk.get_int(F_CODINDSP);
TDate datadoc = dmsk.get_date(F_DATADOC);
if (!datadoc.ok())
datadoc = TODAY;
const TLaundry_contract cont(codcf, indsped, datadoc);
const TRectype& rcont = cont.row(codart);
//cerco la causale relativa all'articolo; se non la trovo prendo quella standard
TString4 causale = rcont.get(LVRCONDV_CAUSLAV);
if (causale.blank() || atoi(causale) == 0 )
{
TConfig* configlv = new TConfig(CONFIG_DITTA,"lv");
causale = configlv->get("CAUSLAV");
}
if (rdoc.get("DOTOD").empty())
{
//gestione campi dotazione odierna e dotazione temporanea
TGiac_per_cli& giac = gbapp().giacenza();
giac.preset(dmsk.doc());
real dotod = giac.giac_att(rdoc, true);
rdoc.put("DOTOD", dotod);
TString16 tmp;
tmp << dotod;
msk.field(FR_JOLLY1).set(tmp);
}
if (rdoc.get(RDOC_CODAGG1).empty())
msk.set(FR_CODAGG1, causale);
if (k == K_ENTER && rcont.get_bool(LVRCONDV_ARROT))
{
TSheet_field* sheet = msk.get_sheet();
TRiga_documento rdoc = dmsk.doc()[sheet->selected()+1];
const real ritor = rdoc.get_real(RDOC_QTAGG4);
const real conor = rdoc.get_real(RDOC_QTAGG3);
const real ritat = msk.get_real(FR_QTAGG1);
const real conat = msk.get_real(FR_QTA);
if (ritor != ritat || conor != conat)
{
const real congor = rcont.get_real(LVRCONDV_QTACONG);
const real congat = conat - ritat + congor;
rdoc.put(RDOC_QTAGG5, congat); //conguaglio dopo modifica manuale
TLocalisamfile rcondv(LF_LVRCONDV);
rcondv.put(LVRCONDV_CODCF,codcf);
rcondv.put(LVRCONDV_CODCONT,cont.get_int(LVCONDV_CODCONT));
rcondv.put(LVRCONDV_CODART,codart);
if (rcondv.read() == NOERR)
{
rcondv.put(LVRCONDV_QTACONG,congat);
rcondv.rewrite();
}
}
}
//controllo se si vuole aggiungere un eventuale nuovo articolo al contratto
if (k == K_ENTER && f.dirty() && msk.get(FR_CODARTMAG).full() && rcont.empty() &&
yesno_box(TR("L'articolo in esame non fa parte della dotazione standard di questo cliente."
"Si desidera aggiungerla ai contratti?")))
cont.edit();
}
}
return ok;
}
//LV_CAUSALE_HANDLER: handler che abilita e/o disabilita i campi di consegnato e ritirato in base alla causale
//e tenendo conto se l'articolo <20> bloccato o meno
bool TGestione_bolle_msk::lv_causale_handler(TMask_field& f, KEY k)
{
if (f.to_check(k, true))
{
TConfig* configlv = new TConfig(CONFIG_DITTA,"lv");
TString4 codmagdef = configlv->get("CODMAG"); //magazzino
TString4 coddepdef = configlv->get("CODMAGC"); //magazzino del circolante (deposito)
//leggo la causale che ho scritto nella riga corrente dello sheet
TString4 causale = f.get();
if (causale.full())
{
TMask& msk = f.mask();
//leggo il codart che ho scritto nella riga corrente delle sheet
const TString& codart = msk.get(FR_CODART);
//srcrivo nel documento la causale
TGestione_bolle_msk& dmsk = (TGestione_bolle_msk&) msk.get_sheet()->mask();
TSheet_field& sheet = dmsk.sfield(F_SHEET);
//esplodo la descrizione della causale
dettaglio_causale(sheet);
TDocumento& doc = dmsk.doc();
TRiga_documento& rdoc = doc[msk.get_sheet()->selected()+1];
TString4 codmag(doc.clifor().vendite().get(CFV_CODMAG));
TString4 coddep(doc.clifor().vendite().get(CFV_CODDEP));
TString4 codmagcoll(codmag);
TString4 coddepcoll(coddep);
rdoc.put(RDOC_CODAGG1, causale);
//recupero i dati di interesse dalla testata per poter trovare il contratto
const long codcf = dmsk.get_long(F_CODCF);
const int indsped = dmsk.get_int(F_CODINDSP);
TDate datadoc = dmsk.get_date(F_DATADOC);
if (!datadoc.ok())
datadoc = TODAY;
//trovo il contratto utlizzato e la riga contratto specifica che mi serve
const TLaundry_contract cont(codcf, indsped, datadoc);
const TRectype& rcont = cont.row(codart);
//instanzio una cache sulle causali
const TRectype& cau = cache().get("&CAU", causale);
//movimento o meno la dotazione temporanea/odierna a seconda di cosa prevede la causale
int sgn_rit = 0;
int sgn_con = 0;
if (cau.get_bool("B0"))
{
const TCausale_magazzino& rit = cached_causale_magazzino(cau.get("S1"));
if (codmagcoll.blank() && rit.has_default_mag())
{
codmagcoll = rit.default_mag();
coddepcoll = rit.default_dep();
}
sgn_rit = rit.sgn(s_dottm);
}
if (cau.get_bool("B1"))
{
const TCausale_magazzino& con = cached_causale_magazzino(cau.get("S2"));
if (codmag.blank() && con.has_default_mag())
{
codmag = con.default_mag();
coddep = con.default_dep();
}
sgn_con = con.sgn(s_dottm);
}
//setto il valore della dotazione temporanea
TGiac_per_cli& giac = gbapp().giacenza();
giac.preset(doc);
real dotmp = giac.giac_att(rdoc, false);
rdoc.put("DOTMP", dotmp);
TString16 tmp;
tmp << dotmp;
msk.field(FR_JOLLY2).set(tmp);
//setto le date di inizio e fine della dotazione temporanea
TDate dadata = rcont.get_date(LVRCONDV_INDTTMP);
TDate adata = rcont.get_date(LVRCONDV_FIDTTMP);
bool fdotmp = false;
//disabilito i campi di dotazione temporanea se la causale non prevede la loro movimentazione
if (sgn_rit == 0 && sgn_con == 0)
{
msk.field(FR_JOLLY2).disable();
msk.field(FR_JOLLY3).disable();
msk.field(FR_JOLLY4).disable();
}
else
{
msk.field(FR_JOLLY2).enable();
msk.field(FR_JOLLY3).enable();
msk.field(FR_JOLLY4).enable();
fdotmp = true;
}
if (dadata.ok() || fdotmp)
{
TLocalisamfile rcondv(LF_LVRCONDV);
rcondv.put(LVRCONDV_CODCF,codcf);
rcondv.put(LVRCONDV_CODCONT,cont.get_int(LVCONDV_CODCONT));
rcondv.put(LVRCONDV_CODART,msk.get(FR_CODART));
if (rdoc.get_date("DADATATMP").empty())
{
if (!dadata.ok() && rcondv.read() == NOERR)
{
rcondv.put(LVRCONDV_INDTTMP, datadoc);
rcondv.rewrite();
}
rdoc.put("DADATATMP", datadoc);
msk.field(FR_JOLLY3).set(datadoc);
}
if (rdoc.get_date("ADATATMP").empty())
{
if (adata.ok() && adata <= datadoc)
{
rdoc.put("ADATATMP", adata);
msk.field(FR_JOLLY4).set(adata);
}
else
{
//instanzio in TRecordset sui giri
TISAM_recordset giri("USE LVRCONSPLAN KEY 3\nSELECT DTCONS>#DATADOC\nFROM CODCF=#CODCF CODCONT=#CODCONT\nTO CODCF=#CODCF CODCONT=#CODCONT");
giri.set_var("#DATADOC", datadoc);
giri.set_var("#CODCF", codcf);
giri.set_var("#CODCONT", cont.get_long(LVCONDV_CODCONT));
if (giri.move_first())
{
rdoc.put("ADATATMP", giri.get(LVRCONSPLAN_DTCONS).as_date());
msk.field(FR_JOLLY4).set(giri.get(LVRCONSPLAN_DTCONS).as_date());
if (rcondv.read() == NOERR)
{
rcondv.put(LVRCONDV_FIDTTMP, giri.get(LVRCONSPLAN_DTCONS).as_date());
rcondv.rewrite();
}
}
}
}
}
//abilito o disabilito azzerandolo il campo "Ritirato" a seconda di cosa prevede la causale
if (cau.get_bool("B0"))
{
msk.field(FR_QTAGG1).enable(true);
if (codmagcoll.blank())
codmagcoll = codmagdef;
if (coddepcoll.blank())
coddepcoll = coddepdef; //magazzino del circolante
msk.field(FR_CODMAGC).set(codmagcoll);
msk.field(FR_CODDEPC).set(coddepcoll);
}
else
{
msk.field(FR_QTAGG1).set("");
msk.field(FR_QTAGG1).disable();
}
//abilito o disabilito azzerandolo il campo "Consegnato" a seconda di cosa prevede la causale
//ATTENZIONE: questo campo risulta sempre disabilitato se l'articolo <20> bloccato
if (cau.get_bool("B1") && rcont.get(LVRCONDV_ARTBLOC).empty())
{
msk.field(FR_QTA).enable(true);
if (codmag.blank())
codmag = codmagdef;
if (coddep.blank())
coddep = coddepdef;
msk.field(FR_CODMAG).set(codmag);
msk.field(FR_CODDEP).set(coddep);
}
else
{
msk.field(FR_QTA).set("");
msk.field(FR_QTA).disable();
}
}
}
return true;
}
//LV_CODMAG_HANDLER: handler che limita l'esecuzione
bool TGestione_bolle_msk::lv_codmag_handler(TMask_field& f, KEY k)
{
bool ok = true;
if (f.to_check(k,true))
{
TMask& msk = f.mask();
const TString& causale = msk.get(FR_CAULAV);
if (causale.full())
{
switch(f.dlg())
{
case FR_CODMAG: ok = codmag_handler( f, k ); break;
default: break;
}
}
}
return ok;
}
bool TGestione_bolle_msk::lv_datatmp_handler(TMask_field& f, KEY k)
{
if (k == K_ENTER)
{
TMask& msk = f.mask();
//leggo il codart che ho scritto nella riga corrente dello sheet
const TString& codart = msk.get(FR_CODART);
const TDate& dadata = msk.get_date(FR_JOLLY3);
const TDate& adata = msk.get_date(FR_JOLLY4);
TGestione_bolle_msk& dmsk = (TGestione_bolle_msk&) msk.get_sheet()->mask();
//recupero il documento e modifico le date sulla riga documento
TDocumento& doc = dmsk.doc();
TRiga_documento& rdoc = doc[msk.get_sheet()->selected()+1];
rdoc.put("DADATATMP", dadata);
rdoc.put("ADATATMP", adata);
//recupero i dati di interesse dalla testata per poter trovare il contratto
const long codcf = dmsk.get_long(F_CODCF);
const int indsped = dmsk.get_int(F_CODINDSP);
TDate datadoc = dmsk.get_date(F_DATADOC);
//trovo il contratto utlizzato e la riga contratto specifica che mi serve
const TLaundry_contract cont(codcf, indsped, datadoc);
TLocalisamfile rcondv(LF_LVRCONDV);
rcondv.put(LVRCONDV_CODCF,codcf);
rcondv.put(LVRCONDV_CODCONT,cont.get_int(LVCONDV_CODCONT));
rcondv.put(LVRCONDV_CODART,msk.get(FR_CODART));
if (rcondv.read() == NOERR)
{
rcondv.put(LVRCONDV_INDTTMP, dadata);
rcondv.put(LVRCONDV_FIDTTMP, adata);
rcondv.rewrite();
}
msk.field(FR_JOLLY3).set_focusdirty(false);
msk.field(FR_JOLLY4).set_focusdirty(false);
}
return true;
}
//metodo che setta gli handler sui campi di riga
void TGestione_bolle_msk::user_set_row_handler(TMask& rm, short field, int index)
{
switch(index)
{
case 4101: rm.set_handler(field, lv_ritirato_handler); break;
case 4102: rm.set_handler(field, lv_consegnato_handler); break;
case 4103: rm.set_handler(field, lv_codart_handler); break;
case 4104: rm.set_handler(field, lv_causale_handler); break;
case 4105: rm.set_handler(field, lv_codmag_handler); break;
case 4106: rm.set_handler(field, lv_datatmp_handler); break;
default : TDocumento_mask::user_set_row_handler(rm, field, index); break;
}
}
//metodo che setta l'handler di bolla
void TGestione_bolle_msk::user_set_handler( short fieldid, int index)
{
switch(index)
{
case 4101: set_field_handler(fieldid, lv_data_handler); break;
case 4102: set_field_handler(fieldid, lv_contratto_handler); break;
case 4103: set_field_handler(fieldid, lv_bolla_handler); break;
default : TDocumento_mask::user_set_handler(fieldid, index); break;
}
}
TGestione_bolle_msk::TGestione_bolle_msk(const char* tipodoc) : TDocumento_mask(tipodoc), _autoselect(-1)
{
TConfig* configlv = new TConfig(CONFIG_DITTA,"lv");
char dtfs = configlv->get_char("Datafissa");
if (dtfs == 'X')
field(F_DATADOC).disable();
sfield(F_SHEET).set_nav_column(FR_QTA, FR_QTAGG1);
sfield(F_SHEET).set_auto_append();
sfield(F_SHEET).set_notify( ss_notify );
}
//////////////////////////////////////////
//// CLASSE TGESTIONE_BOLLE_APP ////
//////////////////////////////////////////
//ridefinisco il metodo get_mask delle TMotore_application
TMask* TGestione_bolle_app::get_mask( int mode )
{
if (mode == MODE_INS || mode == MODE_MOD)
{
TString4 tipodoc;
if (mode == MODE_MOD)
tipodoc = get_relation()->curr().get(DOC_TIPODOC); // Lo prendo dalla relazione (Gelai)
else
tipodoc = TMotore_application::get_mask(MODE_QUERY)->get(F_TIPODOC);
if (_doc_masks.objptr(tipodoc) == NULL)
{
TGestione_bolle_msk* m = new TGestione_bolle_msk(tipodoc);
_doc_masks.add(tipodoc, m);
const TTipo_documento& tdoc = m->doc().tipo();
const TString_array& handlers = tdoc.handlers();
FOR_EACH_ARRAY_ROW(handlers, i, row)
{
m->user_set_handler( row->get_int( 0 ), row->get_int( 1 ) );
}
}
}
return TMotore_application::get_mask(mode);
}
void TGestione_bolle_app::elimina_vuote( const TMask& m)
{
TDocumento_mask& mask = (TDocumento_mask&) m;
TDocumento& d = mask.doc();
TSheet_field& sheet = mask.sfield(F_SHEET);
FOR_EACH_DOC_ROW_BACK(d, r, row)
{
if (row->is_articolo() && row->get_int(RDOC_QTA) == 0 && row->get_int(RDOC_QTAGG1) == 0)
{
d.destroy_row(r,true);
}
}
}
//ridefinisco il metodo write delle TMotore_application
int TGestione_bolle_app::write( const TMask& m )
{
elimina_vuote(m);
TGestione_bolle_msk& mask = (TGestione_bolle_msk&) m;
//_giac.write_giac(m);
return TMotore_application::write(m);
}
//ridefinisco il metodo rewrite delle TMotore_application
int TGestione_bolle_app::rewrite( const TMask& m )
{
elimina_vuote(m);
TGestione_bolle_msk& mask = (TGestione_bolle_msk&) m;
//_giac.write_giac(m);
return TMotore_application::rewrite(m);
}
//ridefinisco il metodo read della TMotore_application
int TGestione_bolle_app::read(TMask& m)
{
const int err = TMotore_application::read(m);
TGestione_bolle_msk& mask = (TGestione_bolle_msk&) m;
TDocumento& d = mask.doc();
_giac.reset(d);
FOR_EACH_DOC_ROW_BACK(d, r, row)
_giac.load_row((TRiga_documento&)*row);
if (err == NOERR)
mask._autoselect = 0;
return err;
}
//ridefinisco il metodo init_insert_mode della TMotore_application
void TGestione_bolle_app::init_insert_mode(TMask &m)
{
TGestione_bolle_msk& mask = (TGestione_bolle_msk&) m;
TDocumento& d = mask.doc();
_giac.reset(d);
mask.reset_var_mask();
mask.first_focus(F_CODCF, false);
return TMotore_application::init_insert_mode(m);
}
//metodo che mi restituisce la giac
TGiac_per_cli& TGestione_bolle_app::giacenza()
{
return _giac;
}
int lv3100( int argc, char* argv[])
{
TGestione_bolle_app a;
a.run( argc, argv, TR("Documenti di Trasporto"));
return 0;
}