Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione 1.5 fino alla patch 811 git-svn-id: svn://10.65.10.50/trunk@8985 c028cbd2-c16b-5b4b-a496-9718f37d4682
476 lines
14 KiB
C++
Executable File
476 lines
14 KiB
C++
Executable File
#include "mr2200.h"
|
|
#include "mr2200a.h"
|
|
#include "mr2200b.h"
|
|
|
|
void TPlanning_mask::print_exceptions(TExceptions_array &excepts)
|
|
{
|
|
if (excepts.items())
|
|
{
|
|
TPrinter& pr = printer();
|
|
pr.open();
|
|
|
|
pr.setheaderhandler(print_except_header);
|
|
pr.headerlen(6);
|
|
pr.setfooterhandler(print_footer);
|
|
pr.footerlen(2);
|
|
|
|
TString_array keys;
|
|
TToken_string key, lastkey;
|
|
TString tmp;
|
|
excepts.get_keys(keys);
|
|
keys.sort();
|
|
int header=0;
|
|
for (int k=0; k< keys.items(); k++)
|
|
{
|
|
key = keys.row(k);
|
|
key.get(0,tmp);
|
|
if (tmp != lastkey.get(0))
|
|
header = 0;
|
|
else if (key.get(1,tmp)&& tmp != lastkey.get(1))
|
|
header = 0;
|
|
else if (key.get(2,tmp) && tmp != lastkey.get(2))
|
|
header = 1;
|
|
else
|
|
header = 2;
|
|
const TException & e = (const TException &)excepts[key];
|
|
const TMRP_line &line = e.mrpline();
|
|
line.print_exception(e.from(), e.to(), e.qta(), header);
|
|
lastkey = key;
|
|
}
|
|
pr.close();
|
|
}
|
|
}
|
|
|
|
void TPlanning_mask::print_except_header(TPrinter& pr)
|
|
{
|
|
TString format;
|
|
TPrintrow row;
|
|
print_header(pr);
|
|
row.put("@48G@BSTAMPA TABULATO ECCEZIONI DA M.S.P.");
|
|
pr.setheaderline(1,row);
|
|
row.reset();
|
|
row.put((const char *)TString(131,'-'));
|
|
pr.setheaderline(4,row);
|
|
}
|
|
|
|
void TPlanning_mask::print_articles(int from_col, int num_cols, const char * row_filter)
|
|
{
|
|
TString repname("mr2200");
|
|
TSheet_field& sf = sfield(F_ARTICOLI);
|
|
const int nrows=sf.items();
|
|
|
|
TIsamtempfile * report = new TIsamtempfile(LF_MRPREPORT,repname, TRUE, TRUE );
|
|
TString8 codimp,codlin;
|
|
TProgind pi(nrows, format("Stampa %s...",get_bool(F_MSCHEDULEPLAN)?
|
|
"Master Schedule Plan":"pianificazione ordini"));
|
|
char block='\0';
|
|
const int a_buck0 = sf.cid2index(F_BUCKET0);
|
|
for (int r=0; r<nrows; r++)
|
|
{
|
|
if (pi.iscancelled())
|
|
{
|
|
delete report;
|
|
return;
|
|
}
|
|
TToken_string &row=sf.row(r);
|
|
TRectype &record=report->curr();
|
|
record.put("TIPO", " ");
|
|
if (sf.cell_disabled(r, a_buck0 +2))
|
|
{
|
|
if (r<nrows-1 && sf.cell_disabled(r+1, a_buck0 +2))
|
|
{
|
|
if (row_filter==NULL || *row_filter=='\0' || strchr(row_filter,'C'))
|
|
{
|
|
record.zero(' ');
|
|
record.put("TIPO", "C");
|
|
}
|
|
} else {
|
|
if (row_filter==NULL || *row_filter=='\0' || strchr(row_filter,'G'))
|
|
record.put("TIPO", "G");
|
|
}
|
|
} else {
|
|
if (row_filter==NULL || *row_filter=='\0' || strchr(row_filter,'C'))
|
|
record.put("TIPO", "R");
|
|
else
|
|
record.put("TIPO", "c");
|
|
}
|
|
record.put("RIGA", r);
|
|
record.put("TIPOCF", row.get(sf.cid2index(F_TIPOCF_SHEET)));
|
|
record.put("CODCLI", row.get(sf.cid2index(F_CLIENTE)));
|
|
record.put("CODART", row.get(sf.cid2index(F_ARTICOLO)));
|
|
TString16 liv;
|
|
livelli_giacenza().pack_grpcode(liv, row.get(sf.cid2index(F_LIV1)),1);
|
|
livelli_giacenza().pack_grpcode(liv, row.get(sf.cid2index(F_LIV2)),2);
|
|
livelli_giacenza().pack_grpcode(liv, row.get(sf.cid2index(F_LIV3)),3);
|
|
livelli_giacenza().pack_grpcode(liv, row.get(sf.cid2index(F_LIV4)),4);
|
|
record.put("LIVELLO", liv);
|
|
record.put("IMPIANTO", row.get(sf.cid2index(F_CODIMP)));
|
|
record.put("LINEA", row.get(sf.cid2index(F_CODLIN)));
|
|
// record.put("CODMAG", row.get(sf.cid2index(F_LIVELLO)));
|
|
record.put("UM", row.get(sf.cid2index(F_UM)));
|
|
TString16 campo;
|
|
bool somevalue = 0;
|
|
for (int nbucket = LAST_BUCKET; nbucket >= 0; nbucket--)
|
|
{
|
|
switch(nbucket)
|
|
{
|
|
case 0:
|
|
campo = "QTAFIRST"; break;
|
|
case LAST_BUCKET:
|
|
campo = "QTALAST"; break;
|
|
default:
|
|
campo.format("QTA%d", nbucket); break;
|
|
}
|
|
record.put(campo, row.get(sf.cid2index(F_BUCKET0+nbucket*2)));
|
|
if (!record.get_real(campo).is_zero())
|
|
somevalue++;
|
|
}
|
|
if (record.get("TIPO")!="" && (somevalue || strchr(row_filter,'G')))
|
|
report->write();
|
|
pi.addstatus(1);
|
|
}
|
|
TMSP_form form(report);
|
|
// stampa
|
|
if (form.cursor()->items() > 0)
|
|
{
|
|
TDate fd(starting_date());
|
|
TDate td = get_date(F_ADATA);
|
|
const short first_id = 3;
|
|
const short last_id = 14;
|
|
|
|
if (num_cols == 0)
|
|
num_cols = last_id - first_id;
|
|
if (num_cols > 11)
|
|
num_cols = 11;
|
|
|
|
for (int c=0; c<14; c++)
|
|
{
|
|
if (c<from_col || c>=from_col+num_cols)
|
|
form.find_field('B', odd_page, first_id+c).hide();
|
|
}
|
|
|
|
short b = -1;
|
|
--fd;
|
|
TString descr;
|
|
descr.format("Fino\nal %s", (const char*)fd);
|
|
form.find_field('B', odd_page, first_id).set_col_head(descr);
|
|
for (;fd <= td;)
|
|
{
|
|
++b;
|
|
++fd;
|
|
descr.format("Da %s\nAl ",(const char*)fd);
|
|
round_date(fd,TRUE,FALSE);
|
|
descr << fd.string();
|
|
if (first_id+b+1 > last_id)
|
|
continue;
|
|
form.find_field('B', odd_page, first_id+b+1).set_col_head(descr);
|
|
}
|
|
++td;
|
|
descr.format("Dal %s", (const char*)td);
|
|
if (b == LAST_BUCKET)
|
|
form.find_field('B', odd_page, first_id+b+1).set_col_head(descr);
|
|
const int hh = 7;
|
|
const int fl = printer().formlen();
|
|
|
|
int rows[4]; // Righe orizzontali
|
|
rows[0] = hh-3;
|
|
rows[1] = hh;
|
|
rows[2] = fl;
|
|
rows[3] = 0;
|
|
|
|
form.genera_intestazioni(odd_page, hh-2);
|
|
form.genera_fincatura(odd_page, hh-3, fl, rows);
|
|
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
|
|
}
|
|
|
|
void TPlanning_mask::print_capacities()
|
|
{
|
|
TString repname("mr2200");
|
|
TSheet_field& sf = sfield(F_LINEE);
|
|
const int nrows=sf.items();
|
|
|
|
TIsamtempfile * report = new TIsamtempfile(LF_MRPREPORT,repname, TRUE, FALSE );
|
|
TString8 codimp,codlin;
|
|
TString codart;
|
|
TProgind pi(nrows, format("Stampa %s...",(*get(F_LOADTYPE)=='M')?
|
|
"carico macchina":"carico uomo"));
|
|
const int a_buck0 = sf.cid2index(F_LBUCKET0);
|
|
char block='\0';
|
|
for (int r=0; r <nrows ; r++)
|
|
{
|
|
if (pi.iscancelled())
|
|
return;
|
|
TToken_string &row=sf.row(r);
|
|
TRectype &record=report->curr();
|
|
record.zero(' ');
|
|
codimp=row.get(sf.cid2index(F_CODIMPCRP));
|
|
codlin=row.get(sf.cid2index(F_CODLINCRP));
|
|
codart=row.get(sf.cid2index(F_CODARTCRP));
|
|
record.put("RIGA", r);
|
|
record.put("IMPIANTO", codimp);
|
|
record.put("LINEA", codlin);
|
|
record.put("CODART", codart);
|
|
char type('D');
|
|
if (!codart.blank())
|
|
type = 'A';
|
|
else if (!codlin.blank())
|
|
type = 'L';
|
|
else if (!codimp.blank())
|
|
type = 'I';
|
|
const bool is_capacity = sf.cell_disabled(r, a_buck0 +2);
|
|
if (!is_capacity)
|
|
type = tolower(type);
|
|
record.put("TIPO",type);
|
|
// record.put("TIPOCF", row.get(sf.cid2index(F_TIPOCF_SHEET)));
|
|
// record.put("CODCLI", row.get(sf.cid2index(F_CLIENTE)));
|
|
record.put("UM", row.get(sf.cid2index(F_LUM)));
|
|
TString16 campo;
|
|
for (int b = LAST_BUCKET; b >= 0; b--)
|
|
{
|
|
switch(b)
|
|
{
|
|
case 0:
|
|
campo = "QTAFIRST"; break;
|
|
case LAST_BUCKET:
|
|
campo = "QTALAST"; break;
|
|
default:
|
|
campo.format("QTA%d", b);
|
|
}
|
|
record.put(campo, row.get(sf.cid2index(F_LBUCKET0+b*2)));
|
|
}
|
|
report->write();
|
|
pi.addstatus(1);
|
|
}
|
|
// delete report;
|
|
// TIsamtempfile * report = new TIsamtempfile(LF_MRPREPORT,repname, FALSE, FALSE );
|
|
TCRP_form form(report);
|
|
// 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
|
|
}
|
|
|
|
|
|
bool TPlanning_mask::find_exceptions(TExceptions_array &e, bool anticipi, bool posticipi, bool extra, bool stockbreak, bool codemiss, bool verbose)
|
|
{
|
|
|
|
e.destroy();
|
|
if (!get_bool(F_RESCHEDULING))
|
|
{
|
|
_mrp_articles.destroy();
|
|
if (verbose)
|
|
message_box("Rescheduling non abilitato");
|
|
}
|
|
else if (load_MRP_lines(_rescheduling))
|
|
{
|
|
const TSheet_field& sf = sfield(F_ARTICOLI);
|
|
const int bucket1 = sf.cid2index(F_BUCKET1);
|
|
// PER OGNI ARTICOLO ...
|
|
const long max_mrp_rows=_mrp_articles.items();
|
|
TProgind pi=((max_mrp_rows+1)*LAST_BUCKET ,"Ricerca eccezioni...", TRUE, TRUE);
|
|
for (long mrp_row=0; mrp_row < max_mrp_rows; mrp_row++)
|
|
{
|
|
pi.addstatus(1);
|
|
if (pi.iscancelled())
|
|
return FALSE;
|
|
TMRP_line &mrpline=_mrp_articles[mrp_row];
|
|
mrpline.find_ad_excepts(anticipi, posticipi, e);
|
|
if (extra)
|
|
mrpline.find_extra_excepts(get_bool(F_NUMBERBYWEEK)||get_bool(F_NUMBERBYCLI), e);
|
|
} // ... for each article
|
|
}
|
|
if (verbose && e.items()<=0)
|
|
message_box("Nessuna eccezione rilevata");
|
|
return e.items()>0;
|
|
}
|
|
|
|
|
|
TObject* TException::dup() const
|
|
{
|
|
return new TException(_mrpline, _from, _to, _q);
|
|
}
|
|
|
|
TException::TException(const TMRP_line * line, int from, int to, const real & q) :
|
|
_mrpline(line), _from(from), _to(to), _q(q)
|
|
{}
|
|
|
|
|
|
TExceptions_array::add(const TException & e)
|
|
{
|
|
return add((TException *)e.dup());
|
|
}
|
|
|
|
TExceptions_array::add(TException * e)
|
|
{
|
|
const TMRP_line & line = e->mrpline();
|
|
TToken_string key;
|
|
key.add(line.articolo());
|
|
key.add(line.livgiac());
|
|
key.add(format("%04d",e->from()));
|
|
key.add(format("%04d",e->from()==e->to() ? 9999 : e->to()));
|
|
key.add(line.codimp());
|
|
key.add(line.codlin());
|
|
key.add(line.codmagdep());
|
|
key.add(line.codmagdep_coll());
|
|
return TAssoc_array::add((const char *)key, e);
|
|
}
|
|
|
|
void TMRP_line::reset_excepts()
|
|
{
|
|
// PER OGNI BUCKET ...
|
|
int last(last_bucket()), first=0;
|
|
for (int nbucket = 0; nbucket <= last; nbucket++)
|
|
{
|
|
TMRP_record& mrprec = record(nbucket);
|
|
real ro=mrprec.resched_orders();
|
|
real uo=mrprec.unsched_orders();
|
|
if (!ro.is_zero())
|
|
mrprec.add_resched_ord(-ro);
|
|
if (!uo.is_zero());
|
|
mrprec.add_unsched_ord(-uo);
|
|
} // ... for each bucket
|
|
}
|
|
|
|
bool TMRP_line::find_ad_excepts(bool anticipi, bool posticipi, TExceptions_array &e)
|
|
{
|
|
bool some=FALSE;
|
|
real totplan,movable,diff;
|
|
// PER OGNI BUCKET ...
|
|
int last(last_bucket()), first=0;
|
|
for (int nbucket = 0; nbucket <= last; nbucket++)
|
|
{
|
|
const real & sr=sched_receipts(nbucket);
|
|
const real & ro=resched_orders(nbucket);
|
|
const real & uo=unsched_orders(nbucket);
|
|
const real & pl=planned_orders(nbucket);
|
|
totplan = planned_orders(nbucket) - sched_receipts(nbucket) - resched_orders(nbucket) + unsched_orders(nbucket);
|
|
if (totplan.sign() > 0)
|
|
{
|
|
for (int pivot = first; totplan.sign() > 0 && pivot <= last; pivot++) if (nbucket != pivot)
|
|
{
|
|
const real & sr=sched_receipts(pivot);
|
|
const real & ro=resched_orders(pivot);
|
|
const real & uo=unsched_orders(pivot);
|
|
const real & pl=planned_orders(pivot);
|
|
movable = sched_receipts(pivot);
|
|
// vecchia logica : posticipo solo se non devo poi ripianificare il pivot
|
|
//if (nbucket > pivot)
|
|
// nuova logica: posticipo o anticipo solo se non devo poi ripianificare il pivot
|
|
movable -= planned_orders(pivot);
|
|
movable -= unsched_orders(pivot);
|
|
if (movable.sign() > 0) //
|
|
{
|
|
first = pivot;
|
|
diff = fnc_min(movable, totplan);
|
|
add_unsched_ord(pivot, diff);
|
|
add_resched_ord(nbucket, diff);
|
|
totplan -= diff;
|
|
movable -= diff;
|
|
if (pivot > nbucket && anticipi || pivot < nbucket && posticipi)
|
|
{
|
|
e.add(new TException(this, pivot, nbucket, diff));
|
|
some = TRUE;
|
|
}
|
|
}
|
|
if (movable.sign() <= 0) //
|
|
first++;
|
|
} // ..look for available sched. receipts to move
|
|
}
|
|
} // ... for each bucket
|
|
return some;
|
|
}
|
|
|
|
bool TMRP_line::find_extra_excepts(bool fixdoc, TExceptions_array &e)
|
|
{
|
|
bool some=FALSE;
|
|
real totplan,movable,diff;
|
|
// PER OGNI BUCKET ...
|
|
for (int nbucket = 1; nbucket <= last_bucket(); nbucket++)
|
|
{
|
|
const real & gr=gross_requirement(nbucket);
|
|
const real & sr=sched_receipts(nbucket);
|
|
const real & ro=resched_orders(nbucket);
|
|
const real & uo=unsched_orders(nbucket);
|
|
const real & pl=planned_orders(nbucket);
|
|
totplan = planned_orders(nbucket) - sched_receipts(nbucket) - resched_orders(nbucket) + unsched_orders(nbucket);
|
|
bool ex = totplan.sign() < 0; // troppa roba
|
|
if (totplan.sign() > 0 && fixdoc) //
|
|
ex = sr>0;
|
|
if (ex)
|
|
{
|
|
diff = -totplan;
|
|
e.add(new TException(this, nbucket, nbucket, diff));
|
|
some = TRUE;
|
|
}
|
|
} // ... for each bucket
|
|
return some;
|
|
}
|
|
|
|
void TMRP_line::print_exception(int from, int to, const real &diff, int header) const
|
|
{
|
|
TPrinter& pr = printer();
|
|
if (!pr.isopen())
|
|
pr.open();
|
|
TPrintrow prow;
|
|
|
|
TToken_string code(articolo());
|
|
TDate fromdate=time(from).date();
|
|
TDate todate=time(to).date();
|
|
if (header <= 0)
|
|
{
|
|
pr.print(prow);
|
|
prow.put(format("@bArticolo %s %s", (const char *)articolo(), (const char *)cache().get(LF_ANAMAG, code).get(ANAMAG_DESCR)));
|
|
pr.print(prow);
|
|
prow.reset();
|
|
if (livelli_giacenza().enabled())
|
|
{
|
|
int pos=0;
|
|
for (int l= 1; l <= livelli_giacenza().last_level(); l++)
|
|
{
|
|
prow.put(format("@%dg%s %s",pos,(const char *)livelli_giacenza().name(l),
|
|
(const char *)livgiac(l)));
|
|
pos += livelli_giacenza().name(l).len()+1;
|
|
pos += livgiac(l).len()+1;
|
|
}
|
|
pr.print(prow);
|
|
prow.reset();
|
|
}
|
|
}
|
|
if (header <= 1)
|
|
{
|
|
prow.put(format("Ordini emessi con scadenza entro il @41g%s", (const char *)fromdate.string()));
|
|
pr.print(prow);
|
|
prow.reset();
|
|
// stampa dettaglio ordini
|
|
TMRP_docrefs * docrefs = record(from).scheduls_refs();
|
|
CHECK(docrefs,"Errore: rischedulazione senza riferimenti");
|
|
const int nrefs=docrefs->items();
|
|
for (int nref = 0; nref < nrefs; nref++)
|
|
{
|
|
TMRP_docref & docref = docrefs->get_ref(nref);
|
|
prow.put(format("@2gDocumento %s %4d n.%8ld riga %d %s %s",
|
|
(const char *)docref.codnumdoc(),docref.annodoc(),docref.numdoc(),docref.numrig(),
|
|
(const char *)docref.qta_residua().string(18,3),(const char *)docref.um()));
|
|
pr.print(prow);
|
|
prow.reset();
|
|
}
|
|
}
|
|
code.add("1");
|
|
TString um =cache().get(LF_UMART,code).get("UM");
|
|
real v = abs(diff);
|
|
prow.put(format("@2g%s %s %s", (from == to) ?
|
|
(diff.sign()>0 ? "Eliminare " : "Aggiungere " ):
|
|
(from < to ? "Posticipare" : "Anticipare "),
|
|
(const char *)v.string(18,3), (const char *)um));
|
|
if (from != to)
|
|
{
|
|
prow.put(format("@38gal %s", (const char *)todate.string()));
|
|
}
|
|
pr.print(prow);
|
|
}
|
|
|