#include "ci2401.h" #include #include #include #include #include #include #include #include #include #include #include #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à 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; }