#include #include #include "../ca/commesse.h" #include "../ca/cdc.h" #include "../ca/fasi.h" #include "rilore.h" #include "ci1350.h" /////////////////////////////////////////////////////////// // Recordset /////////////////////////////////////////////////////////// //recordset per stampe mensili (dettagliate per giorno) TRil_ore_recordset::TRil_ore_recordset() : TAS400_recordset("AS400(512)") { //const char* name, int pos, int len, TFieldtypes t = _alfafld, bool required = false, const TVariant& def = NULL_VARIANT create_field("Key1", -1, 20, _alfafld, true); create_field("Key2", -1, 20, _alfafld, false); create_field("Key3", -1, 10, _alfafld, false); create_field("Des1", -1, 50, _alfafld, true); create_field("Des2", -1, 50, _alfafld, false); create_field("Des3", -1, 50, _alfafld, false); create_field("TotPrev", -1, 7, _realfld, false); create_field("TotCons", -1, 7, _realfld, false); TString4 name; for (int i = 1; i <= 31; i++) { name.format("G%02d", i); create_field(name, -1, 6, _realfld, false); } } /////////////////////////////////////////////////////////// // Recordset /////////////////////////////////////////////////////////// TString_array TRil_ore_cms_recordset::_list; bool TRil_ore_cms_recordset::_ignore; //cerca se la commessa sulla riga di rilore in questione č nella lista.. //..delle commesse da ignorare bool TRil_ore_cms_recordset::cms_cdc_filter(const TRelation* rel) { const TRectype& curr_rec = rel->curr(); const TString& curr_codcms = curr_rec.get(RILORE_CODCMS); FOR_EACH_ARRAY_ROW(_list, r, riga) { const char* lista_codcms = riga->get(0); if (curr_codcms == lista_codcms) return !_ignore; } return _ignore; } void TRil_ore_cms_recordset::set_custom_filter(TCursor& cursor) const { //se la lista non c'č -> niente filtri if (_list.empty()) cursor.set_filterfunction(NULL); else cursor.set_filterfunction(cms_cdc_filter); } /////////////////////////////////////////////////////////////////////////////////////// // Metodi liberi per determinare giorni lavorativi e feriali (nati per ci1300 ci1400) /////////////////////////////////////////////////////////////////////////////////////// bool ci_is_ferial_day(const TDate& data) { return data.wday() < 6 && !data.is_holiday(); } long ci_calcola_giorni_lavorativi(const TDate& dataini, const TDate& datafine) { if (datafine < dataini) return 0L; if (datafine == dataini) return 1L; return datafine - dataini + 1; //per ora viene congeleta la versione figa che considera i ferial day //e qui si parrā l'ultima stilla di nobilitate! deve eliminare i giorni festivi dal mucchio! /*if (num_giorni_lav > 1) { for (TDate data = dataini; data <= datafine; ++data) { if (!ci_is_ferial_day(data)) num_giorni_lav--; } }*/ } void ci_inizio_fine_periodo(const char tipo_stampa, const int anno, const int mese, TDate& inizio_periodo, TDate& fine_periodo) { if (tipo_stampa == 'M') { TDate ini_mese(1, mese, anno); TDate fine_mese = ini_mese; fine_mese.set_end_month(); inizio_periodo = ini_mese; fine_periodo = fine_mese; } else { TDate ini_anno(1, 1, anno); TDate fine_anno(31, 12, anno); inizio_periodo = ini_anno; fine_periodo = fine_anno; } } long ci_calcola_giorni_lavorativi_intersezione(const TDate& ini_1, const TDate& fine_1, const TDate& ini_2, const TDate& fine_2, TDate& ini_int, TDate& fine_int) { if ((fine_1 < ini_2) || (ini_1 > fine_2)) return 0L; ini_int = fnc_max(ini_1, ini_2); fine_int = fnc_min(fine_1, fine_2); return ci_calcola_giorni_lavorativi(ini_int, fine_int); } const TVariant describe_cms(const TString& chiave1) { if (chiave1 == OTHER_ACTIVITIES) return TR("Altre attivita'"); return cache().get(LF_COMMESSE, chiave1, COMMESSE_DESCRIZ); } void ci_fill_recset_from_ass(TAssoc_array& ass, TReport& rep) { //deve informarsi sul tipo di report che č in uso const TString& rep_class = rep.get_class(); const bool per_ris_att = rep_class == "ci1300"; int ordinamento = 0; //richiesta delle variabili di filtro sulla maschera //ca1300 if (per_ris_att) { TVariant var; rep.evaluate("#ORDINAMENTO", var, _intfld); ordinamento = var.as_int(); } //finita l'elaborazione che ha riempito l'assoc_array, asegna il medesimo ad un.. //..csv_recordset e poi sbatte quest'ultimo (ordinato) nel report TRil_ore_recordset* recset = (TRil_ore_recordset*)rep.recordset(); FOR_EACH_ASSOC_OBJECT(ass, obj, key, itm) { //il totale consuntivo va ridistribuito con un TDistrib sui giorni lavorativi TToken_string& record_ass = (TToken_string&)*itm; //aggiunge la riga al recordset recset->new_rec(); //1) valori delle ore // Totale preventivo (lo prende dall'assoc_array e lo butta nel recset appena arrotondato) real totale_p = record_ass.get(0); totale_p.round(2); recset->set("TotPrev", totale_p); // Totale consuntivo (lo prende dall'assoc_array e lo butta nel recset appena arrotondato) real totale_c = record_ass.get(32); totale_c.round(2); recset->set("TotCons", totale_c); //per avere una distribuzione di ore giornaliera che faccia ritornare il totale consuntivo.. //..indipendentemente da arrotondamenti e troncamenti, si ricorre al mitico TGeneric_distrib... TGeneric_distrib esso(totale_c, 2); for (int j = 1; j <= 31; j++) { real ore = record_ass.get(j); esso.add(ore); } // ridistribuzione delle ore per giorno nel recordset TString4 name; for (int k = 1; k <= 31; k++) { const real ore_giorno = esso.get(); name.format("G%02d", k); recset->set(name, ore_giorno); } //2) chiavi delle righe //chiave della riga: dipende dal tipo di report e dai parametri di fordinamento TToken_string chiave = key; TString80 chiave1 = chiave.get(0); TString80 chiave2 = chiave.get(1); TString16 chiave3 = chiave.get(2); recset->set("Key1", chiave1); //se ci1300 ->(cms o cdc) se ci1400 ->(A o R) recset->set("Key2", chiave2); //se ci1300 ->(cdc o cms) se ci1400 ->(codris o codattr) recset->set("Key3", chiave3); //se ci1300 -> fase //report di risorsa / attrezzatura (ci1300) if (per_ris_att) { switch (ordinamento) { case 1: //cms recset->set("Des1", describe_cms(chiave1)); break; case 2: //cms - cdc recset->set("Des1", describe_cms(chiave1)); recset->set("Des2", cache().get(LF_CDC, chiave2, CDC_DESCRIZ)); break; case 3: //cms - fase recset->set("Des1", describe_cms(chiave1)); recset->set("Des2", cache().get(LF_FASI, chiave2, FASI_DESCRIZ)); break; case 4: //cms - cdc - fase recset->set("Des1", describe_cms(chiave1)); recset->set("Des2", cache().get(LF_CDC, chiave2, CDC_DESCRIZ)); recset->set("Des3", cache().get(LF_FASI, chiave3, FASI_DESCRIZ)); break; case 5: //cdc recset->set("Des1", cache().get(LF_CDC, chiave1, CDC_DESCRIZ)); break; case 6: //cdc - cms recset->set("Des1", cache().get(LF_CDC, chiave1, CDC_DESCRIZ)); recset->set("Des2", describe_cms(chiave2)); break; case 7: //cdc - fase recset->set("Des1", cache().get(LF_CDC, chiave1, CDC_DESCRIZ)); recset->set("Des2", cache().get(LF_FASI, chiave2, FASI_DESCRIZ)); break; case 8: //cdc - cms - fase recset->set("Des1", cache().get(LF_CDC, chiave1, CDC_DESCRIZ)); recset->set("Des2", describe_cms(chiave2)); recset->set("Des3", cache().get(LF_FASI, chiave3, FASI_DESCRIZ)); break; } } else //report di commessa / sede (ci1400) { if (chiave1 == "R") //risorsa { recset->set("Des1", "Risorsa"); recset->set("Des2", cache().get("RSS", chiave2, "S0")); } else //attrezzatura { recset->set("Des1", "Attrezzatura"); recset->set("Des2", cache().get("ATR", chiave2, "S0")); } } } //ordina il recordset per chiave recset->sort(); #ifdef DBG recset->save_as("C:/temp/cazzone.txt"); #endif } //formattazione report per stampa mensile dettagliata per giorno void format_report_month(const int anno, const int mese, TReport& rep) { TString16 code; //maggico giro per formattare la testata del calendario di pagina nel report const TDate primo_del_mese(1, mese, anno); TDate ultimo_del_mese = primo_del_mese; ultimo_del_mese.set_end_month(); for (TDate giorno = primo_del_mese; giorno <= ultimo_del_mese; ++giorno) { code.format("H0.%d", giorno.day() + 100); TReport_field* rep_field = rep.field(code); if (rep_field != NULL) { if (!ci_is_ferial_day(giorno)) rep_field->set_back_color(COLOR_LTGRAY); code = itow(giorno.wday()); code.cut(3); code << '\n' << giorno.day(); rep_field->set(code); } } }