campo-sirio/mg/mglib02a.cpp

979 lines
31 KiB
C++
Raw Normal View History

// oggetto TCausale_magazzino
// oggetto TMov_Mag , multirecord del movimento di magazzino
// funzione di ricostruzione saldi
#include <diction.h>
#include <progind.h>
#include <recset.h>
#include <utility.h>
#include "clifogiac.h"
#include "mglib.h"
#include "movmag.h"
#include "rmovmag.h"
#include <cfven.h>
#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()
{
}
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());
//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<67> in uso.");
TTimed_breakbox bbox(mess,10);
key = bbox.run();
}
return FALSE;
}
void TMov_mag::giac_putkey(TLocalisamfile & mag, 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(TLocalisamfile & clifomag, 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);
TLocalisamfile clifomag(LF_CLIFOGIAC);
const TRecord_array& b = body();
const TString8 hcodcaus(get(MOVMAG_CODCAUS));
const long numreg = get_long(MOVMAG_NUMREG);
mag.setkey(2);
clifomag.setkey(2);
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);
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()
)
{
TSaldo_mag & saldo = (TSaldo_mag &)_saldi_mag[*curr_key];
TArticolo_giacenza & art = cached_article_balances(saldo.codart());
if (art.lock_and_prompt(lock ? _testandlock : _nolock))
{
giac_putkey(mag, saldo);
if (mag.read() != NOERR)
{
giac_putkey(mag, saldo);
mag.put(MAG_NRIGA, art.mag(get(MOVMAG_ANNOES)).rows() + 1);
mag.write();
}
update_balances(mag.curr(), saldo);
mag.rewrite();
if (lock)
art.unlock();
}
}
}
if (_saldi_mag_clifo.items() > 0)
{
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, saldo);
if (clifomag.read() != NOERR)
{
// non trovato: aggiungo
clifomag.setkey(1);
giac_putkey_clifo(clifomag, saldo);
clifomag.put(CLIFOGIAC_NRIGA, 999);
if (clifomag.read(_isgteq) == NOERR)
clifomag.prev();
int nriga = 1;
if (clifomag.get_int(CLIFOGIAC_ANNOES) == saldo.codes() &&
clifomag.get_char(CLIFOGIAC_TIPOCF) == saldo.tipocf() &&
clifomag.get(CLIFOGIAC_CODCF) == saldo.codcf() &&
clifomag.get(CLIFOGIAC_CODART) == saldo.codart() &&
clifomag.get(CLIFOGIAC_LIVELLO ) == saldo.livello())
nriga = clifomag.get_int(CLIFOGIAC_NRIGA) + 1;
giac_putkey_clifo(clifomag, saldo);
clifomag.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 * (real)caus.sgn(s_giac)); // update ..
update_balance(magrec, MAG_ACQ, diff * (real)caus.sgn(s_acq)); // update ..
update_balance(magrec, MAG_ENT, diff * (real)caus.sgn(s_ent));
update_balance(magrec, MAG_VEN, diff * (real)caus.sgn(s_ven));
update_balance(magrec, MAG_USC, diff * (real)caus.sgn(s_usc));
update_balance(magrec, MAG_ORDC, diff * (real)caus.sgn(s_ordc));
update_balance(magrec, MAG_ORDF, diff * (real)caus.sgn(s_ordf));
update_balance(magrec, MAG_RIM, diff * (real)caus.sgn(s_rim));
update_balance(magrec, MAG_SCARTI, diff * (real)caus.sgn(s_scart));
update_balance(magrec, MAG_INCL, diff * (real)caus.sgn(s_incl));
update_balance(magrec, MAG_ACL, diff * (real)caus.sgn(s_acl));
update_balance(magrec, MAG_PRODCOMP, diff * (real)caus.sgn(s_prodc));
update_balance(magrec, MAG_PRODFIN, diff * (real)caus.sgn(s_prodf));
update_balance(magrec, MAG_NLABEL, diff * (real)caus.sgn(s_label));
update_balance(magrec, MAG_USER1, diff * (real)caus.sgn(s_user1));
update_balance(magrec, MAG_USER2, diff * (real)caus.sgn(s_user2));
update_balance(magrec, MAG_USER3, diff * (real)caus.sgn(s_user3));
update_balance(magrec, MAG_USER4, diff * (real)caus.sgn(s_user4));
update_balance(magrec, MAG_USER5, diff * (real)caus.sgn(s_user5));
update_balance(magrec, MAG_USER6, diff * (real)caus.sgn(s_user6));
}
if (caus.update_val())
{
const real diff_val = s.valore();
update_balance(magrec, MAG_VALACQ, diff_val * (real)caus.sgn(s_acq)); // update ..
update_balance(magrec, MAG_VALENT, diff_val * (real)caus.sgn(s_ent));
update_balance(magrec, MAG_VALVEN, diff_val * (real)caus.sgn(s_ven));
update_balance(magrec, MAG_VALUSC, diff_val * (real)caus.sgn(s_usc));
update_balance(magrec, MAG_VALORDC, diff_val * (real)caus.sgn(s_ordc));
update_balance(magrec, MAG_VALORDF, diff_val * (real)caus.sgn(s_ordf));
update_balance(magrec, MAG_VALRIM, diff_val* (real)caus.sgn(s_rim));
update_balance(magrec, MAG_VALSCARTI, diff_val * (real)caus.sgn(s_scart));
update_balance(magrec, MAG_USERVAL1, diff_val * (real)caus.sgn(s_user1));
update_balance(magrec, MAG_USERVAL2, diff_val * (real)caus.sgn(s_user2));
update_balance(magrec, MAG_USERVAL3, diff_val * (real)caus.sgn(s_user3));
update_balance(magrec, MAG_USERVAL4, diff_val * (real)caus.sgn(s_user4));
update_balance(magrec, MAG_USERVAL5, diff_val * (real)caus.sgn(s_user5));
update_balance(magrec, MAG_USERVAL6, diff_val * (real)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 * (real)caus.sgn(s_giac)); // update ..
update_balance(clifomagrec, CLIFOGIAC_ACQ, diff * (real)caus.sgn(s_ven)); // update ..
update_balance(clifomagrec, CLIFOGIAC_ENT, diff * (real)caus.sgn(s_usc));
update_balance(clifomagrec, CLIFOGIAC_VEN, diff * (real)caus.sgn(s_acq));
update_balance(clifomagrec, CLIFOGIAC_USC, diff * (real)caus.sgn(s_ent));
update_balance(clifomagrec, CLIFOGIAC_ORDC, diff * (real)caus.sgn(s_ordf));
update_balance(clifomagrec, CLIFOGIAC_ORDF, diff * (real)caus.sgn(s_ordc));
update_balance(clifomagrec, CLIFOGIAC_RIM, -diff * (real)caus.sgn(s_rim));
update_balance(clifomagrec, CLIFOGIAC_SCARTI, -diff * (real)caus.sgn(s_scart));
update_balance(clifomagrec, CLIFOGIAC_INCL, diff * (real)caus.sgn(s_acl));
update_balance(clifomagrec, CLIFOGIAC_ACL, diff * (real)caus.sgn(s_incl));
update_balance(clifomagrec, CLIFOGIAC_PRODCOMP, -diff * (real)caus.sgn(s_prodc));
update_balance(clifomagrec, CLIFOGIAC_PRODFIN, -diff * (real)caus.sgn(s_prodf));
update_balance(clifomagrec, CLIFOGIAC_DOTIN, diff * (real)caus.sgn(s_dotin));
update_balance(clifomagrec, CLIFOGIAC_DOTOD, diff * (real)caus.sgn(s_dotod));
update_balance(clifomagrec, CLIFOGIAC_DOTTM, diff * (real)caus.sgn(s_dottm));
update_balance(clifomagrec, CLIFOGIAC_USER1, diff * (real)caus.sgn(s_user1));
update_balance(clifomagrec, CLIFOGIAC_USER2, diff * (real)caus.sgn(s_user2));
update_balance(clifomagrec, CLIFOGIAC_USER3, diff * (real)caus.sgn(s_user3));
update_balance(clifomagrec, CLIFOGIAC_USER4, diff * (real)caus.sgn(s_user4));
update_balance(clifomagrec, CLIFOGIAC_USER5, diff * (real)caus.sgn(s_user5));
update_balance(clifomagrec, CLIFOGIAC_USER6, diff * (real)caus.sgn(s_user6));
}
if (caus.update_val())
{
const real diff_val = s.valore();
update_balance(clifomagrec, CLIFOGIAC_VALACQ, diff_val * (real)caus.sgn(s_ven)); // update ..
update_balance(clifomagrec, CLIFOGIAC_VALENT, diff_val * (real)caus.sgn(s_usc));
update_balance(clifomagrec, CLIFOGIAC_VALVEN, diff_val * (real)caus.sgn(s_acq));
update_balance(clifomagrec, CLIFOGIAC_VALUSC, diff_val * (real)caus.sgn(s_ven));
update_balance(clifomagrec, CLIFOGIAC_VALORDC, diff_val * (real)caus.sgn(s_ordf));
update_balance(clifomagrec, CLIFOGIAC_VALORDF, diff_val * (real)caus.sgn(s_ordc));
update_balance(clifomagrec, CLIFOGIAC_VALRIM, -diff_val* (real)caus.sgn(s_rim));
update_balance(clifomagrec, CLIFOGIAC_VALSCARTI, -diff_val * (real)caus.sgn(s_scart));
update_balance(clifomagrec, CLIFOGIAC_USERVAL1, diff_val * (real)caus.sgn(s_user1));
update_balance(clifomagrec, CLIFOGIAC_USERVAL2, diff_val * (real)caus.sgn(s_user2));
update_balance(clifomagrec, CLIFOGIAC_USERVAL3, diff_val * (real)caus.sgn(s_user3));
update_balance(clifomagrec, CLIFOGIAC_USERVAL4, diff_val * (real)caus.sgn(s_user4));
update_balance(clifomagrec, CLIFOGIAC_USERVAL5, diff_val * (real)caus.sgn(s_user5));
update_balance(clifomagrec, CLIFOGIAC_USERVAL6, diff_val * (real)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, real diff) const
{
rec.put(fieldname,rec.get_real(fieldname) + diff);
}
struct TBalance_params
{
bool zero_giac;
int codes;
int codesprec;
int esprec;
TTipo_valorizz tipov;
const char * catv;
const char * codl;
};
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);
else
articolo.riporta_saldi(p.codesprec, p.codes, p.tipov, p.catv, p.codl);
return true;
}
bool reset_clifogiac(const TRelation& rel, void* pJolly)
{
TRectype & rec = rel.curr();
TBalance_params & p = *((TBalance_params *)pJolly);
TRectype oldrec(rec);
oldrec.put(CLIFOGIAC_ANNOES, p.codesprec);
if (oldrec.read(rel.lfile()) == NOERR)
{
const real acq = rec.get_real(MAG_ACQ) + rec.get_real(MAG_RIM);
const real valacq = rec.get_real(MAG_VALACQ) + rec.get_real(MAG_VALRIM);
real val = acq.is_zero() ? ZERO : valacq / acq;
const TPrice p(val);
real rim;
rim += rec.get_real(MAG_GIAC);
rim += rec.get_real(MAG_PRODFIN);
rim -= rec.get_real(MAG_PRODCOMP);
rim += rec.get_real(MAG_ACL);
rim -= rec.get_real(MAG_INCL);
const real valrim = p.get_num() * rim;
const TCurrency c(valrim); // Arrontonda alla valuta
rec.put(MAG_RIM, rim); rec.put(MAG_VALRIM, c.get_num());
rec.zero(MAG_ACQ); rec.zero(MAG_VALACQ);
rec.zero(MAG_ENT); rec.zero(MAG_VALENT);
rec.zero(MAG_VEN); rec.zero(MAG_VALVEN);
rec.zero(MAG_USC); rec.zero(MAG_VALUSC);
rec.zero(MAG_SCARTI);
if (!riporta_ordinato())
{
rec.zero(MAG_ORDF); rec.zero(MAG_VALORDF);
rec.zero(MAG_ORDC); rec.zero(MAG_VALORDC);
}
}
else
{
for (int i = 0; zero_fields[i]; i++)
rec.zero(zero_fields[i]);
}
return rec.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.catv = catven;
p.codl = codlis;
// 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 << "==" << codes;
TCursor c(new TRelation(LF_CLIFOGIAC), filter);
msg.format(FR("Ricostruzione saldi esercizio %04d : azzeramento giacenze clienti..."), codes);
c.scan(reset_clifogiac, (void *) &p, msg);
// ricostruisce i saldi (ciclo sui movimenti)
bool ok = true;
TRectype rec(LF_MOVMAG);
rec.put(MOVMAG_ANNOES, codes);
TCursor mov_cur(new TRelation(LF_MOVMAG),"", 2, &rec, &rec);
mov_cur.relation()->lfile().set_curr(new TMov_mag());
mov_cur.freeze();
msg.format(FR("Ricostruzione saldi esercizio %04d : ricalcolo..."), codes);
mov_cur.scan(recalc_mov, (void *) &ok, msg);
a.close();
return ok;
}