// oggetto TArticolo, multirecord dell'articolo di anagrafica magazzino // oggetto TArticolo_giacenza, multirecord dell'articolo di magazzino // oggetto TMov_Mag , multirecord del moviemnto di magazzino // funzione di ricostruzione saldi #include "mglib.h" #include "anamag.h" #include "mag.h" #include "movmag.h" // libreria per i movimenti char * Nome_valorizz[]= { "Ultimo costo", "Media ultimi costi", "Prezzo di listino", "Costo standard", "Costo medio" , "FIFO annuale", "LIFO annuale", "FIFO", "LIFO", "FIFO Ragionieristico", "LIFO Ragionieristico" } ; 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(TRectype & rec, word op, word lockop) { if (op == _isequal && lockop == _nolock &&strcmp(rec.get(ANAMAG_CODART), (const char *) _codice) == 0) return NOERR; *_codice = rec.get(ANAMAG_CODART); const int err = TMultiple_rectype::read(rec, op , lockop); if (err != NOERR) zero(); return err; } int TArticolo::read(const char * cod, word op, word lockop) { put(ANAMAG_CODART,cod); return read( *this, op, lockop); } 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); } void TArticolo::update_ultcosti(real costo,TDate data) { TDate data1(get_date(ANAMAG_DULTCOS1)); if (data>= data1) { real costo1(get_real(ANAMAG_ULTCOS1)); put(ANAMAG_DULTCOS1,data); put(ANAMAG_ULTCOS1,costo); put(ANAMAG_DULTCOS2,data1); put(ANAMAG_ULTCOS2,costo1); } else { if (data>= get_date(ANAMAG_DULTCOS2)) put(ANAMAG_DULTCOS2,data); put(ANAMAG_ULTCOS2,costo); } } bool TArticolo::unlock() { bool rv; if (*(const char *)_codice) { TLocalisamfile anag(LF_ANAMAG); anag.curr()=*this; rv=(anag.read(_isequal,_unlock)==NOERR); return rv; } return FALSE; } bool TArticolo::lock_and_prompt() { TString mess; mess << "Il record di anagrafica dell'articolo ''"<< codice() << "'' risulta essere già in uso.\n Interrompo ?"; TTimed_breakbox bbox((const char *)mess,10); do { TLocalisamfile anag(LF_ANAMAG); anag.curr()=*this; if (anag.read(_isequal,_testandlock)==NOERR) return TRUE; } while (bbox.run()!=K_ESC); return FALSE; } TArticolo::TArticolo(const char* codice) : TMultiple_rectype(LF_ANAMAG) { add_file(LF_UMART,"NRIGA"); add_file(LF_CODCORR,"NRIGA"); add_file(LF_DESLIN,"NRIGA"); _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); if (index < 0 ) return ZERO; 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); if (index < 0 ) return ZERO; 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); if (index < 0 ) return ZERO; 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); if (index < 0 ) return ZERO; 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) { add_file(LF_MAG,"NRIGA"); add_file(LF_STOMAG,"NRIGA"); 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(); } } #include #include #include #include #include #include #include #include #include #include "..\ve\velib.h" #include "..\ve\sconti.h" #include "..\ve\veconf.h" const real CENTO=real(100.0); bool TCondizione_vendita:: ricerca(const char * codice, const real & qta) { 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; } return cerca(tiporic,codice, qta); } bool TCondizione_vendita::cerca( int tiporicerca, const char * codriga , const real & qta) { if( config_ditta().get_bool( "GES", "ve", tiporicerca ) ) { _condv.setkey( 1 ); if (_condv.get("COD").empty()) return FALSE; switch( tiporicerca ) { case A_CONTRATTI: { } break; case A_LISTINI: { _condv.put("TIPOCF", ""); _condv.put("CODCF", ""); if( !config_ditta().get_bool("GESLISCV", "ve")) _condv.put("CATVEN", ""); } break; case A_OFFERTE: { } break; } if( _condv.read( ) == NOERR ) { // si posiziona sulla riga const bool gest_scagl = _condv.get_bool("GESTSCAGL"); const TString16 seqricrighe( _condv.get( "SEQRIC" ) ); bool found = FALSE; 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 (gest_scagl) _rcondv.put("NSCAGL", 1); char ricerca = seqricrighe[ i ]; _rcondv.put( "TIPORIGA", ricerca ); switch( ricerca ) { case 'A': { _rcondv.put( "CODRIGA", codriga); if (_rcondv.read() != NOERR && _rcondv.prev() == NOERR && _rcondv.get("TIPORIGA")[0] == 'A') { const TString cod_found(_rcondv.get("CODRIGA")); return cod_found.compare(codriga, cod_found.len()) == 0; } } break; case 'R': _rcondv.put("CODRIGA", anamag().get( "RAGGFIS")); _rcondv.read(); break; case 'S': { _rcondv.put( "CODRIGA", anamag().get("GRMERC")); _rcondv.read( ); } break; case 'G': { _rcondv.put( "CODRIGA", anamag().get("GRMERC").left(3)); _rcondv.read( ); } break; default: break; } found = _rcondv.good(); } // 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"); return found; } } // Ricerca fallita return FALSE; } void TCondizione_vendita::put_condv(const char *tipocv,const char *codicecv,const char *catven,const char *tipocf,const char *codcf) { _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) { } // ********************* // movimenti di magazzino // causali int TCausale_magazzino::sgn(TTipo_saldomag tiposaldo) { switch (tiposaldo) { case s_giac: return get_int("I0"); case s_acq: return get_int("I1"); case s_ent: return get_int("I2"); case s_ven: return get_int("I3"); case s_usc: return get_int("I4"); case s_ordc: return get_int("I5"); case s_ordf: return get_int("I6"); case s_incl: return get_int("I7"); case s_acl: return get_int("I8"); case s_prodc: return get_int("I9"); case s_prodf: return get_int("I10"); case s_rim: return get_int("I11"); case s_scart: return get_int("I12"); case s_label: return get_int("I13"); default: return 0; } } TCausale_magazzino::TCausale_magazzino(const char * codice): TRectype(LF_TABCOM) { TTable f("%CAU"); settab("CAU"); put("CODTAB", codice); if (TRectype::read(f) != NOERR) zero(); } // movimenti TLine_movmag ::TLine_movmag(const TLine_movmag &l) { um=l.um; quant=l.quant; prezzo=l.prezzo; } int TLine_movmag::operator==(TLine_movmag &l) { return (um==l.um)&&(quant==l.quant)&&(prezzo==l.prezzo); } TMov_mag::TMov_mag() : TMultiple_rectype(LF_MOVMAG), lines_to_add(), lines_to_subtract() { add_file(LF_RMOVMAG,"NRIG"); } TMov_mag::~TMov_mag() { } // valuta il valore della chiave per un nuovo record bool TMov_mag::renum() { put("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("NUMREG",get("NUMREG")); } int TMov_mag::read(TBaseisamfile& f, word op , word lockop) { int res=TMultiple_rectype::read(f,op,lockop); // reset delle strutture per il controlli delle variazioni dei saldi _codcaus=get("CODCAUS"); _annoes=get("ANNOES"); lines_to_add.destroy(); lines_to_subtract.destroy(); const int nrows = rows(); for (int i = 1; i< nrows; i++) line_deleted(line2key(i), line2data(i)); return res; } int TMov_mag::remove(TBaseisamfile& f) const { int res; if ((res=TMultiple_rectype::remove(f))==NOERR ) // effettua la variazione dei saldi res=((TMov_mag *)this)->update_balances(); return res; } void TMov_mag::add_automatiche() { for (int r = rows(); r > 0; r--) { TRecord_array & b = body(); TRectype & row = b[r]; TString16 codcaus(row.get(RMOVMAG_CODCAUS)); if (codcaus.empty()) codcaus=get(MOVMAG_CODCAUS); TCausale_magazzino cau(codcaus); codcaus=cau.caus_collegata(); if (codcaus.not_empty()) { // 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); const char * codmag = codmag_rauto(r); if (codmag != NULL) 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); } } } // ciclo righe } int TMov_mag::write(TBaseisamfile& f) const { int res; ((TMov_mag *)this)->add_automatiche(); // memorizza le variazioni const int nrows = rows(); for (int i = 1; i <= nrows; i++) ((TMov_mag *)this)->line_inserted(line2key(i), line2data(i)); if ((res=TMultiple_rectype::write(f))==NOERR ) // effettua la variazione dei saldi res=((TMov_mag *)this)->update_balances(); return res; } int TMov_mag::rewrite(TBaseisamfile& f) const { int res; ((TMov_mag *)this)->add_automatiche(); // memorizza le variazioni const int nrows = rows(); for (int i = 1; i < nrows; i++) ((TMov_mag *)this)->line_inserted(line2key(i), line2data(i)); if ((res=TMultiple_rectype::rewrite(f))==NOERR ) // effettua la variazione dei saldi res=((TMov_mag *)this)->update_balances(); return res; } const char *TMov_mag::get_next_key() { TLocalisamfile f(LF_MOVMAG); f.last(); int a=atoi(f.get(MOVMAG_NUMREG))+1; return _nextcod.format("%d",a); } //******* // gestione delle variazione dei saldi // // int TMov_mag::force_update_bal() { int res; TToken_string l_key; TLine_movmag l_data; // reset delle strutture per il controlli delle variazioni dei saldi _codcaus=get(MOVMAG_CODCAUS); _annoes=get(MOVMAG_ANNOES); lines_to_add.destroy(); lines_to_subtract.destroy(); // memorizza le variazioni const int nrows = rows(); for (int i= 1; i <= nrows; i++) line_inserted(line2key(i), line2data(i)); res=update_balances(); return res; } TLine_movmag & TMov_mag::line2data(int numriga) const { static TLine_movmag _rest; TRecord_array & b = body(); _rest.um = b.row(numriga).get("UM"); _rest.quant = b.row(numriga).get_real("QUANT"); _rest.prezzo= b.row(numriga).get_real("PREZZO"); return _rest; } TToken_string & TMov_mag::line2key(int numriga) const { static TToken_string _key; TRecord_array & b = body(); TString16 nr; nr << numriga; _key.cut(0); _key.add(b.row(numriga).get(RMOVMAG_CODART)); _key.add(b.row(numriga).get(RMOVMAG_CODMAG)); _key.add(b.row(numriga).get(RMOVMAG_LIVGIAC)); _key.add(nr); return _key; } TString TMov_mag::key2field(TToken_string &key,const char *fieldname) { if (strcmp(fieldname,"CODART")==0) return key.get(0); if (strcmp(fieldname,"CODMAG")==0) return key.get(1); if (strcmp(fieldname,"LIVGIAC")==0) return key.get(2); CHECKS(FALSE, "Nome di campo non appartenente al file righe mov ", fieldname); return ""; } int TMov_mag::line_inserted(TToken_string &k,TLine_movmag &r) { if (_codcaus != get("CODCAUS") || _annoes != get("ANNOES")) { lines_to_add.add(k,r); } else { if (lines_to_subtract.is_key(k)&& (TLine_movmag &)lines_to_subtract[k]==r) // modifica annullata lines_to_subtract.remove(k); else // linea modificata lines_to_add.add(k,r); } return 0; } int TMov_mag::line_deleted(TToken_string &k,TLine_movmag &r) { if (_codcaus != get("CODCAUS") || _annoes != get("ANNOES")) { lines_to_subtract.add(k,r); } else { if (lines_to_add.is_key(k)&& r==(TLine_movmag &)lines_to_add[k] ) // modifica annullata lines_to_add.remove(k); else // linea modificata lines_to_subtract.add(k,r); } return 0; } bool TMov_mag::unlock_anamag(const char *codart) { TLocalisamfile anamag(LF_ANAMAG); anamag.put("CODART",codart); return (anamag.read(_isequal,_unlock)==NOERR); } bool TMov_mag::lock_anamag(const char *codart) { TLocalisamfile anamag(LF_ANAMAG); anamag.put("CODART",codart); bool insert_new=TRUE; TString mess; mess << "Il record di anagrafica dell'articolo ''"<< codart << "'' risulta essere già in uso.\n Interrompo ?"; TTimed_breakbox bbox((const char *)mess,10); do { if (anamag.read(_isequal,_testandlock)==NOERR) return TRUE; } while (bbox.run()!=K_ESC); return FALSE; } void TMov_mag::giac_putkey(TLocalisamfile & mag,TString16 annoes,TToken_string curr_key) { mag.zero(' '); mag.put("ANNOES",annoes); mag.put("CODMAG",key2field(curr_key,"CODMAG")); mag.put("CODART",key2field(curr_key,"CODART")); mag.put("LIVELLO",key2field(curr_key,"LIVGIAC")); } // aggiorna tutti i saldi in base alle modifiche fatte. // il lock su anagrafica dovrebbe garantire il lock su tutte le // giacenze dell'articolo int TMov_mag::update_balances() { bool updated_bal=TRUE; TLocalisamfile mag(LF_MAG); mag.setkey(2); TString_array keys_to_add,keys_to_remove; ((TMov_mag *)this)->lines_to_add.get_keys(keys_to_add); ((TMov_mag *)this)->lines_to_subtract.get_keys(keys_to_remove); // aggiunge i saldi nuovi keys_to_add.sort(); TToken_string * curr_key=(TToken_string *)keys_to_add.first_item(); while (curr_key) { curr_art.read((const char *)key2field(*curr_key,"CODART")); if (curr_art.lock_and_prompt()) { TLine_movmag & line_mov=(TLine_movmag &)lines_to_add[*curr_key]; curr_art.update_ultcosti(line_mov.prezzo,get_date("DATACOMP")); // lock gained giac_putkey(mag,get("ANNOES"),*curr_key); if (mag.read()!=NOERR) { // non trovato: aggiungo giac_putkey(mag,get("ANNOES"),*curr_key); mag.put("NRIGA",1+curr_art.mag(get("ANNOES")).rows()); mag.write(); } // modifica questo record (e lo sblocca) update_balances(mag.curr(),line_mov,get("CODCAUS"),+1); /*// ottimizzazione :(cerca di sfruttare la lettura fatta per un eventuale saldo vecchio) // ciò causa la modifica dell'oggetto TMov_mag (il metodo non è più const) if (_annoes == get("ANNOES") && lines_to_subtract.is_key(*curr_key)) { update_balances(mag.curr(),(TLine_movmag &)lines_to_subtract[*curr_key],_codcaus,-1); ((TMov_mag *)this)->lines_to_add.remove(*curr_key); ((TMov_mag *)this)->lines_to_subtract.remove(*curr_key); }*/ mag.rewrite(); // conclude la TRANSAZIONE prima di sbloccare il record dell'articolo TToken_string *rem_key=(TToken_string *)keys_to_remove.first_item(); while ( rem_key) { if (key2field(*rem_key,"CODART")==key2field(*curr_key,"CODART")) { giac_putkey(mag,_annoes,*rem_key); if (mag.read()==NOERR) { update_balances(mag.curr(),(TLine_movmag &)lines_to_subtract[*rem_key],_codcaus,-1); mag.rewrite(); } keys_to_remove.remove_item(); } rem_key=(TToken_string *)keys_to_remove.succ_item(); } curr_art.unlock(); } else { updated_bal=FALSE; } curr_key=(TToken_string *)keys_to_add.succ_item(); } // togli i saldi vecchi curr_key=(TToken_string *)keys_to_remove.first_item(); while (curr_key) { curr_art.read((const char *)key2field(*curr_key,"CODART")); if (curr_art.lock_and_prompt()) { giac_putkey(mag,_annoes,*curr_key); // modifica questo record (e lo sblocca) if (mag.read()==NOERR) { update_balances(mag.curr(),(TLine_movmag &)lines_to_subtract[*curr_key],_codcaus,-1); mag.rewrite(); } curr_art.unlock(); } else { updated_bal=FALSE; } curr_key=(TToken_string *)keys_to_remove.succ_item(); } if (!updated_bal) { // saldi non aggiornati warning_box("I saldi di magazzino non sono stati del tutto aggiornati. \nProcedere ad una operazione di ''Ricostruzione saldi''"); } return updated_bal; } // aggiorna i saldi del record corrente // in base alla causale e alla modifica fatta (con segno + o -) int TMov_mag::update_balances(TRectype & magrec, const TLine_movmag &l,TString16 codcaus,int rett_sign) { TCausale_magazzino caus(codcaus); TLocalisamfile umart(LF_UMART); real diff,diff_val; umart.setkey(2); umart.put(UMART_CODART,magrec.get(MAG_CODART)); umart.put(UMART_UM , l.um); umart.read(); real fc=umart.get_real("FC"); diff=fc*rett_sign*l.quant; diff_val=rett_sign*l.quant*l.prezzo; update_balance(magrec,"GIAC",diff*caus.sgn(s_giac)); // update .. update_balance(magrec,"ACQ",diff*caus.sgn(s_acq)); // update .. update_balance(magrec,"VALACQ",diff_val*caus.sgn(s_acq)); // update .. update_balance(magrec,"ENT",diff*caus.sgn(s_ent)); update_balance(magrec,"VALENT",diff_val*caus.sgn(s_ent)); update_balance(magrec,"VEN",diff*caus.sgn(s_ven)); update_balance(magrec,"VALVEN",diff_val*caus.sgn(s_ven)); update_balance(magrec,"USC",diff*caus.sgn(s_usc)); update_balance(magrec,"VALUSC",diff_val*caus.sgn(s_usc)); update_balance(magrec,"ORDC",diff*caus.sgn(s_ordc)); update_balance(magrec,"VALORDC",diff_val*caus.sgn(s_ordc)); update_balance(magrec,"ORDF",diff*caus.sgn(s_ordf)); update_balance(magrec,"VALORDF",diff_val*caus.sgn(s_ordf)); update_balance(magrec,"RIM",diff*caus.sgn(s_rim)); update_balance(magrec,"VALRIM",diff_val*caus.sgn(s_rim)); update_balance(magrec,"SCARTI",diff*caus.sgn(s_scart)); update_balance(magrec,"VALSCARTI",diff_val*caus.sgn(s_scart)); update_balance(magrec,"INCL",diff*caus.sgn(s_incl)); update_balance(magrec,"ACL",diff*caus.sgn(s_acl)); update_balance(magrec,"PRODCOMP",diff*caus.sgn(s_prodc)); update_balance(magrec,"PRODFIN",diff*caus.sgn(s_prodf)); update_balance(magrec,"NLABEL",diff*caus.sgn(s_label)); return 0; } void TMov_mag::update_balance(TRectype & magrec, const char * fieldname, real diff) const { magrec.put(fieldname,magrec.get_int(fieldname)+diff); } HIDDEN TEsercizi_contabili _esercizi; int TMov_mag::codice_esercizio(TDate &d) { return _esercizi.date2esc(d); } //********************** bool rebuild_balances(TString16 annoes, bool reset_giac) { TArray used_files; used_files.add(new TLocalisamfile(LF_RMOVMAG),LF_RMOVMAG); used_files.add(new TLocalisamfile(LF_MOVMAG),LF_MOVMAG); used_files.add(new TTable("%CAU"),5); TMov_mag * m_m= new TMov_mag; // record del movimento di magazzino // relazione con un solo file (LF_MOVMAG) ma col record Head_Body TRelation rel(LF_MOVMAG); rel.lfile().set_curr(m_m); int ok=TRUE; TLocalisamfile mag(LF_MAG); if (reset_giac) { // azzera tutte giacenze (ciclo sulle giacenze) mag.put("ANNOES",annoes); mag.read(_isgteq); while (!mag.eof() && annoes==mag.get("ANNOES")) { TString currcode(mag.get("CODART")); TArticolo articolo(currcode); if (articolo.lock_and_prompt()) { while (!mag.eof() && currcode==mag.get("CODART")) { mag.put("ACQ",0);mag.put("VALACQ",0); mag.put("ENT",0);mag.put("VALENT",0); mag.put("VEN",0);mag.put("VALVEN",0); mag.put("USC",0);mag.put("VALUSC",0); mag.put("ORDF",0);mag.put("VALORDF",0); mag.put("ORDC",0);mag.put("VALORDC",0); mag.put("SCARTI",0);mag.put("VALSCARTI",0); mag.put("GIAC",0); mag.put("PRODCOMP",0); mag.put("PRODFIN",0); mag.put("INCL",0); mag.put("ACL",0); mag.put("NLABEL",0); mag.rewrite(); mag.next(); } articolo.unlock(); } else { ok=FALSE; mag.next(); } } } // ricostruisce i saldi (ciclo sui movimenti) TString filterexpr; filterexpr << LF_MOVMAG << "->ANNOES==" << annoes; TCursor cur(&rel,filterexpr); // cursore filtrato for (int i=0; i