campo-sirio/ci/ci1350.cpp

297 lines
8.9 KiB
C++
Raw Normal View History

#include <diction.h>
#include <relation.h>
#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 <20> 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'<27> -> 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<72> 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 <20> 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);
}
}
}