Files correlati : Ricompilazione Demo : [ ] Commento : aggiunti metodi jolly per ricavare le numerazioni dati i tipi documento git-svn-id: svn://10.65.10.50/branches/R_10_00@20745 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			336 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			336 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include "velib.h"
 | |
| 
 | |
| /////////////////////////////////////////////////////////////
 | |
| // TCodice_numerazione
 | |
| /////////////////////////////////////////////////////////////
 | |
| 
 | |
| TCodice_numerazione::TCodice_numerazione(const char* codnum)
 | |
|                    : TRectype(LF_TABCOM)
 | |
| {
 | |
|   settab("NUM");
 | |
|   if (codnum && *codnum)
 | |
|     read(codnum);
 | |
|   else
 | |
|     setempty(TRUE);  
 | |
| }
 | |
| 
 | |
| TCodice_numerazione::TCodice_numerazione(const TRectype& rec)
 | |
|                : TRectype(rec)
 | |
| { }
 | |
| 
 | |
| TCodice_numerazione::~TCodice_numerazione()
 | |
| { }
 | |
| 
 | |
| const TString& TCodice_numerazione::tipo_doc(int i) const
 | |
| {
 | |
|   CHECK(i < 36, "Impossibbile tipo documento"); 
 | |
|   const char * field = i < 17 ? "S2" : "S3";
 | |
|   
 | |
|   if (i >= 17)
 | |
|     i -= 17;
 | |
| 	TString & tmp = get_tmp_string();
 | |
| 	tmp = get(field).mid(i * 4, 4);
 | |
| 	tmp.trim();
 | |
|   return tmp;
 | |
| }                                             
 | |
| 
 | |
| int TCodice_numerazione::ntipi_doc() const
 | |
| {
 | |
|   int l = get("S3").len(); 
 | |
|   if (l > 0)
 | |
|     return ((l - 1) / 4) + 18;
 | |
|   l = get("S2").len();
 | |
|   return l ? (((l - 1) / 4) + 1) : 0;
 | |
| }
 | |
| 
 | |
| void TCodice_numerazione::complete_num(long num, TString& codnum) const
 | |
| {
 | |
|   codnum = prefisso();
 | |
|   codnum << num;
 | |
|   codnum << postfisso();
 | |
| }
 | |
| 
 | |
| int TCodice_numerazione::read(const char* codnum)
 | |
| {                                   
 | |
|   *this = cache().get("%NUM", codnum);
 | |
|   int err = empty() ? _iskeynotfound : NOERR; 
 | |
| #ifdef DBG  
 | |
|   if (err != NOERR)
 | |
|     NFCHECK("Codice numerazione errato: %s", codnum);
 | |
| #endif    
 | |
|   return err;  
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| //  trova le numerazioni documenti in base ai tipi richiesti (ca3800,ca3900,ps1001)
 | |
| //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| int numerazioni_documenti(TString_array& num_doc, TString_array& tip_doc, const int tipo)
 | |
| {
 | |
|   //cominciamo con i tipi
 | |
|   TISAM_recordset tipi_recset("USE %TIP\nSELECT STR(I1=#TIPO)");
 | |
|   tipi_recset.set_var("#TIPO", TVariant(long(tipo)));
 | |
|   for (bool ok = tipi_recset.move_first(); ok; ok = tipi_recset.move_next())    //giro sui vari tipi ordine
 | |
|   {
 | |
|     const TString4 tipo = tipi_recset.get("CODTAB").as_string();
 | |
|     tip_doc.add(tipo);
 | |
|   }
 | |
| 
 | |
|   //e adesso cerca le numerazioni che contengono tipi ordine
 | |
|   TISAM_recordset num_recset("USE %NUM");
 | |
|   for (bool ok = num_recset.move_first(); ok; ok = num_recset.move_next())    //giro sui vari tipi numerazione
 | |
|   {
 | |
|     const TString4 codtab = num_recset.get("CODTAB").as_string();
 | |
| 
 | |
|     const TCodice_numerazione numerazione(codtab);
 | |
|     for (int t = numerazione.ntipi_doc() - 1; t >= 0; t--)
 | |
|     {
 | |
|       const TString& tipo_doc = numerazione.tipo_doc(t);
 | |
|       if (tip_doc.find(tipo_doc) >= 0)
 | |
|       {
 | |
|         if (num_doc.find(codtab) < 0) // Evito aggiunta di doppioni
 | |
|           num_doc.add(codtab);
 | |
|         break;
 | |
|       }
 | |
|     } //for (int t = codnum..
 | |
|   } //for (bool ok = num_recset...
 | |
| 
 | |
|   return num_doc.items();
 | |
| }
 | |
| 
 | |
| 
 | |
| int numerazioni_ordini(TString_array& num_ordini, TString_array& tip_ordini)
 | |
| {
 | |
|   //i documenti che vanno presi in cosiderazione sono quelli che generano un IMPEGNATO secondo le auree regole del..
 | |
|   //..nostro invincibile Adolf!
 | |
|   num_ordini.destroy();
 | |
|   tip_ordini.destroy();
 | |
|   
 | |
|   numerazioni_documenti(num_ordini, tip_ordini, 3);
 | |
| 
 | |
|   return num_ordini.items();
 | |
| }
 | |
| 
 | |
| int numerazioni_fatture(TString_array& num_fatture, TString_array& tip_fatture)
 | |
| {
 | |
|   //i documenti che vanno presi in cosiderazione sono quelli non ancora contabilizzati di tipo 0=Altro 2=Fattura
 | |
|   num_fatture.destroy();
 | |
|   tip_fatture.destroy();
 | |
|   
 | |
|   numerazioni_documenti(num_fatture, tip_fatture, 0);
 | |
|   numerazioni_documenti(num_fatture, tip_fatture, 2);
 | |
| 
 | |
|   return num_fatture.items();
 | |
| }
 | |
| 
 | |
| /////////////////////////////////////////////////////////////
 | |
| // TSpesa_prest
 | |
| /////////////////////////////////////////////////////////////
 | |
| 
 | |
| TSpesa_prest::TSpesa_prest(const char* codice, char tipo)
 | |
|        : TRectype(LF_TAB)
 | |
| { 
 | |
| 	switch (tipo)
 | |
| 	{
 | |
| 		case RIGA_SPESEDOC :
 | |
| 			settab("SPP");
 | |
| 			break;
 | |
| 		case RIGA_PRESTAZIONI :
 | |
| 			settab("PRS");
 | |
| 			break;
 | |
| 		case RIGA_RISORSE :
 | |
| 			settab("RSS");
 | |
| 			break;
 | |
| 		case RIGA_ATTREZZATURE :
 | |
| 			settab("ATR");
 | |
| 			break;
 | |
| 		default :
 | |
| 			settab("SPP");
 | |
| 			break;
 | |
| 	}
 | |
|   if (codice && *codice)
 | |
|   {
 | |
|     const int err = read(codice);
 | |
| #ifdef DBG
 | |
|     if (err != NOERR)
 | |
| 			switch (tipo)
 | |
| 			{
 | |
| 				case RIGA_SPESEDOC :
 | |
| 				  error_box("Spesa %s assente", codice);
 | |
| 					break;
 | |
| 				case RIGA_PRESTAZIONI :
 | |
| 					error_box("Prestazione %s assente", codice);
 | |
| 					break;
 | |
| 				case RIGA_RISORSE :
 | |
| 				  error_box("Risorsa %s assente", codice);
 | |
| 					break;
 | |
| 				case RIGA_ATTREZZATURE :
 | |
| 				  error_box("Attrezzatura %s assente", codice);
 | |
| 					break;
 | |
| 				default :
 | |
| 				  error_box("Spesa %s assente", codice);
 | |
| 					break;
 | |
| 			}
 | |
| #endif
 | |
| 
 | |
|   }
 | |
| }
 | |
| 
 | |
| TSpesa_prest::TSpesa_prest(const TRectype& rec)
 | |
|       : TRectype(rec)
 | |
| {
 | |
| }
 | |
| 
 | |
| char TSpesa_prest::genere() const
 | |
| { 
 | |
| 	const TString & tipo = get("COD"); 
 | |
| 	if (tipo == "SPP")
 | |
| 		return RIGA_SPESEDOC;
 | |
| 	else
 | |
| 		if (tipo == "PRS")
 | |
| 			return RIGA_PRESTAZIONI;
 | |
| 	else
 | |
| 		if (tipo == "RSS")
 | |
| 			return RIGA_RISORSE;
 | |
| 		else
 | |
| 			if (tipo == "ATR")
 | |
| 				return  RIGA_ATTREZZATURE;
 | |
| 	return ' ';
 | |
| }
 | |
| int TSpesa_prest::read(const char* codice)
 | |
| {                      
 | |
|   const TString8 cod = get("COD");
 | |
|   *this = cache().get(cod, codice);
 | |
|   return empty() ? _iskeynotfound : NOERR;
 | |
| }
 | |
| 
 | |
| const TString& TSpesa_prest::cod_iva() const 
 | |
| { 
 | |
|   // La parte seguente di s3 e' utilizzata dalle atrezzature per altri campi
 | |
|   TString& tmp = get_tmp_string();
 | |
|   tmp = get("S3").left(4);
 | |
|   tmp.trim();
 | |
|   return tmp;
 | |
| }
 | |
| 
 | |
| real TSpesa_prest::prezzo() const 
 | |
| { 
 | |
|   real r = get("R10");   // Prezzo con tanti decimali
 | |
|   if (r.is_zero())
 | |
|     r = get_real("R0");  // Prezzo con pochi decimali
 | |
|   return r;
 | |
| }
 | |
| 
 | |
| bool is_real_discount(const TString& exp)
 | |
| {
 | |
|   if (exp.blank())
 | |
|     return  false;
 | |
| 
 | |
| 	TString80 good;
 | |
| 	real perc;
 | |
| 
 | |
| 	return scontoexpr2perc(exp, false , good, perc) && perc != UNO;
 | |
| }
 | |
| 
 | |
| bool scontoexpr2perc(const char * exp, bool signal , TString & goodexp, real & val_perc )
 | |
| {
 | |
|   bool valid = true;
 | |
| 
 | |
|   goodexp.cut(0);  
 | |
|   // Elimina gli spazi molesti
 | |
| //  work.strip_spaces( );
 | |
|   val_perc = 1.0;
 | |
|   if (exp && *exp)
 | |
|   {
 | |
|     TString80 num;
 | |
|     bool dec = false;      // Flag che indica se si attende l'inizio di un numero
 | |
|     bool startnum = true;  // Flag che indica se siamo all'inizio di un numero   
 | |
|     int errorchar = ' ';
 | |
|     
 | |
|     // Flag che indica se sono nella parte decimale di un numero
 | |
|     for (const char * s  = exp; *s  && errorchar == ' '; s++)
 | |
|     { 
 | |
|       const char c = *s;
 | |
|       switch(c)
 | |
|       {
 | |
|       case '+': 
 | |
|       case '-':
 | |
|         // Se ero in in numero ...
 | |
|         if( !startnum )
 | |
|         {
 | |
|           // Aggiunge il numero alla sequenza
 | |
|           real newval( num );
 | |
|           val_perc *= ( CENTO - newval ) / CENTO;
 | |
|           goodexp << num;
 | |
|         }
 | |
|         // Inizia il nuovo numero
 | |
|         num = (c == '-') ? "-" : "+";  
 | |
|         startnum = true;
 | |
|         dec = false;
 | |
|         break;         
 | |
|       case '0':  
 | |
|       case '1':
 | |
|       case '2':
 | |
|       case '3':
 | |
|       case '4':
 | |
|       case '5':
 | |
|       case '6':
 | |
|       case '7':
 | |
|       case '8':
 | |
|       case '9':
 | |
|         num << c;
 | |
|         startnum = false;
 | |
|         break;
 | |
|       case '.':
 | |
|       case ',':
 | |
|         if(!dec)
 | |
|         {
 | |
|           if( startnum )
 | |
|             num << '0';        // Se occorreva un numero ci metto lo 0
 | |
|           num << '.';          // Interpreto la virgola come punto
 | |
|           dec = true;       
 | |
|           startnum = true;
 | |
|         }
 | |
|         else
 | |
|           errorchar = c;        // Se siamo gi` nella parte decimale segnala un errore
 | |
|         break;
 | |
|       case ' ':
 | |
|         break;
 | |
|       default:
 | |
|         errorchar = c;
 | |
|         break;         
 | |
|       }
 | |
|     }
 | |
|     // Controlla la validita`
 | |
|     valid = errorchar == ' ';
 | |
|     
 | |
|     if (valid)
 | |
|     {
 | |
|       // Aggiunge l'ultimo numero preso
 | |
|       real lastval( num ); 
 | |
|       val_perc *= ( CENTO - lastval ) / CENTO;
 | |
|       goodexp << num; // Assegna la nuova espressione formattata bene     
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       if (signal)          // Se richiesto segnala l'errore
 | |
|         warning_box( "Espressione di sconto non valida. Errore sul carattere %c.", errorchar);
 | |
|       val_perc = UNO;      // Azzera la sequenza di percentuali
 | |
|       goodexp = "";
 | |
|     }
 | |
|   }
 | |
|   return valid;
 | |
| }
 | |
| 
 | |
| real prezzo_scontato(const real& prezzo, const TString& sconto)
 | |
| {    
 | |
|   if (sconto.full())
 | |
|   {
 | |
|     TString80 exp;
 | |
|     real val_sconto;
 | |
|     if (scontoexpr2perc(sconto, false , exp, val_sconto) && val_sconto != UNO)
 | |
|       return prezzo * val_sconto;
 | |
|   }               
 | |
|   return prezzo;
 | |
| } 
 | |
| 
 |