Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione 3.1 patch 766 git-svn-id: svn://10.65.10.50/trunk@14628 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			775 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			775 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| // oggetto TCausale_magazzino
 | ||
| // oggetto TMov_Mag , multirecord del movimento di magazzino
 | ||
| //  funzione di ricostruzione saldi
 | ||
| 
 | ||
| #include <diction.h> 
 | ||
| #include <progind.h> 
 | ||
| 
 | ||
| #include "mglib.h" 
 | ||
| #include "movmag.h"
 | ||
| #include "rmovmag.h"
 | ||
| #include <cfven.h>
 | ||
| 
 | ||
| #ifndef __CGLIB01_H
 | ||
| #include "../cg/cglib01.h"
 | ||
| #endif
 | ||
| #ifndef __DBLIB_H
 | ||
| #include "../db/dblib.h"
 | ||
| #endif
 | ||
| 
 | ||
| 
 | ||
| // *********************
 | ||
| // movimenti di magazzino
 | ||
| 
 | ||
| // movimenti
 | ||
| // dati della linea di movimento di magazzino
 | ||
| class TLine_movmag : public TObject
 | ||
| {
 | ||
|   TString8 _codcaus;
 | ||
|   TString4 _um;
 | ||
|   real _quant, _prezzo;
 | ||
| 
 | ||
| public: 
 | ||
|   const TString& codcaus() const { return _codcaus; }
 | ||
|   const TString& um() const  { return _um; }
 | ||
|   const real& quant() const  { return _quant; }
 | ||
|   const real& prezzo() const { return _prezzo; }
 | ||
|   void set(const TString& cau, const TString& um, const real& q, const real& p);
 | ||
|   int operator==(const TLine_movmag&) const;
 | ||
|   
 | ||
|   virtual TObject* dup() const { return new TLine_movmag(*this); }
 | ||
|   
 | ||
|   TLine_movmag() {}; 
 | ||
|   TLine_movmag(const TLine_movmag &); 
 | ||
|   virtual ~TLine_movmag() {}; 
 | ||
| };
 | ||
| 
 | ||
| void TLine_movmag ::set(const TString& cau,const TString& um,const real& q, const real& p)
 | ||
| {
 | ||
|   _codcaus=cau;
 | ||
|   _um=um;
 | ||
|   _quant=q;
 | ||
|   _prezzo=p;
 | ||
| }
 | ||
| 
 | ||
| TLine_movmag ::TLine_movmag(const TLine_movmag &l)
 | ||
| {
 | ||
|   set(l._codcaus, l._um, l._quant, l._prezzo);
 | ||
| }
 | ||
| 
 | ||
| int TLine_movmag::operator==(const TLine_movmag &l) const
 | ||
| {
 | ||
|   return (_codcaus==l._codcaus)&&(_um==l._um)&&(_quant==l._quant)&&(_prezzo==l._prezzo);
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| // ********************************
 | ||
| // TMov_mag  
 | ||
| 
 | ||
| TCausale_magazzino *TMov_mag::_causmag = NULL;
 | ||
| 
 | ||
| TMov_mag::TMov_mag() : 
 | ||
|   TMultiple_rectype(LF_MOVMAG),
 | ||
|   lines_to_add(), lines_to_subtract()
 | ||
| {   
 | ||
|   add_file(LF_RMOVMAG,"NRIG");
 | ||
| }
 | ||
| 
 | ||
| TMov_mag::~TMov_mag() 
 | ||
| {   
 | ||
| }
 | ||
| 
 | ||
| const TCausale_magazzino& TMov_mag::causale(const char* cod) const
 | ||
| {
 | ||
|   if (cod == NULL || *cod == '\0')
 | ||
|     cod = get(MOVMAG_CODCAUS);
 | ||
|   if (!_causmag)
 | ||
|     _causmag = new TCausale_magazzino(cod);
 | ||
|   else
 | ||
|     *_causmag = cache().get("%CAU",cod);
 | ||
|   return *_causmag;
 | ||
| }
 | ||
| 
 | ||
| void TMov_mag::zero(char c)
 | ||
| {
 | ||
|   TMultiple_rectype::zero(c);
 | ||
|   lines_to_add.destroy();   
 | ||
|   lines_to_subtract.destroy();
 | ||
| }
 | ||
| 
 | ||
| // valuta il valore della chiave per un nuovo record
 | ||
| bool TMov_mag::renum()
 | ||
| {
 | ||
|   put(MOVMAG_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(RMOVMAG_NUMREG,get(MOVMAG_NUMREG));
 | ||
| } 
 | ||
| 
 | ||
| void TMov_mag::load_rows_file(int logicnum)
 | ||
| {
 | ||
|   CHECK(logicnum==LF_RMOVMAG,"L'unico file collegabile ai movimenti sono le righe"); 
 | ||
|   TMultiple_rectype::load_rows_file(logicnum);
 | ||
|   mark_current_lines();
 | ||
| }
 | ||
| 
 | ||
| int TMov_mag::remove(TBaseisamfile& f) const 
 | ||
| {
 | ||
|   const int res = TMultiple_rectype::remove(f);
 | ||
|   if (res == NOERR) 
 | ||
|   {
 | ||
|     // effettua la variazione dei saldi
 | ||
|     ((TMov_mag *)this)->update_balances();  
 | ||
|   }
 | ||
|   return res;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| void TMov_mag::add_extrarows() const
 | ||
| {
 | ||
|   add_autorows();
 | ||
|   add_explrows();
 | ||
| //  if (add_explrows())
 | ||
| //    add_autorows();
 | ||
| }
 | ||
| 
 | ||
| bool  TMov_mag::add_autorows() const
 | ||
| {
 | ||
|   bool added=FALSE;
 | ||
|   TString8 codmag;
 | ||
|   
 | ||
|   // aggiunge le righe automatiche
 | ||
|   for (int r = rows(); r > 0; r--) 
 | ||
|   {        
 | ||
|     TRecord_array & b = body();             
 | ||
|     TRectype & row = b[r];
 | ||
|     TString8 codcaus(row.get(RMOVMAG_CODCAUS));
 | ||
|     if (codcaus.empty())
 | ||
|       codcaus=get(MOVMAG_CODCAUS);
 | ||
|     const TCausale_magazzino& cau = causale(codcaus);
 | ||
|     codcaus=cau.caus_collegata();
 | ||
|     if (codcaus.not_empty())
 | ||
|     {
 | ||
|       const TCausale_magazzino& cau_coll = causale(codcaus);
 | ||
|       if (!row.get_bool(RMOVMAG_ESPLOSA))
 | ||
|       {
 | ||
|         // 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);
 | ||
|           
 | ||
|           codmag = codmag_rauto(r);
 | ||
|           if (codmag.empty())
 | ||
|             codmag = cau_coll.default_magdep();
 | ||
|           if (codmag.not_empty())
 | ||
|             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);
 | ||
|           added=TRUE;
 | ||
|         }
 | ||
|       }
 | ||
|     }
 | ||
|   } // ciclo righe
 | ||
|   return added;
 | ||
| }
 | ||
| 
 | ||
| bool TMov_mag::add_explrows() const
 | ||
| {
 | ||
|   TDistinta_tree  distinta;
 | ||
|   TArticolo       articolo;
 | ||
|   TArray boom;
 | ||
|   bool added=FALSE;
 | ||
| 
 | ||
|   TRecord_array& b = body();             
 | ||
|   // aggiunge le righe da explosione distinta
 | ||
|   for (int r = rows(); r > 0; r--) 
 | ||
|   {        
 | ||
|     const TRectype& row = b[r];
 | ||
|     TString8 codcaus(row.get(RMOVMAG_CODCAUS));
 | ||
|     if (codcaus.empty())
 | ||
|       codcaus=get(MOVMAG_CODCAUS);
 | ||
|     const TCausale_magazzino& cau = causale(codcaus);
 | ||
|     if (cau.esplodente() && !row.get_bool(RMOVMAG_ESPLOSA))
 | ||
|     {
 | ||
|       const TCodice_articolo codart = row.get(RMOVMAG_CODART);
 | ||
|       const char tipo_costo = cau.get("S11")[0];
 | ||
|       const int livello = cau.get_int("I0");
 | ||
|       const TString4 umroot(row.get(RMOVMAG_UM));
 | ||
|       const int rigaprec = r - 1;
 | ||
|       const bool is_coll = r > 0 && b[r].get_char(RMOVMAG_TIPORIGA) == riga_automatica;
 | ||
|       // mancano le righe, le inserisco
 | ||
|       boom.destroy();
 | ||
|       bool ok=distinta.set_root(row);
 | ||
|       if (ok)
 | ||
|       { 
 | ||
|         bool stop_prod = cau.get_bool("B4");
 | ||
|         
 | ||
|         distinta.explode(boom, TRUE, RAGGR_EXP_NONE, livello, "A", 0, stop_prod);
 | ||
|         //TString codmag(codmag_rauto(r));
 | ||
|         real prezzo(prezzo_rauto(r));
 | ||
|         TRectype * linea_auto;
 | ||
|         for (int newrow=0; newrow < boom.items() ; newrow++)
 | ||
|         {       
 | ||
|           TRiga_esplosione & riga_esp=(TRiga_esplosione & )(boom[newrow]);
 | ||
|           linea_auto = new TRectype(row);
 | ||
|           linea_auto->put(RMOVMAG_CODART, riga_esp.articolo());
 | ||
|           linea_auto->put(RMOVMAG_LIVGIAC, riga_esp.giacenza());
 | ||
|           linea_auto->put(RMOVMAG_UM, riga_esp.um());
 | ||
|           linea_auto->put(RMOVMAG_QUANT, riga_esp.val());
 | ||
|           //if (codmag.not_empty())
 | ||
|           //  linea_auto->put(RMOVMAG_CODMAG, codmag);
 | ||
|           //if (!prezzo.is_zero())
 | ||
|           articolo.read(riga_esp.articolo());
 | ||
|           if (tipo_costo == 'U')
 | ||
|             prezzo = articolo.get_real(ANAMAG_ULTCOS1);
 | ||
|           else
 | ||
|             if (tipo_costo == 'S')
 | ||
|               prezzo = articolo.get_real(ANAMAG_COSTSTD);
 | ||
|           linea_auto->put(RMOVMAG_PREZZO, prezzo);
 | ||
|           linea_auto->put(RMOVMAG_NRIG, r+1+newrow);
 | ||
|           linea_auto->put(RMOVMAG_ESPLOSA, TRUE);
 | ||
| 
 | ||
|           char coll_type = articolo.get_char(ANAMAG_COLLTYPE);
 | ||
|           TString8 codmag;
 | ||
|             
 | ||
|           if (coll_type == 'M')
 | ||
|           {
 | ||
|             if (is_coll)
 | ||
|               codmag = b[rigaprec].get(RMOVMAG_CODMAG);
 | ||
|           }
 | ||
|           else
 | ||
|             if (coll_type == 'F')
 | ||
|             {                         
 | ||
|               TString16 key("F|");                                
 | ||
|               key << articolo.get(ANAMAG_CODFORN);
 | ||
|               codmag = cache().get(LF_CFVEN, key, CFV_CODMAG);
 | ||
|             }
 | ||
|             else
 | ||
|               if (coll_type == 'A')
 | ||
|                 codmag = articolo.get(ANAMAG_CODMAG);
 | ||
|           if (codmag.not_empty())
 | ||
|             linea_auto->put(RMOVMAG_CODMAG, codmag);
 | ||
|           b.insert_row(linea_auto);
 | ||
|           added=TRUE;
 | ||
|         }
 | ||
|         // ora ci sono, mi basta eliminare la riga "padre"
 | ||
|         if (boom.items() > 0 )
 | ||
|         {
 | ||
|           if (boom.items() == 1 && codart == ((TRiga_esplosione &)boom[0]).articolo())
 | ||
|             error_box(FR("Movimento di magazzino %ld:\ndistinta %s ciclica"), get_long(MOVMAG_NUMREG),(const char *)codart);
 | ||
|           b.destroy_row(r,TRUE);
 | ||
|         }
 | ||
|         else
 | ||
|           message_box(FR("Movimento di magazzino %ld:\nimpossibile esplodere l'articolo %s"), get_long(MOVMAG_NUMREG),(const char *)codart);
 | ||
|       }
 | ||
|     }
 | ||
|   } // ciclo righe
 | ||
|   return added;
 | ||
| }
 | ||
| 
 | ||
| int TMov_mag::write(TBaseisamfile& f) const 
 | ||
| {
 | ||
|   int res;
 | ||
|   add_extrarows();
 | ||
|   if ((res=TMultiple_rectype::write(f))==NOERR ) 
 | ||
|   {
 | ||
|     TMov_mag &myself=((TMov_mag &)*this);
 | ||
|   
 | ||
|     const int nrows = rows();
 | ||
|     
 | ||
|     for (int i = 1; i <= nrows; i++)
 | ||
|       myself.line_inserted(line2key(i), line2data(i));    
 | ||
|       // effettua la variazione dei saldi
 | ||
|     myself.update_balances();  
 | ||
|   }
 | ||
|   return res;
 | ||
| }
 | ||
| 
 | ||
| int TMov_mag::rewrite(TBaseisamfile& f) const 
 | ||
| {
 | ||
|   int res;
 | ||
|   add_extrarows();
 | ||
|   if ((res=TMultiple_rectype::rewrite(f))==NOERR ) 
 | ||
|   {
 | ||
|     TMov_mag &myself=((TMov_mag &)*this);
 | ||
|     
 | ||
|     const int nrows = rows();
 | ||
|   
 | ||
|     for (int i = 1; i <= nrows; i++)
 | ||
|       myself.line_inserted(line2key(i), line2data(i));    
 | ||
|       // effettua la variazione dei saldi
 | ||
|     myself.update_balances();  
 | ||
|   }
 | ||
|   return res;
 | ||
| }
 | ||
| 
 | ||
| const char* TMov_mag::get_next_key()  
 | ||
| {
 | ||
|   TLocalisamfile f(LF_MOVMAG);
 | ||
|   f.last();
 | ||
|   long a = f.get_long(MOVMAG_NUMREG)+1;
 | ||
|   TString& nextcod = get_tmp_string();
 | ||
|   nextcod.format("%ld", a);
 | ||
|   return nextcod;
 | ||
| }
 | ||
| 
 | ||
| bool TMov_mag::key_complete()
 | ||
| {
 | ||
|   const bool ok = head().get_long(MOVMAG_NUMREG) > 0L;
 | ||
|   return ok;
 | ||
| }
 | ||
| 
 | ||
| //*******
 | ||
| // gestione delle variazione dei saldi
 | ||
| //
 | ||
| //
 | ||
| int TMov_mag::force_update_bal()
 | ||
| {
 | ||
|   // reset delle strutture per il controlli delle variazioni dei saldi
 | ||
|   mark_current_lines(FALSE);
 | ||
|   return update_balances();  
 | ||
| }
 | ||
| 
 | ||
| // restituisce il valore dei dati
 | ||
| TLine_movmag& TMov_mag::line2data(int nrig) const
 | ||
| {
 | ||
|   static TLine_movmag line; 
 | ||
|   const TRectype& r = body().row(nrig);
 | ||
|   const TString& c = r.get(RMOVMAG_CODCAUS).blank() ? get(MOVMAG_CODCAUS) : r.get(RMOVMAG_CODCAUS);
 | ||
|   const TString& u = r.get(RMOVMAG_UM);
 | ||
|   const real q = r.get_real(RMOVMAG_QUANT);
 | ||
|   const real p = r.get_real(RMOVMAG_PREZZO);
 | ||
| 
 | ||
|   line.set(c, u, q, p);
 | ||
|   return line;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| TToken_string & TMov_mag::line2key(int numriga) const
 | ||
| {
 | ||
|   const TRectype& r = body().row(numriga);
 | ||
|   TToken_string& key = get_tmp_string();
 | ||
|   key = r.get(RMOVMAG_CODART);
 | ||
|   key.add(r.get(RMOVMAG_CODMAG));
 | ||
|   key.add(r.get(RMOVMAG_LIVGIAC));
 | ||
|   key.add(numriga);
 | ||
|   return key;
 | ||
| }
 | ||
| 
 | ||
| TString TMov_mag::key2field(TToken_string &key,const char *fieldname) 
 | ||
| {
 | ||
|   if (strcmp(fieldname,RMOVMAG_CODART)==0)
 | ||
|     return key.get(0);
 | ||
|   if (strcmp(fieldname,RMOVMAG_CODMAG)==0)
 | ||
|     return key.get(1);
 | ||
|   if (strcmp(fieldname,RMOVMAG_LIVGIAC)==0)
 | ||
|     return key.get(2);
 | ||
|   CHECKS(FALSE, "Nome di campo non appartenente al file righe mov ", fieldname);
 | ||
|   return EMPTY_STRING;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| int TMov_mag::line_inserted(TToken_string &k, TLine_movmag &r)
 | ||
| {
 | ||
|   if (_annoes != get(MOVMAG_ANNOES) || _datacomp != get_date(MOVMAG_DATACOMP))
 | ||
|     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 (_annoes != get(MOVMAG_ANNOES) || _datacomp != get_date(MOVMAG_DATACOMP))
 | ||
|     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;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| void TMov_mag::mark_current_lines(const bool as_deleted)
 | ||
| {
 | ||
|   const int nrows = rows(); // lasciare la riga qui perch<63> comporta il caricamento del body
 | ||
|   _annoes  =get(MOVMAG_ANNOES);
 | ||
|   _datacomp=get_date(MOVMAG_DATACOMP);
 | ||
|   lines_to_add.destroy();   
 | ||
|   lines_to_subtract.destroy();
 | ||
|   for (int i = 1; i<= nrows; i++)
 | ||
|   {
 | ||
|     if (as_deleted)
 | ||
|       line_deleted(line2key(i), line2data(i));    
 | ||
|     else
 | ||
|       line_inserted(line2key(i), line2data(i));    
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| bool TMov_mag::unlock_anamag(const char *codart) 
 | ||
| {
 | ||
|   TLocalisamfile anamag(LF_ANAMAG);
 | ||
|   
 | ||
|   anamag.put(ANAMAG_CODART,codart);
 | ||
|   return (anamag.read(_isequal,_unlock)==NOERR);
 | ||
| }
 | ||
| 
 | ||
| bool TMov_mag::lock_anamag(const char *codart) 
 | ||
| {
 | ||
|   TLocalisamfile anamag(LF_ANAMAG);
 | ||
|   anamag.put(ANAMAG_CODART,codart);
 | ||
|   
 | ||
|   KEY key = K_ENTER;
 | ||
|   while (key != K_ESC)
 | ||
|   {
 | ||
|     if (anamag.read(_isequal,_testandlock)==NOERR) 
 | ||
|       return TRUE;
 | ||
| 
 | ||
|     TString mess;
 | ||
|     mess << TR("Il record di anagrafica dell'articolo '")<< codart << TR("' risulta essere gi<67> in uso.");
 | ||
|     TTimed_breakbox bbox((const char *)mess,10);
 | ||
| 
 | ||
|     key = bbox.run();  
 | ||
|   }
 | ||
|   return FALSE;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| void TMov_mag::giac_putkey(TLocalisamfile & mag,const TString& annoes,TToken_string curr_key) 
 | ||
| {
 | ||
|   mag.zero(' ');    
 | ||
|   mag.put(MAG_ANNOES,annoes);
 | ||
|   mag.put(MAG_CODMAG,key2field(curr_key,RMOVMAG_CODMAG));
 | ||
|   mag.put(MAG_CODART,key2field(curr_key,RMOVMAG_CODART));
 | ||
|   mag.put(MAG_LIVELLO,key2field(curr_key,RMOVMAG_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;
 | ||
| 
 | ||
|   lines_to_add.get_keys(keys_to_add);
 | ||
|   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();
 | ||
|   int nriga=1;
 | ||
|   while (curr_key)        
 | ||
|   { 
 | ||
|     const TCodice_articolo cod = key2field(*curr_key, RMOVMAG_CODART);
 | ||
|     
 | ||
|     if (curr_art.lock_and_prompt(cod))
 | ||
|     {
 | ||
|       // lock gained
 | ||
|       TLine_movmag & line_mov=(TLine_movmag &)lines_to_add[*curr_key];
 | ||
|       const TCausale_magazzino& causmag = causale(line_mov.codcaus());
 | ||
|       
 | ||
|       if (causmag.update_ultcos())
 | ||
|       {              
 | ||
|         const real prezzo = curr_art.convert_to_um(line_mov.prezzo(), line_mov.um(), NULL, false);
 | ||
|         curr_art.update_ultcosti(prezzo,get_date("DATACOMP"), get_long("NUMREG"),nriga++);
 | ||
|         curr_art.rewrite();
 | ||
|       }
 | ||
|       giac_putkey(mag, get(MOVMAG_ANNOES), *curr_key);
 | ||
|       if (mag.read()!=NOERR)
 | ||
|       {
 | ||
|         // non trovato: aggiungo
 | ||
|         giac_putkey(mag, get(MOVMAG_ANNOES), *curr_key);
 | ||
|         mag.put(MAG_NRIGA,1+curr_art.mag(get(MOVMAG_ANNOES)).rows());
 | ||
|         mag.write();
 | ||
|       } 
 | ||
|       // modifica questo record (e lo sblocca)
 | ||
|       update_balances(mag.curr(), line_mov, +1);
 | ||
|       /*// ottimizzazione :(cerca di sfruttare la lettura fatta per un eventuale saldo vecchio)
 | ||
|       // ci<63> causa la modifica dell'oggetto TMov_mag (il metodo non <20> pi<70> const)
 | ||
|       if (_annoes == get("ANNOES") 
 | ||
|           && lines_to_subtract.is_key(*curr_key)) {
 | ||
|         update_balances(mag.curr(),(TLine_movmag &)lines_to_subtract[*curr_key],-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,RMOVMAG_CODART)==key2field(*curr_key,RMOVMAG_CODART)) {
 | ||
|           giac_putkey(mag,_annoes,*rem_key);
 | ||
|           if (mag.read()==NOERR)
 | ||
|           {
 | ||
|             update_balances(mag.curr(),(TLine_movmag &)lines_to_subtract[*rem_key],-1);
 | ||
|             mag.rewrite();
 | ||
|           } 
 | ||
|           keys_to_remove.remove_item();
 | ||
|         }       
 | ||
|         rem_key=(TToken_string *)keys_to_remove.succ_item();
 | ||
|       } 
 | ||
|       curr_art.unlock();
 | ||
|     }
 | ||
|     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 (curr_art.lock_and_prompt((const char *)key2field(*curr_key,RMOVMAG_CODART)))
 | ||
|     {
 | ||
|       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],-1);
 | ||
|         mag.rewrite();
 | ||
|       } 
 | ||
|       curr_art.unlock();
 | ||
|     }
 | ||
|     curr_key=(TToken_string *)keys_to_remove.succ_item();
 | ||
|   }
 | ||
|   mark_current_lines();
 | ||
| 
 | ||
|   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,int rett_sign) 
 | ||
| {
 | ||
|   TLocalisamfile umart(LF_UMART);              
 | ||
|   umart.setkey(2);
 | ||
|   umart.put(UMART_CODART,magrec.get(MAG_CODART));
 | ||
|   umart.put(UMART_UM , l.um());
 | ||
|   const int err = umart.read();
 | ||
|   
 | ||
|   const real fc = err == NOERR ? umart.get_real(UMART_FC) : UNO;
 | ||
|   const real qt = l.quant();
 | ||
|   real diff = real(rett_sign) * qt * fc; 
 | ||
|   
 | ||
|   if (err == NOERR && fc != UNO)
 | ||
|   {
 | ||
|     umart.setkey(1);
 | ||
|     umart.put(UMART_CODART,magrec.get(MAG_CODART));
 | ||
|     umart.put(UMART_NRIGA, 1);
 | ||
|     if (umart.read() == NOERR)
 | ||
|       TArticolo::round_um(diff, umart.get(UMART_UM));
 | ||
|   }
 | ||
| 
 | ||
|   real diff_val = real(rett_sign) * qt * l.prezzo();
 | ||
|   
 | ||
|   // Se <20> una causale che movimenta il valore ma la qta <20> 0
 | ||
|   // anche diff_val avr<76> lo stesso valore, impostando 0 di conseguenza
 | ||
|   // anche nei campi relativi a VALACQ, VALRIM etc etc.
 | ||
|   // Quindi al limite come controllo finale su movimenti che movimentano la qta
 | ||
|   // nel caso il calcolo dia proprio ZERO, impostiamo diff_val all'importo del valore stesso
 | ||
|   const TCausale_magazzino& caus = causale(l.codcaus());
 | ||
|   if (qt.is_zero() && caus.update_val())
 | ||
|     diff_val = real(rett_sign) * l.prezzo();
 | ||
|   
 | ||
|   if (caus.update_qta())
 | ||
|   {
 | ||
|     update_balance(magrec,"GIAC",diff* (real)caus.sgn(s_giac)); // update ..
 | ||
|     update_balance(magrec,"ACQ",diff* (real)caus.sgn(s_acq)); // update ..
 | ||
|     update_balance(magrec,"ENT",diff* (real)caus.sgn(s_ent));
 | ||
|     update_balance(magrec,"VEN",diff* (real)caus.sgn(s_ven));
 | ||
|     update_balance(magrec,"USC",diff* (real)caus.sgn(s_usc));
 | ||
|     update_balance(magrec,"ORDC",diff* (real)caus.sgn(s_ordc));
 | ||
|     update_balance(magrec,"ORDF",diff* (real)caus.sgn(s_ordf));
 | ||
|     update_balance(magrec,"RIM",diff* (real)caus.sgn(s_rim));
 | ||
|     update_balance(magrec,"SCARTI",diff* (real)caus.sgn(s_scart));
 | ||
|     update_balance(magrec,"INCL",diff* (real)caus.sgn(s_incl));
 | ||
|     update_balance(magrec,"ACL",diff* (real)caus.sgn(s_acl));
 | ||
|     update_balance(magrec,"PRODCOMP",diff* (real)caus.sgn(s_prodc));
 | ||
|     update_balance(magrec,"PRODFIN",diff* (real)caus.sgn(s_prodf));
 | ||
|     update_balance(magrec,"NLABEL",diff* (real)caus.sgn(s_label));
 | ||
|     update_balance(magrec,"USER1",diff* (real)caus.sgn(s_user1));
 | ||
|     update_balance(magrec,"USER2",diff* (real)caus.sgn(s_user2));
 | ||
|     update_balance(magrec,"USER3",diff* (real)caus.sgn(s_user3));
 | ||
|     update_balance(magrec,"USER4",diff* (real)caus.sgn(s_user4));
 | ||
|     update_balance(magrec,"USER5",diff* (real)caus.sgn(s_user5));
 | ||
|     update_balance(magrec,"USER6",diff* (real)caus.sgn(s_user6));
 | ||
|   }
 | ||
|   if (caus.update_val())
 | ||
|   {
 | ||
|     update_balance(magrec,"VALACQ",diff_val* (real)caus.sgn(s_acq)); // update ..
 | ||
|     update_balance(magrec,"VALENT",diff_val* (real)caus.sgn(s_ent));
 | ||
|     update_balance(magrec,"VALVEN",diff_val* (real)caus.sgn(s_ven));
 | ||
|     update_balance(magrec,"VALUSC",diff_val* (real)caus.sgn(s_usc));
 | ||
|     update_balance(magrec,"VALORDC",diff_val* (real)caus.sgn(s_ordc));
 | ||
|     update_balance(magrec,"VALORDF",diff_val* (real)caus.sgn(s_ordf));
 | ||
|     update_balance(magrec,"VALRIM",diff_val* (real)caus.sgn(s_rim));
 | ||
|     update_balance(magrec,"VALSCARTI",diff_val* (real)caus.sgn(s_scart));
 | ||
|     update_balance(magrec,"USERVAL1",diff* (real)caus.sgn(s_user1));
 | ||
|     update_balance(magrec,"USERVAL2",diff* (real)caus.sgn(s_user2));
 | ||
|     update_balance(magrec,"USERVAL3",diff* (real)caus.sgn(s_user3));
 | ||
|     update_balance(magrec,"USERVAL4",diff* (real)caus.sgn(s_user4));
 | ||
|     update_balance(magrec,"USERVAL5",diff* (real)caus.sgn(s_user5));
 | ||
|     update_balance(magrec,"USERVAL6",diff* (real)caus.sgn(s_user6));
 | ||
|   }
 | ||
|   return 0;
 | ||
| }
 | ||
| 
 | ||
| int TMov_mag::update_balances(TRectype& magrec, int numrig, int rett_sign) 
 | ||
| {
 | ||
|   const TLine_movmag& lmm = line2data(numrig);
 | ||
|   return update_balances(magrec, lmm, rett_sign);
 | ||
| }
 | ||
| 
 | ||
| HIDDEN TEsercizi_contabili _esercizi;
 | ||
| 
 | ||
| int TMov_mag::codice_esercizio(const TDate &d)
 | ||
| {
 | ||
|   return _esercizi.date2esc(d);
 | ||
| }
 | ||
| 
 | ||
| void TMov_mag::update_balance(TRectype & magrec, const char * fieldname, real diff) const
 | ||
| {
 | ||
|   magrec.put(fieldname,magrec.get_real(fieldname)+diff);
 | ||
| }
 | ||
| 
 | ||
| void zero_balances(TRectype & mag)
 | ||
| {
 | ||
|   mag.put(MAG_GIAC,0);
 | ||
|   mag.put(MAG_RIM,0);mag.put(MAG_VALRIM,0);
 | ||
|   mag.put(MAG_ACQ,0);mag.put(MAG_VALACQ,0);
 | ||
|   mag.put(MAG_ENT,0);mag.put(MAG_VALENT,0);
 | ||
|   mag.put(MAG_VEN,0);mag.put(MAG_VALVEN,0);
 | ||
|   mag.put(MAG_USC,0);mag.put(MAG_VALUSC,0);
 | ||
|   mag.put(MAG_ORDF,0);mag.put(MAG_VALORDF,0);
 | ||
|   mag.put(MAG_ORDC,0);mag.put(MAG_VALORDC,0);
 | ||
|   mag.put(MAG_SCARTI,0);mag.put(MAG_VALSCARTI,0);
 | ||
|   mag.put(MAG_PRODCOMP,0);
 | ||
|   mag.put(MAG_PRODFIN,0);
 | ||
|   mag.put(MAG_INCL,0);
 | ||
|   mag.put(MAG_ACL,0);
 | ||
|   mag.put(MAG_NLABEL,0);
 | ||
| }
 | ||
| 
 | ||
| void copy_oldbalances(const TRectype& oldmag,TRectype & mag)
 | ||
| {
 | ||
|   mag.put(MAG_GIAC,oldmag.get(MAG_GIAC));
 | ||
|   mag.put(MAG_RIM,oldmag.get(MAG_RIM));
 | ||
|   mag.put(MAG_VALRIM,oldmag.get(MAG_VALRIM));
 | ||
|   mag.put(MAG_ACQ,0);
 | ||
|   mag.put(MAG_VALACQ,0);
 | ||
|   mag.put(MAG_ENT,0);
 | ||
|   mag.put(MAG_VALENT,0);
 | ||
|   mag.put(MAG_VEN,0);
 | ||
|   mag.put(MAG_VALVEN,0);
 | ||
|   mag.put(MAG_USC,0);
 | ||
|   mag.put(MAG_VALUSC,0);
 | ||
|   mag.put(MAG_ORDF,oldmag.get(MAG_ORDF));
 | ||
|   mag.put(MAG_VALORDF,oldmag.get(MAG_VALORDF));
 | ||
|   mag.put(MAG_ORDC,oldmag.get(MAG_ORDC));
 | ||
|   mag.put(MAG_VALORDC,oldmag.get(MAG_VALORDC));
 | ||
|   mag.put(MAG_SCARTI,0);
 | ||
|   mag.put(MAG_VALSCARTI,0);
 | ||
|   mag.put(MAG_PRODCOMP,oldmag.get(MAG_PRODCOMP));
 | ||
|   mag.put(MAG_PRODFIN,oldmag.get(MAG_PRODFIN));
 | ||
|   mag.put(MAG_INCL,oldmag.get(MAG_INCL));
 | ||
|   mag.put(MAG_ACL,oldmag.get(MAG_ACL));
 | ||
|   mag.put(MAG_NLABEL,0);
 | ||
| }
 | ||
| 
 | ||
| //**********************
 | ||
| bool rebuild_balances(const TString& annoes,
 | ||
|   const TTipo_valorizz tipo_valorizz, const char* catven, const char* codlis)
 | ||
| {
 | ||
|   bool ok=TRUE;
 | ||
|   // Aggiorna il cazzillo per caricare eventuali date di chiusura e altre amenita' simili
 | ||
|   TEsercizi_contabili esercizi;
 | ||
|   esercizi.update(); // Non fidiamoci troppo
 | ||
| 
 | ||
|   const int cod_pred_es = esercizi.pred(atoi(annoes));
 | ||
|   TString4 pred_es;  pred_es.format("%d",cod_pred_es);
 | ||
|   const bool reset_giac = cod_pred_es != 0 ? esercizi.esercizio(cod_pred_es).chiusura_mag().ok() : TRUE;
 | ||
| 
 | ||
|   TString information;
 | ||
|   // azzera tutte giacenze (ciclo sulle giacenze)
 | ||
|   TRelation rel2(LF_ANAMAG); // relazione con un solo file (LF_ANAMAG) ma col record Head_Body
 | ||
|   TCursor cur2(&rel2);
 | ||
|   const long maxart=cur2.objects();
 | ||
|   
 | ||
|   if (maxart > 0)
 | ||
|   {
 | ||
|     TArticolo_giacenza * a_g= new TArticolo_giacenza; // record dell'articolo di magazzino
 | ||
|     rel2.lfile().set_curr(a_g);
 | ||
|     TArticolo_giacenza& articolo=*a_g;
 | ||
| 
 | ||
|     information.format(FR("Ricostruzione saldi esercizio %s: azzeramento..."),(const char *)annoes);
 | ||
|     TProgind barra_art(maxart,information, false, true);
 | ||
|     cur2.freeze();
 | ||
|     for (long a=0; a<maxart; a++) 
 | ||
|     {
 | ||
|       barra_art.addstatus(1);
 | ||
|       cur2=a;
 | ||
|       if (articolo.lock_and_prompt(articolo.codice()))
 | ||
|       {
 | ||
|         if (reset_giac)
 | ||
|           articolo.azzera_saldi(annoes);
 | ||
|         else
 | ||
|           articolo.riporta_saldi(pred_es, annoes, tipo_valorizz, catven, codlis);
 | ||
|         articolo.unlock();
 | ||
|       }
 | ||
|     } 
 | ||
|   }
 | ||
|   
 | ||
|   // ricostruisce i saldi (ciclo sui movimenti)
 | ||
|   TRelation rel(LF_MOVMAG); // relazione con un solo file (LF_MOVMAG) ma col record Head_Body
 | ||
|   TString filterexpr;
 | ||
|   filterexpr << LF_MOVMAG << "->ANNOES==" << annoes;  
 | ||
|   TCursor cur(&rel,filterexpr); // cursore filtrato
 | ||
|   const long maxmov=cur.objects();
 | ||
|   if (maxmov > 0)
 | ||
|   {
 | ||
|     TMov_mag * m_m= new TMov_mag; // record del movimento di magazzino
 | ||
|     rel.lfile().set_curr(m_m);
 | ||
|     TMov_mag & mov_rec=*m_m;
 | ||
| 
 | ||
|     information.format(FR("Ricostruzione saldi esercizio %s: ricalcolo ..."),(const char *)annoes);
 | ||
|     TProgind barra_mov(maxmov,information, false, true);
 | ||
|     cur.freeze();
 | ||
|     for (long m=0; m<maxmov; m++) 
 | ||
|     {
 | ||
|       cur=m;
 | ||
|       barra_mov.addstatus(1);
 | ||
|       if (!mov_rec.force_update_bal())
 | ||
|         ok = false;
 | ||
|     }
 | ||
|   }  
 | ||
|   return ok;
 | ||
| }
 |