- funzione date2long e period2long per la conversione di date e periodi

- gestione della categoria di vendita
- classe SVRiep_record (campi virtuali e altro)
- classe RWrecord_cache e TStat_cache (cache di lettura/scrittura)


git-svn-id: svn://10.65.10.50/trunk@5234 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
augusto 1997-09-19 10:17:17 +00:00
parent 2b0484e08f
commit 6a6d689c46
2 changed files with 430 additions and 10 deletions

View File

@ -1,9 +1,14 @@
#include <prefix.h>
#include <progind.h>
#include <recarray.h>
#include "svlib01.h"
#include "svriep.h"
#include "svstat.h"
#include "..\mg\anamag.h"
#include "..\pr\agenti.h"
#include "..\ve\clifor.h"
///////////////////////////////////////////////////////////
// Funzioni di utilita' comune
@ -110,6 +115,8 @@ int divide(TFrequenza_statistiche f1, TFrequenza_statistiche f2)
return 0;
}
//@cmember ritorna la parte "periodo" di una data (l'anno si ottiene da year())
// tutti i periodi cominciano da 1
int date2period(const TDate& datadoc, TFrequenza_statistiche freq)
{
int classe;
@ -155,6 +162,18 @@ int date2period(const TDate& datadoc, TFrequenza_statistiche freq)
return classe;
}
//@cmember
long date2long(const TDate d, TFrequenza_statistiche f)
{
return long(d.year())*long(last_period(d.year(),f))+date2period(d,f);
}
long period2long(const int anno, const int periodo, TFrequenza_statistiche f)
{
return long(anno)*long(last_period(anno,f))+periodo;
}
const TDate& floor(TDate& data, TFrequenza_statistiche freq)
{
switch (freq)
@ -268,6 +287,7 @@ void TStats_agg::init()
_zona = ini.get_bool("ZonaGrp");
_giacenza = ini.get_bool("GiacenzaGrp");
_magazzino = ini.get_bool("MagazzinoGrp");
_catvend = ini.get_bool("CatVendGrp");
}
void TStats_agg::test_firm() const
@ -280,6 +300,8 @@ void TStats_agg::test_firm() const
}
}
// scrive la chiave nel record
// utilizza la convenzione in TStats_agg::find per la tokenstring
void TStats_agg::put_key(TRectype& stat, TToken_string& key) const
{
CHECK(stat.num() == LF_SVRIEP, "Ci vuole un record delle statistiche");
@ -292,12 +314,16 @@ void TStats_agg::put_key(TRectype& stat, TToken_string& key) const
stat.put(SVR_CODART, key.get());
stat.put(SVR_UMQTA, key.get());
stat.put(SVR_CODAG, key.get());
stat.put(SVR_TIPOCF, key.get());
stat.put(SVR_CODCF, key.get());
stat.put(SVR_ZONA, key.get());
stat.put(SVR_GIAC, key.get());
stat.put(SVR_MAG, key.get());
stat.put(SVR_CATVEN, key.get());
}
// ricerca la chiave nell'assocarray
// la convenzione per la tokenstring è utilizzata in put_key
TStats_agg::TStats_data& TStats_agg::find(const TRiga_documento& rdoc)
{
test_firm();
@ -326,6 +352,7 @@ TStats_agg::TStats_data& TStats_agg::find(const TRiga_documento& rdoc)
else
codart = rdoc.get(RDOC_CODART);
key.add(codart);
// l'unità di misura non viene MAI RAGGRUPPATA sul riepilogo statistiche!
key.add(rdoc.get(RDOC_UMQTA));
if (_agente)
@ -334,9 +361,13 @@ TStats_agg::TStats_data& TStats_agg::find(const TRiga_documento& rdoc)
key.add("");
if (_cliente)
{
key.add(doc.get(DOC_TIPOCF));
key.add(doc.get(DOC_CODCF));
else
} else {
key.add("");
key.add("");
}
if (_zona)
key.add(doc.get(DOC_ZONA));
@ -353,6 +384,11 @@ TStats_agg::TStats_data& TStats_agg::find(const TRiga_documento& rdoc)
else
key.add("");
if (_catvend)
key.add(doc.get(DOC_CATVEN));
else
key.add("");
TStats_data* ptr = (TStats_data*)_data.objptr(key);
if (ptr == NULL)
{
@ -429,7 +465,8 @@ bool TStats_agg::add(const TRiga_documento& rdoc)
bool TStats_agg::update()
{
TProgind pi(_data.items(), "Aggiornamento statistiche", FALSE, TRUE, 60);
// eliminato perché rompeva a Sandro
// TProgind pi(_data.items(), "Aggiornamento statistiche", FALSE, TRUE, 60);
test_firm();
@ -437,12 +474,14 @@ bool TStats_agg::update()
TToken_string key(64);
TLocalisamfile stat(LF_SVRIEP);
stat.set_curr(new TSVriep_record);
TRectype& curr = stat.curr();
_data.restart();
for (THash_object* h = _data.get_hashobj(); h; h = _data.get_hashobj())
{
pi.addstatus(1);
//pi.addstatus(1);
TStats_data& data = (TStats_data&)h->obj();
if (data._quantita.is_zero() && data._valore.is_zero())
@ -488,3 +527,324 @@ bool TStats_agg::update()
TStats_agg::TStats_agg() : _ditta(-1)
{
}
///////////////////////////////////////////////////////////
// Record del file svriep
///////////////////////////////////////////////////////////
TSVriep_record:: TSVriep_record(): TVariable_rectype(LF_SVRIEP),
_anamag(LF_ANAMAG),
_clifor(LF_CLIFO),
_agenti(LF_AGENTI),
_magazz(LF_MAG),
_tipodoc("%NUM"),
_catven("CVE"),
_zone("ZON"),
_ums("%UMS")
{}
TSVriep_record::~TSVriep_record()
{}
const TString & TSVriep_record::get_str(const char* fieldname) const
{
static TString80 chiavi;
chiavi=TRectype::get_str(SVR_CHIAVI);
if (strcmp(fieldname,SVR_CODART)==0)
return chiavi.mid(0,20);
else if (strcmp(fieldname,SVR_CODAG)==0)
return chiavi.mid(20,5);
else if (strcmp(fieldname,SVR_TIPOCF)==0)
return chiavi.mid(25,1);
else if (strcmp(fieldname,SVR_CODCF)==0)
return chiavi.mid(26,6);
else if (strcmp(fieldname,SVR_ZONA)==0)
return chiavi.mid(32,3);
else if (strcmp(fieldname,SVR_GIAC)==0)
return chiavi.mid(35,15);
else if (strcmp(fieldname,SVR_CATVEN)==0)
return chiavi.mid(50,3);
else if (strcmp(fieldname,SVR_MAG)==0)
return chiavi.mid(53,3);
else
return TRectype::get_str(fieldname);
}
void TSVriep_record::put_str(const char* fieldname, const char* val)
{
static TString80 chiavi;
chiavi=TRectype::get_str(SVR_CHIAVI);
if (strcmp(fieldname,SVR_CODART)==0)
chiavi.overwrite(val,0);
else if (strcmp(fieldname,SVR_CODAG)==0)
chiavi.overwrite(val,20);
else if (strcmp(fieldname,SVR_TIPOCF)==0)
chiavi.overwrite(val,25);
else if (strcmp(fieldname,SVR_CODCF)==0)
chiavi.overwrite(val,26);
else if (strcmp(fieldname,SVR_ZONA)==0)
chiavi.overwrite(val,32);
else if (strcmp(fieldname,SVR_GIAC)==0)
chiavi.overwrite(val,35);
else if (strcmp(fieldname,SVR_CATVEN)==0)
chiavi.overwrite(val,50);
else if (strcmp(fieldname,SVR_MAG)==0)
chiavi.overwrite(val,53);
else
{
TRectype::put_str(fieldname,val);
return ;
}
TRectype::put_str(SVR_CHIAVI,chiavi);
return ;
}
const TString& TSVriep_record::get_part(const char *lev_code) const
{
static TString park(' ',25);
int lev_code_num=atoi(lev_code+1);
switch (*lev_code)
{
case 'D': // tipo documento
return get(SVR_TIPODOC);
case 'A': // articolo
if (lev_code_num==0)
{
park=get(SVR_CODART);
return park.rpad(25);
}
else
{
park =_liv_art.unpack_grpcode(get(SVR_CODART),lev_code_num);
return park.rpad(_liv_art.code_length(lev_code_num));
}
case 'L': // liv giac
CHECK(lev_code_num>0,"I livelli di giacenza sono utilizzabili solo singolarmente");
park = _liv_giac.unpack_grpcode(get(SVR_GIAC),lev_code_num);
return park.rpad(_liv_giac.code_length(lev_code_num));
case 'V': // cat. vendita
park=get(SVR_CATVEN);
return park.rpad(3);
case 'C': // cliente / fornitore
park.format("%c%6d",get_char(SVR_TIPOCF),get_int(SVR_CODCF));
return park;
case 'G': // agente
park.format("%5d",get_int(SVR_CODAG));
return park;
case 'M': // mag
park=get(SVR_MAG);
return park.rpad(3);
case 'Z': // zona
park=get(SVR_ZONA);
return park.rpad(3);
case 'U': // unità di misura
park=get(SVR_UMQTA);
return park.rpad(3);
default:
fatal_box("ai chent recognaiz the code of the key part!");
return "";
}
}
const TString& TSVriep_record::get_descrpart(const char *lev_code)
{
int lev_code_num=atoi(lev_code+1);
switch (*lev_code)
{
case 'D': // tipo documento
return _tipodoc.get(get(SVR_TIPODOC)).get("S0");
case 'A': // articolo
if (lev_code_num==0 || lev_code_num== _liv_art.last_level())
{
return _anamag.get(get(SVR_CODART)).get(ANAMAG_DESCR);
}
else
{
return _liv_art.group_descr(get(SVR_CODART),lev_code_num);
}
case 'L': // liv giac
CHECK(lev_code_num>0,"I livelli di giacenza sono utilizzabili solo singolarmente");
//return _liv_giac.group_descr(unpack_grpcode(get(SVR_GIAC),lev_code_num),lev_code_num);
case 'V': // cat. vendita
return _catven.get(get(SVR_CATVEN)).get("S0");
case 'C': // cliente
{
TToken_string cod;
cod.add(get_char(SVR_TIPOCF));
cod.add(get_int(SVR_CODCF));
return _clifor.get(cod).get(CLI_RAGSOC);
}
case 'G': // agente
return _agenti.get(get(SVR_CODAG)).get(AGE_RAGSOC);
case 'M': // mag
return _magazz.get(get(SVR_MAG)).get("S0");
case 'Z': // zona
return _zone.get(get(SVR_ZONA)).get("S0");
case 'U': // Unità di misura
return _ums.get(get(SVR_UMQTA)).get("S0");
default:
fatal_box("ai chent recognaiz the code of the key part!");
return "";
}
}
///////////////////////////////////////////////////////////
// Cache
///////////////////////////////////////////////////////////
#define RWCACHE_SIZE 10
// funzione di default: prende una chiave a caso chiave
const TString & TRWrecord_cache::getkey2discard()
{
THash_object * o=get_some_obj();
CHECK(o,"E' stata chiamata la funzione getkey2discard con la cache vuota");
return o->key();
}
void TRWrecord_cache::discard(const TString & vittima)
{
if (items())
{
if (_flags.is_key(vittima))
{
const char fl=((TString &)_flags[vittima])[1];
// record modificato o nuovo
int err;
TRectype & rec=(TRectype & )TRecord_cache::get(vittima);
file().curr()=rec;
if (fl == 'D')
{
err=file().rewrite();
if (err!=NOERR)
error_box("Errore nella riscrittura della cache");
} else {
err=file().write();
if (err!=NOERR)
if (err == _isreinsert)
file().rewrite();
else
error_box("Errore nella scrittura della cache");
}
_flags.remove(vittima);
}
_cache.remove(vittima);
}
}
const TRectype& TRWrecord_cache::get(const char* chiave)
{
if (items()>=RWCACHE_SIZE)
discard(getkey2discard());
const TRectype & rec=TRecord_cache::get(chiave);
if (io_result() != NOERR)
{
// record non trovato: è nuovo
_flags.add(chiave,new TString("N"));
}
return rec;
}
void TRWrecord_cache::put(const TRectype &r)
{
test_firm();
TToken_string cachekey;
if (!r.empty())
{
const RecDes* recd = r.rec_des(); // Descrizione del record della testata
const KeyDes& kd = recd->Ky[key_number()-1]; // Elenco dei campi della chiave
for (int i = file().tab() ? 1: 0; i < kd.NkFields; i++) // Riempie la chiave selezionata
{
const int nf = kd.FieldSeq[i] % MaxFields;
const RecFieldDes& rf = recd->Fd[nf];
cachekey.add(r.get(rf.Name));
}
}
TObject* obj = _cache.objptr(cachekey);
if (obj != NULL)
{
// esiste in cache ; tenta di settare il flag a "D"irty; se il flag esiste già è a
TRectype & rec=(TRectype &)*obj;
rec=r;
_flags.add(cachekey , new TString("D"));
} else {
// non esiste in cache
obj = rec2obj(r);
_cache.add(cachekey, obj);
// qui assume che non esista nemmeno su file, perciò sia "N"uovo; al flush correggerà l'errore
_flags.add(cachekey , new TString("N"));
}
if (items()>=RWCACHE_SIZE)
discard(getkey2discard());
}
void TRWrecord_cache::clear()
{
while (items()>0)
{
const TString & vittima=getkey2discard();
if (_flags.is_key(vittima))
_flags.remove(vittima);
_cache.remove(vittima);
}
}
void TRWrecord_cache::flush()
{
while (items()>0)
discard(TRWrecord_cache::getkey2discard());
}
THash_object * TRWrecord_cache::get_some_obj()
{
if (items()==0)
return NULL;
THash_object * o;
while ((o=_cache.get_hashobj()) == NULL) ;
return o;
}
TRWrecord_cache::TRWrecord_cache(int num, int key, bool lock)
:TRecord_cache(num,key)
{
if (lock)
file().lock();
}
TRWrecord_cache::~TRWrecord_cache()
{
flush();
}
// cerca di restituire una chiave di bassa priorità (livello
const TString & TStat_cache::getkey2discard()
{
THash_object * o;
CHECK(items()>0,"E' stata chiamata la funzione getkey2discard con la cache vuota");
while ((o=_cache.get_hashobj()) == NULL) ;
if (((TRectype &)o->obj()).get_int(SVS_LIVELLO)<=1)
{
while ((o=_cache.get_hashobj()) == NULL) ;
if (((TRectype &)o->obj()).get_int(SVS_LIVELLO)==0)
while ((o=_cache.get_hashobj()) == NULL) ;
}
return o->key();
}
TStat_cache ::TStat_cache (bool lock):
TRWrecord_cache( LF_SVSTAT,1,lock)
{
}

View File

@ -9,6 +9,12 @@
#include "..\ve\velib.h"
#endif
#ifndef __TABUTIL_H
#include <tabutil.h>
#endif
#include "..\mg\mglib.h"
enum TFrequenza_statistiche { fs_nulla, fs_giornaliera,
fs_settimanale, fs_quindicinale,
fs_mensile, fs_bimestrale,
@ -17,22 +23,28 @@ enum TFrequenza_statistiche { fs_nulla, fs_giornaliera,
// Converte una carattere in una frequenza delle statisitiche
TFrequenza_statistiche char2frequency(char c);
// Converte una frequenza delle statisitiche in un carattere
//Converte una frequenza delle statisitiche in un carattere
char frequency2char(TFrequenza_statistiche f);
// Arrotondamento di una data alla frequenza specificata
//Arrotondamento di una data alla frequenza specificata
const TDate& floor(TDate& data, TFrequenza_statistiche freq);
const TDate& ceil(TDate& data, TFrequenza_statistiche freq);
// Ritorna il rapporto tra le frequenze: 0 se impossibile stabilirlo
//Ritorna il rapporto tra le frequenze: 0 se impossibile stabilirlo
int divide(TFrequenza_statistiche f1, TFrequenza_statistiche f2);
// Ritorna l'ultimo perido di un anno (primo = 1)
//Ritorna l'ultimo periodo di un anno (primo = 1)
int last_period(int anno, TFrequenza_statistiche freq);
// Converte una data nella classe temporale definita dalla frequenza
//Ritorna la parte "periodo" di una data (l'anno si ottiene da year())
int date2period(const TDate& data, TFrequenza_statistiche freq);
//Converte una data in un long in base alla frequenza passata
long date2long(const TDate d, TFrequenza_statistiche f);
//Converte una coppia anno+periodo in un long in base alla frequenza passata
long period2long(const int anno, const int periodo, TFrequenza_statistiche f);
class TStats_agg : public TObject
{
class TStats_data : public TObject
@ -47,7 +59,7 @@ class TStats_agg : public TObject
TFrequenza_statistiche _frequenza;
bool _merce, _prestazioni, _omaggi, _omaggio_is_merce;
bool _art_nocode, _art_noanag, _art_noanag_grp;
bool _agente, _cliente, _zona, _articolo, _giacenza, _magazzino;
bool _agente, _cliente, _zona, _articolo, _giacenza, _magazzino,_catvend;
protected:
void test_firm() const;
@ -74,6 +86,7 @@ public:
bool grp_articolo() const { test_firm(); return _articolo; }
bool grp_giacenza() const { test_firm(); return _giacenza; }
bool grp_magazzino() const { test_firm(); return _magazzino; }
bool grp_catven() const { test_firm(); return _catvend; }
bool omaggio_is_merce() const { test_firm(); return _omaggio_is_merce; }
@ -81,4 +94,51 @@ public:
virtual ~TStats_agg() { }
};
class TSVriep_record : public TVariable_rectype
{
TCodart_livelli _liv_art;
TCodgiac_livelli _liv_giac;
TRecord_cache _anamag,_clifor,_agenti,_magazz,_tipodoc,_catven,_zone,_ums;
public:
const TString& get_part(const char *lev_code) const;
const TString& get_descrpart(const char *lev_code);
virtual const TString & get_str(const char* fieldname) const;
virtual void put_str(const char* fieldname, const char* val);
TSVriep_record();
virtual ~TSVriep_record();
};
class TRWrecord_cache : public TRecord_cache
{
TAssoc_array _flags;
protected:
THash_object * get_some_obj();
virtual const TString & getkey2discard();
public:
virtual void discard(const TString & k);
virtual void put(const TRectype &r);
virtual const TRectype& get(const char* chiave);
void clear();
void flush();
TRWrecord_cache(int num, int key = 1, bool lock=FALSE);
TRWrecord_cache(const char* table, int key = 1, bool lock=FALSE);
virtual ~TRWrecord_cache() ;
};
class TStat_cache : public TRWrecord_cache
{
protected:
virtual const TString & getkey2discard();
public:
TStat_cache (bool lock=FALSE);
virtual ~TStat_cache()
{}
};
#endif