diff --git a/src/mr/mr2100.cpp b/src/mr/mr2100.cpp index 17b9d7ecd..67904da49 100755 --- a/src/mr/mr2100.cpp +++ b/src/mr/mr2100.cpp @@ -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 } } } diff --git a/src/mr/mr2100.h b/src/mr/mr2100.h index c12255999..33157ebc3 100755 --- a/src/mr/mr2100.h +++ b/src/mr/mr2100.h @@ -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); } diff --git a/src/mr/mr2100a.h b/src/mr/mr2100a.h index 2afd8d763..247fb3852 100755 --- a/src/mr/mr2100a.h +++ b/src/mr/mr2100a.h @@ -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 diff --git a/src/mr/mr2100a.uml b/src/mr/mr2100a.uml index 3e1ae6f64..ee7a82c92 100755 --- a/src/mr/mr2100a.uml +++ b/src/mr/mr2100a.uml @@ -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"