#include "mglib02.h" #include "../cg/cglib.h" void TMultiple_rectype::load_rows_file(int logicnum) { const int index = log2ind(logicnum); TRectype & rec = get_body_record(logicnum); set_body_key(rec); TRecord_array * r = new TRecord_array(logicnum, (TString &) _numfields[index]); _files.add( r, index); } int TMultiple_rectype::find(int logicnum, const char * fieldname, const char * s, int from, bool reverse) const { const TRecord_array & recarray = body(logicnum); const int last = recarray.last_row(); const int len = s ? strlen(s) : 0; if (reverse) { if (from > 0) { if (len == 0) return from - 1; for (int i = recarray.pred_row(from); i > 0; i = recarray.pred_row(i)) if (recarray[i].get(fieldname) == s) return i; } } else { if (last > from) { if (len == 0) return from + 1; for (int i = recarray.succ_row(from); i <= last; i = recarray.succ_row(i)) if (recarray[i].get(fieldname) == s) return i; } } return -1; } int TMultiple_rectype::write_rewrite(TBaseisamfile & f, bool re) const { int err = NOERR; if (_nuovo && re) // E' nuovo di zecca! quindi ... re = FALSE; // ... non fare la rewrite if (re) { for (int i = _nfiles - 1; err == NOERR && i >= 0 ; i--) { TRecord_array * r = (TRecord_array *) _files.objptr(i); if (r) err = r->write(re); } // rewrite: if (err == NOERR) { err = TRectype::rewrite(f); if (err != NOERR) err = TRectype::write(f); } } else { // write: if (_nuovo) { do { err = TRectype::write(f); if (err == _isreinsert) // usa il flag _nuovo per decidere se ((TMultiple_rectype *)this)->renum(); } while (err == _isreinsert); ((TMultiple_rectype *)this)->_nuovo = FALSE; } else { err = TRectype::write(f); if (err != NOERR) err = TRectype::rewrite(f); } for (int i = _nfiles - 1; err == NOERR && i >= 0 ; i--) { TRecord_array * r = (TRecord_array *)_files.objptr(i); if (r) err = r->write(re); } } return err; } void TMultiple_rectype::remove_body(int logicnum) { const int index = log2ind(logicnum); if (_files.objptr(index) != NULL) _files.remove(index); } int TMultiple_rectype::log2ind(int logicnum) const { if (logicnum == 0) return 0; for (int i = _nfiles - 1; i >= 0 ; i--) if (_logicnums[i] == logicnum) return i; NFCHECK("Can't find file %d in multiple record", logicnum); return 0; } TRecord_array & TMultiple_rectype::body(int logicnum) const { const int index = log2ind(logicnum); if (_files.objptr(index) == NULL) ((TMultiple_rectype *) this)->load_rows_file(logicnum); return (TRecord_array &) _files[index]; } void TMultiple_rectype::renum_key(const char * kfield,const char * val) { TRectype::renum_key(kfield, val); // Aggiorna testata for (int i = _nfiles - 1; i >= 0 ; i--) body(_logicnums[i]).renum_key(kfield, val); // Aggiorna righe } TRectype & TMultiple_rectype::operator =(const TRectype & r) { TRectype::operator=(r); reset_fields(*this); set_fields(*this); return *this; } TRectype & TMultiple_rectype::operator =(const char * r) { TRectype::operator=(r); reset_fields(*this); set_fields(*this); return *this; } void TMultiple_rectype::zero(char c) { reset_fields(*this); TAuto_variable_rectype::zero(c); for (int i = _nfiles - 1; i >= 0 ; i--) if (_files.objptr(i) != NULL) _files.remove(i); } int TMultiple_rectype::read(TRectype & rec, word op, word lockop) { TLocalisamfile f(num()); *this = rec; int err = TRectype::read(f, op, lockop); for (int i = _nfiles - 1; i >= 0 ; i--) if (_files.objptr(i) != NULL) _files.remove(i); _nuovo = err != NOERR; return err; } int TMultiple_rectype::remove(TBaseisamfile & f) const { int err = NOERR; for (int i = _nfiles - 1; err == NOERR && i >= 0 ; i--) { TRecord_array & r = body(_logicnums[i]); r.remove(); } if (err == NOERR) err = TRectype::remove(f); return err; } // @doc INTERNAL TMultiple_rectype::TMultiple_rectype(int hfn) : TAuto_variable_rectype(hfn), _nuovo(TRUE), _nfiles(0) { } // @ cmember costruttore dal file void TMultiple_rectype::add_file(int logicnum, const char * numfield) { CHECK(_nfiles < maxfiles, "Too many files added"); _logicnums[_nfiles] = logicnum; _numfields.add(numfield, _nfiles++); } TMultiple_rectype::TMultiple_rectype(const TBaseisamfile* file) :TAuto_variable_rectype(file), _nuovo(TRUE), _nfiles(0) { } // @ cmember costruttore dal record TMultiple_rectype::TMultiple_rectype(const TRectype & rec) :TAuto_variable_rectype(rec), _nuovo(TRUE), _nfiles(0) { } // @mfunc costruttore di copia TMultiple_rectype::TMultiple_rectype(const TMultiple_rectype& r) :TAuto_variable_rectype(r), _files(r._files) { // copia.. _nuovo=r._nuovo; _nfiles=r._nfiles; // file delle righe _numfields=r._numfields; } HIDDEN TString16 _mg_null_str; 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 == '#') index = atoi(fname + 1); const char* op2 = strstr(fname, "->"); CHECKS(op2, "Can't find '->' in string ", fieldname); 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 _mg_null_str; } void TArticolo::set_body_key(TRectype & rowrec) { const int logicnum = rowrec.num(); const char * codice = (const char *) _codice; switch (logicnum) { case LF_UMART: rowrec.put(UMART_CODART, codice); break; case LF_DESLIN: rowrec.put(DESLIN_CODART, codice); break; case LF_CODCORR: rowrec.put(CODCORR_CODART, codice); break; default: break; } } int TArticolo::read(const char * cod, word op, word lockop) { if (op == _isequal && lockop == _nolock &&strcmp(cod, (const char *) _codice) == 0) return NOERR; *_codice = cod; const int err = TMultiple_rectype::read(op , lockop); if (err != NOERR) zero(); return err; } 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); } else return get(ANAMAG_DESCR); } TArticolo::TArticolo(const char* codice) : TMultiple_rectype(LF_ANAMAG) { _codice = new TRecfield(*this, ANAMAG_CODART); if (codice && *codice) read(codice); } TArticolo::TArticolo(const TRectype& rec) : TMultiple_rectype(rec) { _codice = new TRecfield(*this, ANAMAG_CODART); } TArticolo::~TArticolo() { delete _codice; } 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); const char * op1 = strchr(fname, '_'); int index = 0; if (op1 && *op1 == '#') index = atoi(fname + 1); fname = (char *) op1 + 1; const char * op2 = strchr(fname, '_'); fname = (char *) op2 + 1; const char * op3 = strchr(fname, '_'); const char * op4 = strstr(fname, "->"); CHECKS(op4, "Can't find '->' in string ", fieldname); 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, op2); if (index > 0) return storico(op1).row(index).get(op4); break; default: return TArticolo::get_str(fieldname); break; } return _mg_null_str; } 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 (const char * anno) { if (_anno_mag != anno) remove_body(LF_MAG); _anno_mag = anno; } void TArticolo_giacenza::set_anno_sto (const char * 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(const char * annoes, const char * codmag, const char * livello, int from) const { TRecord_array & rmag = mag(annoes); const int last = rmag.last_row(); if (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) return from + 1; 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_storico(const char * annoesrif, const char * annoes, int from) const { ((TArticolo_giacenza *) this)->set_anno_sto(annoesrif); return find(LF_STOMAG, STOMAG_ANNOES, annoes, from); } TRecord_array & TArticolo_giacenza::mag(const char * annoes) const { ((TArticolo_giacenza *) this)->set_anno_mag(annoes); return body(LF_MAG); } TRecord_array & TArticolo_giacenza::storico(const char * annoesrif) const { ((TArticolo_giacenza *) this)->set_anno_sto(annoesrif); return body(LF_STOMAG); } HIDDEN int last_esercizio = -1; real TArticolo_giacenza::ultimo_costo(const char * annoes) const { if (last_esercizio != atoi(annoes)) { const real costo = get_real(ANAMAG_ULTCOS1); return costo == ZERO ? costo_standard(annoes) : costo; } else { const int index = find_storico(annoes, annoes); const real costo = storico(annoes).row(index).get_real(STOMAG_ULTCOS1); return costo == ZERO ? costo_standard(annoes) : costo; } } real TArticolo_giacenza::media_costi(const char * annoes) const { if (last_esercizio != atoi(annoes)) { real costo = get_real(ANAMAG_ULTCOS1); costo = (costo + get_real(ANAMAG_ULTCOS2)) / 2.0; return costo == ZERO ? costo_standard(annoes) : costo; } else { const int index = find_storico(annoes, annoes); const TRectype & rec = storico(annoes).row(index); real costo = rec.get_real(STOMAG_ULTCOS1); costo = (costo + rec.get_real(STOMAG_ULTCOS2)) / 2.0; return costo == ZERO ? costo_standard(annoes) : costo; } } real TArticolo_giacenza::prezzo_listino(const char * annoes, const char * catven, const char * codlist) const { if (last_esercizio != atoi(annoes)) { static TString16 f; if (f.empty()) f.format("#%d->%s", LF_UMART, UMART_PREZZO); return get_real(f); // da terminare } else { const int index = find_storico(annoes, annoes); return storico(annoes).row(index).get_real(STOMAG_PRZLIST); } } real TArticolo_giacenza::costo_standard(const char * annoes) const { if (last_esercizio != atoi(annoes)) return get_real(ANAMAG_COSTSTD); else { const int index = find_storico(annoes, annoes); return storico(annoes).row(index).get_real(STOMAG_COSTSTD); } } real TArticolo_giacenza::costo_medio(const char * annoes, const char * codmag, const char * livello) const { real acq; real valacq; 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 == ZERO ? costo_standard(annoes) : valacq / acq; } real TArticolo_giacenza::LIFO_annuale(const char * annoes, const char * codmag, const char * livello, bool giacenza_effettiva, bool valorizza_componenti) const { real rim; real valrim; real acq; real 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 += rec.get_real(MAG_GIAC); if (giacenza_effettiva) { giacenza += rec.get_real(MAG_INCL); giacenza -= rec.get_real(MAG_ACL); giacenza += valorizza_componenti ? rec.get_real(MAG_PRODCOMP) : rec.get_real(MAG_PRODFIN); } } if (giacenza <= ZERO) return ZERO; if (giacenza > rim) return ((giacenza - rim) * (acq == ZERO ? costo_standard(annoes) : valacq / acq) + valrim) / giacenza; return valrim / rim; } real TArticolo_giacenza::FIFO_annuale(const char * annoes, const char * codmag, const char * livello, bool giacenza_effettiva, bool valorizza_componenti) const { real rim; real valrim; real acq; real 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 += rec.get_real(MAG_GIAC); if (giacenza_effettiva) { giacenza += rec.get_real(MAG_INCL); giacenza -= rec.get_real(MAG_ACL); giacenza += valorizza_componenti ? rec.get_real(MAG_PRODCOMP) : rec.get_real(MAG_PRODFIN); } } if (giacenza <= ZERO) return ZERO; if (giacenza > acq) return ((giacenza - acq) * (valrim / rim) + valacq) / giacenza; return valacq / acq; } real TArticolo_giacenza::LIFO(const char * annoes, const char * codmag, const char * livello, bool giacenza_effettiva, bool valorizza_componenti) const { real rim; real valrim; real acq; real 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 += rec.get_real(MAG_GIAC); if (giacenza_effettiva) { giacenza += rec.get_real(MAG_INCL); giacenza -= rec.get_real(MAG_ACL); giacenza += valorizza_componenti ? rec.get_real(MAG_PRODCOMP) : rec.get_real(MAG_PRODFIN); } } 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(); rim = giacenza; for (i = rstorico.first_row(); i <= last; i = rstorico.succ_row(i)) { const TRectype & rec = rstorico.row(i); const real qta = rec.get(STOMAG_QUANT); if (qta > giacenza) { valrim += (rec.get_real(STOMAG_VALORE) / qta) * giacenza; break; } else { valrim += rec.get_real(STOMAG_VALORE); giacenza -= qta; } } return valrim / rim; } real TArticolo_giacenza::FIFO(const char * annoes, const char * codmag, const char * livello, bool giacenza_effettiva, bool valorizza_componenti) const { real rim; real valrim; real acq; real 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 += rec.get_real(MAG_GIAC); if (giacenza_effettiva) { giacenza += rec.get_real(MAG_INCL); giacenza -= rec.get_real(MAG_ACL); giacenza += valorizza_componenti ? rec.get_real(MAG_PRODCOMP) : rec.get_real(MAG_PRODFIN); } } 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; for (i = last; i > 0; i--) { const TRectype & rec = rstorico.row(i); const real qta = rec.get(STOMAG_QUANT); if (qta > res) { rim += res; valrim += (rec.get_real(STOMAG_VALORE) / qta) * res; } else { rim += qta; valrim += rec.get_real(STOMAG_VALORE); res -= qta; } } return ((giacenza - acq) * (valrim / rim) + valacq) / giacenza; } real TArticolo_giacenza::FIFO_ragionieristico(const char * annoes, const char * codmag, const char * livello, bool giacenza_effettiva, bool valorizza_componenti) const { return ZERO; } real TArticolo_giacenza::LIFO_ragionieristico(const char * annoes, const char * codmag, const char * livello, bool giacenza_effettiva, bool valorizza_componenti) const { return ZERO; } TArticolo_giacenza::TArticolo_giacenza(const char* codice) : TArticolo(codice) { if (last_esercizio < 0 ) { TEsercizi_contabili e; last_esercizio = e.last(); } } TArticolo_giacenza::TArticolo_giacenza(const TRectype& rec) : TArticolo(rec) { if (last_esercizio < 0 ) { TEsercizi_contabili e; last_esercizio = e.last(); } }