// oggetto TCausale_magazzino // oggetto TMov_Mag , multirecord del movimento di magazzino // funzione di ricostruzione saldi #include #include #include #include #include "clifogiac.h" #include "mglib.h" #include "movmag.h" #include #ifndef __CGLIB01_H #include "../cg/cglib01.h" #endif #ifndef __DBLIB_H #include "../db/dblib.h" #endif class TSaldo_mag : public TObject { int _codes; TString8 _codmag; TCodice_articolo _codart; TString16 _livello; TString8 _codcaus; real _quant; real _valore; public: const int codes() const { return _codes;} const TString& codmag() const { return _codmag; } const TCodice_articolo & codart() const { return _codart; } const TString& livello() const { return _livello; } const TString& codcaus() const { return _codcaus; } const real& quant() const { return _quant; } const real& valore() const { return _valore; } void set(int codes, const char * codmag, const char * codart, const char * livello, const char * codcaus); int operator==(const TSaldo_mag&) const; virtual TObject* dup() const { return new TSaldo_mag(*this); } bool is_deletable() const { return _quant == ZERO && _valore == ZERO; } static TToken_string & key(const TRectype & head, const TRectype & row); void add_quant(const real & q, bool plus = true) { _quant = _quant + (plus ? q : -q); } void add_valore(const real & v, bool plus = true) { _valore = _valore + (plus ? v : -v); } void add(const real & q, const real & v, bool plus = true) { add_quant(q, plus); add_valore(v, plus); } void sub_quant(const real & q) { add_quant(q, false); } void sub_valore(const real & v) { add_valore(v, false); } void sub(const real & q, const real & v) { add(q, v, false); } TSaldo_mag(int codes, const char * codmag, const char * codart, const char * livello, const char * codcaus) {set(codes, codmag, codart, livello, codcaus);} TSaldo_mag(const TRectype & head, const TRectype & row); TSaldo_mag(const TSaldo_mag & s); virtual ~TSaldo_mag() {}; }; void TSaldo_mag::set(int codes, const char * codmag, const char * codart, const char * livello, const char * codcaus) { _codes = codes; _codmag = codmag; _codart = codart; _livello = livello; _codcaus = codcaus; } int TSaldo_mag::operator==(const TSaldo_mag & s) const { return (_codes == s._codes) && (_codmag == s._codmag) && (_codart == s._codart) && (_livello == s._livello) && (_codcaus == s._codcaus); } TToken_string & TSaldo_mag::key(const TRectype & head, const TRectype & row) { TToken_string& key = get_tmp_string(); key.add(head.get_int(MOVMAG_ANNOES)); key.add(row.get(RMOVMAG_CODMAG)); key.add(row.get(RMOVMAG_CODART)); key.add(row.get(RMOVMAG_LIVGIAC)); const TString & c = row.get(RMOVMAG_CODCAUS); key.add(c.full() ? c : head.get(MOVMAG_CODCAUS)); return key; } TSaldo_mag::TSaldo_mag(const TRectype & head, const TRectype & row) { _codes = head.get_int(MOVMAG_ANNOES); _codmag = row.get(RMOVMAG_CODMAG); _codart = row.get(RMOVMAG_CODART); _livello = row.get(RMOVMAG_LIVGIAC); _codcaus = row.get(RMOVMAG_CODCAUS); if (_codcaus.blank()) _codcaus = head.get(MOVMAG_CODCAUS); } TSaldo_mag::TSaldo_mag(const TSaldo_mag & s) { set(s._codes, s._codmag, s._codart, s._livello, s._codcaus); _quant = s._quant; _valore = s._valore; } class TSaldo_mag_clifo : public TObject { int _codes; char _tipocf; TString8 _codcf; int _codindsp; TCodice_articolo _codart; TString16 _livello; TString8 _codcaus; real _quant; real _valore; public: const int codes() const { return _codes;} const char tipocf() const { return _tipocf;} const TString& codcf() const { return _codcf; } const int codindsp() const { return _codindsp;} const TCodice_articolo & codart() const { return _codart; } const TString& livello() const { return _livello; } const TString& codcaus() const { return _codcaus; } const real& quant() const { return _quant; } const real& valore() const { return _valore; } void set(int codes, char tipocf, const char * codcf, int codindsp, const char * codart, const char * livello, const char * codcaus); int operator==(const TSaldo_mag_clifo&) const; virtual TObject* dup() const { return new TSaldo_mag_clifo(*this); } bool is_deletable() const { return _quant == ZERO && _valore == ZERO; } static TToken_string & key(const TRectype & head, const TRectype & row); void add_quant(const real & q, bool plus = true) { _quant = _quant + (plus ? q : -q); } void add_valore(const real & v, bool plus = true) { _valore = _valore + (plus ? v : -v); } void add(const real & q, const real & v, bool plus = true) { add_quant(q, plus); add_valore(v, plus); } void sub_quant(const real & q) { add_quant(q, false); } void sub_valore(const real & v) { add_valore(v, false); } void sub(const real & q, const real & v) { add(q, v, false); } TSaldo_mag_clifo(int codes, char tipocf, const char * codcf, int codindsp, const char * codart, const char * livello, const char * codcaus); TSaldo_mag_clifo(const TRectype & head, const TRectype & row); TSaldo_mag_clifo(const TSaldo_mag_clifo & s); virtual ~TSaldo_mag_clifo() {}; }; void TSaldo_mag_clifo::set(int codes, char tipocf, const char * codcf, int codindsp, const char * codart, const char * livello, const char * codcaus) { _codes = codes; _tipocf = tipocf; _codcf = codcf; _codart = codart; _codindsp = codindsp; _codart = codart; _livello = livello; _codcaus = codcaus; } int TSaldo_mag_clifo::operator==(const TSaldo_mag_clifo & s) const { return (_codes == s._codes) && (_tipocf == s._tipocf) && (_codcf == s._codcf) && (_codindsp == s._codindsp) && (_codart == s._codart) && (_livello == s._livello) && (_codcaus == s._codcaus); } TToken_string & TSaldo_mag_clifo::key(const TRectype & head, const TRectype & row) { TToken_string& key = get_tmp_string(); key.add(head.get_int(MOVMAG_ANNOES)); key.add(head.get(MOVMAG_TIPOCF)); key.add(head.get(MOVMAG_CODCF)); key.add(head.get_int(MOVMAG_CODINDSP)); key.add(row.get(RMOVMAG_CODART)); key.add(row.get(RMOVMAG_LIVGIAC)); const TString & c = row.get(RMOVMAG_CODCAUS); key.add(c.full() ? c : head.get(MOVMAG_CODCAUS)); return key; } TSaldo_mag_clifo::TSaldo_mag_clifo(const TRectype & head, const TRectype & row) { _codes = head.get_int(MOVMAG_ANNOES); _tipocf = head.get_char(MOVMAG_TIPOCF); _codcf = head.get(MOVMAG_CODCF); _codindsp = head.get_int(MOVMAG_CODINDSP); _codart = row.get(RMOVMAG_CODART); _livello = row.get(RMOVMAG_LIVGIAC); _codcaus = row.get(RMOVMAG_CODCAUS); if (_codcaus.blank()) _codcaus = head.get(MOVMAG_CODCAUS); } TSaldo_mag_clifo::TSaldo_mag_clifo(const TSaldo_mag_clifo & s) { set(s._codes, s._tipocf, s._codcf, s._codindsp, s._codart, s._livello, s._codcaus); _quant = s._quant; _valore = s._valore; } // ******************************** // TMov_mag TMov_mag::TMov_mag() : TMultiple_rectype(LF_MOVMAG) { add_file(LF_RMOVMAG,"NRIG"); } TMov_mag::TMov_mag(long numreg) : TMultiple_rectype(LF_MOVMAG) { add_file(LF_RMOVMAG,"NRIG"); TLocalisamfile movmag(LF_MOVMAG); put(MOVMAG_NUMREG, numreg); read(movmag); } TMov_mag::~TMov_mag() { } TCausale_magazzino& TMov_mag::causale(int row) const { const TRectype & rowrec = body()[row]; TString8 cod(rowrec.get(RMOVMAG_CODCAUS)); if (cod.blank()) cod = get(MOVMAG_CODCAUS); return cached_causale_magazzino(cod); } void TMov_mag::zero(char c) { TMultiple_rectype::zero(c); _saldi_mag.destroy(); _saldi_mag_clifo.destroy(); } // valuta il valore della chiave per un nuovo record bool TMov_mag::renum() { put(MOVMAG_NUMREG,get_next_key()); return TRUE; } // copia la chiave dal file principale a quello delle righe void TMov_mag::set_body_key(TRectype & rowrec) { rowrec.put(RMOVMAG_NUMREG,get(MOVMAG_NUMREG)); } /*void TMov_mag::load_rows_file(int logicnum) { CHECK(logicnum==LF_RMOVMAG,"L'unico file collegabile ai movimenti sono le righe"); TMultiple_rectype::load_rows_file(logicnum); }*/ int TMov_mag::read(TBaseisamfile& f, word op, word lockop) { _saldi_mag.destroy(); _saldi_mag_clifo.destroy(); const int err = TMultiple_rectype::read(f, op, lockop); if (err == NOERR) add_saldi(false); return err; } int TMov_mag::remove(TBaseisamfile& f) const { const int res = TMultiple_rectype::remove(f); if (res == NOERR) ((TMov_mag *)this)->update_balances(); return res; } void TMov_mag::add_extrarows() const { add_autorows(); add_explrows(); // if (add_explrows()) // add_autorows(); } bool TMov_mag::add_autorows() const { bool added=FALSE; TString8 codmag; // aggiunge le righe automatiche for (int r = rows(); r > 0; r--) { TRecord_array & b = body(); TRectype & row = b[r]; const TCausale_magazzino& cau = causale(r); const TString& codcaus = cau.caus_collegata(); if (codcaus.not_empty()) { const TCausale_magazzino& cau_coll = cached_causale_magazzino(codcaus); if (!row.get_bool(RMOVMAG_ESPLOSA)) { // deve esserci una riga collegata if (!b.exist(r + 1) || b[r + 1].get_char(RMOVMAG_TIPORIGA) != riga_automatica) { // manca, la inserisco TRectype * linea_auto = new TRectype(row); codmag = codmag_rauto(r); if (codmag.empty()) codmag = cau_coll.default_magdep(); if (codmag.not_empty()) linea_auto->put(RMOVMAG_CODMAG, codmag); const char * prezzo = prezzo_rauto(r); if (prezzo != NULL) linea_auto->put(RMOVMAG_PREZZO, prezzo); linea_auto->put(RMOVMAG_NRIG, r+1); linea_auto->put(RMOVMAG_TIPORIGA, (char) riga_automatica); linea_auto->put(RMOVMAG_CODCAUS, codcaus); b.insert_row(linea_auto); added=TRUE; } } } } // ciclo righe return added; } bool TMov_mag::add_explrows() const { TDistinta_tree distinta; TArray boom; bool added=FALSE; TRecord_array& b = body(); // aggiunge le righe da explosione distinta for (int r = rows(); r > 0; r--) { const TRectype& row = b[r]; const TCausale_magazzino& cau = causale(r); if (cau.esplodente() && !row.get_bool(RMOVMAG_ESPLOSA)) { const TCodice_articolo codart = row.get(RMOVMAG_CODART); const char tipo_costo = cau.get("S11")[0]; const int livello = cau.get_int("I0"); const TString4 umroot(row.get(RMOVMAG_UM)); const int rigaprec = r - 1; const bool is_coll = r > 0 && b[r].get_char(RMOVMAG_TIPORIGA) == riga_automatica; // mancano le righe, le inserisco boom.destroy(); bool ok=distinta.set_root(row); if (ok) { bool stop_prod = cau.get_bool("B4"); distinta.explode(boom, TRUE, RAGGR_EXP_NONE, livello, "A", 0, stop_prod); //TString codmag(codmag_rauto(r)); real prezzo(prezzo_rauto(r)); TRectype * linea_auto; for (int newrow=0; newrow < boom.items() ; newrow++) { TRiga_esplosione & riga_esp=(TRiga_esplosione & )(boom[newrow]); linea_auto = new TRectype(row); linea_auto->put(RMOVMAG_CODART, riga_esp.articolo()); linea_auto->put(RMOVMAG_LIVGIAC, riga_esp.giacenza()); linea_auto->put(RMOVMAG_UM, riga_esp.um()); linea_auto->put(RMOVMAG_QUANT, riga_esp.val()); linea_auto->put(RMOVMAG_CODCAUS, cau.codice()); //if (codmag.not_empty()) // linea_auto->put(RMOVMAG_CODMAG, codmag); //if (!prezzo.is_zero()) const TArticolo & articolo = cached_article(riga_esp.articolo()); if (tipo_costo == 'U') prezzo = articolo.get_real(ANAMAG_ULTCOS1); else if (tipo_costo == 'S') prezzo = articolo.get_real(ANAMAG_COSTSTD); linea_auto->put(RMOVMAG_PREZZO, prezzo); linea_auto->put(RMOVMAG_NRIG, r+1+newrow); linea_auto->put(RMOVMAG_ESPLOSA, TRUE); char coll_type = articolo.get_char(ANAMAG_COLLTYPE); TString8 codmag; if (coll_type == 'M') { if (is_coll) codmag = b[rigaprec].get(RMOVMAG_CODMAG); } else if (coll_type == 'F') { TString16 key("F|"); key << articolo.get(ANAMAG_CODFORN); codmag = cache().get(LF_CFVEN, key, CFV_CODMAG); } else if (coll_type == 'A') codmag = articolo.get(ANAMAG_CODMAG); if (codmag.not_empty()) linea_auto->put(RMOVMAG_CODMAG, codmag); b.insert_row(linea_auto); added=TRUE; } // ora ci sono, mi basta eliminare la riga "padre" if (boom.items() > 0 ) { if (boom.items() == 1 && codart == ((TRiga_esplosione &)boom[0]).articolo()) error_box(FR("Movimento di magazzino %ld:\ndistinta %s ciclica"), get_long(MOVMAG_NUMREG),(const char *)codart); b.destroy_row(r,TRUE); } else message_box(FR("Movimento di magazzino %ld:\nimpossibile esplodere l'articolo %s"), get_long(MOVMAG_NUMREG),(const char *)codart); } else if (b[r].get_char(RMOVMAG_TIPORIGA) == riga_automatica) b.destroy_row(r,TRUE); } } // ciclo righe return added; } int TMov_mag::write(TBaseisamfile& f) const { int res; add_extrarows(); if ((res=TMultiple_rectype::write(f))==NOERR ) { TMov_mag &myself=((TMov_mag &)*this); myself.add_saldi(); myself.update_balances(); myself.add_saldi(false); } return res; } int TMov_mag::rewrite(TBaseisamfile& f) const { int res; add_extrarows(); if ((res=TMultiple_rectype::rewrite(f))==NOERR ) { TMov_mag &myself=((TMov_mag &)*this); myself.add_saldi(); myself.update_balances(); myself.add_saldi(false); } return res; } const char* TMov_mag::get_next_key() { TLocalisamfile f(LF_MOVMAG); f.last(); long a = f.get_long(MOVMAG_NUMREG)+1; TString& nextcod = get_tmp_string(); nextcod.format("%ld", a); return nextcod; } bool TMov_mag::key_complete() { const bool ok = head().get_long(MOVMAG_NUMREG) > 0L; return ok; } //******* // gestione delle variazione dei saldi // // bool TMov_mag::force_update_bal() { // reset delle strutture per il controlli delle variazioni dei saldi const TRecord_array & b = body(); _saldi_mag.destroy(); _saldi_mag_clifo.destroy(); add_saldi(); return update_balances(false); } void TMov_mag::renum_mov(const long numreg) { put(MOVMAG_NUMREG, numreg); renum_key(); } // restituisce il valore dei dati void TMov_mag::add_saldi(const bool plus) { const TRecord_array& b = body(); for (int i = b.last_row(); i > 0; i = b.pred_row(i)) { const TRectype & rec = b[i]; TToken_string & key_mag = TSaldo_mag::key(*this, rec); TSaldo_mag * s_mag = (TSaldo_mag*) _saldi_mag.objptr(key_mag); if (s_mag == NULL) { s_mag = new TSaldo_mag(*this, rec); _saldi_mag.add(key_mag, s_mag); } real quant = rec.get_real(RMOVMAG_QUANT); const TCausale_magazzino& caus = causale(i); TArticolo & art = articolo(i); quant =art.convert_to_um(quant, NULL, rec.get(RMOVMAG_UM)); real valore = (quant.is_zero() && caus.update_val()) ? rec.get_real(RMOVMAG_PREZZO) : rec.get_real(RMOVMAG_PREZZO) * quant; s_mag->add(quant, valore, plus); if (caus.aggiorna_clifo()&& get_long(MOVMAG_CODCF) > 0L) { TToken_string & key_clifo = TSaldo_mag_clifo::key(*this, rec); TSaldo_mag_clifo * s_clifo = (TSaldo_mag_clifo*) _saldi_mag_clifo.objptr(key_clifo); if (s_clifo == NULL) { s_clifo = new TSaldo_mag_clifo(*this, rec); _saldi_mag_clifo.add(key_clifo, s_clifo); } s_clifo->add(quant, valore, plus); } } } bool TMov_mag::unlock_anamag(const char *codart) { TLocalisamfile anamag(LF_ANAMAG); anamag.put(ANAMAG_CODART,codart); return (anamag.read(_isequal,_unlock)==NOERR); } bool TMov_mag::lock_anamag(const char *codart) { TLocalisamfile anamag(LF_ANAMAG); anamag.put(ANAMAG_CODART,codart); KEY key = K_ENTER; while (key != K_ESC) { if (anamag.read(_isequal,_testandlock)==NOERR) return TRUE; TString mess; mess << TR("Il record di anagrafica dell'articolo '")<< codart << TR("' risulta essere già in uso."); TTimed_breakbox bbox(mess,10); key = bbox.run(); } return FALSE; } void TMov_mag::giac_putkey(TRectype& mag, const TSaldo_mag & s) { mag.zero(); mag.put(MAG_ANNOES, s.codes()); mag.put(MAG_CODMAG, s.codmag()); mag.put(MAG_CODART, s.codart()); mag.put(MAG_LIVELLO, s.livello()); } void TMov_mag::giac_putkey_clifo(TRectype& clifomag, const TSaldo_mag_clifo & s) { clifomag.zero(); clifomag.put(CLIFOGIAC_ANNOES, s.codes()); clifomag.put(CLIFOGIAC_TIPOCF, s.tipocf()); clifomag.put(CLIFOGIAC_CODCF, s.codcf()); clifomag.put(CLIFOGIAC_INDSPED, s.codindsp()); clifomag.put(CLIFOGIAC_CODART, s.codart()); clifomag.put(CLIFOGIAC_LIVELLO, s.livello()); } // aggiorna tutti i saldi in base alle modifiche fatte. // il lock su anagrafica dovrebbe garantire il lock su tutte le giacenze dell'articolo bool TMov_mag::update_balances(bool lock) { bool updated_bal = true; TLocalisamfile mag(LF_MAG); mag.setkey(2); TRectype& magcurr = mag.curr(); const TRecord_array& b = body(); const TString8 hcodcaus = get(MOVMAG_CODCAUS); for (int i = b.last_row(); i > 0; i = b.pred_row(i)) if (causale(i).update_ultcos()) { const TRectype & rec = b[i]; TArticolo & art = articolo(i); if (art.lock_and_prompt(lock ? _testandlock : _nolock)) { const real prezzo = art.convert_to_um(rec.get_real(RMOVMAG_PREZZO), NULL, rec.get(RMOVMAG_UM), false); const long numreg = get_long(MOVMAG_NUMREG); art.update_ultcosti(prezzo,get_date(MOVMAG_DATACOMP), numreg, i); art.rewrite(); } else { if (lock) art.unlock(); } } if (_saldi_mag.items() > 0) { TString_array keys_mag; _saldi_mag.get_keys(keys_mag); keys_mag.sort(); for (TToken_string* curr_key = (TToken_string*)keys_mag.first_item(); curr_key != NULL; curr_key = (TToken_string*)keys_mag.succ_item()) { const TSaldo_mag& saldo = (const TSaldo_mag&)_saldi_mag[*curr_key]; const TCodice_articolo& codart = saldo.codart(); TArticolo_giacenza& art = cached_article_balances(codart); if (art.lock_and_prompt(lock ? _testandlock : _nolock)) { giac_putkey(magcurr, saldo); int err = mag.read(); if (err != NOERR) { TRecord_array& sld = art.mag(saldo.codes()); const int nriga = sld.rows() + 1; giac_putkey(magcurr, saldo); magcurr.put(MAG_NRIGA, nriga); sld.add_row(magcurr); err = mag.write(); } update_balances(magcurr, saldo); err = mag.rewrite(); if (err != NOERR) updated_bal = false; if (lock) art.unlock(); } } } if (_saldi_mag_clifo.items() > 0) { TLocalisamfile clifomag(LF_CLIFOGIAC); clifomag.setkey(2); TRectype& clifomag_curr = clifomag.curr(); TString_array keys_clifo; _saldi_mag_clifo.get_keys(keys_clifo); keys_clifo.sort(); for (TToken_string* curr_key = (TToken_string*)keys_clifo.first_item(); curr_key != NULL; curr_key = (TToken_string*)keys_clifo.succ_item()) { TSaldo_mag_clifo & saldo=(TSaldo_mag_clifo &)_saldi_mag_clifo[*curr_key]; TArticolo_giacenza & art = cached_article_balances(saldo.codart()); if (art.lock_and_prompt(lock ? _testandlock : _nolock)) { giac_putkey_clifo(clifomag_curr, saldo); if (clifomag.read() != NOERR) { // non trovato: aggiungo clifomag.setkey(1); giac_putkey_clifo(clifomag_curr, saldo); clifomag_curr.put(CLIFOGIAC_NRIGA, 999); if (clifomag.read(_isgteq) == NOERR) clifomag.prev(); 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_CODART) == saldo.codart() && clifomag_curr.get(CLIFOGIAC_LIVELLO ) == saldo.livello()) nriga = clifomag_curr.get_int(CLIFOGIAC_NRIGA) + 1; giac_putkey_clifo(clifomag_curr, saldo); clifomag_curr.put(CLIFOGIAC_NRIGA, nriga); clifomag.write(); clifomag.setkey(2); } update_balances_clifo(clifomag_curr, saldo); clifomag.rewrite(); if (lock) art.unlock(); } } } _saldi_mag.destroy(); _saldi_mag_clifo.destroy(); return updated_bal; } // aggiorna i saldi del record corrente // in base alla causale e alla modifica fatta (con segno + o -) void TMov_mag::update_balances(TRectype & magrec, const TSaldo_mag & s) { const TCausale_magazzino& caus = cached_causale_magazzino(s.codcaus()); if (caus.update_qta()) { const real diff = s.quant(); update_balance(magrec, MAG_GIAC, diff, caus.sgn(s_giac)); // update .. update_balance(magrec, MAG_ACQ, diff, caus.sgn(s_acq)); // update .. update_balance(magrec, MAG_ENT, diff, caus.sgn(s_ent)); update_balance(magrec, MAG_VEN, diff, caus.sgn(s_ven)); update_balance(magrec, MAG_USC, diff, caus.sgn(s_usc)); update_balance(magrec, MAG_ORDC, diff, caus.sgn(s_ordc)); update_balance(magrec, MAG_ORDF, diff, caus.sgn(s_ordf)); update_balance(magrec, MAG_RIM, diff, caus.sgn(s_rim)); update_balance(magrec, MAG_SCARTI, diff, caus.sgn(s_scart)); update_balance(magrec, MAG_INCL, diff, caus.sgn(s_incl)); update_balance(magrec, MAG_ACL, diff, caus.sgn(s_acl)); update_balance(magrec, MAG_PRODCOMP, diff, caus.sgn(s_prodc)); update_balance(magrec, MAG_PRODFIN, diff, caus.sgn(s_prodf)); update_balance(magrec, MAG_NLABEL, diff, caus.sgn(s_label)); update_balance(magrec, MAG_USER1, diff, caus.sgn(s_user1)); update_balance(magrec, MAG_USER2, diff, caus.sgn(s_user2)); update_balance(magrec, MAG_USER3, diff, caus.sgn(s_user3)); update_balance(magrec, MAG_USER4, diff, caus.sgn(s_user4)); update_balance(magrec, MAG_USER5, diff, caus.sgn(s_user5)); update_balance(magrec, MAG_USER6, diff, caus.sgn(s_user6)); } if (caus.update_val()) { const real diff_val = s.valore(); update_balance(magrec, MAG_VALACQ, diff_val, caus.sgn(s_acq)); // update .. update_balance(magrec, MAG_VALENT, diff_val, caus.sgn(s_ent)); update_balance(magrec, MAG_VALVEN, diff_val, caus.sgn(s_ven)); update_balance(magrec, MAG_VALUSC, diff_val, caus.sgn(s_usc)); update_balance(magrec, MAG_VALORDC, diff_val, caus.sgn(s_ordc)); update_balance(magrec, MAG_VALORDF, diff_val, caus.sgn(s_ordf)); update_balance(magrec, MAG_VALRIM, diff_val, caus.sgn(s_rim)); update_balance(magrec, MAG_VALSCARTI, diff_val, caus.sgn(s_scart)); update_balance(magrec, MAG_USERVAL1, diff_val, caus.sgn(s_user1)); update_balance(magrec, MAG_USERVAL2, diff_val, caus.sgn(s_user2)); update_balance(magrec, MAG_USERVAL3, diff_val, caus.sgn(s_user3)); update_balance(magrec, MAG_USERVAL4, diff_val, caus.sgn(s_user4)); update_balance(magrec, MAG_USERVAL5, diff_val, caus.sgn(s_user5)); update_balance(magrec, MAG_USERVAL6, diff_val, caus.sgn(s_user6)); } } // aggiorna i saldi del record corrente // in base alla causale e alla modifica fatta (con segno + o -) void TMov_mag::update_balances_clifo(TRectype & clifomagrec, const TSaldo_mag_clifo & s) { const TCausale_magazzino& caus = cached_causale_magazzino(s.codcaus()); if (caus.update_qta()) { const real diff = s.quant(); update_balance(clifomagrec, CLIFOGIAC_GIAC, -diff, caus.sgn(s_giac)); // update .. update_balance(clifomagrec, CLIFOGIAC_ACQ, diff, caus.sgn(s_ven)); // update .. update_balance(clifomagrec, CLIFOGIAC_ENT, diff, caus.sgn(s_usc)); update_balance(clifomagrec, CLIFOGIAC_VEN, diff, caus.sgn(s_acq)); update_balance(clifomagrec, CLIFOGIAC_USC, diff, caus.sgn(s_ent)); update_balance(clifomagrec, CLIFOGIAC_ORDC, diff, caus.sgn(s_ordf)); update_balance(clifomagrec, CLIFOGIAC_ORDF, diff, caus.sgn(s_ordc)); update_balance(clifomagrec, CLIFOGIAC_RIM, -diff, caus.sgn(s_rim)); update_balance(clifomagrec, CLIFOGIAC_SCARTI, -diff, caus.sgn(s_scart)); update_balance(clifomagrec, CLIFOGIAC_INCL, diff, caus.sgn(s_acl)); update_balance(clifomagrec, CLIFOGIAC_ACL, diff, caus.sgn(s_incl)); update_balance(clifomagrec, CLIFOGIAC_PRODCOMP, -diff, caus.sgn(s_prodc)); update_balance(clifomagrec, CLIFOGIAC_PRODFIN, -diff, caus.sgn(s_prodf)); update_balance(clifomagrec, CLIFOGIAC_DOTIN, diff, caus.sgn(s_dotin)); update_balance(clifomagrec, CLIFOGIAC_DOTOD, diff, caus.sgn(s_dotod)); update_balance(clifomagrec, CLIFOGIAC_DOTTM, diff, caus.sgn(s_dottm)); update_balance(clifomagrec, CLIFOGIAC_CONSANNO, diff, caus.sgn(s_consanno)); update_balance(clifomagrec, CLIFOGIAC_USER1, diff, caus.sgn(s_user1)); update_balance(clifomagrec, CLIFOGIAC_USER2, diff, caus.sgn(s_user2)); update_balance(clifomagrec, CLIFOGIAC_USER3, diff, caus.sgn(s_user3)); update_balance(clifomagrec, CLIFOGIAC_USER4, diff, caus.sgn(s_user4)); update_balance(clifomagrec, CLIFOGIAC_USER5, diff, caus.sgn(s_user5)); update_balance(clifomagrec, CLIFOGIAC_USER6, diff, caus.sgn(s_user6)); } if (caus.update_val()) { const real diff_val = s.valore(); update_balance(clifomagrec, CLIFOGIAC_VALACQ, diff_val, caus.sgn(s_ven)); // update .. update_balance(clifomagrec, CLIFOGIAC_VALENT, diff_val, caus.sgn(s_usc)); update_balance(clifomagrec, CLIFOGIAC_VALVEN, diff_val, caus.sgn(s_acq)); update_balance(clifomagrec, CLIFOGIAC_VALUSC, diff_val, caus.sgn(s_ven)); update_balance(clifomagrec, CLIFOGIAC_VALORDC, diff_val, caus.sgn(s_ordf)); update_balance(clifomagrec, CLIFOGIAC_VALORDF, diff_val, caus.sgn(s_ordc)); update_balance(clifomagrec, CLIFOGIAC_VALRIM, -diff_val, caus.sgn(s_rim)); update_balance(clifomagrec, CLIFOGIAC_VALSCARTI, -diff_val, caus.sgn(s_scart)); update_balance(clifomagrec, CLIFOGIAC_USERVAL1, diff_val, caus.sgn(s_user1)); update_balance(clifomagrec, CLIFOGIAC_USERVAL2, diff_val, caus.sgn(s_user2)); update_balance(clifomagrec, CLIFOGIAC_USERVAL3, diff_val, caus.sgn(s_user3)); update_balance(clifomagrec, CLIFOGIAC_USERVAL4, diff_val, caus.sgn(s_user4)); update_balance(clifomagrec, CLIFOGIAC_USERVAL5, diff_val, caus.sgn(s_user5)); update_balance(clifomagrec, CLIFOGIAC_USERVAL6, diff_val, caus.sgn(s_user6)); } } void TMov_mag::update_balances(TRectype& magrec, int numrig, bool plus) { const TRectype & rec = body()[numrig]; TSaldo_mag saldo(*this, rec); real quant = rec.get_real(RMOVMAG_QUANT); const TCausale_magazzino& caus = cached_causale_magazzino(saldo.codcaus()); TArticolo & art = articolo(numrig); quant = art.convert_to_um(quant, NULL, rec.get(RMOVMAG_UM)); real valore = (quant.is_zero() && caus.update_val()) ? rec.get_real(RMOVMAG_PREZZO) : rec.get_real(RMOVMAG_PREZZO) * quant; saldo.add(quant, valore, plus); return update_balances(magrec, saldo); } void TMov_mag::update_balances_clifo(TRectype& cliforec, int numrig, bool plus) { const TRectype & rec = body()[numrig]; TSaldo_mag_clifo saldo(*this, rec); real quant = rec.get_real(RMOVMAG_QUANT); const TCausale_magazzino& caus = cached_causale_magazzino(saldo.codcaus()); TArticolo & art = articolo(numrig); quant = art.convert_to_um(quant, NULL, rec.get(RMOVMAG_UM)); real valore = (quant.is_zero() && caus.update_val()) ? rec.get_real(RMOVMAG_PREZZO) : rec.get_real(RMOVMAG_PREZZO) * quant; saldo.add(quant, valore, plus); return update_balances_clifo(cliforec, saldo); } int TMov_mag::codice_esercizio(const TDate &d) { return esercizi().date2esc(d); } void TMov_mag::update_balance(TRectype & rec, const char * fieldname, const real& val, const int sgn) const { if (sgn != 0) { if (sgn > 0) rec.add(fieldname, val); else rec.add(fieldname, -val); } } struct TBalance_params { bool zero_giac; bool closed; int codes; int codesprec; int esprec; TTipo_valorizz tipov; const char * catv; const char * codl; }; HIDDEN bool reset_giac(const TRelation& rel, void* pJolly) { TArticolo_giacenza & articolo = (TArticolo_giacenza &) rel.lfile().curr(); TBalance_params & p = *((TBalance_params *)pJolly); if (p.zero_giac) articolo.azzera_saldi(p.codes, p.codesprec); else articolo.riporta_saldi(p.codesprec, p.codes, p.tipov, p.catv, p.codl); return true; } void reset_clifogiac(TRectype & rec, const TRectype & oldrec, bool closed) { if (!oldrec.empty()) { const real acq = oldrec.get_real(CLIFOGIAC_ACQ) + oldrec.get_real(CLIFOGIAC_RIM); const real valacq = oldrec.get_real(CLIFOGIAC_VALACQ) + oldrec.get_real(CLIFOGIAC_VALRIM); real val = acq.is_zero() ? ZERO : valacq / acq; const TPrice p(val); real rim; rim += oldrec.get_real(CLIFOGIAC_GIAC); rim += oldrec.get_real(CLIFOGIAC_PRODFIN); rim -= oldrec.get_real(CLIFOGIAC_PRODCOMP); rim += oldrec.get_real(CLIFOGIAC_ACL); rim -= oldrec.get_real(CLIFOGIAC_INCL); const real valrim = p.get_num() * rim; const TCurrency c(valrim); // Arrontonda alla valuta rec.put(CLIFOGIAC_RIM, rim); rec.put(CLIFOGIAC_VALRIM, c.get_num()); rec.zero(CLIFOGIAC_ACQ); rec.zero(CLIFOGIAC_VALACQ); rec.zero(CLIFOGIAC_ENT); rec.zero(CLIFOGIAC_VALENT); rec.zero(CLIFOGIAC_VEN); rec.zero(CLIFOGIAC_VALVEN); rec.zero(CLIFOGIAC_USC); rec.zero(CLIFOGIAC_VALUSC); rec.zero(CLIFOGIAC_SCARTI); if (!riporta_ordinato() || !closed) { rec.zero(CLIFOGIAC_ORDF); rec.zero(CLIFOGIAC_VALORDF); rec.zero(CLIFOGIAC_ORDC); rec.zero(CLIFOGIAC_VALORDC); } if (closed) { rec.put(CLIFOGIAC_DOTOD, oldrec.get(CLIFOGIAC_DOTOD)); rec.put(CLIFOGIAC_DOTIN, oldrec.get(CLIFOGIAC_DOTIN)); rec.put(CLIFOGIAC_DOTTM, oldrec.get(CLIFOGIAC_DOTTM)); } else { rec.zero(CLIFOGIAC_DOTOD); rec.zero(CLIFOGIAC_DOTIN); rec.zero(CLIFOGIAC_DOTTM); } } else { for (int i = 0; zero_fields[i]; i++) rec.zero(zero_fields[i]); rec.zero(CLIFOGIAC_DOTIN); rec.zero(CLIFOGIAC_DOTOD); rec.zero(CLIFOGIAC_DOTTM); } rec.zero(CLIFOGIAC_CONSANNO); } void update_clifogiac(TRectype & rec, const TRectype & oldrec) { if (!oldrec.empty()) { const real acq = oldrec.get_real(CLIFOGIAC_ACQ) + oldrec.get_real(CLIFOGIAC_RIM); const real valacq = oldrec.get_real(CLIFOGIAC_VALACQ) + oldrec.get_real(CLIFOGIAC_VALRIM); real val = acq.is_zero() ? ZERO : valacq / acq; const TPrice p(val); const real rim_prec = rec.get_real(CLIFOGIAC_RIM); real rim = oldrec.get_real(CLIFOGIAC_GIAC); rim += oldrec.get_real(CLIFOGIAC_PRODFIN); rim -= oldrec.get_real(CLIFOGIAC_PRODCOMP); rim += oldrec.get_real(CLIFOGIAC_ACL); rim -= oldrec.get_real(CLIFOGIAC_INCL); const real valrim = p.get_num() * rim; const TCurrency c(valrim); // Arrontonda alla valuta rec.put(CLIFOGIAC_RIM, rim); rec.put(CLIFOGIAC_VALRIM, c.get_num()); rec.add(CLIFOGIAC_GIAC, rim - rim_prec); if (riporta_ordinato()) { rec.add(CLIFOGIAC_ORDF, oldrec.get_real(CLIFOGIAC_ORDF)); rec.add(CLIFOGIAC_VALORDF, oldrec.get_real(CLIFOGIAC_VALORDF)); rec.add(CLIFOGIAC_ORDC, oldrec.get_real(CLIFOGIAC_ORDC)); rec.add(CLIFOGIAC_VALORDC, oldrec.get_real(CLIFOGIAC_VALORDC)); } rec.add(CLIFOGIAC_DOTOD, oldrec.get_real(CLIFOGIAC_DOTOD)); rec.add(CLIFOGIAC_DOTIN, oldrec.get_real(CLIFOGIAC_DOTIN)); rec.add(CLIFOGIAC_DOTTM, oldrec.get_real(CLIFOGIAC_DOTTM)); } } HIDDEN bool rel_reset_clifogiac(const TRelation& rel, void* pJolly) { TRectype & rec = rel.curr(); TBalance_params & p = *((TBalance_params *)pJolly); TRectype newrec(rec); newrec.put(CLIFOGIAC_ANNOES, p.codes); if (newrec.read(rel.lfile()) != NOERR) { newrec = rec; newrec.put(CLIFOGIAC_ANNOES, p.codes); } reset_clifogiac(newrec, rec, p.closed); return newrec.write_rewrite(rel.lfile()) == NOERR; } bool recalc_mov(const TRelation& rel, void* pJolly) { TMov_mag & mov_rec = (TMov_mag &) rel.lfile().curr(); bool & ok = *((bool *) pJolly); ok = mov_rec.force_update_bal(); return true; } bool rebuild_balances(int codes, const TTipo_valorizz tipo_valorizz, const char* catven, const char* codlis) { TSystemisamfile a(LF_MOVMAG); if (a.open(_excllock) != NOERR) return false; TBalance_params p; p.codes = codes; p.codesprec = esercizi().pred(codes); //p.zero_giac = p.codesprec > 0 && esercizi().esercizio(p.codesprec).chiusura_mag().ok(); p.closed = esercizi().esercizio(p.codesprec).chiusura_mag().ok(); p.zero_giac = p.codesprec <= 0 || esercizi().esercizio(p.codesprec).chiusura_mag().ok(); p.catv = catven; p.codl = codlis; p.tipov = tipo_valorizz; // azzera tutte giacenze (ciclo sulle giacenze) TCursor anamag_cur(new TRelation(LF_ANAMAG)); TString msg; anamag_cur.relation()->lfile().set_curr(new TArticolo_giacenza()); anamag_cur.freeze(); msg.format(FR("Ricostruzione saldi esercizio %04d : azzeramento..."), codes); anamag_cur.scan(reset_giac, (void *) &p, msg); TString filter; filter << CLIFOGIAC_ANNOES << "==" << p.codesprec; TCursor c(new TRelation(LF_CLIFOGIAC), filter); msg.format(FR("Ricostruzione saldi esercizio %04d : azzeramento giacenze clienti..."), codes); c.scan(rel_reset_clifogiac, (void *) &p, msg); // ricostruisce i saldi (ciclo sui movimenti) bool ok = true; TRelation relmovmag(LF_MOVMAG); TRectype& rec = relmovmag.curr(); rec.put(MOVMAG_ANNOES, codes); TCursor mov_cur(&relmovmag ,"", 2, &rec, &rec); relmovmag.lfile().set_curr(new TMov_mag()); msg.format(FR("Ricostruzione saldi esercizio %04d : ricalcolo..."), codes); mov_cur.scan(recalc_mov, (void *) &ok, msg); a.close(); return ok; }