diff --git a/src/mg/mg1200.cpp b/src/mg/mg1200.cpp index 7ebcf54a5..8d022e010 100755 --- a/src/mg/mg1200.cpp +++ b/src/mg/mg1200.cpp @@ -66,7 +66,14 @@ void TApp_rebuildbalances::main_loop() TMask_buildmov m; while (m.run()==K_ENTER) { - if (!rebuild_balances(m.get_int(F_ANNOES))) + bool ok = true; + + if (m.get(F_CODART_DA).full() || m.get(F_CODART_A).full()) + ok = articles_rebuild_balances(m.get_int(F_ANNOES), m.get(F_CODART_DA), m.get(F_CODART_A)); + else + ok = rebuild_balances(m.get_int(F_ANNOES)); + + if (!ok) warning_box(TR("A causa degli errori riscontrati, i saldi di magazzino potrebbero non essere aggiornati.\n" "Si consiglia di procedere ad una nuova operazione di \"Ricostruzione saldi\"")); } diff --git a/src/mg/mg1200.h b/src/mg/mg1200.h index faf9b4643..b16540138 100755 --- a/src/mg/mg1200.h +++ b/src/mg/mg1200.h @@ -1,2 +1,4 @@ -#define F_ANNOES 101 -#define F_DATA 102 +#define F_ANNOES 101 +#define F_DATA 102 +#define F_CODART_DA 103 +#define F_CODART_A 104 diff --git a/src/mg/mg1200.uml b/src/mg/mg1200.uml index 6141fcace..a71d31598 100755 --- a/src/mg/mg1200.uml +++ b/src/mg/mg1200.uml @@ -1,6 +1,6 @@ #include "mg1200.h" -PAGE "Ricostruzione Saldi" -1 -1 40 3 +PAGE "Ricostruzione Saldi" -1 -1 60 9 DATE F_DATA BEGIN @@ -22,6 +22,34 @@ BEGIN FLAGS "Z" END +STRING F_CODART_DA 20 +BEGIN + PROMPT 1 3 "Da codice articolo " + FLAGS "UG" + USE LF_ANAMAG + JOIN LF_UMART INTO CODART==CODART NRIGA==1 + INPUT CODART F_CODART_DA + DISPLAY "Codice@20" CODART + DISPLAY "Descrizione@50" DESCR + OUTPUT F_CODART_DA CODART + CHECKTYPE SEARCH + ADD RUN ve2 -3 +END + +STRING F_CODART_A 20 +BEGIN + PROMPT 2 5 "A codice articolo " + FLAGS "UG" + COPY USE F_CODART_DA + INPUT CODART F_CODART_A + COPY DISPLAY F_CODART_DA + OUTPUT F_CODART_A CODART + CHECKTYPE SEARCH + ADD RUN ve2 -3 + GE_IF_SET(F_CODART_DA) + WARNING "Il codice articolo deve essere maggiore o uguale al precedente" +END + ENDPAGE TOOLBAR "topbar" 0 0 0 2 diff --git a/src/mg/mglib.h b/src/mg/mglib.h index ac12488e2..7945e90c8 100755 --- a/src/mg/mglib.h +++ b/src/mg/mglib.h @@ -656,8 +656,12 @@ public: bool rebuild_balances(int annoes, const TTipo_valorizz tipo=valorizz_costmediopond, - const char* catven=NULL, - const char* codlis=NULL); + const char* catven=nullptr, + const char* codlis=nullptr); + +bool articles_rebuild_balances(int annoes, + const char* from, const char* to, + const TTipo_valorizz tipo = valorizz_costmediopond); #define FORM_MAXGIACLEV 4 // numero di livelli giacenza nel form #define FORM_MAXARTLEV 8 // numero di livelli codice nel form diff --git a/src/mg/mglib02.cpp b/src/mg/mglib02.cpp index 4ccfee57a..0119ac5d9 100755 --- a/src/mg/mglib02.cpp +++ b/src/mg/mglib02.cpp @@ -1709,7 +1709,7 @@ void TArticolo_giacenza_data::al(const TDate& data, const char* codmag, const ch else riporta_saldi(anno_pred, anno, tipo, catven, codlis, false); - TRelation rel(LF_RMOVMAG); rel.add(LF_MOVMAG, "NUMREG==NUMREG"); + TRelation rel(LF_RMOVMAG); rel.add(LF_MOVMAG, RMOVMAG_NUMREG "==" MOVMAG_NUMREG); TRectype filter(LF_RMOVMAG); filter.put(RMOVMAG_CODART, codice()); @@ -1721,25 +1721,17 @@ void TArticolo_giacenza_data::al(const TDate& data, const char* codmag, const ch TCursor cur(&rel, "", 2, &filter, &filter, 0x2); const long items = cur.items(); cur.freeze(); - - TProgress_monitor* pi = NULL; - if (items >= 16) - { - TString80 str; str << TR("Calcolo giacenza articolo ") << codice(); - pi = new TProgress_monitor(items, str, false); - } - /* - TMov_mag* p_movmag = new TMov_mag; - rel.lfile(LF_MOVMAG).set_curr(p_movmag); - TMov_mag& movmag = *p_movmag; - */ + + TString80 str; str << TR("Calcolo giacenza articolo ") << codice(); + TProgress_monitor pi(items, str, false); const TRectype& rmovmag = rel.curr(); TRecord_array& rmag = mag(anno); - for (cur = 0; cur.pos() < items; ++cur) + for (cur = 0; cur.pos() < items && pi.add_status(); ++cur) { const TDate datacomp = rel.curr(LF_MOVMAG).get_date(MOVMAG_DATACOMP); const TString& codart = rmovmag.get(RMOVMAG_CODART); + if (codart == codice() && datacomp >= inizio && datacomp <= data) { const TString8 codmag = rmovmag.get(RMOVMAG_CODMAG); @@ -1753,23 +1745,20 @@ void TArticolo_giacenza_data::al(const TDate& data, const char* codmag, const ch if (i >= 0) // Se il record di giacenza esiste lo aggiorno ... { TRectype& rec = (TRectype&)rmag.row(i); + movmag.update_balances(rec, nrig); } else // ... altrimenti lo creo e poi lo aggiorno { - TRectype& rec = rmag.row(-1, TRUE); + TRectype& rec = rmag.row(-1, true); + rec.put(MAG_ANNOES, anno); // Setto i campi fondamentali! rec.put(MAG_CODMAG, codmag); rec.put(MAG_LIVELLO, livello); movmag.update_balances(rec, nrig); } } - - if (pi && !pi->add_status()) - break; } - - if (pi) delete pi; } TArticolo_giacenza_data::TArticolo_giacenza_data(const char* codice) diff --git a/src/mg/mglib02a.cpp b/src/mg/mglib02a.cpp index 450addb62..416ffcc29 100755 --- a/src/mg/mglib02a.cpp +++ b/src/mg/mglib02a.cpp @@ -461,6 +461,8 @@ TSaldo_mag_clifo::TSaldo_mag_clifo(const TSaldo_mag_clifo & s) static bool __cache_saldi = false; static TAssoc_array __saldi_mag; static TAssoc_array __saldi_mag_clifo; +static TString __from_art; +static TString __to_art; // ******************************** // TMov_mag @@ -755,7 +757,18 @@ void TMov_mag::add_saldi(const bool plus) for (int i = b.last_row(); i > 0; i = b.pred_row(i)) { - const TRectype & rec = b[i]; + const TRectype & rec = b[i]; + + if (__cache_saldi) + { + const TString & codart = rec.get(ANAMAG_CODART); + + if (__from_art.full() && codart < __from_art) + continue; + if (__to_art.full() && codart > __to_art) + continue; + } + TToken_string & key_mag = TSaldo_mag::key(*this, rec); TSaldo_mag * s_mag = (TSaldo_mag*)(__cache_saldi ? __saldi_mag.objptr(key_mag) : _saldi_mag.objptr(key_mag)); @@ -1212,7 +1225,7 @@ bool rebuild_balances(int codes, const TTipo_valorizz tipo_valorizz, relmovmag.lfile().set_curr(new TMov_mag()); msg.format(FR("Ricostruzione saldi esercizio %04d ..."), codes); __cache_saldi = true; - mov_cur.scan(recalc_mov, (void*)&ok, msg); + mov_cur.scan(recalc_mov, (void*)&ok, msg); if (__cache_saldi && __saldi_mag.items() > 0) { @@ -1325,3 +1338,197 @@ bool rebuild_balances(int codes, const TTipo_valorizz tipo_valorizz, return ok; } + +bool articles_rebuild_balances(int codes, const char* from_art, const char* to_art, + const TTipo_valorizz tipo_valorizz) +{ + TSystemisamfile a(LF_MOVMAG); + + if (a.open(_excllock) != NOERR) + return false; + + const TEsercizi_contabili& esc = esercizi(); + TBalance_params p; + + p.codes = codes; + p.codesprec = esc.pred(codes); + p.closed = p.codesprec <= 0 || esc[p.codesprec].chiusura_mag().ok(); + p.zero_giac = p.closed; + p.catv = ""; + p.codl = ""; + p.tipov = tipo_valorizz; + + TString msg; + + { + // azzera tutte giacenze (ciclo sulle giacenze) + TRelation anamag_rel(LF_ANAMAG); + TCursor anamag_cur(&anamag_rel); + TRectype from(LF_ANAMAG); + TRectype to(from); + + if (from_art) + from.put(ANAMAG_CODART, from_art); + if (to_art) + to.put(ANAMAG_CODART, to_art); + anamag_cur.setregion(from, to); + + //anamag_cur.relation()->lfile().set_curr(new TArticolo_giacenza()); + msg.format(FR("Ricostruzione saldi esercizio %04d: azzeramento..."), codes); + anamag_cur.scan(reset_giac, (void*)&p, msg); + } + + if (p.codesprec > 0) + { + TRelation clifogiac_rel(LF_CLIFOGIAC); + TRectype filter = clifogiac_rel.curr(); + + filter.put(CLIFOGIAC_ANNOES, p.codesprec); + + TString select("BETWEEN(CODART,"); + + select << '"' << from_art << '"' << ',' << '"' << to_art << '"' << ')'; + // Scandisce anno precedente + TCursor c(&clifogiac_rel, select, 1, &filter, &filter); // ANNO+CODCF+CODART+NRIGA + msg.format(FR("Ricostruzione saldi esercizio %04d: azzeramento giacenze clienti..."), codes); + c.scan(rel_reset_clifogiac, (void*)&p, msg); + + filter.put(CLIFOGIAC_ANNOES, p.codes); // Scandisce anno corrente + c.setregion(filter, filter); + msg.format(FR("Ricostruzione saldi esercizio %04d: ricalcolo dotazione iniziale..."), codes); + c.scan(rel_reset_newclifogiac, (void*)&p, msg); + } + + // ricostruisce i saldi (ciclo sui movimenti) + bool ok = true; + + __from_art = from_art; + __to_art = to_art; + { + TRelation relmovmag(LF_MOVMAG); + TRectype filter(LF_MOVMAG); + filter.put(MOVMAG_ANNOES, codes); + + TCursor mov_cur(&relmovmag, "", 2, &filter, &filter); + + mov_cur = 0L; //non togliere + mov_cur.freeze(); // non togliere + + relmovmag.lfile().set_curr(new TMov_mag()); + msg.format(FR("Ricostruzione saldi esercizio %04d ..."), codes); + __cache_saldi = true; + mov_cur.scan(recalc_mov, (void*)&ok, msg); + + if (__cache_saldi && __saldi_mag.items() > 0) + { + TFast_isamfile mag(LF_MAG); + TRectype& mag_curr = mag.curr(); + TString_array keys_mag; + + mag.setkey(2); + __saldi_mag.get_keys(keys_mag); + keys_mag.sort(); + + TString msg = TR("Aggiornamento saldi magazzini"); + TProgress_monitor pi(keys_mag.items(), msg, false); + + FOR_EACH_ARRAY_ROW(keys_mag, r, curr_key) + { + const TSaldo_mag& saldo = (const TSaldo_mag&)__saldi_mag[*curr_key]; + const TCodice_articolo& codart = saldo.codart(); + + saldo.putkey(mag_curr); + + int readerr = mag_curr.read(mag, _isequal); + + if (readerr != NOERR) + { + mag.setkey(1); + saldo.putkey(mag_curr); + mag_curr.put(MAG_NRIGA, 999); + if (mag.read(_isgteq) == NOERR) + mag.prev(); + + int nriga = 1; + + if (mag_curr.get_int(MAG_ANNOES) == saldo.codes() && + mag_curr.get(MAG_CODART) == saldo.codart()) + nriga = mag_curr.get_int(MAG_NRIGA) + 1; + saldo.putkey(mag_curr); + mag_curr.put(MAG_NRIGA, nriga); + + const int err = mag.write(); + + CHECKD(err == NOERR, "Mag : Errore di write:", err); + mag.setkey(2); + } + saldo.update_record(mag_curr); + if (mag.rewrite() != NOERR) + ok = false; + pi.add_status(); + } + } + + if (__cache_saldi && __saldi_mag_clifo.items() > 0) + { + TFast_isamfile clifomag(LF_CLIFOGIAC); + TRectype& clifomag_curr = clifomag.curr(); + TString_array keys_clifo; + + clifomag.setkey(2); + __saldi_mag_clifo.get_keys(keys_clifo); + keys_clifo.sort(); + + TString msg = TR("Aggiornamento saldi magazzini clienti"); + TProgress_monitor pi(keys_clifo.items(), msg, false); + + for (TToken_string* curr_key = (TToken_string*)keys_clifo.first_item(); + curr_key != nullptr; curr_key = (TToken_string*)keys_clifo.succ_item()) + { + TSaldo_mag_clifo & saldo = (TSaldo_mag_clifo &)__saldi_mag_clifo[*curr_key]; + const TCodice_articolo& codart = saldo.codart(); + + saldo.putkey(clifomag_curr); + if (clifomag.read(_isequal) != NOERR) + { + // non trovato: aggiungo + clifomag.setkey(1); + saldo.putkey(clifomag_curr); + clifomag_curr.put(CLIFOGIAC_NRIGA, 999); + if (clifomag.read(_isgteq) == NOERR) + clifomag.prev(); + + saldo.putkey(clifomag_curr); + + int nriga = 1; + + if (clifomag_curr.get_int(CLIFOGIAC_ANNOES) == saldo.codes() && + clifomag_curr.get_char(CLIFOGIAC_TIPOCF) == saldo.tipocf() && + clifomag_curr.get(CLIFOGIAC_CODCF) == saldo.codcf() && + clifomag_curr.get(CLIFOGIAC_INDSPED) == saldo.codindsp() && + clifomag_curr.get(CLIFOGIAC_CODART) == saldo.codart()) + nriga = clifomag_curr.get_int(CLIFOGIAC_NRIGA) + 1; + clifomag_curr.put(CLIFOGIAC_NRIGA, nriga); + + const int err = clifomag.write(); + + CHECKD(err == NOERR, "Clifomag : Errore di write:", err); + clifomag.setkey(2); + } + saldo.update_record(clifomag_curr); + if (clifomag.rewrite() != NOERR) + ok = false; + pi.add_status(); + } + } + __saldi_mag.destroy(); + __saldi_mag_clifo.destroy(); + __cache_saldi = false; + __from_art = EMPTY_STRING; + __to_art = EMPTY_STRING; + } + + a.close(); + + return ok; +}