campo-sirio/mr/mr1100.cpp
alex c8d2a302e3 Patch level : 02.0.369
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
Riportata la versione AGA 1.7 patch 349


git-svn-id: svn://10.65.10.50/trunk@10708 c028cbd2-c16b-5b4b-a496-9718f37d4682
2002-12-20 16:15:03 +00:00

1040 lines
28 KiB
C++
Executable File

// Applicazione di generazione reports & stampe per MRP
#include <applicat.h>
#include <form.h>
#include <relation.h>
#include <printer.h>
#include <progind.h>
#include "mrplib.h"
#include "../ve/velib.h"
#include "../mg/mglib.h"
#include "mr1.h"
#include "mr1100a.h"
#include <defmask.h>
#include <doc.h>
#include <rdoc.h>
#define LF_MRPREP 132
#define LAST_BUCKET 12
// Tipi di stampa
enum tipo_stampa {
articoli, // produzione articoli nel tempo
linee, // carico linee
scheduling, // scheduling delle linee
available // Tipo di stampa non definita: ordinata per articoli e stampa del carico della linea
};
// I tipi di stampa si identificano secondo la seguente tabella, tramite l'intersezione
// tra l'ordinamento ed il valore impostati:
/*
|----------------------+
|quantita | carico |
-----------+-----------------------
articoli |articoli | available|
-----------+----------------------+
linea |scheduling | linee |
-----------+-----------------------
*/
enum tipo_ordinamento {
articolo,
linea
};
enum tipo_valore {
quantita,
carico
};
enum tipo_dettaglio {
det_articolo,
det_giacenza,
det_impianto,
det_linea
};
///////////////////////////////////////////////////////////
// _TCapacitaLinea, usato per calcolare le capacita' delle linee
///////////////////////////////////////////////////////////
class _TCapacitaLinea : public TObject
{
TArray _cap_min, // Array 1..LAST_BUCKET-1 di capacita' minime
_cap_max; // Array 1..LAST_BUCKET-1 di capacita' massime
public:
TArray& cap_min() { return _cap_min; }
TArray& cap_max() { return _cap_max; }
_TCapacitaLinea() ;
virtual ~_TCapacitaLinea() {}
};
_TCapacitaLinea::_TCapacitaLinea()
{
for (int i = 0; i<LAST_BUCKET-1; i++)
{
_cap_min.add(new real);
_cap_max.add(new real);
}
}
///////////////////////////////////////////////////////////
// TMRP_rep_record
///////////////////////////////////////////////////////////
class TMRP_rep_record : public TObject
{
public:
real _qta;
TMRP_rep_record() { }
};
///////////////////////////////////////////////////////////
// TMRP_rep_record_array;
///////////////////////////////////////////////////////////
class TMRP_rep_record_array : public TObject
{
TArray _buckets;
public:
int items() const { return _buckets.items(); }
int last() const { return _buckets.last(); }
int pred(int i) const { return _buckets.pred(i); }
TMRP_rep_record& operator[](int b);
};
TMRP_rep_record& TMRP_rep_record_array::operator[](int b)
{
CHECKD(b >= 0, "Invalid TMRP_rep_record_array ", b);
TMRP_rep_record* qta = (TMRP_rep_record*)_buckets.objptr(b);
if (qta == NULL)
{
qta = new TMRP_rep_record;
_buckets.add(qta, b);
}
return *qta;
}
///////////////////////////////////////////////////////////
// TMRP_rep_line
///////////////////////////////////////////////////////////
class TMRP_rep_line : public TSortable
{
TCodice_articolo _codart;
TString16 _giac, _imp, _lin, _um;
TMRP_rep_record_array _bucket;
protected:
virtual int compare(const TSortable& s) const;
public:
const TCodice_articolo& codice() const { return _codart; }
const TString& livgiac() const { return _giac; }
const TString& codimp() const { return _imp; }
const TString& codlin() const { return _lin; }
const TString& um() const { return _um; }
int last() const { return _bucket.last(); }
int pred(int i) const { return _bucket.pred(i); }
real& qta(int b) { return _bucket[b]._qta; }
void fill(TRectype& record, TAssoc_array* capacita = NULL);
TMRP_rep_line(const TCodice_articolo& codart,
const TString& giac, const TString& imp,
const TString& lin, const TString& um);
virtual ~TMRP_rep_line() { }
};
void TMRP_rep_line::fill(TRectype& record, TAssoc_array* capacita)
{
record.zero();
record.put("TIPO", "R");
record.put("CODART", _codart);
record.put("LIVELLO", _giac);
record.put("IMPIANTO", _imp);
record.put("LINEA", _lin);
record.put("UM", _um);
TString16 campo;
for (int b = last(); b >= 0; b = pred(b))
{
switch(b)
{
case 0:
campo = "QTAFIRST"; break;
case LAST_BUCKET:
campo = "QTALAST"; break;
default:
campo.format("QTA%d", b); break;
}
record.put(campo, qta(b));
}
if (capacita)
for (b=1; b<LAST_BUCKET; b++)
{
_TCapacitaLinea* cl = (_TCapacitaLinea*)capacita->objptr(_lin);
if (cl)
{
TArray& cmin = cl->cap_min();
TArray& cmax = cl->cap_max();
campo.format("CMIN%d", b);
record.put(campo, (real&)cmin[b-1]); // Capacita' minima...
campo.format("CMAX%d", b);
record.put(campo, (real&)cmax[b-1]); // e massima
}
}
}
int TMRP_rep_line::compare(const TSortable& s) const
{
const TMRP_rep_line& c = (const TMRP_rep_line&)s;
int cmp = _codart.compare(c._codart);
if (cmp == 0)
{
cmp = _giac.compare(c._giac);
if (cmp == 0)
{
cmp = _imp.compare(c._imp);
if (cmp == 0)
{
cmp = _lin.compare(c._lin);
if (cmp == 0)
cmp = _um.compare(c._um);
}
}
}
return cmp;
}
TMRP_rep_line::TMRP_rep_line(const TCodice_articolo& codart,
const TString& giac,
const TString& imp, const TString& lin,
const TString& um)
: _codart(codart), _giac(giac), _imp(imp), _lin(lin), _um(um)
{ }
///////////////////////////////////////////////////////////
// TMRP_rep_lines
///////////////////////////////////////////////////////////
class TMRP_rep_lines : public TMRP_array
{
protected:
virtual TSortable* new_obj(const TToken_string& key) const;
public:
TMRP_rep_line* find(const TCodice_articolo& codart,
const TString& giac, const TString& imp,
const TString& lin, const TString& um,
bool create);
TMRP_rep_line& operator[](long n) const
{ return (TMRP_rep_line&)find_obj(n); }
};
TSortable* TMRP_rep_lines::new_obj(const TToken_string& key) const
{
TCodice_articolo art; key.get(0, art);
TString gia; key.get(1, gia);
TString imp; key.get(2, imp);
TString lin; key.get(3, lin);
TString um ; key.get(4, um);
return new TMRP_rep_line(art, gia, imp, lin, um);
}
TMRP_rep_line* TMRP_rep_lines::find(const TCodice_articolo& codart,
const TString& giac,
const TString& imp,
const TString& lin,
const TString& um,
bool create)
{
_key = codart;
_key.add(giac);
_key.add(imp);
_key.add(lin);
_key.add(um);
TSortable* s = create ? add_obj(_key) : find_obj(_key);
return (TMRP_rep_line*)s;
}
///////////////////////////////////////////////////////////
// MRP report generator mask
///////////////////////////////////////////////////////////
class TRepgen_mask : public TCalendar_mask
{
protected:
void calcola_capacita(TAssoc_array&) const ;
bool test_tipodoc_num( const TSheet_field &sheet_num , const TSheet_field &sheet_type) ;
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
void round_field(TMask_field& fld, bool up) const;
public:
int round_date(TDate& date, bool up) const;
bool elabora() const;
TRepgen_mask();
virtual ~TRepgen_mask() { }
};
bool TRepgen_mask::test_tipodoc_num(const TSheet_field &sheet_num ,const TSheet_field &sheet_type)
{
TString16 tipo;
TString_array& nums = sheet_num.rows_array();
TString_array& types = sheet_type.rows_array();
for (int j = types.items()-1; j >= 0; j--)
{
bool ok=FALSE;
tipo = types.row(j).get(0) ;
for (int i = nums.items()-1; i >= 0; i--)
{
TCodice_numerazione num(nums.row(i).get(0));
for (int n = num.ntipi_doc()-1;n >= 0; n--)
{
const char* t = num.tipo_doc(n);
if (tipo == t)
ok = TRUE;
}
}
if (!ok)
return error_box("Il tipo '%s' non appartiene a nessuna delle numerazioni scelte",(const char*)tipo);
}
return TRUE;
}
int TRepgen_mask::round_date(TDate& date, bool up) const
{
// Dimensione del bucket in giorni
int bucket_size = get_int(F_BUCKET) * 7;
if (bucket_size < 7) bucket_size = 7;
// Riporta la data al primo lunedi prima dell'inizio
TDate inizio = get(F_DADATA);
const int wday = inizio.wday();
if (wday > 1) inizio -= wday-1;
// Calcola il bucket di appartenenza
const int days = int(date - inizio);
const int bucket = days / bucket_size;
if (up) // Arrotonda alla fine del bucket
date = inizio + long((bucket+1) * bucket_size - 1);
else // Arrotonda all'inizio del bucket
date = inizio + long(bucket * bucket_size);
return bucket;
}
void TRepgen_mask::round_field(TMask_field& fld, bool up) const
{
TDate date = fld.get();
if (date.ok())
{
round_date(date, up);
fld.set(date);
}
}
void TRepgen_mask::calcola_capacita(TAssoc_array& capacita) const
{
if (capacita.items() == 0)
return;
const bool carico_uomo = get_bool(F_MANLOAD);
const TDate df(get_date(F_DADATA));
const TDate dt(get_date(F_ADATA));
TDate wd1,wd2;
TString16 codimp;
capacita.restart();
TProgind pi(capacita.items(), "Calcolo capacita linee", FALSE, TRUE);
THash_object* ho = capacita.get_hashobj();
for (;ho != NULL; ho = capacita.get_hashobj())
{
pi.addstatus(1L);
const TString& linea = ho->key();
_TCapacitaLinea& cl = (_TCapacitaLinea&) ho->obj();
TLinea_prod lp(linea);
codimp = lp.codimp();
TMRP_calendar& mc = TMRP_time::get_calendar(codimp, linea);
TArray& cap_min = cl.cap_min();
TArray& cap_max = cl.cap_max();
for (wd1 = df; wd1 <= dt; ++wd1) // Piglia tutte le date nel range! (very, very heavy...)
{
wd2 = wd1;
const int bucket = round_date(wd2, FALSE); // da 0 a 10 al massimo
if (bucket > 10)
break; // Fine
real & v1 = (real&) cap_min[bucket];
v1 += carico_uomo ? mc.add_oreuomo(v1, wd1) : mc.add_oremacchina(v1, wd1);
real & v2 = (real&) cap_max[bucket];
v2 += carico_uomo ? mc.add_oreuomo_max(v2, wd1) : mc.add_oremacchina_max(v2, wd1);
}
}
}
bool TRepgen_mask::elabora() const
{
TRelation rel(LF_RIGHEDOC);
TCursor cur(&rel);
const TRectype& riga = cur.curr();
TRectype filter_fr(riga), filter_to(riga);
const TDate date_fr = get(F_DADATA);
const int year_fr = date_fr.year();
TDate date_to = get(F_ADATA);
const int year_to = date_to.year();
const int bucket_size = get_int(F_BUCKET) * 7;
const TExplosion_grouping raggr = (TExplosion_grouping)get_int(F_RAGGRUM);
const tipo_valore ts = (tipo_valore) get_int(F_VAL2PRINT);
const bool carico_uomo = get_bool(F_MANLOAD);
const int last_bucket = round_date(date_to,TRUE)+1;
TString16 ws;
TDistinta_tree distinta;
TArray lav_array;
TMRP_rep_lines articles;
TAssoc_array capacita;
TString msg;
TSheet_field& numerazioni = sfield(F_NUMERAZIONI);
FOR_EACH_SHEET_ROW(numerazioni, r, row)
{
const TString16 codnum = row->get(0);
// Filtra il cursore in modo da limitarlo alla numerazione
// corrente ed agli anni specificati dalle due date limite
filter_fr.put(RDOC_PROVV, "D");
filter_fr.put(RDOC_CODNUM, codnum);
filter_fr.put(RDOC_ANNO, year_fr);
filter_to.put(RDOC_PROVV, "D");
filter_to.put(RDOC_CODNUM, codnum);
filter_to.put(RDOC_ANNO, year_to);
cur.setregion(filter_fr, filter_to);
const long items = cur.items();
cur.freeze(TRUE);
msg = "Elaborazione numerazione "; msg << codnum;
TProgind pi(items, msg, FALSE, TRUE);
// Scandisce le righe dei documenti
for (cur = 0; cur.pos() < items; ++cur)
{
pi.addstatus(1);
const TCodice_articolo art = riga.get(RDOC_CODARTMAG);
if (art.not_empty())
{
TDate datacons = riga.get(RDOC_DATACONS);
// Seleziona tutte le righe! Altrimenti LAST_BUCKET non viene mai settato
//if (datacons <= date_to)
{
real qta;
if (!riga.get_bool(RDOC_RIGAEVASA))
{
qta = riga.get_real(RDOC_QTA);
qta -= riga.get_real(RDOC_QTAEVASA);
}
// Seleziona le righe articolo non ancora evase
if (qta > ZERO)
{
const TString16 liv = riga.get(RDOC_LIVELLO);
const TString16 imp = riga.get(RDOC_IMPIANTO);
const TString16 lin = riga.get(RDOC_LINEA);
const TCodice_um um = riga.get(RDOC_UMQTA);
TQuantita q(art, um, qta);
int bucket = 0;
if (datacons >= date_fr)
{
bucket = round_date(datacons, FALSE) + 1;
if (bucket > last_bucket)
bucket = LAST_BUCKET;
}
// Calcoli per carico
if (ts == carico)
{
distinta.set_root(riga);
real ore,tot;
TRiga_esplosione * llav = distinta.first_labor(lav_array, raggr);
TLavorazione * lavorazione = TDistinta_tree::find_labor(llav);
while (llav)
{
const int linea = lavorazione->find_linea(lin);
const real prod_linea = lavorazione->produttiv_linea(linea);
ore = (llav->val() * lavorazione->um_temporale().converti_in_ore()) / prod_linea;
if (carico_uomo)
ore *= lavorazione->numpers_linea(linea);
//rep.qta(bucket) += ore;
tot += ore;
llav = distinta.next_labor(lav_array);
}
if (tot > ZERO)
{
TMRP_rep_line& rep = *articles.find(art, liv, imp, lin, ws, TRUE);
rep.qta(bucket) += tot;
}
// Sbatte nella cache le linee di cui dopo calcolera' le capacita' minime e massime
// In modo che il calcolo venga effettuato una volta sola per ogni linea.
if (capacita.objptr(lin) == NULL)
capacita.add(lin, new _TCapacitaLinea); // Vuoto per ora... lo riempie poco piu' giu'
}
else // Produzione articoli nel tempo & scheduling linee
{
TMRP_rep_line& rep = *articles.find(art, liv, imp, lin, q.um(), TRUE);
switch (raggr)
{
case RAGGR_EXP_UMBASE:
q.convert2umbase();
break;
case RAGGR_EXP_UMDIST:
q.convert2umdist();
break;
default: break;
}
rep.qta(bucket) += q.val();
}
}
}
}
}
cur.freeze(FALSE);
}
if (ts == carico && get_bool(F_CAPACITA))
calcola_capacita(capacita);
const long total = articles.items();
TProgind pi(total, "Generazione file", FALSE, TRUE);
TMask_field& fld = field(F_FILENAME);
TFilename filename = fld.get();
if (filename.empty())
filename.temp("mrprep");
fld.set(filename);
filename.insert("%");
TIsamtempfile rep(LF_MRPREP, filename);
// Scrive la testata (Record tipo "H");
rep.put("TIPO","H");
rep.put("CODART", date_fr.string());
rep.put("LIVELLO", get(F_ADATA));
rep.put("IMPIANTO", bucket_size);
rep.put("LINEA", ts == quantita ? "Q" : "C");
rep.write();
for (long i = 0; i < total; i++)
{
pi.addstatus(1);
articles[i].fill(rep.curr(), ts == carico ? &capacita : NULL);
int err = rep.write();
if (err != NOERR)
rep.rewrite();
}
return rep.good();
}
bool TRepgen_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch(o.dlg())
{
case F_DADATA:
if (e == fe_modify)
round_field(o, FALSE);
break;
case F_ADATA:
if (e == fe_modify)
round_field(o, TRUE);
break;
case F_BUCKET:
if (e == fe_modify)
{
round_field(field(F_DADATA), FALSE);
round_field(field(F_ADATA), TRUE);
}
break;
case F_NUMERAZIONI:
if (e == fe_init)
{
TSheet_field& s = (TSheet_field&)o;
if (s.items() == 0)
{
s.row(0);
s.force_update();
}
}
if (e == fe_close)
{
const TSheet_field& s = (const TSheet_field&)o;
FOR_EACH_SHEET_ROW_BACK(s, r, row)
if (!row->empty_items()) return TRUE;
return error_box("E' necessario inserire almeno una numerazione");
}
break;
case F_TIPI:
if (e == fe_init)
{
TSheet_field& s = (TSheet_field&)o;
if (s.items() == 0)
{
s.row(0);
s.force_update();
}
}
if (e == fe_close)
{
const TSheet_field& s = (const TSheet_field&)o;
FOR_EACH_SHEET_ROW_BACK(s, r, row)
if (!row->empty_items())
{
const bool ok=test_tipodoc_num(sfield(F_NUMERAZIONI), s );
return ok;
}
return error_box("E' necessario inserire almeno una riga");
}
break;
case F_YEAR:
case F_IMPIANTO:
case F_LINEA:
if (e == fe_modify)
update_calendar(F_CALENDAR, F_YEAR, F_IMPIANTO, F_LINEA);
break;
case DLG_PRINT:
case DLG_ELABORA:
if (e == fe_button)
{
if (check_fields())
save_profile();
if (o.dlg() == DLG_ELABORA)
elabora();
}
break;
default:
break;
}
return TRUE;
}
TRepgen_mask::TRepgen_mask()
: TCalendar_mask("mr1100a")
{
load_profile();
}
///////////////////////////////////////////////////////////
// MRP Form
///////////////////////////////////////////////////////////
class TMRP_form : public TForm
{
TCodgiac_livelli *_codgiac;
int _level;
protected:
virtual bool validate(TForm_item &, TToken_string &); // gestione dei messaggi estesi nei campi
public:
TMRP_form(const char* name, TCodgiac_livelli* c, int l);
virtual ~TMRP_form() {} ;
};
TMRP_form::TMRP_form(const char* name, TCodgiac_livelli* c, int l) : TForm(name)
{
_codgiac = c;
_level = l;
}
bool TMRP_form::validate(TForm_item &cf, TToken_string &s)
{
const TString code(s.get(0));
if (code == "_MRP")
{
TLocalisamfile& rep = cf.form().cursor()->file();
TString action(s.get(1));
TString livello, descr;
if (action == "DESCRLIV")
{
if (_level > 0)
livello = rep.get("LIVELLO");
if (livello.not_empty())
{
for (int lev=1; lev <= _level; lev++)
{
if (!_codgiac->enabled(lev))
continue;
const int starts = _codgiac->code_start(lev) -1;
const int length = _codgiac->code_length(lev);
descr << "/";
descr << livello.mid(starts,length);
}
descr << " " << _codgiac->name(_level);
descr << " " << _codgiac->group_descr(livello,_level);
}
cf.set(descr);
}
else
if (action == "LOAD")
{
//CALCOLO percentuale carico
// MESSAGE _MRP,LOAD,<id campo1>,<id campo2>
// formula: #id campo1 * 100 / #id campo2
// prende i contenuti dei campi specificati e ne calcola il rapporto % come indicato
real v1(cf.find_field(s.get(2)).get());
real v2(cf.find_field(s.get(3)).get());
v1 *= 100;
if (v2 != ZERO)
v1 /= v2;
if (v1 > ZERO && v1 <= 100.0)
cf.set(v1.string("##@,@@ %"));
else
if (v1 <= ZERO)
cf.set("");
else
cf.set("*****");
}
// Ignore any other command
}
return TForm::validate(cf, s);
}
///////////////////////////////////////////////////////////
// MRP report file generator
///////////////////////////////////////////////////////////
class TMRP_repgen : public TSkeleton_application
{
TRepgen_mask * _m;
TMRP_form * _form;
TLocalisamfile * _mrprep;
TCodgiac_livelli *_codgiac;
int _livello;
tipo_ordinamento _tipo_ord;
tipo_valore _tipo_val;
tipo_dettaglio _dettaglio;
protected:
void set_buckets_description();
void set_buckets();
void set_form();
virtual bool create();
virtual bool destroy();
virtual void main_loop();
public:
TMRP_repgen() { _m = NULL; }
virtual ~TMRP_repgen() {}
};
bool TMRP_repgen::create()
{
_m = new TRepgen_mask;
_mrprep = new TLocalisamfile(LF_MRPREP);
_codgiac = new TCodgiac_livelli;
if (!_codgiac->enabled())
_m->hide(F_LIVDET);
return TSkeleton_application::create();
}
bool TMRP_repgen::destroy()
{
delete _codgiac;
if (_m)
delete _m;
if (_mrprep)
delete _mrprep;
return TSkeleton_application::destroy();
}
void TMRP_repgen::set_buckets_description()
{
TString descr;
TDate fd = _m->get_date(F_DADATA);
TDate td = _m->get_date(F_ADATA);
TConfig ini(CONFIG_DITTA, "mr");
const bool week_complete = ini.get_bool("WEEKCOMPLETE");
int bucket_size = _m->get_int(F_BUCKET) * 7;
if (bucket_size < 7) bucket_size = 7;
int weekd, yeard;
const short first_id = 3;
const short last_id = 15;
--fd;
descr.format("\nAl %s", (const char*)fd);
if (bucket_size == 7)
{
fd.get_week_year(weekd, yeard, week_complete);
descr << "\nSett. " << weekd << ' ' << yeard;
}
_form->find_field('B', odd_page, first_id).set_col_head(descr);
TDate wd;
for (;fd <= td;)
{
++fd;
descr.format("Dal %s\nAl ", (const char*)fd);
fd += bucket_size-1;
wd = fd;
descr << (const char*)fd;
const short id = first_id+_m->round_date(wd,FALSE)+1;
if (id >= last_id)
break;
if (bucket_size == 7)
{
wd.get_week_year(weekd, yeard, week_complete);
descr << "\nSett. " << weekd << ' ' << yeard;
}
_form->find_field('B', odd_page, id).set_col_head(descr);
}
descr.format("Dal %s", (const char*)wd);
if (bucket_size == 7)
{
wd.get_week_year(weekd, yeard, week_complete);
descr << "\n\nSett. " << weekd << ' ' << yeard;
}
_form->find_field('B', odd_page, last_id).set_col_head(descr);
}
void TMRP_repgen::set_buckets()
{
TString tmp;
TDate last_date = _m->get_date(F_ADATA);
// Calcola l'ultimo bucket visibile:
// Il bucket iniziale e quello finale dovrebbero essere sempre visibili
const short last_bucket = _m->round_date(last_date,TRUE)+1;
// Disabilita le colonne in base al numero di buckets da visualizzare
const short first_id = 4; // Bucket 1
const short last_id = 14; // Bucket 11
for (short id = first_id+last_bucket; id <= last_id; id++)
_form->find_field('B',odd_page,id).disable();
// Nella stampa scheduling linee, non esiste un totale per linea/impianto ma per articolo/liv giacenza
for (id = first_id+last_bucket+100; id <= (last_id+100); id++)
_form->find_field('B',odd_page,id).disable();
set_buckets_description();
// Show delle subsections necessarie
TToken_string sections;
const bool tl = _tipo_ord == linea;
switch (_dettaglio)
{
case det_articolo:
sections = tl ? "IMPIANTI|LINEE" : "";
break;
case det_giacenza:
sections = tl ? "IMPIANTI|LINEE|ARTICOLI" : "ARTICOLI";
break;
case det_impianto:
sections = tl ? "" : "ARTICOLI|LIVELLI";
break;
case det_linea:
sections = tl ? "IMPIANTI" : "ARTICOLI|LIVELLI|IMPIANTI";
break;
default: break;
}
const int items = sections.items();
for (int i=0; i<items; i++)
_form->find_field('B', odd_page, sections.get(i)).show();
if ((tl && _dettaglio == det_giacenza) || (!tl && _dettaglio >= det_giacenza))
if (_livello > 0)
{
tmp.format("LIVELLO[1,%d]", _codgiac->packed_length(_livello));
_form->find_field('B', odd_page, "LIVELLI").setcondition(tmp,_strexpr);
}
if (tl && _m->get_bool(F_CAPACITA)) // Abilitato il calcolo capacita/carico linea?
{
_form->find_field('B', odd_page, 238).show();
const short lid = 240 + (last_bucket >= LAST_BUCKET ? 11 : last_bucket);
for (short id = 240; id<lid; id++)
_form->find_field('B', odd_page, id).show();
}
if (tl && _tipo_val == quantita) // Stampa scheduling, disabilita totali per linea/impianto)
{
// Abilita i campi per l'unita di misura sui totali per livello giac. e articolo
_form->find_field('B', odd_page, 2).show();
_form->find_field('B', odd_page, 302).show();
_form->find_field('B', odd_page, 402).show();
_form->find_field('B', odd_page, 502).show();
for (short id = 201; id <= 215; id++)
_form->find_field('B', odd_page, id).hide(); // Riga totale linea
for (id = 101; id <= 115; id++)
_form->find_field('B', odd_page, id).hide(); // Riga totale impianto
}
if (!tl && _tipo_val == carico) // Stampa carico per articoli
{
// Nasconde la colonna delle unita' di misura.
// Il calcolo capacita' non ha senso e quindi viene omesso in
// stampa, sebbene sia possibile effettuarne il calcolo.
_form->find_field('B', odd_page, 2).hide();
_form->find_field('B', odd_page, 102).hide();
_form->find_field('B', odd_page, 202).hide();
_form->find_field('B', odd_page, 302).hide();
_form->find_field('B', odd_page, 402).hide();
}
// Prende il titolo della stampa dal nome profilo
_form->find_field('H', odd_page,4).set(_m->get(DLG_PROFILE));
}
void TMRP_repgen::set_form()
{
TString expr,tmp;
TString from(_m->get(_tipo_ord == articolo ? F_ARTFROM : F_IMPIANTOFROM));
TString to(_m->get(_tipo_ord == articolo ? F_ARTTO : F_IMPIANTOTO));
expr.format("(TIPO==\"R\")");
if (_tipo_ord == articolo)
{
if (from.not_empty())
{
expr << "&&";
tmp.format("(CODART>=\"%s\")",(const char*)from);
expr << tmp;
}
if (to.not_empty())
{
if (expr.not_empty())
expr << "&&";
tmp.format("(CODART<=\"%s\")",(const char*)to);
expr << tmp;
}
}
else
{
if (from.not_empty())
{
expr << "&&";
tmp.format("(IMPIANTO>=\"%s\")",(const char*)from);
expr << tmp;
}
if (to.not_empty())
{
if (expr.not_empty())
expr << "&&";
tmp.format("(IMPIANTO<=\"%s\")",(const char*)to);
expr << tmp;
}
from = _m->get(F_LINEAFROM);
to = _m->get(F_LINEAFROM);
if (from.not_empty())
{
if (expr.not_empty())
expr << "&&";
tmp.format("(LINEA>=\"%s\")",(const char*)from);
expr << tmp;
}
if (to.not_empty())
{
if (expr.not_empty())
expr << "&&";
tmp.format("(LINEA<=\"%s\")",(const char*)to);
expr << tmp;
}
}
if (expr.not_empty()) // Filtronzo... il filtro gonzo
_form->cursor()->setfilter(expr);
set_buckets();
}
void TMRP_repgen::main_loop()
{
while (_m->run() != K_QUIT)
{
const bool use_file = _m->get_bool(F_USAFILE);
if (use_file || _m->elabora())
{
_tipo_ord = (tipo_ordinamento) _m->get_int(F_ORDINAMENTO);
_tipo_val = (tipo_valore) _m->get_int(F_VAL2PRINT);
_livello = _m->get_int(F_LIVDET);
TFilename fname(_m->get(F_FILENAME)); // Presente 24 ore su 24
fname.insert("%"); // e questo dove lo mettiamo?
const bool delfile = !_m->get_bool(F_GENREPORT) && !use_file;
if (delfile)
_m->reset(F_FILENAME);
// Utilizza questo file per la stampa del form
TIsamtempfile * report = new TIsamtempfile(LF_MRPREP,fname, FALSE, delfile);
TRelation* rel;
_dettaglio = (tipo_dettaglio) _m->get_int(_tipo_ord == articolo ? F_DETTAGLIO1 : F_DETTAGLIO2);
_form = new TMRP_form(_tipo_ord == articolo ? "mr1100a" : "mr1100b", _codgiac, _livello);
rel = _form->relation();
rel->replace(report);
set_form();
const int hh = 7;
const int fl = printer().formlen();
int rows[4]; // Righe orizzontali
rows[0] = hh-4;
rows[1] = hh;
rows[2] = fl;
rows[3] = 0;
_form->genera_intestazioni(odd_page, hh-3);
_form->genera_fincatura(odd_page, hh-4, fl, rows);
// stampa
if (_form->cursor()->items() > 0)
_form->print();
// report non va cancellato, poiche' ne viene fatta la sostituzione nella relazione del form
// quindi la delete viene gia' fatta alla distruzione di _form
delete _form;
}
}
}
int mr1100(int argc, char* argv[])
{
TMRP_repgen a;
a.run(argc, argv, "Generazione MRP reports");
return 0;
}