Patch level : 12.0 1070

Files correlati     : mg1.exe mg1200.msk
Commento        :

Ricostruzione saldi di magazzino per articolo

Interno :

Provare oltre alla ricostruzione anche qualche movimento da documenti o da gestione interattiva la ricostruzione
This commit is contained in:
Alessandro Bonazzi 2021-07-27 14:32:38 +02:00
parent b1f1142085
commit b94b73389f
6 changed files with 265 additions and 28 deletions

View File

@ -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\""));
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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;
}