campo-sirio/sv/sv2100.cpp
guy 6c31e4ce6a Eliminato ricalcolo statistiche in tempo reale. Ora solo batch.
git-svn-id: svn://10.65.10.50/branches/R_10_00@23145 c028cbd2-c16b-5b4b-a496-9718f37d4682
2015-11-30 16:25:09 +00:00

294 lines
7.3 KiB
C++
Executable File
Raw Blame History

#include <applicat.h>
#include <progind.h>
#include "sv2.h"
#include "svlib01.h"
#include "sv2100a.h"
#include "svriep.h"
class TRicalcolo_stats : public TSkeleton_application
{
static TStats_agg _agg;
static TAssoc_array _tipi_doc;
static TDate _datalast;
static bool tipi_stat_filter(const TRelation* r);
protected:
virtual void main_loop();
virtual bool create();
virtual void on_config_change();
public:
static bool datein_handler(TMask_field& f, KEY k);
static bool datefin_handler(TMask_field& f, KEY k);
bool kill_stats(const TDate& dfr, const TDate& dto);
void calc_stats(const TDate& dfr, const TDate& dto);
};
TStats_agg TRicalcolo_stats::_agg;
TDate TRicalcolo_stats::_datalast;
TAssoc_array TRicalcolo_stats::_tipi_doc;
bool TRicalcolo_stats::create()
{
open_files(LF_TABCOM, 0); // File comuni
open_files(LF_TAB, LF_CLIFO, LF_OCCAS, 0); // File ditta
open_files(LF_CFVEN, LF_DOC, LF_RIGHEDOC, 0); // File vendite
return TSkeleton_application::create();
}
void TRicalcolo_stats::on_config_change()
{
_agg.init();
TWait_cursor hourglass;
TISAM_recordset tip("USE %TIP");
const TRectype& rec_tip = tip.cursor()->curr();
for (bool ok = tip.move_first(); ok; ok = tip.move_next())
{
if (rec_tip.get_bool("B2")) // E' un tipo per le statistiche
_tipi_doc.add(rec_tip.get("CODTAB"), NULL);
}
TDate datamin = TDate(TODAY); datamin.set_day(1); datamin.set_month(1);
TISAM_recordset doc("USE DOC KEY 3");
const TRectype& rec_doc = doc.cursor()->curr();
for (bool ok = doc.move_first(); ok; ok = doc.move_next())
{
const TString& tipodoc = rec_doc.get(DOC_TIPODOC);
if (_tipi_doc.is_key(tipodoc))
{
TDate dd = rec_doc.get(DOC_DATADOC);
if (dd.ok())
{
datamin = floor(dd, _agg.frequency());
break;
}
else
{
const int anno = rec_doc.get_int(DOC_ANNO);
if (anno > 1900)
{
datamin = TDate(1, 1, anno);
break;
}
}
}
}
_datalast = ini_get_string(CONFIG_DITTA, "sv", "UltimoCalcolo");
if (_datalast < datamin)
{
_datalast = datamin;
--_datalast;
}
ceil(_datalast, _agg.frequency());
}
bool TRicalcolo_stats::kill_stats(const TDate& dfr, const TDate& dto)
{
TFast_isamfile fdoc(LF_SVRIEP);
TRelation rel(LF_SVRIEP);
TRectype recfrom(LF_SVRIEP), recto(LF_SVRIEP);
if (dfr.ok())
{
recfrom.put(SVR_ANNO, dfr.year());
recfrom.put(SVR_PERIODO, _agg.date2period(dfr));
}
if (dto.ok())
{
recto.put(SVR_ANNO, dto.year());
recto.put(SVR_PERIODO, _agg.date2period(dto));
}
TCursor cur(&rel, "", 1, &recfrom, &recto);
const long items = cur.items();
TProgress_monitor pi(items, TR("Azzeramento statistiche"), false);
cur.freeze();
for (cur = 0; cur.pos() < items; ++cur)
{
pi.add_status();
const int err = rel.remove();
if (err != NOERR)
return error_box(FR("Errore %d durante l'azzeramento archivi"), err);
}
return true;
}
bool TRicalcolo_stats::tipi_stat_filter(const TRelation* r)
{
return _tipi_doc.is_key(r->curr().get(DOC_TIPODOC));
}
void TRicalcolo_stats::calc_stats(const TDate& dfr, const TDate& dto)
{
TFast_isamfile fdoc(LF_DOC);
TRectype recfrom(LF_DOC), recto(LF_DOC);
if (dfr.ok())
{
recfrom.put(DOC_DATADOC, dfr);
recfrom.put(DOC_PROVV, "D");
}
if (dto.ok())
{
recto.put(DOC_DATADOC, dto);
recto.put(DOC_PROVV, "D");
}
TRelation rel(LF_DOC);
TCursor cur(&rel, "PROVV='D'", 3, &recfrom, &recto);
cur.set_filterfunction(tipi_stat_filter);
TRecnotype items = 0;
{
TProgress_monitor pi(1, TR("Selezione documenti"), false);
items = cur.items();
}
cur.freeze();
TString msg; msg << TR("Ricalcolo");
if (dfr.ok())
msg << TR(" dal ") << dfr;
if (dto.ok())
msg << TR(" al ") << dto;
TProgress_monitor pi(items, msg, false);
TRecnotype records = 0;
_agg.reset();
const TRectype& curr = rel.curr();
for (cur = 0; cur.pos() < items; ++cur)
{
pi.add_status();
const TString& tipodoc = curr.get(DOC_TIPODOC);
if (!_tipi_doc.is_key(tipodoc))
continue; // Dovrebbe gi<67> essere filtrato
const TDocumento doc(rel.curr());
const bool nota_cr = doc.tipo().nota_credito();
FOR_EACH_PHYSICAL_RDOC(doc, r, rdoc)
{
if (nota_cr)
_agg.sub(*rdoc);
else
_agg.add(*rdoc);
}
records++;
if (records % 1000 == 0)
{
_agg.update();
TString m; m << msg << '\n' << records << TR(" documenti elaborati");
pi.set_text(m);
xvt_app_process_pending_events();
}
}
_agg.update();
if (_agg.empty())
warning_box(TR("L'archivio riepilogativo delle statistiche ora ricalcolato risulta vuoto"));
}
bool TRicalcolo_stats::datein_handler(TMask_field& f, KEY k)
{
if (f.to_check(k))
{
const TMask& m = f.mask();
const bool def = m.get_bool(F_DEFINITIVE);
const TDate data = f.get();
TDate inizio = data; floor(inizio, _agg.frequency());
if (data != inizio)
f.set(inizio.string());
TDate consiglio = _datalast; ++consiglio;
if (def)
{
if (inizio > consiglio)
return f.error_box(FR("Impossibile effettuare la ricostruzione statistiche\nda una data successiva al %s"), consiglio.stringa());
}
else
{
if (inizio < consiglio)
return f.error_box(FR("Impossibile effettuare la ricostruzione statistiche\nda una data antecedente il %s"), consiglio.stringa());
}
}
return true;
}
bool TRicalcolo_stats::datefin_handler(TMask_field& f, KEY k)
{
if (f.to_check(k))
{
const TMask& m = f.mask();
const TDate inizio = m.get_bool(F_FROMDATE);
const TDate data = f.get();
TDate fine = data; ceil(fine, _agg.frequency());
if (data != fine)
f.set(fine.string());
if (fine <= inizio)
return f.error_box(FR("Impossibile effettuare la ricostruzione statistiche\nfino ad una data antecedente il %s"), inizio.stringa());
}
return true;
}
void TRicalcolo_stats::main_loop()
{
if (argc() >= 3 && xvt_str_same(argv(2), "-A"))
{
TDate dto(TODAY); ceil(dto, _agg.frequency());
TDate dfr = dto; floor(dfr, _agg.frequency());
dfr.addmonth(-12);
if (dfr <= _datalast)
{
dfr = _datalast;
++dfr;
}
if (kill_stats(dfr, dto))
calc_stats(dfr, dto);
}
else
{
TMask m("sv2100a");
m.set_handler(F_FROMDATE, datein_handler);
m.set_handler(F_TODATE, datefin_handler);
if (_datalast.ok())
{
TDate fd = _datalast; ++fd;
m.set(F_FROMDATE, fd);
m.set(F_LASTDATE, _datalast);
}
while (m.run() == K_ENTER)
{
const bool def = m.get_bool(F_DEFINITIVE);
const TDate dfr(m.get(F_FROMDATE));
const TDate dto(m.get(F_TODATE));
if (kill_stats(dfr, def ? TDate() : dto))
calc_stats(dfr, dto);
if (def)
{
_datalast = dto.ok() ? dto : TDate(TODAY);
ini_set_string(CONFIG_DITTA, "sv", "UltimoCalcolo", _datalast);
m.set(F_LASTDATE, _datalast);
}
}
}
}
int sv2100(int argc, char* argv[])
{
TRicalcolo_stats app;
app.run(argc, argv, TR("Ricalcolo statistiche"));
return 0;
}