Patch level : 12.0 412

Files correlati     : mr2.exe mr2100a.msk

Aggiunto ordinamento per data fornitore articolo.
Aggiunto filtro per articolo.
Gestite le varianti  bisogna :
1) mettere la variante nello stesso documento
2) con la stessa quantità
3) spuntare separa i figli.



git-svn-id: svn://10.65.10.50/branches/R_10_00@23880 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
bonazzi 2017-06-27 18:19:00 +00:00
parent 9b80ad9a7a
commit 15a91761d2
4 changed files with 473 additions and 132 deletions

View File

@ -220,6 +220,7 @@ TMRP_line& TMRP_line::operator=(const TMRP_line & a)
_codimp=a._codimp;
_codlin=a._codlin;
_codclifor=a._codclifor;
_da_doc_key=a._da_doc_key;
_da_rdoc_key=a._da_rdoc_key;
// contents
_descr=a._descr;
@ -443,6 +444,7 @@ TMRP_lines & TMRP_lines::operator= (const TMRP_lines &a)
_ignore_imp=a._ignore_imp;
_ignore_lin=a._ignore_lin;
_ignore_key=a._ignore_key;
_key=a._key;
return *this;
}
@ -500,6 +502,79 @@ TMRP_line* TMRP_lines::find(const TCodice_articolo& codart, const TString& gia,
_key.add(rdoc_key,7);
TSortable* s = create ? add_obj(_key) : find_obj(_key);
if (create)
((TMRP_line *) s)->set_da_rdoc_key(rdoc_key);
return (TMRP_line*)s;
}
TMRP_line* TMRP_lines::create(const TCodice_articolo& codart, const TString& gia,
const TString& mag, const TString& magc,
const TString& imp, const TString& lin,
long codcli, const char* rdoc_key)
{
_key = codart;
_key.add(gia);
_key.trim(); // trim to trim giaclevel...
if (_ignore_mag)
{
_key.add(" ",2);
_key.add(" ",3);
}
else
{
if (_ignore_dep)
{
_key.add(mag.left(3) ,2);
_key.add(magc.left(3),3);
}
else
{
_key.add(mag,2);
_key.add(magc,3);
}
}
if (_ignore_imp || imp.blank())
_key.add(" ",4);
else
_key.add(imp,4);
if (_ignore_lin || lin.blank())
_key.add(" ",5);
else
_key.add(lin,5);
_key.add(codcli,6);
/* if (_ignore_key)
_key.add(" ",7);
else */
_key.add(rdoc_key,7);
TSortable* s = add_obj(_key);
((TMRP_line *) s)->set_da_rdoc_key(rdoc_key);
return (TMRP_line*)s;
}
TMRP_line* TMRP_lines::search(const TCodice_articolo& codart, const TString& gia,
const TString& mag, const TString& magc,
const TString& imp, const TString& lin,
long codcli, const char* rdoc_key)
{
_key = codart;
_key.add(gia);
_key.trim(); // trim to trim giaclevel...
_key.add(mag,2);
_key.add(magc,3);
if (imp.blank())
_key.add(" ",4);
else
_key.add(imp,4);
if (lin.blank())
_key.add(" ",5);
else
_key.add(lin,5);
_key.add(codcli,6);
_key.add(rdoc_key,7);
TSortable* s = find_obj(_key);
return (TMRP_line*)s;
}
@ -527,16 +602,17 @@ TMRP_lines::~TMRP_lines()
#define COMPARE_DATF -8 // data documento + data di consegna + articolo + fornitore
#define COMPARE_ATFD -9 //
#define COMPARE_ADTF -10 //
#define COMPARE_TCFA -11 //
#define COMPARE_TCAF -12 //
#define COMPARE_TFAC -13 //
#define COMPARE_TFCA -14 //
#define COMPARE_TAFC -15 //
#define COMPARE_TACF -16 //
#define COMPARE_CTFA -17 // data di consegna + data documento + fornitore + articolo
#define COMPARE_CATF -18 // data di consegna + data documento + articolo + fornitore
#define COMPARE_ATFC -19 //
#define COMPARE_ACTF -20 //
#define COMPARE_DCFA -11 //
#define COMPARE_TCFA -21 //
#define COMPARE_TCAF -22 //
#define COMPARE_TFAC -23 //
#define COMPARE_TFCA -24 //
#define COMPARE_TAFC -25 //
#define COMPARE_TACF -26 //
#define COMPARE_CTFA -27 // data di consegna + data documento + fornitore + articolo
#define COMPARE_CATF -28 // data di consegna + data documento + articolo + fornitore
#define COMPARE_ATFC -29 //
#define COMPARE_ACTF -30 //
class TRiga_ordine : public TToken_string
{
@ -606,6 +682,7 @@ int TRiga_ordine::compare(const TToken_string& riga, bool compare_orig_doc, int
short fields_CATF[] = {F_DATACONS, F_DATADOC, F_ARTICOLO, F_LIV1, F_LIV2, F_LIV3, F_LIV4, F_ORD_TYPE, F_FORNITORE};
short fields_ATFC[] = {F_ARTICOLO, F_LIV1, F_LIV2, F_LIV3, F_LIV4, F_ORD_TYPE, F_FORNITORE, F_DATACONS, F_DATADOC};
short fields_ACTF[] = {F_ARTICOLO, F_LIV1, F_LIV2, F_LIV3, F_LIV4, F_ORD_TYPE, F_DATACONS, F_DATADOC, F_FORNITORE};
short fields_DFCA[] = {F_DATACONS, F_FORNITORE, F_ARTICOLO, F_LIV1, F_LIV2, F_LIV3, F_LIV4, F_ORD_TYPE, F_DATADOC};
for (int i = 0; i < 9 && cmp == 0; i++)
{
@ -632,6 +709,7 @@ int TRiga_ordine::compare(const TToken_string& riga, bool compare_orig_doc, int
case COMPARE_CATF: f=fields_CATF[i]; break;
case COMPARE_ACTF: f=fields_ACTF[i]; break;
case COMPARE_ATFC: f=fields_ATFC[i]; break;
case COMPARE_DCFA: f=fields_DFCA[i]; break;
default:
NFCHECK("Ordinamento sconosciuto");
break;
@ -931,6 +1009,7 @@ class TMatResMask : public TCalendar_mask
void sort_orders();
bool orders_selected(char type, const char * dacatmer,const char * acatmer);
void select_orders(char type, const char * dacatmer, const char * acatmer);
void select_orders_art(char type, const char * daart, const char * aart);
public:
int round_date(TDate& date, bool up = false) const;
@ -944,6 +1023,7 @@ public:
class TMatResPlanning : public TSkeleton_application
{
TMRP_lines _articles;
TAssoc_array _negatives;
TLav_finder _artinfo;
TMatResMask* _mask;
@ -1299,10 +1379,23 @@ bool TMatResMask::on_field_event(TOperable_field& o, TField_event e, long jolly)
break;
case F_SELECT_ORD:
if (e == fe_button)
if (*get(F_SEL_ORD_TYPE)=='F')
select_orders('F', get(F_OF_DAGRMERC), get(F_OF_AGRMERC));
else
select_orders('P', get(F_OP_DAGRMERC), get(F_OP_AGRMERC));
{
if (get(F_OF_DAGRMERC).full() || get(F_OF_AGRMERC).full())
{
if (*get(F_SEL_ORD_TYPE)=='F')
select_orders('F', get(F_OF_DAGRMERC), get(F_OF_AGRMERC));
else
select_orders('P', get(F_OP_DAGRMERC), get(F_OP_AGRMERC));
}
else
if (get(F_DA_ART).full() || get(F_A_ART).full())
{
if (*get(F_SEL_ORD_TYPE)=='F')
select_orders_art('F', get(F_DA_ART), get(F_A_ART));
else
select_orders_art('P', get(F_DA_ART), get(F_A_ART));
}
}
break;
case DLG_SAVEREC:
if (e == fe_button && check_fields())
@ -1542,6 +1635,8 @@ static int order_compareTAFD(TSheet_field &s,int i1,int i2)
{ return order_compare(s,i1,i2,COMPARE_TAFD);}
static int order_compareTADF(TSheet_field &s,int i1,int i2)
{ return order_compare(s,i1,i2,COMPARE_TADF);}
static int order_compareDCFA(TSheet_field &s,int i1,int i2)
{ return order_compare(s,i1,i2,COMPARE_DCFA);}
static int order_compareCTFA(TSheet_field &s,int i1,int i2)
{ return order_compare(s,i1,i2,COMPARE_CTFA);}
@ -1568,7 +1663,7 @@ void TMatResMask::sort_orders()
{
TWait_cursor clessidra;
TSheet_field& a = sfield(F_ORDINI);
int choose = -(get_int(F_SORT)+ (get_bool(F_DATE_SORT_ORDER) ? 10 : 1));
int choose = -(get_int(F_SORT)+ (get_bool(F_DATE_SORT_ORDER) ? 20 : 0));
switch (choose)
{
case COMPARE_ATFD: a.sort(order_compareATFD); break;
@ -1581,6 +1676,7 @@ void TMatResMask::sort_orders()
case COMPARE_TADF: a.sort(order_compareTADF); break;
case COMPARE_TDAF: a.sort(order_compareTDAF); break;
case COMPARE_TDFA: a.sort(order_compareTDFA); break;
case COMPARE_DCFA: a.sort(order_compareDCFA); break;
case COMPARE_ATFC: a.sort(order_compareATFC); break;
case COMPARE_ACTF: a.sort(order_compareACTF); break;
@ -1620,6 +1716,8 @@ void TMatResMask::select_orders(char type, const char * dacatmer,const char * ac
TSheet_field& s = sfield(F_ORDINI);
bool on=!orders_selected(type, dacatmer, acatmer);
const int it=s.items();
int first_selected = -1;
for (int r=0; r< it; r++)
{
if ( *s.cell(r, s.cid2index(F_ORD_TYPE))==type )
@ -1628,12 +1726,44 @@ void TMatResMask::select_orders(char type, const char * dacatmer,const char * ac
if (*acatmer <= ' ' ||
cache().get(LF_ANAMAG,s.cell(r, s.cid2index(F_ARTICOLO))).get(ANAMAG_GRMERC).left(3) <= acatmer)
{
if (on && first_selected < 0)
first_selected = r;
s.row(r).add(on ? "X" : " ", s.cid2index(F_SELECTED));
s.force_update(r);
// s.force_update(r);
}
}
TString msg=format(FR("Ordini %s %s"),type=='F' ? TR("fornitore") : TR("di produzione") ,on ? TR("selezionati") :TR("de-selezionati"));
xvtil_statbar_set(msg);
if (first_selected >= 0)
s.select(first_selected);
s.force_update();
}
void TMatResMask::select_orders_art(char type, const char * daart,const char * aart)
{
TSheet_field& s = sfield(F_ORDINI);
bool on=!orders_selected(type, daart , aart);
const int it=s.items();
int first_selected = -1;
for (int r=0; r< it; r++)
{
if ( *s.cell(r, s.cid2index(F_ORD_TYPE))==type )
if (*daart <= ' ' ||
cache().get(LF_ANAMAG,s.cell(r, s.cid2index(F_ARTICOLO))).get(ANAMAG_CODART) >= daart)
if (*aart <= ' ' ||
cache().get(LF_ANAMAG,s.cell(r, s.cid2index(F_ARTICOLO))).get(ANAMAG_CODART) <= aart)
{
if (on && first_selected < 0)
first_selected = r;
s.row(r).add(on ? "X" : " ", s.cid2index(F_SELECTED));
}
}
TString msg=format(FR("Ordini %s %s"),type=='F' ? TR("fornitore") : TR("di produzione") ,on ? TR("selezionati") :TR("de-selezionati"));
xvtil_statbar_set(msg);
if (first_selected >= 0)
s.select(first_selected);
s.force_update();
}
static bool handle_interval(TMask_field &fld, KEY k)
@ -2157,11 +2287,16 @@ bool TMatResPlanning::load_gross_requirements()
// GUY was Here, but it's Koki fault!
const long codcli = is_production_article(art) ? doc.get_long(DOC_CODCF) : 0;
TString80 rdoc_key = riga.build_key();
TString80 doc_key;
rdoc_key.format("%-4s%4dD%7ld%4d",
(const char *) riga.get(RDOC_CODNUM), riga.get_int(RDOC_ANNO),
riga.get_long(RDOC_NDOC), riga.get_int(RDOC_IDRIGA));
doc_key.format("%-4s%4dD%7ld",
(const char *) riga.get(RDOC_CODNUM), riga.get_int(RDOC_ANNO),
riga.get_long(RDOC_NDOC));
TPrice prz(riga.prezzo(TRUE,TRUE));
TQuantita q(art, um, qta);
q.convert2umbase();
@ -2176,6 +2311,8 @@ bool TMatResPlanning::load_gross_requirements()
line = _articles.find(art, liv, mag, EMPTY_STRING, imp, lin, codcli, rdoc_key, true);
line->set_description(riga.get(RDOC_DESCR));
line->set_final_product();
line->set_da_doc_key(doc_key);
line->set_qta_doc(q.val());
}
const int anno = doc.get_int(DOC_ANNO);
const TString4 codnum = doc.get(DOC_CODNUM);
@ -2222,6 +2359,8 @@ bool TMatResPlanning::explode_articles()
int maxlevel = m.get_int(F_MAXLEVEL);
bool finiti = TRUE;
TProgind* pi = NULL;
const bool split_sons = m.get_bool(F_SPLIT_SONS);
// Inizializza la cache delle lavorazioni
// _artinfo.init(m.get_bool(F_KEEP_IMP)); ??
@ -2246,7 +2385,7 @@ bool TMatResPlanning::explode_articles()
if (!pi->addstatus(1))
{
delete pi; pi = NULL;
return FALSE;
return false;
}
TMRP_line& line = _articles[a];
@ -2282,8 +2421,10 @@ bool TMatResPlanning::explode_articles()
{
const TRiga_esplosione& riga = (const TRiga_esplosione&)boom[i];
const TCodice_articolo& art = riga.articolo();
const real & qta = riga.val();
const TRectype& articolo=cache().get(LF_ANAMAG,art);
bool add=true;
if (articolo.get(ANAMAG_CODART).full())
{
const char reorder_type=articolo.get_char(ANAMAG_RIORDINO);
@ -2298,22 +2439,61 @@ bool TMatResPlanning::explode_articles()
TString8 lin = line.codlin();
_artinfo.art2magimpline(art, mag, imp, lin);
// GUY was here with Koki
const long codcli = is_production_article(art) ? line.codclifor() : 0L;
const TString& rdoc_key = line.da_rdoc_key();
TMRP_line* son = _articles.find(art, riga.giacenza(), mag, EMPTY_STRING, imp, lin, codcli, rdoc_key);
if (son == NULL)
if (qta > ZERO)
{
son = _articles.find(art, riga.giacenza(), mag, EMPTY_STRING, imp, lin, codcli, rdoc_key, true);
son->set_description(distinta.describe(art));
}
const int son_depth = line.explosion_depth()+1;
if (son_depth > son->explosion_depth())
son->set_explosion_depth(son_depth);
// GUY was here with Koki
const long codcli = is_production_article(art) ? line.codclifor() : 0L;
const TString& rdoc_key = line.da_rdoc_key();
TMRP_line* son = NULL;
if (split_sons)
{
son = _articles.create(art, riga.giacenza(), mag, EMPTY_STRING, imp, lin, codcli, rdoc_key);
son->set_description(distinta.describe(art));
son->set_da_doc_key(line.da_doc_key());
}
else
{
son = _articles.find(art, riga.giacenza(), mag, EMPTY_STRING, imp, lin, codcli, rdoc_key);
line.add_son(riga.val(), son);
distinta.describe(art);
if (son == NULL)
{
son = _articles.find(art, riga.giacenza(), mag, EMPTY_STRING, imp, lin, codcli, rdoc_key, true);
son->set_description(distinta.describe(art));
son->set_da_doc_key(line.da_doc_key());
}
}
const TString art = line.articolo();
TToken_string rdoc_key1;
rdoc_key1.add(rdoc_key.sleft(4));
rdoc_key1.add(rdoc_key.smid(4, 4));
rdoc_key1.add(rdoc_key.smid(8, 1));
rdoc_key1.add(atol(rdoc_key.smid(9, 7)));
rdoc_key1.add(atoi(rdoc_key.sright(4)));
const TRectype & rdoc = cache().get(LF_RIGHEDOC, rdoc_key1);
const real gross_req = rdoc.get_real(RDOC_QTA);
son->set_qta_doc(gross_req);
const int son_depth = line.explosion_depth()+1;
if (son_depth > son->explosion_depth())
son->set_explosion_depth(son_depth);
line.add_son(qta, son);
distinta.describe(art);
}
else
if (qta < ZERO)
{
TToken_string key(art);
key.add(a);
key.add(line.qta_doc());
_negatives.add(key, qta);
}
}
}
}
@ -2321,7 +2501,96 @@ bool TMatResPlanning::explode_articles()
else
line.set_final_product(true);
}
FOR_EACH_ASSOC_OBJECT(_negatives, obj, key, q)
{
real qta(*((real *)q));
TToken_string key(key);
const TString art = key.get();
const int nline = key.get_int();
const real req(key.get());
TMRP_line & orig_line = _articles[nline];
const TString orig_doc_key = _articles[nline].da_doc_key();
bool found = false;
real rate = UNO;
for (long a = 0; !found && a < _articles.items(); a++)
{
TMRP_line& line = _articles[a];
for (int i = line.sons()-1; !found && i >= 0; i--)
{
TMRP_line& r = line.son(i);
TString line_art = r.articolo();
real qta1 = line.qta_son(i);
TString da_doc_key = r.da_doc_key();
const real req_orig = r.qta_doc();
found = art == line_art && da_doc_key == orig_doc_key && req_orig == req;
if (found)
{
rate = UNO + (qta / line.qta_son(i));
real diff = line.qta_son(i) + qta;
if (diff < ZERO)
diff = ZERO;
line.set_qta_son(i, diff);
r.destroy(i);
}
}
}
if (found)
{
found = false;
for (long a = _articles.items() - 1; !found && a >= 0 ; a--)
{
TMRP_line& line = _articles[a];
const TString line_art = line.articolo();
TString da_doc_key = line.da_doc_key();
const real req_orig = line.qta_doc();
found = art == line_art && da_doc_key == orig_doc_key && req_orig == req;
if (found)
{
const int buckets = line.last_bucket();
if (buckets < 0)
{
if (rate == ZERO)
line.delete_line();
}
else
{
for (int j = 0; !found && j <= buckets; j++)
{
TMRP_docrefs * reqs = line.record(j).requirements_refs();
if (reqs != NULL)
{
for (int n = reqs->last(); n >= 0; n = reqs->pred(n))
{
TMRP_docref * dr = (TMRP_docref *) reqs->objptr(n);
TString doc_key;
doc_key.format("%-4s%4dD%7ld", (const char *) dr->codnumdoc(), dr->annodoc(), dr->numdoc());
real gross_to_reduce = rate * req;
found = doc_key == orig_doc_key && dr->qta_residua() >= gross_to_reduce;
if (found)
{
if (dr->qta_residua() == gross_to_reduce)
reqs->destroy(n, true);
else
dr->set_qta_residua(dr->qta_residua() - gross_to_reduce);
line.record(j).add_gross_requirement(-req);
}
}
}
}
}
}
}
}
}
if (pi != NULL) delete pi;
return _articles.items() > 0;
@ -2438,30 +2707,41 @@ bool TMatResPlanning::load_planned_orders()
// GUY was Here, but it's Koki fault!
const long codcli = is_production_article(art) ? doc.get_long(DOC_CODCF) : 0;
TString80 rdoc_key ;
TString80 doc_key;
rdoc_key.format("%-4s%4dD%7ld%4d",
(const char *) riga.get(RDOC_DACODNUM), riga.get_int(RDOC_DAANNO),
riga.get_long(RDOC_DANDOC), riga.get_int(RDOC_DAIDRIGA));
doc_key.format("%-4s%4dD%7ld",
(const char *) riga.get(RDOC_CODNUM), riga.get_int(RDOC_ANNO),
riga.get_long(RDOC_NDOC));
TMRP_line* line = _articles.find(art, liv, mag, EMPTY_STRING, imp, lin, codcli, rdoc_key);
if (line == NULL)
TPrice prz(riga.prezzo(true, true));
const TCodice_um um = riga.get(RDOC_UMQTA);
TQuantita q(art, um, qta);
q.convert2umbase();
q.currency2umbase(prz);
TMRP_line* line = _articles.find(art, liv, mag, EMPTY_STRING, imp, lin, codcli, rdoc_key);
if (line == NULL)
{
line = _articles.find(art, liv, mag, EMPTY_STRING, imp, lin, codcli, rdoc_key, true);
line->set_description(riga.get(RDOC_DESCR));
line->set_da_doc_key(doc_key);
line->set_qta_doc(q.val());
}
TPrice prz(riga.prezzo(TRUE,TRUE));
const TCodice_um um = riga.get(RDOC_UMQTA);
TQuantita q(art, um, qta);
q.convert2umbase();
q.currency2umbase(prz);
const TString4 codnum = doc.get(DOC_CODNUM);
const TString4 codnum = doc.get(DOC_CODNUM);
const long docnum = doc.get_long(DOC_NDOC);
const int numriga = riga.get_int(RDOC_NRIGA);
TMRP_docref* docref = new TMRP_docref(doc.get_int(DOC_ANNO), codnum, docnum,
numriga, um, q.val(), prz.get_num());
const TMRP_time t(consegna, 0, imp, lin);
if (has_confirmed_status(doc, a.row(sheetrow)) ||
if (has_confirmed_status(doc, a.row(sheetrow)) ||
(codnum != m.get(F_NUM_PROD) && codnum != m.get(F_NUM_FORN)))
line->add_sched_rec(t, q.val(), docref);
else
@ -2639,29 +2919,29 @@ bool TMatResPlanning::net_requirement_cycle()
// cicla iterativamente sugli elementi di _articles
for (long a = 0; a < total; a++)
{
pi.addstatus(1);
TMRP_line& curr_article = _articles[a];
const int last = curr_article.last_bucket();
if (last >= 0)
pi.addstatus(1);
if (last >= 0)
{
real curgiac;
if (use_mag)
curr_article.giacenza_attuale(curgiac, m.get_date(F_DADATA));
curr_article.set_on_hand(0, curgiac);
if (use_mag)
curr_article.giacenza_attuale(curgiac, m.get_date(F_DADATA));
curr_article.set_on_hand(0, curgiac);
bool sc_used = false;
for (int bucket = 0; ok && bucket <= last; bucket = curr_article.next_bucket(bucket))
{
// !?!?! la logica gross2net dovrebbe funzionare in termini di intervalli di date
// (bucket-utente) piuttosto che di bucket di MRPline (che possono essere più di uno
// in un intervallo, altrimenti i ragionamenti di scorte minime e lotti
// funzionano in modo sbagliato, perchè approssimano più volte
ok = gross2net_logic(curr_article, bucket, sc_used);
if (!ok)
break;
}
bool sc_used = false;
for (int bucket = 0; ok && bucket <= last; bucket = curr_article.next_bucket(bucket))
{
// !?!?! la logica gross2net dovrebbe funzionare in termini di intervalli di date
// (bucket-utente) piuttosto che di bucket di MRPline (che possono essere più di uno
// in un intervallo, altrimenti i ragionamenti di scorte minime e lotti
// funzionano in modo sbagliato, perchè approssimano più volte
ok = gross2net_logic(curr_article, bucket, sc_used);
if (!ok)
break;
}
}
}
return ok;
@ -2686,46 +2966,35 @@ bool TMatResPlanning::build_orders()
{
pi.addstatus(1);
const TMRP_line& line = _articles[a];
const bool prod = is_production_article(line.articolo());
long codforn = 0;
if (!prod) // Se l'articolo NON e' di produzione ...
{
TString80 key = line.codimp();
key.rpad(5);
key << line.articolo();
// Cerco il fornitore specifico per l'impianto
codforn = atol(cache().get("FIA", key, "I0"));
if (codforn == 0L) // Cerco il fornitore di default in anagrafica
{
const TRectype& anarec = cache().get(LF_ANAMAG,line.articolo());
codforn = anarec.get_long("CODFORN");
if (codforn == 0L) // Prendo il codice "eventualmente" proveniente dall'ordine
codforn = line.codclifor();
}
}
else
codforn = line.codclifor(); // Prendo il codice "eventualmente" proveniente dall'ordine
if (!line.line_deleted())
{
const bool prod = is_production_article(line.articolo());
long codforn = 0;
for (int b = line.last_bucket(); b >= 0; b--)
{
/*
const TMRP_record & rrr = line.record(b);
const real r0 = line.gross_requirement(b);
const real r1 = line.planned_orders(b);
const real r2 = line.sched_receipts(b);
real qta = line.net_requirement(b);
qta -= line.planned_orders(b);
qta.round(5);
if (!qta.is_zero() ||
line.planned_orders(b)>0 ||
line.sched_receipts(b)>line.gross_requirement(b))
m.add_order_line(forn, line, b);
else
*/
m.add_order_line(codforn, line, b);
}
}
if (!prod) // Se l'articolo NON e' di produzione ...
{
TString80 key = line.codimp();
key.rpad(5);
key << line.articolo();
// Cerco il fornitore specifico per l'impianto
codforn = atol(cache().get("FIA", key, "I0"));
if (codforn == 0L) // Cerco il fornitore di default in anagrafica
{
const TRectype& anarec = cache().get(LF_ANAMAG,line.articolo());
codforn = anarec.get_long("CODFORN");
if (codforn == 0L) // Prendo il codice "eventualmente" proveniente dall'ordine
codforn = line.codclifor();
}
}
else
codforn = line.codclifor(); // Prendo il codice "eventualmente" proveniente dall'ordine
for (int b = line.last_bucket(); b >= 0; b--)
m.add_order_line(codforn, line, b);
}
}
}
const int orders=sf.items();
@ -2936,25 +3205,38 @@ TMRP_line* TMatResPlanning::find_risalita_line(TToken_string &row)
TMRP_line* line = NULL;
if (_mask->get_bool(F_SINGLE_DOC))
line = _articles.find(art, liv, mag, magc, imp, lin, codcf, rdoc_key);
if (_mask->get_bool(F_SINGLE_DOC) || _mask->get_bool(F_SPLIT_SONS))
{
line = _articles.search(art, liv, mag, magc, imp, lin, codcf, rdoc_key);
if (line == NULL)
{
line = _articles.search(art, liv, mag, magc, imp, lin, 0L, rdoc_key); // Riprovo senza clifo
if (line == NULL)
{
line = _articles.search(art, liv, mag, magc, imp, EMPTY_STRING, codcf, rdoc_key); // Riprovo senza linea
if (line == NULL)
{
line = _articles.search(art, liv, mag, magc, EMPTY_STRING, lin, codcf, rdoc_key); // Riprovo senza impianto
if (line == NULL)
line = _articles.search(art, liv, mag, magc, imp, EMPTY_STRING, 0L, rdoc_key); // Riprovo senza nulla
}
}
}
}
if (line == NULL)
{
line = _articles.find(art, liv, mag, magc, imp, lin, codcf, EMPTY_STRING);
line = _articles.search(art, liv, mag, magc, imp, lin, codcf, EMPTY_STRING);
if (line == NULL)
{
line = _articles.find(art, liv, mag, magc, imp, lin, 0L, EMPTY_STRING); // Riprovo senza clifo
line = _articles.search(art, liv, mag, magc, imp, lin, 0L, EMPTY_STRING); // Riprovo senza clifo
if (line == NULL)
{
line = _articles.find(art, liv, mag, magc, imp, EMPTY_STRING, codcf, EMPTY_STRING); // Riprovo senza linea
line = _articles.search(art, liv, mag, magc, imp, EMPTY_STRING, codcf, EMPTY_STRING); // Riprovo senza linea
if (line == NULL)
{
line = _articles.find(art, liv, mag, magc, EMPTY_STRING, lin, codcf, EMPTY_STRING); // Riprovo senza impianto
line = _articles.search(art, liv, mag, magc, EMPTY_STRING, lin, codcf, EMPTY_STRING); // Riprovo senza impianto
if (line == NULL)
{
line = _articles.find(art, liv, mag, magc, imp, EMPTY_STRING, 0L, EMPTY_STRING); // Riprovo senza nulla
}
line = _articles.search(art, liv, mag, magc, imp, EMPTY_STRING, 0L, EMPTY_STRING); // Riprovo senza nulla
}
}
}

View File

@ -3,6 +3,7 @@
#include "mrplib.h"
#include "../ve/velib.h"
#define ART_DELETED "----"
void print_header(TPrinter& pr);
void print_footer(TPrinter& pr);
@ -38,6 +39,7 @@ public:
const real& gross_requirement() const { return _gross_requirement; }
const real& sched_receipts() const { return _sched_receipts; }
const real& planned_orders() const { return _planned_orders; }
const real& add_gross_requirement(const real & req) { return _gross_requirement += req;}
TMRP_docrefs *requirements_refs() const { return _requirements; }
TMRP_docrefs *scheduls_refs() const { return _scheduls; }
@ -100,9 +102,11 @@ class TMRP_line : public TSortable
TString8 _codlin;
long _codclifor;
TString _da_rdoc_key;
bool _final_product;
TString _da_doc_key;
bool _final_product;
int _explosion_depth;
TToken_string * _sheet_row;
real _qta_doc;
static TArticolo_giacenza* _articolo_giac;
@ -122,6 +126,9 @@ public:
TMRP_record& record(const TMRP_time& t) const;
const TCodice_articolo& articolo() const { return _codart; }
void delete_line() { _codart = ART_DELETED; }
bool line_deleted() const { return _codart == ART_DELETED; }
const TString& livgiac() const { return _livgiac; }
const TString& codmagdep() const { return _codmag; }
const TString& codmagdep_coll() const { return _codmag_coll; }
@ -129,7 +136,14 @@ public:
const TString& codlin() const { return _codlin; }
long codclifor() const { return _codclifor; }
const TString& description() const { return _descr; }
const TString& da_rdoc_key() const { return _da_rdoc_key; }
const TString& da_rdoc_key() const { return _da_rdoc_key;}
void set_da_rdoc_key(const char * rdoc_key) { _da_rdoc_key = rdoc_key;}
const TString& da_doc_key() const { return _da_doc_key;}
void set_da_doc_key(const char * doc_key) { _da_doc_key = doc_key;}
const real& qta_doc() const { return _qta_doc;}
void set_qta_doc(const real & qta) { _qta_doc = qta;}
const TString& codmag() const;
const TString& codmagaz_coll() const;
@ -144,10 +158,12 @@ public:
int next_bucket(int i) const { return _req_per_bucket.succ(i); }
int add_son(const real& qta, TMRP_line* son);
void destroy(int i) { _sons.destroy(i, true); _qta_sons.destroy(i, true);}
int sons() const { return _sons.items(); }
const TMRP_line& son(int i) const { return (const TMRP_line&)_sons[i]; }
TMRP_line& son(int i) { return (TMRP_line&)_sons[i]; }
const real& qta_son(int i) const { return (const real&)_qta_sons[i]; }
void set_qta_son(int i, const real & r) {_qta_sons[i] = r; }
const real & on_hand(int i) const
{return record(i).on_hand();}
@ -239,6 +255,14 @@ public:
const TString& giac, const TString& mag, const TString& magc,
const TString& imp, const TString& lin,
long codcli, const char* rdoc_key, bool create = false);
TMRP_line* create(const TCodice_articolo& codart,
const TString& giac, const TString& mag, const TString& magc,
const TString& imp, const TString& lin,
long codcli, const char* rdoc_key);
TMRP_line* search(const TCodice_articolo& codart,
const TString& giac, const TString& mag, const TString& magc,
const TString& imp, const TString& lin,
long codcli, const char* rdoc_key);
TMRP_line& operator[](long n) const
{ return (TMRP_line&)find_obj(n); }

View File

@ -43,23 +43,26 @@
#define F_OP_AGRMERC 236
#define F_OF_DAGRMERC 237
#define F_OF_AGRMERC 238
#define F_DATE_SORT_ORDER 239
#define F_DATE_SORT_ORDER 239
//#define F_NUMBERBYCLI 240
//#define F_NUMBERBYWEEK 241
#define F_DIVIDEBYDATE 242
#define F_DIVIDEBYART 243
#define F_DAYXBUCK 244
#define F_XTRA_LDTIME 245
#define F_XTRA_PLTIME 246
#define F_LDTIME_MODE 247
#define F_DIVIDEBYDATE 242
#define F_DIVIDEBYART 243
#define F_DAYXBUCK 244
#define F_XTRA_LDTIME 245
#define F_XTRA_PLTIME 246
#define F_LDTIME_MODE 247
#define F_ALL_ORDERSCHANGES 250
#define F_DISABLESAVE 251
#define F_ALL_MRPLINES 252
#define F_DOC_YEAR_PREC 253
#define F_MAXLEVEL 254
#define F_RIFERIMENTO_MRP 255
#define F_LOAD_EVASI 256
#define F_DONT_USE_MAG 257
#define F_DISABLESAVE 251
#define F_ALL_MRPLINES 252
#define F_DOC_YEAR_PREC 253
#define F_MAXLEVEL 254
#define F_RIFERIMENTO_MRP 255
#define F_LOAD_EVASI 256
#define F_DONT_USE_MAG 257
#define F_DA_ART 258
#define F_A_ART 259
#define F_SPLIT_SONS 260
// campi senza default sul profilo
#define F_YEAR 301

View File

@ -138,14 +138,19 @@ BEGIN
PROMPT 2 12 "Non suddividere per linee"
END
BOOLEAN F_SINGLE_DOC
BEGIN
PROMPT 2 13 "Suddividi per vincolo (ordine)"
END
BOOLEAN F_DOC_YEAR_PREC
BEGIN
PROMPT 2 14 "Considera i documenti dell'anno precedente"
END
BOOLEAN F_SINGLE_DOC
BOOLEAN F_SPLIT_SONS
BEGIN
PROMPT 2 13 "Suddividi per vincolo (ordine)"
PROMPT 2 15 "Suddividi i figli (varianti)"
END
ENDPAGE
@ -467,7 +472,7 @@ END
ENDPAGE
PAGE "Fabbisogni" -1 -1 78 20
GROUPBOX DLG_NULL 78 4
GROUPBOX DLG_NULL 78 5
BEGIN
PROMPT 0 0 ""
END
@ -518,12 +523,38 @@ END
STRING F_OF_AGRMERC 3
BEGIN
FLAGS "U"
PROMPT 22 2 " a "
PROMPT 34 2 " a "
COPY USE F_OP_DAGRMERC
COPY DISPLAY F_OP_DAGRMERC
INPUT CODTAB F_OF_AGRMERC
OUTPUT F_OF_AGRMERC CODTAB
GROUP G_SEL_ORDF
STR_EXPR (#F_OF_AGRMERC=="")||(#F_OF_AGRMERC>=#F_OF_DAGRMERC)
WARNING "Il gruppo merceologico deve essere maggiore o uguale al precedente"
END
STRING F_DA_ART 20 10
BEGIN
PROMPT 2 3 "Da Articolo "
USE LF_ANAMAG
INPUT CODART F_DA_ART
DISPLAY "Codice@20" CODART
DISPLAY "Descrizione@50" DESCR
OUTPUT F_DA_ART CODART
CHECKTYPE NORMAL
END
STRING F_A_ART 20 10
BEGIN
PROMPT 34 3 " a "
USE LF_ANAMAG
INPUT CODART F_A_ART
DISPLAY "Codice@20" CODART
DISPLAY "Descrizione@50" DESCR
OUTPUT F_A_ART CODART
STR_EXPR (#F_A_ART=="")||(#F_A_ART>=#F_DA_ART)
CHECKTYPE NORMAL
WARNING "Il codice articolo deve essere maggiore o uguale al precedente"
END
BUTTON F_SELECT_ORD 10 2
@ -534,7 +565,7 @@ END
LIST F_SORT 26
BEGIN
PROMPT 1 4 "Ordinamento "
PROMPT 1 5 "Ordinamento "
ITEM "1|Tipo/data/fornit./articolo"
ITEM "2|Tipo/data/articolo/fornit."
ITEM "3|Tipo/fornit./articolo/data"
@ -545,26 +576,27 @@ BEGIN
ITEM "8|Data/articolo/tipo/fornit."
ITEM "9|Articolo/tipo/fornit./data"
ITEM "10|Articolo/data/tipo/fornit."
ITEM "11|Data/fornit./articolo"
END
BOOLEAN F_SORT_ORDER
BEGIN
PROMPT 13 5 "Inverso"
PROMPT 13 6 "Inverso"
END
BOOLEAN F_DATE_SORT_ORDER
BEGIN
PROMPT 30 5 "Data di consegna"
PROMPT 30 6 "Data di consegna"
END
BUTTON F_RESORT_ORDINI 10
BEGIN
PROMPT 64 4 "Riordina"
PROMPT 64 5 "Riordina"
END
SPREADSHEET F_ORDINI
BEGIN
PROMPT 0 7 ""
PROMPT 0 8 ""
ITEM "@1"
ITEM "@1"
ITEM "Documento@10"