#include #include #include #include #include #include #include "mglib01.h" #include "..\cg\cglib.h" // ************************************** // ************************************** // ************************************** // *** classi per la libreria // *** //***** // THead_lines_record // metodi protected void THead_lines_record::renum_key(const char * kfield,const char * val) { TRectype::renum_key(kfield, val); // Aggiorna testata _rows->renum_key(kfield, val); // Aggiorna righe } TRectype & THead_lines_record::row(int index) const // riga del corpo { if (index > _rows->rows() || index < 0) CHECKD(FALSE, "Riga non esistente ", index); return _rows->row(index, FALSE); } void THead_lines_record::put_str(const char* fieldname, const char* val) { TString v(val); // cambio //if (strcmp(fieldname, "TIPODOC") == 0 && TRectype::get("TIPODOC") != v) //{ // TAuto_variable_rectype::put_str(fieldname, v); // reset_fields(*this); // set_fields(*this); //} //else { TAuto_variable_rectype::put_str(fieldname, v); dirty_fields(); } } //***** // metodi public THead_lines_record::THead_lines_record(int hfn, int rfn,const char *numfield): TAuto_variable_rectype(hfn), _file(hfn), _rfile(rfn), _numfield(numfield) { _rows= new TRecord_array(rfn,numfield); // inizializza il record array delle righe } THead_lines_record::THead_lines_record(const TBaseisamfile* i,int rfn,const char *numfield): TAuto_variable_rectype(i), _numfield(numfield) { _rows= new TRecord_array(rfn,numfield); // inizializza il record array delle righe } THead_lines_record::THead_lines_record(const TRectype & r,int rfn,const char *numfield): TAuto_variable_rectype(r), _numfield(numfield) { _rows= new TRecord_array(rfn,numfield); // inizializza il record array delle righe } // @doc INTERNAL // @mfunc costruttore di copia THead_lines_record::THead_lines_record(const THead_lines_record& r): TAuto_variable_rectype((TAuto_variable_rectype &)r) { // copia.. _rows= new TRecord_array(* r._rows); // inizializza il record array delle righe _nuovo=r._nuovo; _file=r._file; // file principale _rfile=r._rfile; // file delle righe _numfield=r._numfield; } THead_lines_record::~THead_lines_record() { delete _rows; } // setta a dirty i campi void THead_lines_record::dirty_fields() { } TRectype & THead_lines_record::operator =(const TRectype & r) { TRectype::operator=(r); reset_fields(*this); set_fields(*this); return *this; } TRectype & THead_lines_record::operator =(const char * r) { TRectype::operator=(r); reset_fields(*this); set_fields(*this); return *this; } void THead_lines_record::zero(const char * fieldname) { // resetta il record righe solo se ..... // if (strcmp(fieldname, "TIPODOC") == 0) reset_fields(*this); TAuto_variable_rectype::zero(fieldname); dirty_fields(); } void THead_lines_record::zero(char c) { reset_fields(*this); TAuto_variable_rectype::zero(c); } // settaggio campi variabili void THead_lines_record::set_fields(TAuto_variable_rectype & rec) { } int THead_lines_record::read(TBaseisamfile& f, word op, word lockop) { TRectype line_key(_rfile); copy_linekey(head(),line_key); int err = TRectype::read(f,op,lockop); if (err == NOERR) { _nuovo = FALSE; _rows->read(line_key); //ok } else { // nuovo oggetto: resetta tutto _nuovo = TRUE; destroy_rows(); _rows->set_key((TRectype *)(line_key.dup())); // ok } return err; } /*int THead_lines_record::read(const TRectype& rec) { head() = rec; TRectype line_key(_rows->key()); copy_linekey(head(),line_key); TLocalisamfile afile(_file); int err = TRectype::read(afile); if (err == NOERR) { _nuovo = FALSE; _rows->read(line_key); //ok } else { // nuovo oggetto: resetta tutto _nuovo = TRUE; head() = rec; destroy_rows(); _rows->set_key(&line_key); // ok } return err; } */ int THead_lines_record::write(TBaseisamfile& f) const { return write_rewrite(f,FALSE); } int THead_lines_record::rewrite(TBaseisamfile& f) const { return write_rewrite(f,TRUE); } int THead_lines_record::write_rewrite(TBaseisamfile& f,bool re ) const { const bool nuovo = _nuovo; // E' nuovo di zecca! if (nuovo && re) // quindi ... re = FALSE; // ... non fare la rewrite int err = NOERR; if (re) { // rewrite: err = _rows->write(re); if (err == NOERR) { err = TRectype::rewrite(f); if (err != NOERR) err = TRectype::write(f); } } else { // write: if (nuovo) { //THead_lines_record &myself=*this; //if (numero() <= 0) // myself.renum(); do { err = TRectype::write(f); if (err == _isreinsert) // usa il flag _nuovo per decidere se ((THead_lines_record *)this)->renum(); } while (err == _isreinsert); ((THead_lines_record *)this)->_nuovo = FALSE; } else { err = TRectype::write(f); if (err != NOERR) err = TRectype::rewrite(f); } if (err == NOERR) err = _rows->write(re); } return err; } int THead_lines_record::remove(TBaseisamfile& f) const { int err = _rows->remove(); if (err == NOERR) err = TRectype::remove(f); return err; } // @doc INTERNAL // @mfunc costruttore di copia TTimed_box::TTimed_box(const char * header,const char * message,int seconds,short button_id,int x,int y) : TMask(header,1,x,y) { // costruisce una maschera run time add_memo(FIRST_FIELD, 0, "", 1, 0,-1,-3); set(FIRST_FIELD, message); // setta il timer per l'evento _timer_delay=seconds *1000+1; _timer_id=XVT_TIMER_ERROR; _button_id=button_id; } void TTimed_box::start_run() { if (_timer_id!=XVT_TIMER_ERROR) xvt_timer_destroy(_timer_id); _timer_id=xvt_timer_create(win(),_timer_delay); TMask::start_run(); } void TTimed_box::handler(WINDOW win, EVENT* ep) { if (ep->type == E_TIMER && ep->v.timer.id==_timer_id) { send_key(K_SPACE,DLG_OK); } TMask::handler(win, ep); } class TTimed_breakbox: public TTimed_box { public: TTimed_breakbox(const char * message,int seconds,int x=40,int y=10); }; TTimed_breakbox::TTimed_breakbox(const char * message,int seconds,int x,int y) : TTimed_box("Richiesta di interruzione",message,seconds,DLG_OK,x,y) { add_button(DLG_CANCEL, 0, "Interrompi", -22, -1, 12, 2,"",0); add_button(DLG_OK, 0, "Riprova", -12, -1, 12, 2,"",0); } // ********************************** // ********************************** // ********************************** // ********************************** // fine classi per la libreria // ************************** // classe livelli giacenze TMag_livelli:: TMag_livelli(const char *tabname) { TTable _tabformato(tabname); int e; _last_level=0; e=_tabformato.first(); for (int i=0; i< MANY_MAG_LEV; i++) { _enabled[i]=(e==NOERR); if (_enabled[i]) { _name[i]=_tabformato.get("S0"); _code_lenght[i]=atoi(_tabformato.get("I0")); _picture[i]=_tabformato.get("S1"); _last_level=i+1; } else { _name[i]=""; _code_lenght[i]=0; _picture[i]=""; } e=_tabformato.next(); } } const bool TMag_livelli::enabled(int levnum) { if (levnum<=MANY_MAG_LEV && levnum>0) return(_enabled[levnum-1]); else return(FALSE) ; } const int TMag_livelli::code_lenght(int levnum) { if (levnum<=MANY_MAG_LEV && levnum>0) return(_code_lenght[levnum-1]); else return(0) ; } const TString & TMag_livelli::name(int levnum) { if (levnum<=MANY_MAG_LEV && levnum>0) return(_name[levnum-1]); else return(""); } const TString & TMag_livelli::picture(int levnum) { if (levnum<=MANY_MAG_LEV && levnum>0) return(_picture[levnum-1]); else return(""); } void TMag_livelli::pack_grpcode(TString & pc, const TString &codlev, const int levnum) { int start=0; for (int i=1; i=pc.len()) return(""); else { if (levnum != _last_level && !_enabled[levnum-1]) return(""); return(pc.mid(start,levnum == _last_level ? -1 : _code_lenght[levnum-1])); } } // ******************************* // ******************************* // ******************************* TStateset::TStateset() { empty(); } TStateset & TStateset::empty() { _current=0; for (int i= 0; i< MAXSTATES; _container[i++]=0); return *this; } TStateset & TStateset::enclose(int el) { if (el< MAXSTATES && el>=0) _container[el]=1; return *this; } TStateset & TStateset::singleton(int el) { empty(); _container[el]=1; return *this; } TStateset & TStateset::cap(TStateset & s) { for (int i= 0; i< MAXSTATES; i++) _container[i]|=s._container[i]; return *this; } bool TStateset::is_empty() const { for (int i= 0; i< MAXSTATES; i++) { if (_container[i]) return FALSE; } return TRUE; } bool TStateset::is_member(int e) const { return ((e< MAXSTATES && e>=0)? _container[e] : FALSE ); } int TStateset::get_first() { _current=-1; return(get_next()); } int TStateset::get_next() { while (_current+1 < MAXSTATES) { if (_container[++_current]) return _current; } return (-1); } // ******************************* // ******************************* // automa per il riconoscimento di metacaratteri #define EPSILON 0 #define FIRST_STATE 1 #define FIRST_NEMPTY_SYMBOL 1 // labels and states bool TR_automa::is_state(int statenum) { return(statenum<=_maxstate && statenum>0); } // restituisce il numero dello stato con quella etichetta int TR_automa::label2state(const char *label) { for (int s=0; s<_maxstate;s++) { if (*(st[s]._label)==label) return(s+1); } return(0); } // resetta uno stato dell'automa (senza eliminarlo) TR_automa & TR_automa::reset_state(int statenum) { int _from,_to; if (statenum>0 && statenum<=_maxstate) { _from=statenum; _to=statenum; } else { _maxstate=0; _isdeterministic=TRUE; _from=1; _to=MAXSTATES; } { for (int i=_from; i<=_to;i++) { set_label(i,""); set_final(i,FALSE); for (int j=0; j0); return retv; } TR_automa & TR_automa::set_final(int statenum,bool v) { st[statenum-1]._final=v; return *this; } //******************* // bows void TR_automa::add_tran(int statenum, unsigned char symbol,int next) { st[statenum-1]._transaction[symbol]=next; if (symbol==EPSILON) _isdeterministic=FALSE; } void TR_automa::del_trans(int statenum, unsigned char symbol) { st[statenum-1]._transaction[symbol]=0; } int TR_automa::trans_to(int statenum, unsigned char symbol) { return (st[statenum-1]._transaction[symbol]); } // costruttore che crea un automa non deterministico // (transazioni Epsilon ma nessuna transazione multipla) // eventualmente duplica un automa (e lo rende deterministico) TR_automa::TR_automa(TR_automa * aa,bool makedet) { TStateset arrival; TStateset newstateset; TString16 tmplabel; int curr_new_state; for (int i=0; iunion_of_closures(newstateset.singleton(FIRST_STATE)),tmplabel); add_state(tmplabel); curr_new_state=FIRST_STATE; while (is_state(curr_new_state)) { // determina l'insieme degli stati dell'automa non deterministico // che corrispondono a questo stato dell'automa deterministico label2set(label(curr_new_state),newstateset); // lo stato è finale se include stati finali dell'automa non det. set_final(curr_new_state,aa->is_final(newstateset)); // determina tutte le transazioni for (short symbol=FIRST_NEMPTY_SYMBOL; symboltrans_to(old_state,symbol)) arrival.enclose(old_next); } while ((old_state=newstateset.get_next())>0); if (!arrival.is_empty()) { // crea il nuovo arco nell'automa deterministico set2label(aa->union_of_closures(arrival),tmplabel); if (!(new_next=label2state(tmplabel))) { new_next=add_state(tmplabel); } add_tran(curr_new_state,symbol,new_next); } } curr_new_state++; } _isdeterministic=TRUE; } // fine conversione else { *this=*aa; for (int i=0; ist[i]._label; } } } TR_automa::~TR_automa() { for (int i=0; i0); } while (toadd) ; u_of_clo.cap(clo); } while ((_state=start_set.get_next())>0); return u_of_clo; } // tenta di riconoscere la stringa passata bool TR_automa::recognized(const char * t_str) { if (_isdeterministic) { // ricoNosce la stringa di token int curr_state=FIRST_STATE; for (int i=0; t_str[i]; i++) { if (!(curr_state=trans_to(curr_state,t_str[i]))) // fine per mancanza di trasizioni return FALSE; } // fine per mancanza di caratteri di input della stringa return (is_final(curr_state)); } else { // return FALSE; } } // ******************************* // gestione di stringhe di metacaratteri // ******************************* #define C_ESCAPEMETA '\\' #define S_BLANK 1 #define S_DIGIT 2 #define S_LETTER 3 #define S_ANY 4 bool TMetachar::recognized(const char * s) { return(_au->recognized(s)); } void TMetachar::add_tran(int s,unsigned char metasymbol, int nextstate) { unsigned char c; switch (metasymbol) { case EPSILON:// blank _au->add_tran(s,EPSILON,nextstate); break; case S_BLANK:// blank _au->add_tran(s,' ',nextstate); break; case S_DIGIT:// cifra for (c='0';c<='9';c++) _au->add_tran(s,c,nextstate); break; case S_LETTER: // lettera for (c='a';c<='z';c++) _au->add_tran(s,c,nextstate); for (c='A';c<='Z';c++) _au->add_tran(s,c,nextstate); break; case S_ANY: // qualsiasi carattere for (c=MAXSIMBOLS-1;c>=FIRST_NEMPTY_SYMBOL;c--) _au->add_tran(s,c,nextstate); break; default: _au->add_tran(s,metasymbol,nextstate); break; } } // restituisce la stringa di metacaratteri del linguaggio riconosciuto const char * TMetachar::language() const { return(_language); } void TMetachar::set_language(const char * language) { int s; bool escaped_char=FALSE; TString16 label("-"),nextlabel("-"); // crea gli insiemi di metacaratteri standard strcpy(_metach_mand,"0LA&"); strcpy(_metach_opz,"#9?ac"); _language=language; // crea l'automa _au->reset_state(); for (int i=0; language[i]; i++) { label[0]='a'+i; nextlabel[0]='a'+i+1; if (language[i]!=C_ESCAPEMETA) { if (!escaped_char) { // meta-caratteri e literal fuori set s=_au->add_state(label); switch (language[i]) { case '#':// cifra o blank opzionale add_tran(s,S_BLANK,s+1); add_tran(s,'-',s+1); add_tran(s,'+',s+1); case '9':// cifra opzionale add_tran(s,EPSILON,s+1); case '0':// cifra obbligatoria add_tran(s,S_DIGIT,s+1); break; case '?': // lettera opzionale add_tran(s,EPSILON,s+1); case 'L': // lettera obbligatoria add_tran(s,S_LETTER,s+1); break; case 'a': // lettera o numero opzionale add_tran(s,EPSILON,s+1); case 'A': // lettera o numero obbligatorio add_tran(s,S_LETTER,s+1); add_tran(s,S_DIGIT,s+1); break; case 'c': // qualsiasi carattere opzionale add_tran(s,EPSILON,s+1); case '&': // qualsiasi carattere obbligatorio add_tran(s,S_ANY,s+1); break; default: _au->add_tran(s,language[i],s+1); break; } } else { // escaped char s=_au->add_state(label); _au->add_tran(s,language[i],s+1); } } escaped_char=(language[i]==C_ESCAPEMETA); } // end of loop // aggiunge lo stato finale s=_au->add_state(nextlabel); _au->set_final(s); } // ricerca caratteri del set opzionale bool TMetachar::has_opzchars(const char * pattern) { int i=0; bool next_literal=FALSE; while (pattern[i]) { if (!next_literal && strchr(_metach_opz,pattern[i])) return(TRUE); next_literal=(!next_literal && pattern[i]==C_ESCAPEMETA); i++; } return(FALSE); } // ricerca caratteri del set opzionale bool TMetachar::has_mandchars(const char * pattern) { int i=0; bool next_literal=FALSE; while (pattern[i]) { if (next_literal || strchr(_metach_mand,pattern[i])) return(TRUE); next_literal=(!next_literal && pattern[i]==C_ESCAPEMETA); i++; } return(FALSE); } // stabilisce la lunghezza della stringa di metacaratteri int TMetachar::maxstrlen(const char * pattern) const { int i=0,l=0; bool next_literal=FALSE; while (pattern[i]) { if (!next_literal) l++; next_literal=(!next_literal && pattern[i]==C_ESCAPEMETA); i++; } return(l); } // costruttore e distruttore TMetachar::TMetachar () { _au = new TR_automa; set_language(""); } TMetachar::TMetachar (const char * metastr) { // crea l'automa e lo trasforma in deterministico // TR_automa auxau; // set_language(&auxau,metastr); _au=new TR_automa; set_language(metastr); if (!_au->is_deterministic()) { TR_automa * auxau = new TR_automa(_au,TRUE); delete _au; _au=auxau; } } TMetachar::~TMetachar () { delete _au; } // ************************************** // ************************************** // ************************************** // *** classi per il magazzino // *** long giac_last_item(const char * annoes, const char *codart) { long r=0; TLocalisamfile mag(LF_MAG); mag.put("ANNOES",annoes); mag.put("CODART",codart); mag.put("NRIGA",1); if (mag.read()==NOERR) { do { r=mag.get_long("NRIGA"); } while (mag.next()==NOERR && mag.get("CODART")==codart); } return r; } // ********************* // 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_TAB) { TTable f("CAU"); f.put("CODTAB",codice); if (f.read() != NOERR) zero(); else *this=(TCausale_magazzino &)f.curr(); } // 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() : THead_lines_record(LF_MOVMAG,LF_RMOVMAG,"NRIG"), lines_to_add(), lines_to_subtract() { } TMov_mag::~TMov_mag() { } //void TMov_mag::dirty_fields() //{ //} // rinumerazione automatica: numdoc>=0 // (con creazione nuova chiave) long TMov_mag::renum(long numdoc) { if (numdoc <= 0) numdoc = atoi(get_next_key()); char num[16]; sprintf(num, "%ld", numdoc); renum_key("NUMREG", num); // Aggiorna testata return numdoc; } // copia la chiave dal file principale a quello delle righe void TMov_mag::copy_linekey(const TRectype & headrec, TRectype & linesrec) { // ...qui basta una put tra Rectype.... linesrec.put("NUMREG",headrec.get("NUMREG")) ; } int TMov_mag::read(TBaseisamfile& f, word op , word lockop) { TToken_string l_key; TLine_movmag l_data; int res=THead_lines_record::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(); for (int i=0; iinsert_line(l_key,l_data); } if ((res=THead_lines_record::write(f))==NOERR ) // effettua la variazione dei saldi res=update_balances(); return res; } int TMov_mag::rewrite(TBaseisamfile& f) const { int res; TToken_string l_key; TLine_movmag l_data; // memorizza le variazioni for (int i=0; iinsert_line(l_key,l_data); } if ((res=THead_lines_record::rewrite(f))==NOERR ) // effettua la variazione dei saldi res=update_balances(); return res; } const char *TMov_mag::get_next_key() { TLocalisamfile f(LF_MOVMAG); f.last(); int a=atoi(f.get("NUMREG"))+1; return _nextcod.format("%d",a); } // settaggio campi variabili //void TMov_mag::set_fields(TAuto_variable_rectype & rec) //{ //} //******* // gestione delle variazione dei saldi // // TLine_movmag TMov_mag::line2data(int numriga) const { TLine_movmag rest; rest.um=row(numriga).get("UM"); rest.quant=(const char *)row(numriga).get("QUANT"); rest.prezzo=(const char *)row(numriga).get("PREZZO"); return rest; } TToken_string TMov_mag::line2key(int numriga) const { TToken_string key; key.add(row(numriga).get("CODART")); key.add(row(numriga).get("CODMAG")); key.add(row(numriga).get("LIVGIAC")); 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::insert_line(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::delete_line(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_putkey2(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() const { 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) { if (lock_anamag(key2field(*curr_key,"CODART"))) { // lock gained giac_putkey2(mag,get("ANNOES"),*curr_key); if (mag.read()!=NOERR) { // non trovato: aggiungo giac_putkey2(mag,get("ANNOES"),*curr_key); mag.put("NRIGA",giac_last_item(get("ANNOES"),key2field(*curr_key,"CODART"))+1); mag.write(); } // modifica questo record (e lo sblocca) update_balances(mag.curr(),(TLine_movmag &)lines_to_add[*curr_key],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_putkey2(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(); } unlock_anamag(key2field(*curr_key,"CODART")); } 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) { if (lock_anamag(key2field(*curr_key,"CODART"))) { giac_putkey2(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(); } unlock_anamag(key2field(*curr_key,"CODART")); } 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 0; } // 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) const { TCausale_magazzino caus(codcaus); TLocalisamfile anamag(LF_ANAMAG); TLocalisamfile umart(LF_UMART); real diff,diff_val; umart.put("CODART",magrec.get("CODART")); umart.put("UM",l.um); umart.read(); real fc=umart.get_real("FC"); diff=fc*rett_sign*l.quant; diff_val=diff*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); }