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