campo-sirio/mg/mglib02.cpp

2010 lines
58 KiB
C++
Executable File
Raw Blame History

// oggetto TArticolo, multirecord dell'articolo di anagrafica magazzino
// oggetto TArticolo_giacenza, multirecord dell'articolo di magazzino
// oggetto TMov_Mag , multirecord del movimento di magazzino
// funzione di ricostruzione saldi
#include <config.h>
#include <diction.h>
#include <fraction.h>
#include <progind.h>
#include "mglib.h"
#include "../cg/cglib01.h"
#include "../ve/veconf.h"
#include "anamag.h"
#include "mag.h"
#include "movmag.h"
#include "rmovmag.h"
// libreria per i movimenti
class TTimed_skipbox: public TTimed_breakbox
{
public:
TTimed_skipbox(const char * message,int seconds,int x=40,int y=10);
~TTimed_skipbox();
};
TTimed_skipbox:: TTimed_skipbox(const char * message,int seconds,int x,int y)
: TTimed_breakbox(message,seconds,x,y)
{
hide(DLG_OK);
hide(DLG_CANCEL);
add_button(DLG_OK, 0, TR("Continua"), -11, -1, 12, 2,"",0);
}
TTimed_skipbox::~TTimed_skipbox()
{}
const char* const nome_valorizz(TTipo_valorizz tipo)
{
switch (tipo)
{
case valorizz_ultcos: return TR("Ultimo costo");
case valorizz_mediacos: return TR("Media ultimi costi");
case valorizz_przlist: return TR("Prezzo di listino");
case valorizz_coststd: return TR("Costo standard");
case valorizz_costmedio: return TR("Costo medio acquisto");
case valorizz_costmediopond: return TR("Costo medio ponderato");
case valorizz_FIFOa: return TR("FIFO annuale");
case valorizz_LIFOa: return TR("LIFO annuale");
case valorizz_FIFO: return TR("FIFO");
case valorizz_LIFO: return TR("LIFO");
case valorizz_FIFOr: return TR("FIFO Ragionieristico");
case valorizz_LIFOr: return TR("LIFO Ragionieristico");
default: break;
}
return "";
}
const TString & TArticolo::get_str(const char* fieldname) const
{
if (*fieldname != '#')
return TRectype::get_str(fieldname);
char * fname = (char *) fieldname + 1;
const int logicnum = atoi(fname);
const char * op1 = strchr(fname, '_');
int index = 0;
if (op1)
{
op1=op1+1;
if (*op1 == '#')
index = atoi(fname + 1);
}
const char* op2 = strstr(fname, "->");
CHECKS(op2, "Can't find '->' in string ", fieldname);
op2=op2+2;
switch (logicnum)
{
case LF_UMART:
{
if (index == 0)
index = find_um(op1);
if (index > 0 && op2)
return um().row(index).get(op2);
}
break;
case LF_CODCORR:
{
if (index == 0)
index = find_codcorr(op1);
if (index > 0 && op2)
return codcorr().row(index).get(op2);
}
break;
case LF_DESLIN:
{
if (index == 0)
index = find_deslin(op1);
if (index > 0 && op2)
return deslin().row(index).get(op2);
}
break;
default:
break;
}
return EMPTY_STRING;
}
void TArticolo::set_body_key(TRectype & rowrec)
{
const int logicnum = rowrec.num();
const TString& cod = codice();
switch (logicnum)
{
case LF_UMART:
rowrec.put(UMART_CODART, cod);
break;
case LF_DESLIN:
rowrec.put(DESLIN_CODART, cod);
break;
case LF_CODCORR:
rowrec.put(CODCORR_CODART, cod);
break;
default:
break;
}
}
int TArticolo::read(TRectype & rec, word op, word lockop)
{
const TString& compstr = rec.get(ANAMAG_CODART);
if (op == _isequal && lockop == _nolock && codice() == compstr)
return NOERR;
int err = _iskeyerr;
if (!compstr.blank())
{
put(ANAMAG_CODART, compstr);
err = TMultiple_rectype::read(rec, op , lockop);
}
if (err != NOERR)
zero();
return err;
}
int TArticolo::read(const char * cod, word op, word lockop)
{
TRectype tmp(*this);
tmp.put(ANAMAG_CODART,cod);
return read( tmp, op, lockop);
}
const TCodice_articolo& TArticolo::codice() const
{
((TCodice_articolo&)_codice) = get(ANAMAG_CODART);
return _codice;
}
const TString & TArticolo::descrizione(const char* lingua) const
{
if (lingua && *lingua)
{
TString16 f; f.format("#%d_%s->%s", LF_DESLIN, lingua, DESLIN_DESCR);
return get(f);
}
return get(ANAMAG_DESCR);
}
void TArticolo::update_ultcosti(const real& costo, const TDate& data, long numreg, int _unused_)
{
const TDate data1(get_date(ANAMAG_DULTCOS1));
const TDate data2(get_date(ANAMAG_DULTCOS2));
// modificato il 2-2-1999;
const long numreg1 = get_long(ANAMAG_NUMREG1);
const long numreg2 = get_long(ANAMAG_NUMREG2);
if (data >= data1 || (numreg == numreg1 && // movimento piu' recente o aggiornamento dello stesso movimento ...
(data > data2 || numreg > numreg2))) // ... e "data" superiore al penultimo
{
const real costo1(get_real(ANAMAG_ULTCOS1));
put(ANAMAG_ULTCOS1,costo);
put(ANAMAG_DULTCOS1,data);
put(ANAMAG_NUMREG1,numreg);
if (numreg != numreg1 && (data > data1 || numreg > numreg1))
{
// trasforma l'ultimo costo in penultimo
put(ANAMAG_ULTCOS2,costo1);
put(ANAMAG_DULTCOS2,data1);
put(ANAMAG_NUMREG2,numreg1);
}
}
else
{
const real costo2 = get_real(ANAMAG_ULTCOS2);
if (data >= data2 || numreg == numreg2 || numreg == numreg1)
{
put(ANAMAG_DULTCOS2,data);
put(ANAMAG_ULTCOS2,costo);
put(ANAMAG_NUMREG2,numreg);
}
if (numreg == numreg1 )
{
// trasforma il penultimo costo in ultimo
put(ANAMAG_ULTCOS1,costo2);
put(ANAMAG_DULTCOS1,data2);
put(ANAMAG_NUMREG1,numreg2);
}
}
}
void TArticolo::set_prezzo_vendita(const real& prezzo, const char* unita)
{
TPrice p; // Arrotondatore automatico
if (unita && *unita)
{
const int i = find_um(unita);
if (i > 0)
{
TRectype& rec = (TRectype&)um().row(i);
p.set_num(prezzo);
rec.put(UMART_PREZZO, p.get_num());
}
}
else
{
TString16 codum;
for (int i = um().rows(); i > 0; i--)
{
TRectype& rec = (TRectype&)um().row(i);
codum = rec.get(UMART_UM);
if (i == 1)
p.set_num(prezzo);
else
p.set_num(convert_to_um(prezzo, codum, NULL, false));
rec.put(UMART_PREZZO, p.get_num());
}
}
}
bool TArticolo::unlock()
{
bool rv = false;
if (codice().not_empty())
{
TLocalisamfile anag(LF_ANAMAG);
rv = anag.read(*this, _isequal,_unlock) == NOERR;
}
return rv;
}
bool TArticolo::lock_and_prompt(word lockop)
{
if (lockop != _nolock)
{
int err = read(_codice, _isequal, _testandlock);
if (err != NOERR)
{
TString mess;
if (err == _islocked)
{
mess << TR("Il record di anagrafica\ndell'articolo '") << _codice << TR("' e' gia' usato da un altro programma.");
TTimed_skipbox bbox((const char *)mess,10);
while (err == _islocked)
{
bbox.run();
err = read(_codice,_isequal,_testandlock);
}
}
else
{
if (err == _iskeyerr)
mess << TR("Il codice articolo '") << _codice << TR("' non e' valido");
else
if (err == _iskeynotfound)
mess << TR("Il record di anagrafica\ndell'articolo '")<< _codice << TR("' non esiste.");
else
mess << TR("Non riesco ad accedere al\nrecord di anagrafica dell'articolo '")<< _codice << TR("' - errore ") << err << ".";
TTimed_skipbox bbox((const char *)mess,10);
bbox.run();
return false;
}
}
}
return true;
}
int TArticolo::find_um(const char* um, int from) const
{
return find(LF_UMART, UMART_UM, um, from);
}
int TArticolo::find_deslin(const char * deslin, int from) const
{
return find(LF_DESLIN, DESLIN_CODLIN, deslin, from);
}
int TArticolo::find_codcorr(const char * codcorr, int from) const
{
return find(LF_CODCORR, CODCORR_CODARTALT, codcorr, from);
}
const TString& TArticolo::first_um() const
{
const TRecord_array& a = um();
return a.rows() > 0 ? a[1].get(UMART_UM) : EMPTY_STRING;
}
// Funzione statica utilizzabile da tutti
void TArticolo::round_um(real& r, const char* to_um)
{
if (to_um && *to_um)
{
const TRectype& baseum = cache().get("%UMS", to_um);
if (baseum.get_bool("B0"))
{
const int dec = baseum.get_int("I0");
r.round(dec);
}
}
}
real TArticolo::convert_to_um(const real& v, const TString& to_um, const TString& from_um, bool arrotonda)
{
// Inutile convertire valori nulli
if (v.is_zero() || to_um == from_um) // (|| um().rows() <= 1) Non funzionerebbe coi pesi che non appartengano a LF_UMART
return v;
// Se from_um non specificato significa che la qta che si desidera convertire e' in UM base
// Gli indici delle unita; di misura valide partono da 1
int i1 = to_um.full() ? find_um(to_um) : 1;
int i2 = from_um.full() ? find_um(from_um) : 1;
if (i1 == i2 && i1 > 0) // Inutile convertire in se stessi
return v;
fraction f(v, UNO);
// Se l'unita' di partenza NON e' quella base, converti in quella base
if (i2 != 1)
{
fraction fc2(1, 1);
if (i2 > 0)
fc2 = (um()[i2]).get_real(UMART_FC);
else
{
// Tentativo estremo di usare le unita' di misura comuni
const TRectype& fromum = cache().get("%UMS", from_um);
if (fromum.get("S7") == to_um)
{
fc2 = fromum.get_real("R10");
i1 = 1; // La conversione termina qui: non moltiplicare per fc1!
}
}
f *= fc2;
}
// Se l'unita' di destinazione NON e' quella base converti
if (i1 > 1)
{
const fraction fc1( (um()[i1]).get_real(UMART_FC), UNO );
f /= fc1;
}
real r = f;
// Se devi arrotondare ad un'unita' valida ... fallo!
if (arrotonda && i1 > 0 && um().exist(i1))
round_um(r, um()[i1].get(UMART_UM));
return r;
}
TArticolo::TArticolo(const char* codice) : TMultiple_rectype(LF_ANAMAG)
{
add_file(LF_UMART,"NRIGA");
add_file(LF_CODCORR,"NRIGA");
add_file(LF_DESLIN,"NRIGA");
if (codice && *codice)
{
const int err = read(codice);
if (err != NOERR)
error_box(FR("Impossibile leggere l'articolo %s: Errore %d"), codice, err);
}
}
TArticolo::TArticolo(const TRectype& rec)
: TMultiple_rectype(rec)
{
add_file(LF_UMART, "NRIGA");
add_file(LF_CODCORR,"NRIGA");
add_file(LF_DESLIN, "NRIGA");
read(rec.get(ANAMAG_CODART));
}
///////////////////////////////////////////////////////////
// TCache_articoli
///////////////////////////////////////////////////////////
class TCache_articoli : public TRecord_cache
{
protected:
virtual TObject* rec2obj(const TRectype& rec) const { return new TArticolo(rec); }
public:
TArticolo& art(const char* key) { return (TArticolo&)query(key); }
TCache_articoli();
virtual ~TCache_articoli() { }
};
TCache_articoli::TCache_articoli()
: TRecord_cache(LF_ANAMAG, 1)
{
test_file_changes(); // Tieni d'occhio le modifiche sul file
set_items_limit(257); // Numero primo!
}
TArticolo& cached_article(const char* codart)
{
HIDDEN TCache_articoli __cache_articoli;
if (codart == NULL)
{
__cache_articoli.destroy();
codart = "";
}
return __cache_articoli.art(codart);
}
// *****************
// TArticolo_giacenza
const TString & TArticolo_giacenza::get_str(const char* fieldname) const
{
if (*fieldname != '#')
return TRectype::get_str(fieldname);
char * fname = (char *) fieldname + 1;
const int logicnum = atoi(fname);
if (logicnum !=LF_MAG && logicnum !=LF_STOMAG)
return TArticolo::get_str(fieldname);
const char * op1 = strchr(fname, '_');
int index = 0;
if (op1)
{
op1=op1+1;
fname = (char *) op1;
if (*op1 == '#')
index = atoi(fname + 1);
}
const char * op2 = strchr(fname, '_');
if (op2)
{
op2=op2+1;
fname = (char *) op2 + 1;
}
const char * op3 = strchr(fname, '_');
if (op3)
op3=op3+1;
const char * op4 = strstr(fname, "->");
CHECKS(op4, "Can't find '->' in string ", fieldname);
op4=op4+2;
switch (logicnum)
{
case LF_MAG:
if (index == 0)
index = find_mag(op1, op2, op3);
if (index > 0 && op3)
return mag(op1).row(index).get(op4);
break;
case LF_STOMAG:
if (index == 0)
index = find_storico(op1);
if (index > 0)
return storico(op1).row(index).get(op4);
break;
}
return EMPTY_STRING;
}
void TArticolo_giacenza::set_body_key(TRectype & rowrec)
{
const int logicnum = rowrec.num();
const char * cod = (const char *) codice();
switch (logicnum)
{
case LF_STOMAG:
rowrec.put(STOMAG_CODART, cod);
rowrec.put(STOMAG_ANNOESRIF, _anno_sto);
break;
case LF_MAG:
rowrec.put(MAG_ANNOES, _anno_mag);
rowrec.put(MAG_CODART, cod);
break;
default:
TArticolo::set_body_key(rowrec);
break;
}
}
void TArticolo_giacenza::set_anno_mag (int anno)
{
if (_anno_mag != anno)
{
remove_body(LF_MAG);
_anno_mag = anno;
}
}
void TArticolo_giacenza::set_anno_sto (int anno)
{
if (_anno_sto != anno)
remove_body(LF_STOMAG);
_anno_sto = anno;
}
void TArticolo_giacenza::zero(char c)
{
reset_anno_sto();
reset_anno_mag();
TArticolo::zero(c);
}
int TArticolo_giacenza::find_mag(TRecord_array& rmag, const char * codmag, const char * livello, int from) const
{
const int last = rmag.last_row();
if (last > 0 && from < last)
{
const int codmag_len = codmag ? strlen(codmag) : 0;
const int livello_len = livello ? strlen(livello) : 0;
if (codmag_len == 0 && livello_len == 0)
{
const int row = rmag.succ_row(from);
return row > last ? -1 : row;
}
for (int i = rmag.succ_row(from); i <= last; i = rmag.succ_row(i))
{
const TRectype & rec = rmag.row(i);
if (codmag_len == 0 || rec.get(MAG_CODMAG).compare(codmag, codmag_len) == 0)
if (livello_len == 0 || rec.get(MAG_LIVELLO).compare(livello, livello_len) == 0)
return i;
}
}
return -1;
}
int TArticolo_giacenza::find_mag(int annoes, const char * codmag, const char * livello, int from) const
{
TRecord_array & rmag = mag(annoes);
return find_mag(rmag, codmag, livello, from);
}
int TArticolo_giacenza::find_storico(TRecord_array& rsto, const char * codmag, int from) const
{
const int last = rsto.last_row();
if (last > 0 && from < last)
{
const int codmag_len = codmag ? strlen(codmag) : 0;
if (codmag_len == 0)
{
const int row = rsto.succ_row(from);
return row > last ? -1 : row;
}
for (int i = rsto.succ_row(from); i <= last; i = rsto.succ_row(i))
{
const TRectype & rec = rsto.row(i);
if (rec.get(STOMAG_CODMAG).compare(codmag, codmag_len) == 0)
return i;
}
}
return -1;
}
int TArticolo_giacenza::find_storico(int annoesrif, const char * codmag, int from) const
{
TRecord_array & rsto = storico(annoesrif);
return find_storico(rsto, codmag, from);
}
TRecord_array& TArticolo_giacenza::mag(int annoes) const
{
((TArticolo_giacenza*)this)->set_anno_mag(annoes > 0 ? annoes : esercizi().last_mag());
return body(LF_MAG);
}
TRecord_array & TArticolo_giacenza::storico(int annoesrif) const
{
((TArticolo_giacenza *) this)->set_anno_sto(annoesrif > 0 ? annoesrif : esercizi().last_mag());
return body(LF_STOMAG);
}
bool TArticolo_giacenza::is_last_esercizio(int annoes) const
{
return annoes > 0 ? !esercizi().esercizio(annoes).chiusura_mag().ok() : false;
}
const char* const protected_fields[] =
{
MAG_UBICAZ, MAG_LIVRIOR, MAG_SCORTAMIN, MAG_LOTTORIOR, MAG_LOTTOIRIOR, MAG_GIORNIRIOR, NULL
};
bool TArticolo_giacenza::is_deletable(const TRectype& mag) const
{
int i;
for (i = 0; protected_fields[i]; i++)
{
const TString& val = mag.get(protected_fields[i]);
if (val.full() && !real::is_null(val))
return false;
}
for (i = 0; zero_fields[i]; i++)
{
const TString& val = mag.get(zero_fields[i]);
if (val.full() && !real::is_null(val))
return false;
}
return true;
}
bool TArticolo_giacenza::azzera_saldi(int codes, int codespre, bool save_to_disk)
{
CHECKD(codes > 0 && codespre != codes, "Davvero azzereresti i saldi dall'esercizio ", codes);
TRecord_array oldmag(LF_MAG, MAG_NRIGA);
if (codespre > 0)
oldmag = mag(codespre); // Non usare TRecord_array& in quanto mag(codes) lo sovrascriebbe!
TRecord_array& rec_arr = mag(codes);
const int last = rec_arr.last_row();
for (int r = last; r > 0; r = rec_arr.pred_row(r)) // Scorre le righe
{
TRectype& mag = rec_arr[r];
for (int i = 0; zero_fields[i]; i++)
mag.zero(zero_fields[i]);
if (codespre > 0 && oldmag.rows() > 0)
{
const TString16 liv(mag.get(MAG_LIVELLO));
const int row = find_mag(oldmag, mag.get(MAG_CODMAG), liv);
if (row >= 0)
{
const TRectype& oldrec = oldmag[row];
for (int i = 0; protected_fields[i]; i++)
{
const TString& val = oldrec.get(protected_fields[i]);
if (val.full() && !real::is_null(val))
mag.put(protected_fields[i], val);
}
}
}
if (is_deletable(mag))
rec_arr.destroy_row(r, TRUE);
}
bool ok = true;
if (save_to_disk)
ok = rec_arr.write(true) == NOERR;
return ok;
}
//bool azzera_saldi(const char* codes, bool save_to_disk = true)
//{ return azzera_saldi(atoi(codes), save_to_disk); }
bool TArticolo_giacenza::riporta_saldi(int oldes, int newes, const TTipo_valorizz tipo,
const char* catven, const char* codlis, bool save_to_disk)
{
CHECKD(oldes > 0 && oldes != newes, "Davvero riporteresti i saldi dall'esercizio ", oldes);
TString8 codmag;
TString16 liv;
TRecord_array& rec_arr = mag(oldes);
TRecord_array oldmag = rec_arr;
const int last = rec_arr.last_row();
real rim, val, giac, inpf, proc, icl, acl;
rec_arr.renum_key(MAG_ANNOES, newes); // Rinumera
for (int r = last; r > 0 ; r = rec_arr.pred_row(r)) // Scorre le righe
{
TRectype& rec = rec_arr[r];
codmag = rec.get(MAG_CODMAG); codmag.cut(3);
liv = rec.get(MAG_LIVELLO);
giac = rec.get_real(MAG_GIAC);
inpf = rec.get_real(MAG_PRODFIN);
proc = rec.get_real(MAG_PRODCOMP);
acl = rec.get_real(MAG_ACL);
icl = rec.get_real(MAG_INCL);
rim = giac + inpf - proc + acl - icl;
switch (tipo)
{
case valorizz_costmedio:
val = costo_medio(oldes, codmag, liv);
break;
case valorizz_costmediopond:
val = costo_mediopond(oldes, codmag, liv);
break;
case valorizz_ultcos:
val = ultimo_costo(oldes);
break;
case valorizz_mediacos:
val = media_costi(oldes);
break;
case valorizz_przlist:
val = prezzo_listino(oldes, catven, codlis);
break;
case valorizz_coststd:
val = costo_standard(oldes);
break;
case valorizz_FIFOa:
val = FIFO_annuale(oldes, codmag, liv);
break;
case valorizz_LIFOa:
val = LIFO_annuale(oldes, codmag, liv);
break;
case valorizz_FIFO:
val = FIFO(oldes, codmag, liv);
break;
case valorizz_LIFO:
val = LIFO(oldes, codmag, liv);
break;
case valorizz_FIFOr:
val = FIFO_ragionieristico(oldes, codmag, liv);
break;
case valorizz_LIFOr:
val = LIFO_ragionieristico(oldes, codmag, liv);
break;
default:
break;
}
// Setta il prezzo al nr di decimali fissati per i prezzi della valuta corrente
if (tipo < valorizz_FIFOa)
{
TPrice p;
p.set_num(val);
val = p.get_num();
}
val *= rim;
// Setta l'importo al nr di decimali fissati per gli importi della valuta corrente
TCurrency c;
c.set_num(val);
val = c.get_num();
rec.put(MAG_RIM, rim); rec.put(MAG_VALRIM, val);
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);
}
const int row = find_mag(oldmag, rec.get(MAG_CODMAG), liv);
if (row >= 0)
{
const TRectype& oldrec = oldmag[row];
for (int i = 0; protected_fields[i]; i++)
{
const TString& val = oldrec.get(protected_fields[i]);
if (val.not_empty() && !real::is_null(val))
rec.put(protected_fields[i], val);
}
}
if (is_deletable(rec))
rec_arr.destroy_row(r, TRUE);
}
// Per non perdere le modifiche in memoria, al fine di avere i saldi riportati correttamente
// visto che non vengono salvati e poi riletti da disco, li si salvano nel TRecord_array
// dell'esercizio newes
if (!save_to_disk)
{
const TRecord_array copia(rec_arr);
if (copia.rows() > 0)
{
TRecord_array& nuovo = mag(newes);
nuovo = copia;
}
else
azzera_saldi(newes, oldes, false);
}
// Scrive il pastrocchio (eventualmente sovrascrive)
return save_to_disk ? (rec_arr.write(true) == NOERR) : true;
}
real TArticolo_giacenza::disponibilita(const char * annoes, const char * codmag, const char * livello, bool solo_giac) const
{
real giac;
TRecord_array & rmag = mag(annoes);
for (int i = find_mag(annoes, codmag, livello); i > 0;
i = find_mag(annoes, codmag, livello, i))
{
const TRectype & rec = rmag.row(i);
giac += rec.get_real(MAG_GIAC);
if (!solo_giac)
{
giac += rec.get_real(MAG_ORDF) - rec.get_real(MAG_ORDC);
giac += rec.get_real(MAG_PRODFIN) - rec.get_real(MAG_PRODCOMP);
giac += rec.get_real(MAG_ACL) - rec.get_real(MAG_INCL);
}
}
if (!solo_giac && !riporta_ordinato()) // Se l'ordinato viene riportato
{
const int prev = esercizi().pred(atoi(annoes)); // Controllo anche l'anno precedente
if (prev > 0)
{
TString8 oldannoes; oldannoes.format("%04d", prev);
const TRecord_array& oldrmag = mag(oldannoes);
for (int i = find_mag(oldannoes, codmag, livello); i > 0;
i = find_mag(oldannoes, codmag, livello, i))
{
const TRectype& rec = oldrmag.row(i);
giac += rec.get_real(MAG_ORDF); // Sommo l'ordinato fornitori
giac -= rec.get_real(MAG_ORDC); // Sottraggo l'ordinato clienti
}
}
}
return giac;
}
real TArticolo_giacenza::ultimo_costo(int annoes) const
{
if (is_last_esercizio(annoes))
{
const real costo = get_real(ANAMAG_ULTCOS1);
return costo.is_zero() ? costo_standard(annoes) : costo;
}
else
{
const int nextes = esercizi().next(annoes);
if (nextes > 0)
{
const int index = find_storico(nextes);
if (index >= 0 )
{
const real costo = storico(nextes).row(index).get_real(STOMAG_ULTCOS1);
return costo.is_zero() ? costo_standard(annoes) : costo;
}
}
}
return ZERO;
}
real TArticolo_giacenza::media_costi(int annoes) const
{
if (is_last_esercizio(annoes))
{
real costo = get_real(ANAMAG_ULTCOS1);
costo = (costo + get_real(ANAMAG_ULTCOS2)) / 2.0;
return costo.is_zero() ? costo_standard(annoes) : costo;
}
else
{
const int nextes = esercizi().next(annoes);
if (nextes > 0)
{
const int index = find_storico(nextes);
if (index >= 0 )
{
const TRectype & rec = storico(nextes).row(index);
real costo = rec.get_real(STOMAG_ULTCOS1);
costo = (costo + rec.get_real(STOMAG_ULTCOS2)) / 2.0;
return costo.is_zero() ? costo_standard(annoes) : costo;
}
}
}
return ZERO;
}
real TArticolo_giacenza::prezzo_listino(int annoes, const char * catven, const char * codlist) const
{
if (is_last_esercizio(annoes))
{
TString codart=codice();
TConfig cfg(CONFIG_DITTA);
if (codlist && *codlist>' ')
{
TCondizione_vendita cv(&cfg);
cv.put_listino(codlist,catven);
if (cv.ricerca(codart))
return cv.get_prezzo();
}
// se non lo trova, cerca nel prezzo indicato nelle UM
TString16 f;
f.format("#%d->%s", LF_UMART, UMART_PREZZO);
return get_real(f);
}
else
{
const int nextes = esercizi().next(annoes);
if (nextes > 0)
{
const int index = find_storico(nextes);
if (index >= 0 )
return storico(nextes).row(index).get_real(STOMAG_PRZLIST);
}
}
return ZERO;
}
real TArticolo_giacenza::costo_standard(int annoes) const
{
if (is_last_esercizio(annoes))
return get_real(ANAMAG_COSTSTD);
else
{
const int nextes = esercizi().next(annoes);
if (nextes > 0)
{
const int index = find_storico(nextes);
if (index >= 0 )
return storico(nextes).row(index).get_real(STOMAG_COSTSTD);
}
}
return ZERO;
}
real TArticolo_giacenza::costo_medio(int annoes, const char * codmag, const char * livello) const
{
real acq, valacq;
#ifdef DBG
if (strlen(codmag)>3)
NFCHECK("Non <20> pi<70> possibile avere valorizzazione a livello di deposito");
#endif
TRecord_array & rmag = mag(annoes);
for (int i = find_mag(annoes, codmag, livello); i > 0;
i = find_mag(annoes, codmag, livello, i))
{
const TRectype & rec = rmag.row(i);
acq += rec.get_real(MAG_ACQ);
valacq += rec.get_real(MAG_VALACQ);
}
return acq.is_zero() ? costo_standard(annoes) : valacq / acq;
}
// costo medio ponderato per periodi pari alla durata dell'esercizio
real TArticolo_giacenza::costo_mediopond(int annoes, const char * codmag, const char * livello) const
{
real acq;
real valacq;
#ifdef DBG
if (strlen(codmag)>3)
NFCHECK("Non <20> pi<70> possibile avere valorizzazione a livello di deposito");
#endif
TRecord_array & rmag = mag(annoes);
for (int i = find_mag(annoes, codmag, livello); i > 0; i = find_mag(annoes, codmag, livello, i))
{
const TRectype & rec = rmag.row(i);
acq += rec.get_real(MAG_ACQ) ;
acq += rec.get_real(MAG_RIM) ;
valacq += rec.get_real(MAG_VALACQ);
valacq += rec.get_real(MAG_VALRIM);
}
return acq.is_zero() ? costo_standard(annoes) : valacq / acq;
}
real TArticolo_giacenza::LIFO_annuale(int annoes, const char * codmag, const char * livello,
bool giac_eff, bool valorizza_componenti) const
{
CHECK(strlen(codmag) <= 3,"Non <20> pi<70> possibile avere valorizzazione a livello di deposito");
real rim,valrim;
real acq,valacq;
real giacenza;
TRecord_array & rmag = mag(annoes);
for (int i = find_mag(annoes, codmag, livello); i > 0; i = find_mag(annoes, codmag, livello, i))
{
const TRectype & rec = rmag.row(i);
rim += rec.get_real(MAG_RIM);
valrim += rec.get_real(MAG_VALRIM);
acq += rec.get_real(MAG_ACQ);
valacq += rec.get_real(MAG_VALACQ);
giacenza += giacenza_corretta(rec,giac_eff,valorizza_componenti);
}
if (giacenza <= ZERO)
return ZERO;
if (giacenza > rim)
return ((giacenza - rim) * (acq.is_zero() ? costo_standard(annoes) : valacq / acq) + valrim) / giacenza;
return valrim / rim;
}
real TArticolo_giacenza::FIFO_annuale(int annoes, const char * codmag, const char * livello,
bool giac_eff, bool valorizza_componenti) const
{
CHECK(strlen(codmag) <= 3,"Non <20> pi<70> possibile avere valorizzazione a livello di deposito");
real rim,valrim;
real acq,valacq;
real giacenza;
TRecord_array & rmag = mag(annoes);
for (int i = find_mag(annoes, codmag, livello); i > 0; i = find_mag(annoes, codmag, livello, i))
{
const TRectype & rec = rmag.row(i);
rim += rec.get_real(MAG_RIM);
valrim += rec.get_real(MAG_VALRIM);
acq += rec.get_real(MAG_ACQ);
valacq += rec.get_real(MAG_VALACQ);
giacenza += giacenza_corretta(rec,giac_eff,valorizza_componenti);
}
if (giacenza <= ZERO)
return ZERO;
if (rim.is_zero())
return ZERO;
if (giacenza > acq)
return ((giacenza - acq) * (valrim / rim) + valacq) / giacenza;
return valacq / acq;
}
real TArticolo_giacenza::LIFO(int annoes, const char * codmag, const char * livello,
bool giac_eff, bool valorizza_componenti) const
{
CHECK(strlen(codmag) <= 3,"Non <20> pi<70> possibile avere valorizzazione a livello di deposito");
real rim,valrim;
real acq,valacq;
real giacenza;
TRecord_array & rmag = mag(annoes);
int i;
for (i = find_mag(annoes, codmag, livello); i > 0; i = find_mag(annoes, codmag, livello, i))
{
const TRectype & rec = rmag.row(i);
rim += rec.get_real(MAG_RIM);
valrim += rec.get_real(MAG_VALRIM);
acq += rec.get_real(MAG_ACQ);
valacq += rec.get_real(MAG_VALACQ);
giacenza += giacenza_corretta(rec,giac_eff,valorizza_componenti);
}
if (giacenza <= ZERO)
return ZERO;
if (giacenza > rim)
return ((giacenza - rim) * (acq == ZERO ? costo_standard(annoes) : valacq / acq) + valrim) / giacenza;
TRecord_array & rstorico = storico(annoes);
// const int last = rstorico.last_row();
valrim=ZERO;
rim = giacenza;
for (i = find_storico(annoes, codmag); i > 0; i = find_storico(annoes, codmag, i))
{
TRectype & rec = rstorico[i];
const real qta = rec.get_real(STOMAG_QUANT);
if (qta > giacenza)
{
valrim += (rec.get_real(STOMAG_VALORE)) * giacenza;
break;
}
else
{
valrim += rec.get_real(STOMAG_VALORE) * qta;
giacenza -= qta;
}
}
return rim == ZERO ? ZERO :valrim / rim;
}
real TArticolo_giacenza::FIFO(int annoes, const char * codmag, const char * livello,
bool giac_eff, bool valorizza_componenti) const
{
CHECK(strlen(codmag)<=3,"Non <20> pi<70> possibile avere valorizzazione a livello di deposito");
real rim,valrim;
real acq,valacq;
real giacenza;
TRecord_array & rmag = mag(annoes);
int i;
for (i = find_mag(annoes, codmag, livello); i > 0; i = find_mag(annoes, codmag, livello, i))
{
const TRectype & rec = rmag.row(i);
rim += rec.get_real(MAG_RIM);
valrim += rec.get_real(MAG_VALRIM);
acq += rec.get_real(MAG_ACQ);
valacq += rec.get_real(MAG_VALACQ);
giacenza += giacenza_corretta(rec,giac_eff,valorizza_componenti);
}
if (giacenza <= ZERO)
return ZERO;
if (giacenza <= acq)
{
return valacq / acq;
}
TRecord_array & rstorico = storico(annoes);
const int last = rstorico.last_row();
real res = giacenza - acq;
rim = ZERO;
valrim = ZERO;
TFixed_string cmag(codmag);
int codmag_len = codmag ? strlen(cmag) : 0;
for (i = last; i > 0; i--)
{
const TRectype & rec = rstorico.row(i);
if (codmag_len == 0 || rec.get(STOMAG_CODMAG).compare(codmag, codmag_len) == 0)
{
const real qta = rec.get_real(STOMAG_QUANT);
if (qta > res)
{
rim += res;
valrim += (rec.get_real(STOMAG_VALORE)) * res;
}
else
{
rim += qta;
valrim += rec.get_real(STOMAG_VALORE) * qta;
res -= qta;
}
}
}
if (rim.is_zero() || giacenza.is_zero())
return ZERO;
return ((giacenza - acq) * (valrim / rim) + valacq) / giacenza;
}
real TArticolo_giacenza::FIFO_ragionieristico(int annoes, const char * codmag, const char * livello,
bool giac_eff, bool valorizza_componenti) const
{
CHECK(strlen(codmag)<=3, "Non <20> pi<70> possibile avere valorizzazione a livello di deposito");
return ZERO; // da implementare
}
real TArticolo_giacenza::LIFO_ragionieristico(int annoes, const char * codmag, const char * livello,
bool giac_eff, bool valorizza_componenti) const
{
CHECK(strlen(codmag)<=3, "Non <20> pi<70> possibile avere valorizzazione a livello di deposito");
return ZERO; // da implementare
}
void TArticolo_giacenza::copia_valori(TRectype& rec, const char * catven, const char * codlist, real & przlist)
{
rec.put(STOMAG_ULTCOS1, get(ANAMAG_ULTCOS1));
rec.put(STOMAG_ULTCOS2, get(ANAMAG_ULTCOS2));
rec.put(STOMAG_COSTSTD, get(ANAMAG_COSTSTD));
rec.put(STOMAG_PRZLIST, przlist);
rec.put(STOMAG_CODLISTINO, codlist);
rec.put(STOMAG_CATVEN, catven);
}
void TArticolo_giacenza::copia_storico(TRecord_array& nrstorico, int annoes, const char * codmag, int annoprec, real rim, real valrim, const char * catven, const char * codlist, real & przlist)
{
CHECK(annoes > 0,"Copia_storico: Indicare l'anno esercizio dello storico");
TString nuovoanno(nrstorico.key().get(STOMAG_ANNOESRIF));
//nrstorico.destroy_rows();
TRecord_array & rstorico = storico(annoes);
int last = nrstorico.last_row();
int annoes_index = 0;
int codmag_len = (codmag && *codmag) ? strlen(codmag) : 0;
int last_old = rstorico.last_row();
for (int i = 1; i <= last_old; i++)
{
const TRectype& rst = rstorico[i];
if (codmag_len == 0 || rst.get(STOMAG_CODMAG).compare(codmag, codmag_len) == 0)
{
TRectype newrec(rst);
newrec.put(STOMAG_ANNOESRIF,nuovoanno);
newrec.put(STOMAG_NRIGA,++last);
int r = nrstorico.insert_row(newrec);
if (rst.get(STOMAG_ANNOES) == annoes)
annoes_index =r;
real q = rst.get_real(STOMAG_QUANT);
rim -= q;
valrim -= rst.get_real(STOMAG_VALORE) * q;
copia_valori(newrec, catven, codlist, przlist);
}
}
if (annoprec > 0 && (rim != ZERO || valrim != ZERO))
{
if (annoes_index <= 0)
{
TRectype newrec(LF_STOMAG);
newrec.put(STOMAG_ANNOESRIF, nuovoanno);
newrec.put(STOMAG_ANNOES, annoprec);
newrec.put(STOMAG_CODART,codice());
newrec.put(STOMAG_CODMAG,codmag);
newrec.put(STOMAG_NRIGA, ++last_old);
annoes_index = nrstorico.insert_row(newrec);
copia_valori(newrec, catven, codlist, przlist);
}
TRectype & rec = nrstorico[annoes_index];
real q = rec.get_real(STOMAG_QUANT);
real v = rec.get_real(STOMAG_VALORE) * q;
const int dec_price = rec.ndec(STOMAG_VALORE);
q += rim;
rec.put(STOMAG_QUANT, q);
v += valrim;
v /= q;
rec.put(STOMAG_VALORE, v.round(dec_price));
}
}
HIDDEN int sort_storico(const TObject ** a, const TObject ** b)
{
TRectype * rec_a = (TRectype *) *a;
TRectype * rec_b = (TRectype *) *b;
TString16 mag_a = rec_a->get(STOMAG_CODMAG);
int res = mag_a.compare(rec_b->get(STOMAG_CODMAG));
if (res == 0)
res = rec_a->get_int(STOMAG_ANNOES) - rec_b->get_int(STOMAG_ANNOES);
return res;
}
HIDDEN int sort_storico_rev(const TObject ** a, const TObject ** b)
{
return -sort_storico(a, b);
}
void TArticolo_giacenza::add_storico(TRecord_array& nrstorico,int annoes,const char * codmag, const real & qta, const real & prz, const char * catven, const char * codlist, real & przlist)
{
TString8 annorif(nrstorico.key().get(STOMAG_ANNOESRIF));
int i;
for (i=nrstorico.last_row(); i>0; i--)
{
TString16 mag=nrstorico[i].get(STOMAG_CODMAG);
if (mag<=codmag)
break;
}
TRectype storec(LF_STOMAG);
storec.put(STOMAG_ANNOESRIF,annorif);
storec.put(STOMAG_ANNOES,annoes);
storec.put(STOMAG_CODART,codice());
storec.put(STOMAG_NRIGA,i+1);
storec.put(STOMAG_CODMAG,codmag);
storec.put(STOMAG_QUANT,qta);
const int dec_price = storec.ndec(STOMAG_VALORE);
storec.put(STOMAG_VALORE, prz.string(0, dec_price));
copia_valori(storec, catven, codlist, przlist);
nrstorico.insert_row(storec);
}
// annoes indica l'anno dell'esercizio da chiudere
void TArticolo_giacenza::agg_storicoLIFO(int annoes, const char * codmag,
bool giac_eff, bool valorizza_componenti,
const char * catven, const char * codlist, real & przlist)
{
CHECK(codmag && *codmag,"Necessario indicare il magazzino");
CHECK(strlen(codmag)<=3,"Non <20> pi<70> possibile avere valorizzazione a livello di deposito");
real rim, valrim, acq, valacq, giacenza;
TRecord_array & rmag = mag(annoes);
int i;
for (i = find_mag(annoes, codmag, ""); i > 0; i = find_mag(annoes, codmag, "", i))
{
const TRectype & rec = rmag.row(i);
rim += rec.get_real(MAG_RIM);
valrim += rec.get_real(MAG_VALRIM);
acq += rec.get_real(MAG_ACQ);
valacq += rec.get_real(MAG_VALACQ);
giacenza += giacenza_corretta(rec,giac_eff,valorizza_componenti);
}
real prz;
real qta;
const int nuovoanno = esercizi().next(annoes);
const int annoprec = esercizi().pred(annoes);
TRecord_array nuovo_storico(storico(nuovoanno));
copia_storico(nuovo_storico, annoes, codmag, annoprec, rim , valrim, catven, codlist, przlist);
nuovo_storico.sort(sort_storico_rev);
if (giacenza <= ZERO)
return;
// giacenza=ZERO;
if (giacenza > rim)
{
qta=giacenza-rim;
if (!acq.is_zero())
prz = valacq/acq;
add_storico(nuovo_storico,annoes,codmag,qta,prz, catven, codlist, przlist);
}
else
{
real res = rim-giacenza;
//TRecord_array & rstorico = storico(nuovoanno);
for (i = find_storico(nuovo_storico, codmag); i > 0; i = find_storico(nuovo_storico, codmag, i))
{
TRectype & rec = nuovo_storico[i];
const real qta_sto=rec.get_real(STOMAG_QUANT);
if (qta_sto > res)
{
qta=qta_sto-res;
rec.put(STOMAG_QUANT,qta);
break;
}
else
{
nuovo_storico.destroy_row(i);
res -= qta_sto;
}
}
}
nuovo_storico.pack();
nuovo_storico.sort(sort_storico);
nuovo_storico.write();
}
void TArticolo_giacenza::agg_storicoFIFO(int annoes, const char * codmag,
bool giac_eff, bool valorizza_componenti,
const char * catven, const char * codlist, real & przlist)
{
CHECK(codmag && *codmag,"Necessario indicare il magazzino");
CHECK(strlen(codmag)<=3,"Non <20> pi<70> possibile avere valorizzazione a livello di deposito");
real rim, valrim, acq, valacq, giacenza;
TRecord_array & rmag = mag(annoes);
int i;
for (i = find_mag(annoes, codmag, ""); i > 0; i = find_mag(annoes, codmag, "", i))
{
const TRectype & rec = rmag.row(i);
rim += rec.get_real(MAG_RIM);
valrim += rec.get_real(MAG_VALRIM);
acq += rec.get_real(MAG_ACQ);
valacq += rec.get_real(MAG_VALACQ);
giacenza += giacenza_corretta(rec,giac_eff,valorizza_componenti);
}
if (giacenza <= ZERO)
return ;
const int nuovoanno = esercizi().next(annoes);
const int annoprec = esercizi().pred(annoes);
TRecord_array nuovo_storico(storico(nuovoanno));
copia_storico(nuovo_storico, annoes, codmag, annoprec, rim, valrim, catven, codlist, przlist);
nuovo_storico.sort(sort_storico_rev);
real qta;
real res = giacenza - acq;
for (i = find_storico(nuovo_storico, codmag); i > 0; i = find_storico(nuovo_storico, codmag, i))
{
TRectype & rec = nuovo_storico[i];
const real qta_sto = rec.get_real(STOMAG_QUANT);
if (res > qta_sto)
{
res -= qta_sto;
} else {
if (res>ZERO)
{
qta=res;
rec.put(STOMAG_QUANT, qta);
res=ZERO;
} else {
nuovo_storico.destroy_row(i);
}
}
}
// aggiunge la quota dell'anno in corso
// qta=giacenza-rim;
qta = min(giacenza, acq);
if (!qta.is_zero())
{
real prz;
if (!acq.is_zero())
prz = valacq/acq;
add_storico(nuovo_storico, annoes, codmag, qta, prz, catven, codlist, przlist);
}
nuovo_storico.pack();
nuovo_storico.sort(sort_storico);
nuovo_storico.write();
}
void TArticolo_giacenza::agg_storico(int annoes, const char * codmag,
bool giac_eff, bool valorizza_componenti, const real& val,
const char * catven, const char * codlist, real & przlist)
{
CHECK(codmag && *codmag,"Necessario indicare il magazzino");
CHECK(strlen(codmag)<=3,"Non <20> pi<70> possibile avere valorizzazione a livello di deposito");
real qta;
TRecord_array & rmag = mag(annoes);
for (int i = find_mag(annoes, codmag, ""); i > 0; i = find_mag(annoes, codmag, "", i))
{
const TRectype & rec = rmag.row(i);
qta += giacenza_corretta(rec, giac_eff, valorizza_componenti);
}
const int nuovoanno = esercizi().next(annoes);
TRecord_array& nuovo_storico = storico(nuovoanno);
//nuovo_storico.destroy_rows();
add_storico(nuovo_storico, annoes, codmag, qta, val, catven, codlist, przlist);
nuovo_storico.sort(sort_storico);
nuovo_storico.write();
}
void TArticolo_giacenza::put_ultimo_costo(const real& costo, const TDate& data)
{
TDate d = get_date(ANAMAG_DULTCOS1);
if (data >= d)
{
if (data > d)
{
put(ANAMAG_ULTCOS2, get(ANAMAG_ULTCOS1));
put(ANAMAG_DULTCOS2, get(ANAMAG_DULTCOS1));
}
put(ANAMAG_DULTCOS1, data);
put(ANAMAG_ULTCOS1, costo);
}
else
{
d = get(ANAMAG_DULTCOS2);
if (data >= d)
{
put(ANAMAG_ULTCOS2, costo);
put(ANAMAG_DULTCOS2, data);
}
}
}
void TArticolo_giacenza::put_costo_standard(const real& costo)
{
put(ANAMAG_COSTSTD, costo);
}
// calcola la giacenza corretta dai campi Conto Lavoro e Produzione
real TArticolo_giacenza::giacenza_corretta(const TRectype& rec, bool giac_eff, bool valorizza_componenti) const
{
CHECK(rec.num() == LF_MAG, "Record non su LF_MAG");
real giacenza(rec.get_real(MAG_GIAC));
if (giac_eff)
{
giacenza -= rec.get_real(MAG_INCL);
giacenza += rec.get_real(MAG_ACL);
if (!valorizza_componenti)
giacenza += rec.get_real(MAG_PRODFIN)-rec.get_real(MAG_PRODCOMP);
}
return giacenza;
}
real TArticolo_giacenza::giacenza_anno(const char* codmag, const char* livello, int anno) const
{
TString4 annoes;
if (anno > 0)
annoes.format("%04d", anno);
const TRecord_array& rmag = mag(annoes);
real giac;
for (int i = find_mag(annoes, codmag, livello); i > 0;
i = find_mag(annoes, codmag, livello, i))
{
const TRectype& rec = rmag.row(i);
if (!rec.get(MAG_CODMAG).empty())
giac += rec.get_real(MAG_GIAC);
}
return giac;
}
real TArticolo_giacenza::scorta_minima(const char* codmag,
const char* livello,
int anno, bool liv_riordino) const
{
TString4 annoes;
if (anno > 0)
annoes.format("%04d", anno);
const TRecord_array& rmag = mag(annoes);
real sm;
for (int i = find_mag(annoes, codmag, livello); i > 0;
i = find_mag(annoes, codmag, livello, i))
{
const TRectype& rec = rmag.row(i);
if (!rec.get(MAG_CODMAG).empty())
{
if (liv_riordino)
sm += rec.get_real(MAG_LIVRIOR);
else
sm += rec.get_real(MAG_SCORTAMIN);
}
}
return sm;
}
long TArticolo_giacenza::lead_time(const char* codmag, const char* livello, int anno) const
{
TString4 annoes;
if (anno > 0)
annoes.format("%04d", anno);
const TRecord_array& rmag = mag(annoes);
real sm;
int nmag=0;
for (int i = find_mag(annoes, codmag, livello); i > 0;
i = find_mag(annoes, codmag, livello, i))
{
const TRectype& rec = rmag.row(i);
if (!rec.get(MAG_CODMAG).empty())
{
if (rec.get_real(MAG_GIORNIRIOR).is_zero())
sm += get_real(ANAMAG_GIORNIRIOR);
else
sm += rec.get_real(MAG_GIORNIRIOR);
nmag++;
}
}
if (nmag)
sm /= real(nmag);
else
sm = get_real(ANAMAG_GIORNIRIOR);
return sm.integer();
}
TArticolo_giacenza::TArticolo_giacenza(const char* codice)
: TArticolo(codice), _anno_mag(0), _anno_sto(0)
{
add_file(LF_MAG,"NRIGA");
add_file(LF_STOMAG,"NRIGA");
}
TArticolo_giacenza::TArticolo_giacenza(const TRectype& rec)
: TArticolo(rec), _anno_mag(0), _anno_sto(0)
{
add_file(LF_MAG,"NRIGA");
add_file(LF_STOMAG,"NRIGA");
}
// Giacenze alla data
void TArticolo_giacenza_data::al(const TDate& data, const char* codmag, const char* livello,
TTipo_valorizz tipo, const char* catven, const char* codlis)
{
const int anno = esercizi().date2esc(data);
const TDate inizio = esercizi()[anno].inizio();
bool reset_giac = true;
const int anno_pred = esercizi().pred(anno);
if (anno_pred != 0)
{
const TDate dc = esercizi()[anno_pred].chiusura_mag();
reset_giac = dc.ok();
}
remove_body(LF_MAG); // Azzero la cache dei magazzini
if (reset_giac)
azzera_saldi(anno, anno_pred, false);
else
riporta_saldi(anno_pred, anno, tipo, catven, codlis, false);
TRelation rel(LF_RMOVMAG); rel.add(LF_MOVMAG, "NUMREG==NUMREG");
TRectype filter(LF_RMOVMAG);
filter.put(RMOVMAG_CODART, codice());
if (livello && *livello)
filter.put(RMOVMAG_LIVGIAC, livello);
if (codmag && *codmag)
filter.put(RMOVMAG_CODMAG, codmag);
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;
*/
const TRectype& rmovmag = rel.curr();
TRecord_array& rmag = mag(anno);
for (cur = 0; cur.pos() < items; ++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);
const TString16 livello = rmovmag.get(RMOVMAG_LIVGIAC);
const long nreg = rmovmag.get_int(RMOVMAG_NUMREG);
const int nrig = rmovmag.get_int(RMOVMAG_NRIG);
const int i = find_mag(anno, codmag, livello);
TMov_mag movmag(nreg);
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);
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)
: TArticolo_giacenza(codice)
{ }
TArticolo_giacenza_data::TArticolo_giacenza_data(const TRectype& rec)
: TArticolo_giacenza(rec)
{ }
// TArticolo_giacenza_loadable
TArticolo_giacenza_loadable::TArticolo_giacenza_loadable(const char* codice)
: TArticolo_giacenza_data(codice)
{ }
TArticolo_giacenza_loadable::TArticolo_giacenza_loadable(const TRectype& rec)
: TArticolo_giacenza_data(rec)
{ }
// Carica il record array delle giacenza dal file temporaneo specificato
void TArticolo_giacenza_loadable::load(TIsamtempfile& f)
{
TString16 annoes;
TString codart(codice());
int err;
// Il file temporaneo contiene le giacenze alla data per tutti
// gli articoli per un SOLO anno esercizio.
// Reperisce l'anno esercizio dal record corrente, visto che deve essere uguale su tutti
const TRecnotype pos = f.recno();
annoes = f.get("ANNOES");
f.put("CODART", codart);
remove_body(LF_MAG);
TRecord_array& rmag = mag(annoes);
rmag.destroy_rows();
// Scorre le giacenze del file temporaneo per questo articolo
int key = f.getkey();
f.setkey(1);
for (err = f.read(_isgteq) ; err == NOERR && codart == f.get("CODART"); err = f.next())
rmag.add_row(f.curr());
// Ripristina la posizione
f.setkey(key);
f.readat(pos);
}
///////////////////////////////////////////////////////////
// TArticolo_giacenza_cache
///////////////////////////////////////////////////////////
class TCache_articoli_giacenza : public TRecord_cache
{
protected:
virtual TObject* rec2obj(const TRectype& rec) const { return new TArticolo_giacenza(rec);}
public:
TArticolo_giacenza& art(const char* key) { return (TArticolo_giacenza&)query(key); }
TCache_articoli_giacenza();
virtual ~TCache_articoli_giacenza() { }
};
TCache_articoli_giacenza::TCache_articoli_giacenza()
: TRecord_cache(LF_ANAMAG, 1)
{
test_file_changes(); // Tieni d'occhio le modifiche sul file
set_items_limit(257); // Numero primo!
}
TArticolo_giacenza& cached_article_balances(const char* codart)
{
HIDDEN TCache_articoli_giacenza __cache_articoli_giacenza;
if (codart == NULL) // Segnale di azzeramento cache
{
__cache_articoli_giacenza.destroy();
codart = ""; // Evita errori fatali successivi
}
return __cache_articoli_giacenza.art(codart);
}
// causali
int TCausale_magazzino::sgn(TTipo_saldomag tiposaldo) const
{
int index = -1;
switch (tiposaldo)
{
case s_giac : index = 0; break;
case s_acq : index = 2; break;
case s_ent : index = 4; break;
case s_ven : index = 6; break;
case s_usc : index = 8; break;
case s_ordc : index = 10; break;
case s_ordf : index = 12; break;
case s_incl : index = 14; break;
case s_acl : index = 16; break;
case s_prodc: index = 18; break;
case s_prodf: index = 20; break;
case s_rim : index = 22; break;
case s_scart: index = 24; break;
case s_label: index = 26; break;
case s_dotin: index = 28; break;
case s_dotod: index = 30; break;
case s_dottm: index = 32; break;
case s_consanno: index = 34; break;
case s_consmese: index = 36; break;
default : index = -1; break;
}
int segno = 0;
if (index >= 0)
{
const TString& segni = get("S2");
segno = atoi(segni.mid(index, 2));
}
return segno;
}
bool TCausale_magazzino::is_fiscale()
{
bool rt = FALSE;
if (raggfisc().not_empty()) // Per essere fiscale deve avere il raggruppamento fiscale
{
const char tm = tipomov();
rt = tm == 'S' || tm == 'C'; // La causale deve essere Carico o Scarico...
if (rt)
{
const TRectype& rfc = cache().get("%RFC", raggfisc());
const char ragg = rfc.get_char("S6");
rt &= (ragg == 'S' || ragg == 'C'); // Ed il raggruppamento deve essere Carico o Scarico
}
}
return rt;
}
TCausale_magazzino::TCausale_magazzino(const char * codice):
TRectype(cache().get("%CAU", codice))
{ }
TCausale_magazzino::TCausale_magazzino(const TRectype &r):
TRectype(r)
{
CHECK(r.num() == LF_TABCOM, "Tipo record errato sulla causale di magazzino");
}
///////////////////////////////////////////////////////////
// TCache_causali_magazzino
///////////////////////////////////////////////////////////
class TCache_causali_magazzino : public TRecord_cache
{
protected:
virtual TObject* rec2obj(const TRectype& rec) const{ return new TCausale_magazzino(rec); }
public:
TCausale_magazzino& caus(const char* key);
TCache_causali_magazzino();
virtual ~TCache_causali_magazzino() { }
};
TCache_causali_magazzino::TCache_causali_magazzino()
: TRecord_cache("%CAU", 1)
{
test_file_changes(); // Tieni d'occhio le modifiche sul file
set_items_limit(83); // Numero primo
}
TCausale_magazzino & TCache_causali_magazzino::caus(const char* key)
{
TString16 k;
k << "CAU|" << key;
return (TCausale_magazzino &)query(k);
}
TCausale_magazzino & cached_causale_magazzino(const char * codcaus)
{
HIDDEN TCache_causali_magazzino __cache_causali_magazzino;
return __cache_causali_magazzino.caus(codcaus);
}
bool TCondizione_vendita::ricerca(const char * codice, const real & qta, bool ignore_umart)
{
int tiporic;
switch (_condv.get_char("TIPO"))
{
case 'L':
tiporic = A_LISTINI;
break;
case 'C':
tiporic = A_CONTRATTI;
break;
case 'O':
tiporic = A_OFFERTE;
break;
default:
tiporic = ' ';
break;
}
return cerca(tiporic,codice, qta, NULL, ignore_umart);
}
bool TCondizione_vendita::cerca( int tiporicerca, const char * codriga , const real & qta, const char * um, bool ignore_umart)
{
// if (_condv.get("COD").empty())
// return FALSE;
bool found = FALSE;
TString80 cod; cod << codriga << "|1";
if(config_ditta().get_bool("GES", "ve", tiporicerca))
{
_condv.setkey( 1 );
switch( tiporicerca )
{
case A_LISTINI:
{
_condv.put("TIPOCF", "");
_condv.put("CODCF", "");
if( !config_ditta().get_bool("GESLISCV", "ve"))
_condv.put("CATVEN", "");
}
break;
default:
break;
}
if( _condv.read() == NOERR )
{
// si posiziona sulla riga
const bool gest_scagl = _condv.get_bool("GESTSCAGL");
const TString16 seqricrighe( _condv.get( "SEQRIC" ) );
for( int i = 0; !found && i < seqricrighe.len( ); i ++ )
{
_rcondv.zero(' ');
_rcondv.put( "TIPO", _condv.get( "TIPO"));
_rcondv.put( "CATVEN", _condv.get( "CATVEN"));
_rcondv.put( "TIPOCF", _condv.get( "TIPOCF"));
_rcondv.put( "CODCF", _condv.get( "CODCF"));
_rcondv.put("COD", _condv.get("COD"));
if( _condv.get_bool( "GESTUM" ) )
_rcondv.put( "UM", (um && *um ) ? um : (const char *) cache().get(LF_UMART, cod).get("UM"));
if (gest_scagl)
_rcondv.put("NSCAGL", 1);
char ricerca = seqricrighe[ i ];
_rcondv.put( "TIPORIGA", ricerca );
switch( ricerca )
{
case 'A':
{
_rcondv.put( "CODRIGA", codriga);
int err = _rcondv.read();
found = (err == NOERR);
if (!found && config_ditta().get_bool("GESLIVART", "mg")) // Per articoli strutturati prova la riga precedente
{
if ((err = _rcondv.prev()) == NOERR && _rcondv.get("TIPORIGA")[0] == 'A')
{
const TString& cod_found(_rcondv.get("CODRIGA"));
found = cod_found.compare(codriga, cod_found.len()) == 0;
}
}
}
break;
case 'R':
_rcondv.put("CODRIGA", anamag().get( "RAGGFIS"));
_rcondv.read();
found = _rcondv.good();
break;
case 'S':
{
_rcondv.put( "CODRIGA", anamag().get("GRMERC"));
_rcondv.read( );
found = _rcondv.good();
}
break;
case 'G':
{
_rcondv.put( "CODRIGA", anamag().get("GRMERC").left(3));
_rcondv.read( );
found = _rcondv.good();
}
break;
default:
break;
}
}
// individua lo scaglione corretto in base alla quantita'
if (found && gest_scagl)
{
TRectype rec(_rcondv.curr());
int last_scagl = 0;
int scagl = _rcondv.get_int("NSCAGL");
real qta_lim(_rcondv.get_real("QLIM"));
while (_rcondv.good() && scagl > last_scagl && qta_lim > ZERO && qta > qta_lim)
{
if (_rcondv.next() == NOERR)
{
last_scagl = scagl;
scagl = _rcondv.get_int("NSCAGL");
qta_lim =_rcondv.get_real("QLIM");
rec = _rcondv.curr();
}
}
_rcondv.read(rec);
}
_prezzo = _rcondv.get_real("PREZZO");
}
}
if (!found && !ignore_umart)
{
const TRectype& um = cache().get(LF_UMART, cod);
_prezzo = um.get_real("PREZZO");
found = !_prezzo.is_zero();
}
return found;
}
void TCondizione_vendita::put_condv(const char *tipocv,const char *codicecv,const char *catven,const char *tipocf,const char *codcf)
{
_condv.zero(' ');
_condv.put("TIPO",tipocv);
_condv.put("CATVEN",catven);
_condv.put("TIPOCF",tipocf);
_condv.put("CODCF",codcf);
_condv.put("COD",codicecv);
}
void TCondizione_vendita::put_listino(const char * codlist,const char *catven)
{
if ( !config_ditta().get_bool("GESLISCV", "ve"))
put_condv("L",codlist,"","","");
else
put_condv("L",codlist,catven,"","");
}
void TCondizione_vendita::put_contratto(const char * codcontr,const char *tipocf,const char *codcf)
{
put_condv("C",codcontr,"",tipocf,codcf);
}
void TCondizione_vendita::put_offerta(const char * codoff)
{
put_condv("C",codoff,"","","");
}
TCondizione_vendita::TCondizione_vendita(TConfig * ditta,
TLocalisamfile * anamag, TLocalisamfile * umart)
: _condv(LF_CONDV), _rcondv(LF_RCONDV),
_sconti( LF_SCONTI ),
_anamag(anamag), _umart(umart), _config_ditta(ditta), _ivarid(FALSE)
{
}