campo-sirio/at/at3300.cpp

740 lines
19 KiB
C++
Raw Normal View History

#include <applicat.h>
#include <mask.h>
#include <printer.h>
#include <progind.h>
#include <real.h>
#include <relation.h>
#include <tabutil.h>
#include <urldefid.h>
#include <utility.h>
#include "at3.h"
// nomi campi maschera
#include "at3300a.h"
// nomi dei campi
#include "soggetti.h"
#include "atstats.h"
#include "sezioni.h"
// classe per la definizione di una riga di statistica
class TRigaSxCat : public TObject
{
TString16 _catdon;
TArray _valori;
protected:
const TRigaSxCat& copy(const TRigaSxCat& riga);
public:
const TString16 catdon() const { return _catdon; }
TObject* dup() const { return new TRigaSxCat(*this); }
const TRigaSxCat& operator = (const TRigaSxCat& riga);
const real& operator [] (int colonna) const;
void aggiorna_valore(int colonna, const real& numero) ;
void azzera_valori();
// costruttore
TRigaSxCat(TString16 catdon) {_catdon = catdon;}
// costruttore di copia
TRigaSxCat(const TRigaSxCat& riga) { copy(riga); }
virtual ~TRigaSxCat() {};
};
const TRigaSxCat& TRigaSxCat::copy(const TRigaSxCat& riga)
{
_catdon = riga._catdon;
_valori = riga._valori;
return (*this);
}
const TRigaSxCat& TRigaSxCat::operator = (const TRigaSxCat& riga)
{
copy(riga);
return (*this);
}
const real& TRigaSxCat::operator [] (int colonna) const
{
real* valore = (real*)_valori.objptr(colonna);
if (valore == NULL)
return ZERO;
else
return *valore;
}
void TRigaSxCat::aggiorna_valore(int colonna, const real& numero)
{
real* valore = (real*)_valori.objptr(colonna);
if (valore == NULL)
_valori.add(new real(numero), colonna);
else
*valore += numero;
}
void TRigaSxCat::azzera_valori()
{
_valori.destroy();
}
class TStatSogxCat : public TApplication
{
TMask* _msk;
TRelation* _rel;
TCursor* _cur;
TLocalisamfile* _sezioni;
TLocalisamfile* _soggetti;
TLocalisamfile* _atstats;
TAssoc_array* _colonne;
TAssoc_array* _categorie;
TAssoc_array _categmsk;
TArray _righe;
TString16 _sezini, _sotini, _sezfin, _sotfin, _gruppoazie;
TDate _dataini, _datafin;
bool _solotot, _pergruppo;
int _sezionistampate;
static bool filter_func_statxcat(const TRelation* rel);
protected:
virtual bool create();
virtual bool destroy();
virtual bool menu(MENU_TAG m);
virtual TMask& get_mask() { return *_msk; }
virtual TRelation* get_relation() const { return _rel; }
int data2row(const TString16 catdon);
bool riepilogo();
bool stampa();
bool crea_colonne();
bool crea_righe();
void azzera_righe();
void stampa_sezione(TString16 codsez, TString16 codsot);
void crea_intestazione();
public:
TStatSogxCat() {}
};
HIDDEN inline TStatSogxCat& app() { return (TStatSogxCat&) main_app(); }
int TStatSogxCat::data2row(const TString16 catdon)
{
real& indicer = (real&)_categorie->find((const char*) catdon);
return ((int) indicer.integer());
}
bool TStatSogxCat::filter_func_statxcat(const TRelation* rel)
{
bool filtrato = TRUE;
TLocalisamfile& sog = rel->lfile(LF_SOGGETTI);
// filtro per categorie
TAssoc_array& categorie = app()._categmsk;
if (categorie.items() != 0)
{
const TString16 cat = sog.get(SOG_CATDON);
filtrato = categorie.is_key((const char*) cat);
}
return filtrato;
}
bool TStatSogxCat::crea_colonne()
{
_colonne->destroy();
real contatore(ZERO);
real* oggetto = new real(contatore);
const char* indice = "N"; // nuovi
_colonne->add(indice,(TObject*)oggetto);
indice = "T"; // totale
contatore = contatore+1;
real* oggetto2 = new real(contatore);
_colonne->add(indice,(TObject*)oggetto2);
return TRUE;
}
bool TStatSogxCat::crea_righe()
{
TTable ctd("CTD");
TString16 catdon = "**";
int indice = 0;
_categorie->destroy();
real* oggetto1 = new real(indice);
_categorie->add((const char*) catdon, (TObject*) oggetto1);
_righe.add(new TRigaSxCat(catdon), indice);
for (ctd.first(); !ctd.eof(); ctd.next())
{
catdon = ctd.get("CODTAB");
if ((_categmsk.is_key((const char*) catdon)) || (_categmsk.items()==0))
{
indice++;
_righe.add(new TRigaSxCat(catdon), indice);
real* oggetto = new real(indice);
_categorie->add((const char*) catdon,(TObject*) oggetto);
}
}
return _righe.items()>0;
}
bool TStatSogxCat::create()
{
TApplication::create();
_msk = new TMask("at3300a");
_rel = new TRelation(LF_SOGGETTI);
_soggetti = new TLocalisamfile(LF_SOGGETTI);
_atstats = new TLocalisamfile(LF_ATSTATS);
_sezioni = new TLocalisamfile(LF_SEZIONI);
_colonne = new TAssoc_array();
_categorie = new TAssoc_array();
dispatch_e_menu(BAR_ITEM(1));
return TRUE;
}
bool TStatSogxCat::destroy()
{
delete _categorie;
delete _colonne;
delete _sezioni;
delete _atstats;
delete _soggetti;
delete _rel;
delete _msk;
return TApplication::destroy();
}
bool TStatSogxCat::menu(MENU_TAG m)
{
TMask& msk = get_mask();
KEY tasto;
tasto = msk.run();
if (tasto == K_ENTER)
{
_sezini = _msk->get(F_SEZINI);
_sotini = _msk->get(F_SOTINI);
_sezfin = _msk->get(F_SEZFIN);
_sotfin = _msk->get(F_SOTFIN);
_dataini = _msk->get_date(F_DATAINI);
_datafin = _msk->get_date(F_DATAFIN);
_pergruppo = _msk->get_bool(F_PERGRUPPO);
_gruppoazie = _msk->get(F_GRUPPOAZIE);
_solotot = msk.get_bool(F_SOLOTOT);
if (riepilogo())
stampa();
}
return FALSE;
}
void TStatSogxCat::crea_intestazione()
{
TPrintrow row;
TString256 sep;
sep = "STATISTICA SOGGETTI PER CATEGORIA";
sep.center_just(80);
row.put(sep);
row.put("@>", 1);
row.put("Pag. @#", 70);
printer().setheaderline(2, row);
sep = "dal ";
sep << _dataini.string();
sep << " al ";
sep << _datafin.string();
sep.center_just(80);
row.reset();
row.put(sep);
printer().setheaderline(3, row);
sep = "";
sep << "Categoria Nuovi Totale";
row.reset();
row.put(sep);
printer().setheaderline(5, row);
sep = "";
sep.fill('-',80);
row.reset();
row.put(sep);
printer().setheaderline(6, row);
}
bool TStatSogxCat::stampa()
{
if (printer().open())
{
_sezionistampate = 0;
crea_intestazione();
TRelation* relstat = new TRelation(LF_ATSTATS);
TCursor* curstat = new TCursor(relstat, "", 1);
TString16 oldsez = "**";
TString16 oldsot = "**";
double numero, numero2;
TString16 actsez, actsot;
TString16 catdon;
long last = curstat->items();
for ( *curstat=0; curstat->pos() < last; ++(*curstat) )
{
actsez = curstat->curr().get(ATSS_CODSEZ);
actsot = curstat->curr().get(ATSS_CODSOT);
catdon = curstat->curr().get(ATSS_CATDON);
numero = (double)curstat->curr().get_long(ATSS_NUMERO);
numero2 = (double)curstat->curr().get_long(ATSS_NUMERO2);
if (actsez != oldsez || actsot != oldsot)
{
if (oldsez != "**" && oldsot != "**")
{
stampa_sezione(oldsez,oldsot);
azzera_righe();
}
oldsez = actsez;
oldsot = actsot;
}
if (catdon.empty())
catdon = "**";
TRigaSxCat& riga = (TRigaSxCat&)_righe[data2row(catdon)];
const char* indicen = "N";
real& colonnan = (real&)_colonne->find(indicen);
real n = numero;
riga.aggiorna_valore((int) colonnan.integer(),n);
const char* indicet = "T";
real& colonnat = (real&)_colonne->find(indicet);
n = numero2;
riga.aggiorna_valore((int) colonnat.integer(),n);
}
if (oldsez != "**" && oldsot != "**")
stampa_sezione(oldsez,oldsot);
delete curstat;
delete relstat;
printer().close();
return TRUE;
}
else
return FALSE;
}
void TStatSogxCat::azzera_righe()
{
TString16 catdon = "**";
int indice = data2row(catdon);
TRigaSxCat& riga = (TRigaSxCat&)_righe[indice];
riga.azzera_valori();
TTable ctd("CTD");
for (ctd.first(); !ctd.eof(); ctd.next())
{
catdon = ctd.get("CODTAB");
if ((_categmsk.is_key((const char*) catdon)) || (_categmsk.items()==0))
{
indice = data2row(catdon);
TRigaSxCat& riga = (TRigaSxCat&)_righe[indice];
riga.azzera_valori();
}
}
}
void TStatSogxCat::stampa_sezione(TString16 codsez, TString16 codsot)
{
TPrintrow row;
TString256 rigastampa;
if (codsez == "ZZ" && codsot == "ZZ")
{
if (_sezionistampate != 1)
{
rigastampa = "";
rigastampa << "RIEPILOGO TOTALE SEZIONI DA " << _sezini << '/' << _sotini << " A " << _sezfin << '/' << _sotfin;
if (_pergruppo)
rigastampa << " - SOLO GRUPPI AZIENDALI";
}
}
else
{
_sezionistampate++;
if (_pergruppo)
{
rigastampa = "Gruppo aziendale ";
rigastampa << codsez;
rigastampa << codsot;
}
else
{
rigastampa = "Sezione: ";
rigastampa << codsez;
if (codsot.not_empty())
{
rigastampa << "/";
rigastampa << codsot;
}
rigastampa << " ";
TLocalisamfile sezioni(LF_SEZIONI);
sezioni.setkey(1);
sezioni.zero();
sezioni.put(SEZ_CODSEZ,codsez);
sezioni.put(SEZ_CODSOT,codsot);
if (sezioni.read() == NOERR)
{
TString80 den = sezioni.get(SEZ_DENSEZ);
rigastampa << den;
den = sezioni.get(SEZ_DENSOT);
if (den.not_empty())
{
rigastampa << "/";
rigastampa << den;
}
}
}
}
if ((codsez == "ZZ" && codsot == "ZZ" && _sezionistampate != 1) || (codsez != "ZZ"))
{
rigastampa.center_just(80);
row.put(rigastampa);
printer().setheaderline(1, row);
TRigaSxCat rigatotali(" ");
TString16 valore;
TString16 catdon;
TTable ctd("CTD");
for (ctd.first(); !ctd.eof(); ctd.next())
{
TString16 catdon = ctd.get("CODTAB");
if ((_categmsk.is_key((const char*) catdon)) || (_categmsk.items()==0))
{
TRigaSxCat& riga = (TRigaSxCat&)_righe[data2row(catdon)];
row.reset();
rigastampa = "";
rigastampa << catdon;
rigastampa << " ";
rigastampa << ctd.get("S0");
int pos = 41;
const char* indicen = "N";
real& colonnan = (real&)_colonne->find(indicen);
rigatotali.aggiorna_valore((int) colonnan.integer(),riga[(int) colonnan.integer()]);
valore = "";
valore.format("%8ld",riga[(int) colonnan.integer()].integer());
rigastampa.overwrite((const char*)valore, pos);
pos = pos+8;
const char* indicet = "T";
real& colonnat = (real&)_colonne->find(indicet);
rigatotali.aggiorna_valore((int) colonnat.integer(),riga[(int) colonnat.integer()]);
valore = "";
// valore.format("%8ld",riga[(int) colonnat.integer()].integer());
valore = riga[(int) colonnat.integer()].string("####.###");
rigastampa.overwrite((const char*)valore, pos);
pos = pos+8;
row.put((const char*) rigastampa);
printer().print(row);
}
}
// stampa totali per sezione
rigastampa = "";
rigastampa.fill('-',80);
row.reset();
row.put(rigastampa);
printer().print(row);
row.reset();
rigastampa = "";
rigastampa = "Totale";
int pos = 41;
const char* indicen = "N";
real& colonnan = (real&)_colonne->find(indicen);
valore = "";
valore.format("%8ld",rigatotali[(int) colonnan.integer()].integer());
rigastampa.overwrite((const char*)valore, pos);
pos = pos+8;
const char* indicet = "T";
real& colonnat = (real&)_colonne->find(indicet);
valore = "";
valore.format("%8ld",rigatotali[(int) colonnat.integer()].integer());
rigastampa.overwrite((const char*)valore, pos);
pos = pos+8;
row.put((const char*) rigastampa);
printer().print(row);
printer().formfeed();
}
}
bool TStatSogxCat::riepilogo()
{
_categmsk.destroy();
const TString16 catpri = _msk->get(F_CAT1);
const TString16 catsec = _msk->get(F_CAT2);
const TString16 catter = _msk->get(F_CAT3);
const TString16 catqua = _msk->get(F_CAT4);
const TString16 catqui = _msk->get(F_CAT5);
const TString16 catses = _msk->get(F_CAT6);
if (catpri.not_empty())
_categmsk.add((const char*) catpri);
if (catsec.not_empty())
_categmsk.add((const char*) catsec);
if (catter.not_empty())
_categmsk.add((const char*) catter);
if (catqua.not_empty())
_categmsk.add((const char*) catqua);
if (catqui.not_empty())
_categmsk.add((const char*) catqui);
if (catses.not_empty())
_categmsk.add((const char*) catses);
if (crea_colonne() && crea_righe())
{
// cancello i risultati della elaborazione precedente
TLocalisamfile stat(LF_ATSTATS);
for (stat.first(); !stat.eof(); stat.next())
stat.remove();
stat.setkey(1);
_cur = new TCursor(_rel, "", 1);
TString256 filtro = "";
// filtro per sezione/sottogruppo
if (_sezini.not_empty())
{
if (_sotini.not_empty())
{
filtro << "(";
filtro << format("(90->CODSEZ > \"%s\")",(const char*)_sezini);
filtro << " || ";
filtro << "(" << format("(90->CODSEZ == \"%s\")",(const char*)_sezini);
filtro << " && ";
filtro << format("(90->CODSOT >= \"%s\")",(const char*)_sotini);
filtro << ")";
filtro << ")";
}
else
filtro << format("(90->CODSEZ >= \"%s\")",(const char*)_sezini);
}
if (_sezfin.not_empty())
{
if (filtro.not_empty())
filtro << " && ";
if (_sotfin.not_empty())
{
filtro << "(";
filtro << format("(90->CODSEZ < \"%s\")",(const char*)_sezfin);
filtro << " || ";
filtro << "(" << format("(90->CODSEZ == \"%s\")",(const char*)_sezfin);
filtro << " && ";
filtro << format("(90->CODSOT <= \"%s\")",(const char*)_sotfin);
filtro << ")";
filtro << ")";
}
else
filtro << format("(90->CODSEZ <= \"%s\")",(const char*)_sezfin);
}
if (_pergruppo)
{
if (filtro.not_empty())
filtro << " && ";
if (_gruppoazie.not_empty())
filtro << format("(90->GRUPPOAZIE == \"%s\")",(const char*)_gruppoazie);
else
filtro << format("(90->GRUPPOAZIE != \"\")");
}
_cur->setfilter((const char*) filtro, TRUE);
_cur->set_filterfunction(filter_func_statxcat);
TString16 codsez, codsot, gruppoazie;
long numero,numero2;
TString16 catdon, cati, catd;
TDate dataisc, datadim;
bool nuovoi, totalei, nuovod, totaled;
TTable ctd("CTD");
TRectype& recsog = _cur->curr();
long last = _cur->items();
TProgind prg (last, "Elaborazione in corso... Prego attendere", FALSE, TRUE, 30);
for ( *_cur=0; _cur->pos() < last; ++(*_cur) )
{
prg.addstatus(1);
nuovoi = FALSE;
totalei = FALSE;
nuovod = FALSE;
totaled = FALSE;
if (_pergruppo)
{
gruppoazie = recsog.get(SOG_GRUPPOAZIE);
codsez = gruppoazie.sub(0,2);
codsot = gruppoazie.sub(2,4);
}
else
{
codsez = recsog.get(SOG_CODSEZ);
codsot = recsog.get(SOG_CODSOT);
}
catdon = recsog.get(SOG_CATDON);
cati = "";
catd = "";
if (catdon.not_empty())
{
ctd.put("CODTAB",catdon);
if (ctd.read() == NOERR)
{
bool dimissione = ctd.get_bool("B0");
if (dimissione)
{
catd = catdon;
datadim = recsog.get_date(SOG_DATADIM);
nuovod = (datadim >= _dataini && datadim <= _datafin);
totaled = (datadim <= _datafin);
cati = ctd.get("S6");
// aggiungere la ricerca della vera categoria di partenza in base al numero donazioni (e al fatto che sia stata o meno stampata la tessera)
dataisc = recsog.get_date(SOG_DATAISC);
nuovoi = (dataisc >= _dataini && dataisc <= _datafin);
totalei = (dataisc <= _datafin && datadim > _datafin);
}
else
{
cati = catdon;
dataisc = recsog.get_date(SOG_DATAISC);
nuovoi = (dataisc >= _dataini && dataisc <= _datafin);
totalei = (dataisc <= _datafin);
}
}
}
if (cati.not_empty() && (_categmsk.is_key((const char *) cati) || _categmsk.items()==0))
{
if (!_solotot)
{
stat.zero();
stat.put(ATSS_CODSEZ, codsez);
stat.put(ATSS_CODSOT, codsot);
stat.put(ATSS_CATDON, cati);
if (stat.read() == NOERR)
{
numero = stat.get_long(ATSS_NUMERO);
numero2 = stat.get_long(ATSS_NUMERO2);
if (nuovoi)
numero++;
if (totalei)
numero2++;
stat.put(ATSS_NUMERO, numero);
stat.put(ATSS_NUMERO2, numero2);
stat.rewrite();
}
else
{
stat.put(ATSS_CODSEZ, codsez);
stat.put(ATSS_CODSOT, codsot);
stat.put(ATSS_CATDON, cati);
if (nuovoi)
numero = 1;
else
numero = 0;
if (totalei)
numero2 = 1;
else
numero2 = 0;
stat.put(ATSS_NUMERO, numero);
stat.put(ATSS_NUMERO2, numero2);
stat.write();
}
}
stat.zero();
stat.put(ATSS_CODSEZ, "ZZ");
stat.put(ATSS_CODSOT, "ZZ");
stat.put(ATSS_CATDON, cati);
if (stat.read() == NOERR)
{
numero = stat.get_long(ATSS_NUMERO);
numero2 = stat.get_long(ATSS_NUMERO2);
if (nuovoi)
numero++;
if (totalei)
numero2++;
stat.put(ATSS_NUMERO, numero);
stat.put(ATSS_NUMERO2, numero2);
stat.rewrite();
}
else
{
stat.put(ATSS_CODSEZ, "ZZ");
stat.put(ATSS_CODSOT, "ZZ");
stat.put(ATSS_CATDON, cati);
if (nuovoi)
numero = 1;
else
numero = 0;
if (totalei)
numero2 = 1;
else
numero2 = 0;
stat.put(ATSS_NUMERO, numero);
stat.put(ATSS_NUMERO2, numero2);
stat.write();
}
}
if (catd.not_empty() && (_categmsk.is_key((const char *) catd) || _categmsk.items()==0))
{
if (!_solotot)
{
stat.zero();
stat.put(ATSS_CODSEZ, codsez);
stat.put(ATSS_CODSOT, codsot);
stat.put(ATSS_CATDON, catd);
if (stat.read() == NOERR)
{
numero = stat.get_long(ATSS_NUMERO);
numero2 = stat.get_long(ATSS_NUMERO2);
if (nuovod)
numero++;
if (totaled)
numero2++;
stat.put(ATSS_NUMERO, numero);
stat.put(ATSS_NUMERO2, numero2);
stat.rewrite();
}
else
{
stat.put(ATSS_CODSEZ, codsez);
stat.put(ATSS_CODSOT, codsot);
stat.put(ATSS_CATDON, catd);
if (nuovod)
numero = 1;
else
numero = 0;
if (totaled)
numero2 = 1;
else
numero2 = 0;
stat.put(ATSS_NUMERO, numero);
stat.put(ATSS_NUMERO2, numero2);
stat.write();
}
}
stat.zero();
stat.put(ATSS_CODSEZ, "ZZ");
stat.put(ATSS_CODSOT, "ZZ");
stat.put(ATSS_CATDON, catd);
if (stat.read() == NOERR)
{
numero = stat.get_long(ATSS_NUMERO);
numero2 = stat.get_long(ATSS_NUMERO2);
if (nuovod)
numero++;
if (totaled)
numero2++;
stat.put(ATSS_NUMERO, numero);
stat.put(ATSS_NUMERO2, numero2);
stat.rewrite();
}
else
{
stat.put(ATSS_CODSEZ, "ZZ");
stat.put(ATSS_CODSOT, "ZZ");
stat.put(ATSS_CATDON, catd);
if (nuovod)
numero = 1;
else
numero = 0;
if (totaled)
numero2 = 1;
else
numero2 = 0;
stat.put(ATSS_NUMERO, numero);
stat.put(ATSS_NUMERO2, numero2);
stat.write();
}
}
}
return (stat.eod() > 0);
}
else
return FALSE;
}
int at3300(int argc, char* argv[])
{
TStatSogxCat a;
a.run(argc, argv, "Statistica soggetti per categoria");
return 0;
}