campo-sirio/ci/ci2401.cpp
guy c3d63f12b2 Esportazione rilevazione ore a paghe
git-svn-id: svn://10.65.10.50/branches/R_10_00@23073 c028cbd2-c16b-5b4b-a496-9718f37d4682
2015-04-30 09:42:59 +00:00

747 lines
20 KiB
C++
Raw Blame History

#include "ci2401.h"
#include <automask.h>
#include <colors.h>
#include <diction.h>
#include <golem.h>
#include <progind.h>
#include <recarray.h>
#include <relation.h>
#include <reputils.h>
#include <textset.h>
#include <toolfld.h>
#include <urldefid.h>
#include "ci2400a.h"
////////////////////////////////////////////////////////////////////////////
// Recordset per paghe Zucchetti
////////////////////////////////////////////////////////////////////////////
class TRP_set : public TAS400_recordset
{
public:
bool find_or_create(const TString& risorsa);
bool load(const TFilename& filename);
bool find(const long matricola);
TRP_set(int ditta, int filiale);
};
bool TRP_set::find(const long mat)
{
if (mat > 0)
{
for (bool good = move_first(); good; good = move_next())
if (get("MATRICOLA").as_int() == mat)
return true;
}
return false;
}
bool TRP_set::find_or_create(const TString& risorsa)
{
const TRectype& rss = cache().get("RSS", risorsa);
const long num_mat = atol(rss.get("S3").mid(4, 6));
bool found = false;
if (num_mat > 0)
{
found = find(num_mat);
if (!found)
{
new_rec("");
found = move_last();
set("MATRICOLA", num_mat);
TString80 descr = rss.get("S0"); descr.strip_double_spaces();
const int spc = descr.find(' ');
if (spc > 0)
{
set("COGNOME", descr.left(min(spc, 34)));
set("NOME", descr.mid(spc+1, 34));
}
else
set("COGNOME", descr);
}
}
return found;
}
bool TRP_set::load(const TFilename& filename)
{
bool done = load_file(filename);
if (done)
_query = filename;
return done;
}
TRP_set::TRP_set(int ditta, int filiale) : TAS400_recordset("AS400(1707)")
{
create_field("DITTA" , 0, 4, _intzerofld, true, (long)ditta);
create_field("FILIALE", -1, 2, _intzerofld, true, (long)filiale);
create_field("SIGLA", -1, 3, _alfafld, true, "RP ");
create_field("MATRICOLA", -1, 6, _longzerofld, true);
create_field("COGNOME", -1, 34, _alfafld, true);
create_field("NOME", -1, 34, _alfafld, true);
create_field("DATAINI", -1, 6, _longfld, true);
create_field("DATAFIN", -1, 6, _longfld, true);
TString16 fld;
for (int gg = 1; gg <= 31; gg++)
{
fld.format("ORE_ORDIN_%02d", gg);
create_field(fld, -1, 4, _intzerofld);
for (int i = 1; i <= 6; i++)
{
fld.format("SIGLA_PRES%d_%02d", i, gg);
create_field(fld, -1, 2, _alfafld);
fld.format("SOMMA_ORDIN%d_%02d", i, gg);
create_field(fld, -1, 1, _alfafld);
fld.format("STAMPA_MESS%d_%02d", i, gg);
create_field(fld, -1, 1, _alfafld);
fld.format("ORE_GIUST%d_%02d", i, gg);
create_field(fld, -1, 4, _intzerofld);
}
}
}
////////////////////////////////////////////////////////////////////////////
// Recordset per Excel
////////////////////////////////////////////////////////////////////////////
class TRP_xlset : public TCSV_recordset
{
public:
TRP_xlset(TRP_set& rp);
};
static int rp_cmp(const TObject** o1, const TObject** o2)
{
TToken_string& s1 = *(TToken_string*)*o1;
TToken_string& s2 = *(TToken_string*)*o2;
return s1.get_long(0) - s2.get_long(0);
}
TRP_xlset::TRP_xlset(TRP_set& rp) : TCSV_recordset("")
{
create_column("MATRICOLA", _intfld);
create_column("COGNOME", _alfafld);
create_column("NOME", _alfafld);
create_column("Totale", _realfld);
create_column("Ordinarie", _realfld);
for (bool ok = rp.move_first(); ok; ok = rp.move_next())
{
TToken_string data(127, separator());
for (int i = 0; i < 3; i++)
{
const char* name = column_info(i)._name;
data.add(rp.get(name).as_string());
}
TString16 fld;
for (int gg = 1; gg <= 31; gg++)
{
fld.format("ORE_ORDIN_%02d", gg);
real ord = rp.get(fld).as_real();
if (!ord.is_zero())
{
ord /= CENTO;
real tot = data.get(4);
tot += ord;
data.add(tot.string(), 4);
}
for (int i = 1; i <= 6; i++)
{
fld.format("SIGLA_PRES%d_%02d", i, gg);
const TString4 sigla = rp.get(fld).as_string();
if (sigla.blank())
break;
unsigned int col = 0;
for (col = columns()-1; col > 4; col--)
{
if (column_info(col)._name == sigla)
break;
}
if (col <= 4)
{
create_column(sigla, _realfld);
col = columns()-1;
}
fld.format("ORE_GIUST%d_%02d", i, gg);
const real qta = rp.get(fld).as_real();
if (!qta.is_zero())
{
real ore = data.get(col);
ore += qta / CENTO;
data.add(ore.string(), col);
}
}
}
real tot;
for (unsigned col = columns()-1; col > 3; col--)
tot += real(data.get(col));
data.add(tot.string(), 3);
new_rec(data);
}
sort(rp_cmp);
}
////////////////////////////////////////////////////////////////////////////
// Maschera edit
////////////////////////////////////////////////////////////////////////////
class TEdit_mask : public TAutomask
{
TRP_set& _ps;
TString_array _tipi;
bool _ris_dirty;
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
bool save_if_dirty_ris();
void load_ris();
bool save_ris();
void select_ris(bool by_name);
public:
TEdit_mask(TRP_set& ps);
};
inline bool is_red_day(const TDate& d)
{ return d.wday() >= 6 || d.is_holiday(); }
void TEdit_mask::load_ris()
{
const long dataini = _ps.get("DATAINI").as_int(); // 010115
const long datafin = _ps.get("DATAFIN").as_int(); // 310115
const int anno = 2000 + dataini % 100;
const int mese = dataini / 100 % 100;
set(F_ANNO, anno);
set(F_MESE, mese);
set(F_CODRIS, _ps.get("MATRICOLA").as_int());
set(F_DESRIS, _ps.get("COGNOME").as_string());
TSheet_field& s = sfield(F_SHEET);
short tot_id = 102;
const TMask& sm = s.sheet_mask();
for (tot_id = 108; sm.id2pos(tot_id) > 0; tot_id++);
tot_id --;
s.hide();
s.destroy();
TToken_string row;
TString16 fld;
const int ug = datafin/10000; // Ultimo giorno
for (int gg = 1; gg <= ug; gg++)
{
fld.format("ORE_ORDIN_%02d", gg);
real totale = _ps.get(fld).as_int();
if (!totale.is_zero())
{
totale /= CENTO;
row = totale.string();
}
else
row.cut(0);
for (int i = 1; i <= 6; i++)
{
fld.format("SIGLA_PRES%d_%02d", i, gg);
const TString& tipo = _ps.get(fld).as_string();
if (tipo.full())
{
const int idx = _tipi.find(tipo);
if (idx >= 0 && short(102+idx) < tot_id)
{
fld.format("ORE_GIUST%d_%02d", i, gg);
real ore = _ps.get(fld).as_int();
if (!ore.is_zero())
{
ore /= CENTO;
row.add(ore.string(), idx+1);
totale += ore;
}
}
}
}
if (!totale.is_zero())
row.add(totale.string(), s.cid2index(tot_id));
s.rows_array().add(row);
const TDate d(gg, mese, anno);
if (is_red_day(d))
s.set_back_and_fore_color(REQUIRED_BACK_COLOR, NORMAL_COLOR, gg-1);
else
{
TDate ieri = d; --ieri;
TDate domani = d; ++domani;
if (is_red_day(ieri) && is_red_day(domani))
s.set_back_and_fore_color(EASY_RIDER_COLOR, NORMAL_COLOR, gg-1);
}
}
s.force_update();
s.show();
enable(DLG_SAVEREC, _ris_dirty = false);
}
void TEdit_mask::select_ris(bool by_name)
{
if (save_if_dirty_ris())
{
const long cur_mat = get_long(F_CODRIS);
const char* header = by_name ? HR("Cognome@34|Nome@34|Matricola@8R") : HR("Matricola@8R|Cognome@34|Nome@34");
TArray_sheet a(-1, 3, 0, -3, TR("Selezione risorse"), header);
for (bool good = _ps.move_first(); good; good = _ps.move_next())
{
TToken_string row;
TString8 zmat; zmat.format("%06ld", _ps.get("MATRICOLA").as_int());
if (!by_name)
row.add(zmat);
row.add(_ps.get("COGNOME").as_string());
row.add(_ps.get("NOME").as_string());
if (by_name)
row.add(zmat);
a.add(row);
}
a.rows_array().sort();
for (int i = a.items()-1; i >= 0; i--)
{
const long mat = a.row(i).get_long(by_name ? 2 : 0);
if (mat == cur_mat)
{
a.select(i);
break;
}
}
if (a.run() == K_ENTER)
{
TToken_string& row = a.row(a.selected());
const long matricola = row.get_long(by_name ? 2 : 0);
if (_ps.find(matricola))
load_ris();
}
}
}
bool TEdit_mask::save_ris()
{
const long matricola = get_long(F_CODRIS);
if (!_ps.find(matricola))
{
TString msg;
msg << TR("Matricola sconosciuta ") << matricola;
return cantread_box(msg);
}
ini_set_int(CONFIG_DITTA, "ci", "RILPRE_RIS", matricola);
TSheet_field& s = sfield(F_SHEET);
short last_id = 102;
const TMask& sm = s.sheet_mask();
for (last_id = 108; sm.id2pos(last_id) > 0; last_id++);
last_id -= 2; // Identificatore dell'ultimo tipo ora
TString16 fld;
real ore;
FOR_EACH_SHEET_ROW(s, r, row)
{
const int gg = r+1;
row->get(0, ore);
ore *= CENTO;
fld.format("ORE_ORDIN_%02d", gg);
_ps.set(fld, ore.integer());
// Azzera straordinari preesistenti
int og = 1;
for (og = 1; og <= 6; og++)
{
fld.format("SIGLA_PRES%d_%02d", og, gg);
_ps.set(fld, EMPTY_STRING);
fld.format("ORE_GIUST%d_%02d", og, gg);
_ps.set(fld, 0L);
}
og = 1;
for (int i = 0; i < _tipi.items() && og <= 6; i++)
{
const short id = 102+i;
if (id > last_id)
break;
row->get(i+1, ore);
if (!ore.is_zero())
{
ore *= CENTO;
const TString& tipo_ora = _tipi.row(i);
fld.format("SIGLA_PRES%d_%02d", og, gg);
_ps.set(fld, tipo_ora);
fld.format("ORE_GIUST%d_%02d", og, gg);
_ps.set(fld, ore.integer());
og++;
}
}
}
const TFilename fn = _ps.query_text();
bool done = fn.exist() && _ps.save_as(fn);
if (done)
enable(DLG_SAVEREC, _ris_dirty = false);
else
cantwrite_box(fn);
return done;
}
bool TEdit_mask::save_if_dirty_ris()
{
bool ok = true;
if (_ris_dirty)
{
const KEY k = yesnocancel_box(TR("La risorsa risulta modificata:\nSi desidera salvarla prima di continuare?"));
if (k == K_YES)
save_ris();
ok = k != K_ESC;
}
return ok;
}
bool TEdit_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case DLG_SAVEREC:
if (e == fe_button && _ris_dirty)
save_ris();
break;
case DLG_FIRSTREC:
if (e == fe_button && save_if_dirty_ris())
{
_ps.move_first();
load_ris();
}
return false;
case DLG_PREVREC:
if (e == fe_button && save_if_dirty_ris())
{
_ps.move_prev();
load_ris();
}
return false;
case DLG_FINDREC:
if (e == fe_button)
select_ris(true);
return false;
case DLG_NEXTREC:
if (e == fe_button && save_if_dirty_ris())
{
_ps.move_next();
load_ris();
}
return false;
case DLG_LASTREC:
if (e == fe_button && save_if_dirty_ris())
{
_ps.move_last();
load_ris();
}
return false;
case F_CODRIS:
if (e == fe_button)
select_ris(false);
if (e == fe_modify && save_if_dirty_ris())
{
const long mat = atol(o.get());
if (_ps.find(mat))
load_ris();
else
return error_box("Matricola inesistente");
}
break;
case F_DESRIS:
if (e == fe_button)
select_ris(true);
break;
case F_SHEET:
if (e == se_query_del || e == se_query_add)
return false;
if (e == se_notify_modify)
enable(DLG_SAVEREC, _ris_dirty = true);
if (e == fe_close)
return save_if_dirty_ris();
break;
default: break;
}
return true;
}
TEdit_mask::TEdit_mask(TRP_set& ps) : TAutomask("ci2400e"), _ps(ps), _ris_dirty(false)
{
TSheet_field& s = sfield(F_SHEET);
TISAM_recordset ore("USE &ORE");
for (bool good = ore.move_first(); good; good = ore.move_next())
{
const TString4 codice = ore.get("S1").as_string().left(2);
if (codice.full())
{
const TString& tipo = ore.get("S6").as_string();
if (tipo.full() && _tipi.find(codice) < 0)
_tipi.add(codice);
}
}
_tipi.sort();
short last_id = 102;
const TMask& sm = s.sheet_mask();
for (last_id = 108; sm.id2pos(last_id) > 0; last_id++);
last_id -= 2;
int i = 0;
short id = 102;
for (i = 0; id <= last_id; i++, id++)
{
if (i < _tipi.items())
{
const TString& t = _tipi.row(i);
s.set_column_header(i+1, t);
TEdit_field& f = sm.efield(id);
f.set_prompt(t);
}
else
s.enable_column(id, false);
}
const long mat = ini_get_int(CONFIG_DITTA, "ci", "RILPRE_RIS");
if (_ps.find(mat) || _ps.move_first())
load_ris();
else
error_box(TR("Formato file paghe non valido"));
}
////////////////////////////////////////////////////////////////////////////
// Maschera parametri
////////////////////////////////////////////////////////////////////////////
class TPaghe_mask : public TAutomask
{
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
TPaghe_mask();
};
bool TPaghe_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case F_ANNO:
case F_MESE:
if (e == fe_init || e == fe_modify)
{
TFilename n = get(121);
TString16 f; f.format("RP%4d%02d.txt", get_int(F_ANNO), get_int(F_MESE));
n.add(f);
enable(DLG_EDIT, n.exist());
} else
if (e == fe_close)
{
const int anno = get_int(F_ANNO);
const int mese = get_int(F_MESE);
if (anno < 2000 || mese < 1)
return error_box(TR("Specificare un anno ed un mese validi"));
}
break;
case DLG_EDIT:
if (e == fe_button)
{
TFilename n = get(121);
TString16 f; f.format("RP%4d%02d.txt", get_int(F_ANNO), get_int(F_MESE));
n.add(f);
TRP_set ps(1030, 1);
if (ps.load(n))
{
TEdit_mask em(ps);
em.run();
}
else
cantread_box(n);
}
break;
case DLG_EXPORT:
if (e == fe_button)
{
TFilename n = get(121);
TString16 f; f.format("RP%4d%02d.txt", get_int(F_ANNO), get_int(F_MESE));
n.add(f);
TRP_set ps(1030, 1);
if (ps.load(n))
{
TRP_xlset xls(ps);
n.ext("xls");
if (xls.save_as(n, fmt_html))
goto_url(n);
}
}
break;
default: break;
}
return true;
}
TPaghe_mask::TPaghe_mask() : TAutomask(TR("Esportazione ore"), 1, 64, 7)
{
add_button_tool(DLG_OK, PR("Esporta"), TOOL_ELABORA);
add_button_tool(DLG_EDIT, PR("Modifica"), TOOL_EDIT);
add_button_tool(DLG_EXPORT, PR("Excel"), TOOL_EXCEL);
add_button_tool(DLG_CANCEL, "", TOOL_CANCEL);
add_number(F_ANNO, 0, PR("Anno "), 1, 1, 4).check_type(CHECK_REQUIRED);
add_list (F_MESE, 0, PR("Mese "), 21, 1,12, "M");
add_number(111, 0, PR("Ditta "), 1, 2, 4, "Z").check_type(CHECK_REQUIRED); // 1030
add_number(112, 0, PR("Filiale "), 21, 2, 2, "Z").check_type(CHECK_REQUIRED); // 01
add_string(121, 0, PR("Cartella "), 1, 3, 260, "", 50).check_type(CHECK_REQUIRED);
add_boolean(113, 0, TR("Esportazione completa (comprese ore gi<67> esportate)"), 1, 4);
set_handlers();
}
////////////////////////////////////////////////////////////////////////////
// Procedura esportazione
////////////////////////////////////////////////////////////////////////////
bool esportazione_paghe(int anno, int mese)
{
TPaghe_mask m;
m.set(F_ANNO, anno);
m.set(F_MESE, mese);
int ditta = 1030, filiale = 1;
m.set(111, ini_get_int(CONFIG_DITTA, "ci", "RILPRE_DIT", ditta));
m.set(112, ini_get_int(CONFIG_DITTA, "ci", "RILPRE_FIL", filiale));
TFilename n; n.tempdir();
m.set(121, ini_get_string(CONFIG_DITTA, "ci", "RILPRE_DIR", n));
if (m.run() != K_ENTER)
return false;
const bool all = m.get_bool(113);
ini_set_int (CONFIG_DITTA, "ci", "RILPRE_DIT", ditta = m.get_int(111));
ini_set_int (CONFIG_DITTA, "ci", "RILPRE_FIL", filiale = m.get_int(112));
ini_set_string(CONFIG_DITTA, "ci", "RILPRE_DIR", n = m.get(121));
TString16 f; f.format("RP%4d%02d.txt", anno, mese);
if (n.blank() || !n.exist())
n.tempdir();
n.add(f);
const TDate dal(1, mese, anno);
TDate al(dal); al.set_end_month();
TString query;
query << "USE RILORE KEY 2"
<< "\nSELECT (TIPORA='R')";
if (!all) // Export all?
query << "&&(INVPAG!='X')";
query << "\nFROM TIPO=C DADATA=" << dal << "\nTO TIPO=C DADATA=" << al;
TISAM_recordset ore(query);
TRP_set rp(ditta, filiale);
if (!all)
rp.load(n);
TString_array tipi;
TLog_report log(TR("Esportazione ore"));
log.kill_duplicates();
TLocalisamfile& file = ore.cursor()->file();
const TRectype& curr = file.curr();
const TRecnotype tot = ore.items();
TString msg;
if (tot > 0)
{
msg.format(FR("Elaborazione di %ld rilevazioni dal %s al %s"), tot, dal.stringa(), al.stringa());
log.log(0, msg);
TProgress_monitor pi(tot, log.title());
for (bool go = ore.move_first(); go; go = ore.move_next())
{
const TString4 tpora = curr.get("TPORA");
const TRectype& tpore = cache().get("&ORE", tpora);
const TString4 tipo_ora = tpore.get("S1").left(2); // Codice esterno Zucchetti
if (tipo_ora.blank())
{
msg.format("Tipo ora '%s' non codificata per l'esportazione", (const char*)tpora);
log.log(1, msg);
continue; // Ignora ora non codificata
}
const real qta = curr.get_real("QTAORE") * CENTO;
if (qta<=ZERO)
continue;
const TString8 matricola = curr.get("CODICE");
if (!rp.find_or_create(matricola))
{
msg.format(FR("Risorsa '%s' priva del numero di matricola"), (const char*)matricola);
log.log(2, msg);
continue;
}
rp.set("DATAINI", dal.string(brief, '\0'));
rp.set("DATAFIN", al.string(brief, '\0'));
const int gg = curr.get_date("DADATA").day();
int i = 0; // ore ordinarie
TString16 fld;
const TString& tipologia = tpore.get("S6");
if (tipologia.blank()) // ordinari
fld.format("ORE_ORDIN_%02d", gg);
else
{
for (i = 1; i <= 6; i++)
{
fld.format("SIGLA_PRES%d_%02d", i, gg);
TString4 to = rp.get(fld).as_string();
if (to.blank())
rp.set(fld, to = tipo_ora);
if (to == tipo_ora)
break;
}
fld.format("ORE_GIUST%d_%02d", i, gg);
}
if (i <= 6)
{
long val = rp.get(fld).as_int();
val += qta.integer();
rp.set(fld, val);
file.put("INVPAG", true);
file.rewrite();
}
else
log.log(2, TR("Si possono esportare al massimo 6 tipi ora lo stesso giorno"));
}
}
msg.format(FR("Sono state generate %ld righe"), rp.items());
log.log(0, msg);
log.preview();
bool done = !rp.empty();
if (done)
{
done = rp.save_as(n);
if (done)
message_box(FR("E' stato generato il file %s con %ld record."), (const char*)n, rp.items());
else
error_box(FR("Impossibile generare il file %s"), (const char*)n);
}
return done;
}