Files correlati : ve0.exe Ricompilazione Demo : [ ] Commento : Migliorato aggiornamento formule di testa git-svn-id: svn://10.65.10.50/branches/R_10_00@22442 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			3150 lines
		
	
	
		
			88 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			3150 lines
		
	
	
		
			88 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <applicat.h>
 | ||
| #include <diction.h>
 | ||
| #include <dongle.h>
 | ||
| #include <modaut.h>
 | ||
| #include <tabutil.h>
 | ||
| #include <utility.h>
 | ||
| 
 | ||
| #include <doc.h>
 | ||
| #include "../cg/cg2103.h"
 | ||
| #include "../db/dblib.h"
 | ||
| #include "../pr/prlib.h"
 | ||
| #include "../sv/svlib01.h"
 | ||
| #include "../li/letint.h"
 | ||
| 
 | ||
| #include "veini.h"
 | ||
| #include "velib.h"
 | ||
| #include "sconti.h"
 | ||
| #include "vepriv.h"
 | ||
| #include "veuml.h"
 | ||
| 
 | ||
| 
 | ||
| #include <clifo.h>
 | ||
| #include <cfven.h>
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // TTipo_documento_cache
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| class TTipo_documento_cache : public TRecord_cache
 | ||
| {
 | ||
| protected:
 | ||
| 	virtual TObject* rec2obj(const TRectype& rec) const;
 | ||
| 
 | ||
| public:
 | ||
| 	TTipo_documento& tipo(const char* key);
 | ||
| 	TTipo_documento_cache();
 | ||
| 	virtual ~TTipo_documento_cache() { }
 | ||
| };
 | ||
| 
 | ||
| TTipo_documento_cache::TTipo_documento_cache()
 | ||
|                       : TRecord_cache("%TIP", 1)
 | ||
| { 
 | ||
|   test_file_changes();  // Tieni d'occhio le modifiche sul file
 | ||
|   set_items_limit(59);  // Standard
 | ||
| }        
 | ||
| 
 | ||
| TObject* TTipo_documento_cache::rec2obj(const TRectype& curr) const
 | ||
| {
 | ||
|   return new TTipo_documento(curr);
 | ||
| }
 | ||
| 
 | ||
| TTipo_documento & TTipo_documento_cache::tipo(const char* key)
 | ||
| {
 | ||
| 	TString8 k;
 | ||
| 	k << "TIP|" << key;
 | ||
|   TTipo_documento & tipo = (TTipo_documento &) query(k);
 | ||
|   return tipo;
 | ||
| }
 | ||
| 
 | ||
| const TTipo_documento & cached_tipodoc(const char * tipodoc)
 | ||
| {
 | ||
| 	HIDDEN TTipo_documento_cache __cache_tipi_documento;
 | ||
| 	return __cache_tipi_documento.tipo(tipodoc);
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // TTipo_numerazione_cache
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| class TNumerazione_cache : public TRecord_cache
 | ||
| {
 | ||
| protected:
 | ||
| 	virtual TObject* rec2obj(const TRectype& rec) const;
 | ||
| 
 | ||
| public:
 | ||
| 	TCodice_numerazione & num(const char* key);
 | ||
| 	TNumerazione_cache();
 | ||
| 	virtual ~TNumerazione_cache() { }
 | ||
| };
 | ||
| 
 | ||
| TNumerazione_cache::TNumerazione_cache()
 | ||
|                    : TRecord_cache("%NUM", 1)
 | ||
| { 
 | ||
|   test_file_changes();   // Tieni d'occhio le modifiche sul file
 | ||
|   set_items_limit(59);   // Standard
 | ||
| }        
 | ||
| 
 | ||
| TObject* TNumerazione_cache::rec2obj(const TRectype& curr) const
 | ||
| {
 | ||
|   return new TCodice_numerazione(curr);
 | ||
| }
 | ||
| 
 | ||
| TCodice_numerazione & TNumerazione_cache::num(const char* key)
 | ||
| {
 | ||
| 	TString8 k;
 | ||
| 	
 | ||
| 	k << "NUM|" << key;
 | ||
|   TCodice_numerazione & num = (TCodice_numerazione &) query(k);
 | ||
|   return num;
 | ||
| }
 | ||
| 
 | ||
| const TCodice_numerazione& cached_numerazione(const char * codnum)
 | ||
| {
 | ||
| 	HIDDEN TNumerazione_cache __cache_numerazioni;
 | ||
| 	return __cache_numerazioni.num(codnum);
 | ||
| }
 | ||
| 
 | ||
| // calcola il prezzo per le spese
 | ||
| void sppr_calc(const TRectype & rec, const TString & valuta_doc, const real & cambio, real & prezzo, exchange_type controeuro)
 | ||
| {     
 | ||
|   const TString4 sppr_valuta(rec.get("S4"));                        
 | ||
|         
 | ||
|   if (sppr_valuta != valuta_doc)
 | ||
|   {                                          
 | ||
|     const bool prezzo_un = rec.get_char("S6") == 'Q';
 | ||
|     if (prezzo_un)
 | ||
|     {
 | ||
|       TPrice val(prezzo, sppr_valuta);
 | ||
|     
 | ||
|       val.change_value(valuta_doc, cambio, controeuro);
 | ||
|       prezzo = val.get_num();
 | ||
|     }
 | ||
|     else
 | ||
|     {
 | ||
|       TCurrency val(prezzo, sppr_valuta);
 | ||
|     
 | ||
|       val.change_value(valuta_doc, cambio, controeuro);
 | ||
|       prezzo = val.get_num();
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // Movimento di magazzino
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| class TMov_mag_doc : public TMov_mag
 | ||
| {
 | ||
|   TString_array _codmagc;
 | ||
|   
 | ||
| protected:
 | ||
|   virtual const char* codmag_rauto(int r) const;
 | ||
| 
 | ||
| public:
 | ||
|   void add_magc(const char* magc) 
 | ||
|   { 
 | ||
|     CHECKS(magc && strlen(magc) <= 5, "Invalid CODMAG ", magc);
 | ||
|     _codmagc.add(magc); 
 | ||
|   }
 | ||
| 	void reset_magc(int r) { _codmagc.add("", r - 1); }
 | ||
| 	void destroy_magc(int r) { _codmagc.destroy(r - 1); }
 | ||
| };
 | ||
| 
 | ||
| const char* TMov_mag_doc::codmag_rauto(int r) const
 | ||
| {
 | ||
|   const char* codmagc = NULL;
 | ||
|   const int num_magc = _codmagc.items();
 | ||
|   if (num_magc > 0)  // Impossibile trovare un codmagc
 | ||
|   {
 | ||
|     const TRecord_array& b = body();
 | ||
|     if (r > 0 && r <= b.rows()) // Can't check non-existent rows
 | ||
|     {
 | ||
|       const char tr = b[r].get_char(RMOVMAG_TIPORIGA);
 | ||
|       if (tr == 'D' || tr == 'A') // These are customer's added rows
 | ||
|       {
 | ||
|         int j = -1; // Indice per reperire il mag. collegato da _codmagc
 | ||
|         for (int i = r; i > 0; i--) // Scorre dalla riga r in su e conta quante righe D
 | ||
|           if (b[i].get_char(RMOVMAG_TIPORIGA) == 'D')
 | ||
|             j++;  
 | ||
|         if (j >= 0 && j < num_magc)
 | ||
|           codmagc = _codmagc.row(j);
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
|   return codmagc;
 | ||
| }
 | ||
| 
 | ||
| /////////////////////////////////////////////////////////////
 | ||
| // TRiepilogo IVA
 | ||
| /////////////////////////////////////////////////////////////
 | ||
| TRiepilogo_iva& TRiepilogo_iva::copy(const TRiepilogo_iva& a)
 | ||
| { 
 | ||
|   _codiva = a.cod_iva();
 | ||
|   _imp = a._imp;
 | ||
|   _imp_orig = a._imp_orig;
 | ||
|   _imp_spese = a._imp_spese;
 | ||
|   _imp_spese_row = a._imp_spese_row;
 | ||
|   _iva = a._iva;
 | ||
|   _iva_spese = a._iva_spese;
 | ||
|   _sconto_perc = a._sconto_perc;
 | ||
|   _sconto_imp = a._sconto_imp;
 | ||
|   _iva_sconto = a._iva_sconto;
 | ||
|   _tipo = a._tipo;
 | ||
|   return *this;
 | ||
| }
 | ||
| 
 | ||
| TRiepilogo_iva::TRiepilogo_iva(const TCodiceIVA & codiva) : _codiva(codiva)
 | ||
| {
 | ||
|   const TString& t =_codiva.tipo();
 | ||
|   if (t == "VE")
 | ||
|     _tipo = 2; else
 | ||
|   if (t == "ES")
 | ||
|     _tipo = 4; else
 | ||
|   if (t == "NI")      
 | ||
|     _tipo = 8; else
 | ||
|   if (t == "NS")       
 | ||
|     _tipo = 16;
 | ||
|   else
 | ||
|     _tipo = 1;
 | ||
| }  
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // Agenti
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| class TAgenti_cache : public TRecord_cache
 | ||
| {                                                
 | ||
| protected:
 | ||
|   virtual TObject* rec2obj(const TRectype& rec) const { return new TAgente(rec);}
 | ||
|   
 | ||
| public:
 | ||
|   const TAgente& agente(const char* chiave) { return (const TAgente &) get(chiave);}
 | ||
| 
 | ||
|   TAgenti_cache() : TRecord_cache(LF_AGENTI) {}
 | ||
|   virtual ~TAgenti_cache() { }
 | ||
| };
 | ||
| 
 | ||
| HIDDEN TAgenti_cache * _agenti = NULL; 
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // Documento per vendite
 | ||
| ///////////////////////////////////////////////////////////
 | ||
|  
 | ||
| long TDocumento::_firm = -1;
 | ||
| TString4 TDocumento::_codiva_spese;
 | ||
| TString4 TDocumento::_codiva_bolli;
 | ||
| short TDocumento::_has_mag = 3;
 | ||
| short TDocumento::_has_stat_ven = 3;
 | ||
| short TDocumento::_has_provv = 3;
 | ||
| TCodgiac_livelli * TDocumento::_livelli=NULL;
 | ||
| 
 | ||
| // HIDDEN TStats_agg _st_agg;
 | ||
| HIDDEN TAssoc_array _docs_to_agg;
 | ||
| 
 | ||
| void TDocumento::init()
 | ||
| {
 | ||
|   add_file(LF_RIGHEDOC, RDOC_NRIGA);
 | ||
|   set_memo_fld("G1");
 | ||
| 
 | ||
|   _tipocf = new TRecfield(*this, DOC_TIPOCF);
 | ||
|   _codcf = new TRecfield(*this, DOC_CODCF);
 | ||
|   _cod_occas = new TRecfield(*this, DOC_OCFPI);
 | ||
|   
 | ||
| 
 | ||
|   _sconto = _esenzione = NULL;
 | ||
|   _stato_originale = ' ';
 | ||
|   _dirty_deny = false;
 | ||
|   
 | ||
|   check_modules();
 | ||
| }
 | ||
| 
 | ||
| TDocumento::TDocumento()
 | ||
|           : TMultiple_rectype(LF_DOC)
 | ||
| {                      
 | ||
|   init();
 | ||
| }
 | ||
| 
 | ||
| TDocumento::TDocumento(const TDocumento & d)
 | ||
|           : TMultiple_rectype(LF_DOC)
 | ||
| {                                                                             
 | ||
|   init();
 | ||
|   copy(d);
 | ||
| }
 | ||
| 
 | ||
| TDocumento::TDocumento(char provv, int anno, const char* codnum, long numdoc)
 | ||
|           : TMultiple_rectype(LF_DOC)
 | ||
| {
 | ||
|   init();
 | ||
|   if (numdoc <= 0)
 | ||
|   { 
 | ||
|     numdoc = 0;
 | ||
|     set_key(*this, provv, anno, codnum, numdoc);
 | ||
|   }
 | ||
|   else
 | ||
|     read(provv, anno, codnum, numdoc);
 | ||
| }
 | ||
| 
 | ||
| TDocumento::TDocumento(const TRectype& rec)
 | ||
|           : TMultiple_rectype(LF_DOC)
 | ||
| {
 | ||
|   init();
 | ||
|   read(rec);
 | ||
| }
 | ||
| 
 | ||
| TDocumento::~TDocumento()
 | ||
| {
 | ||
|   delete _tipocf;
 | ||
|   delete _codcf;
 | ||
|   delete _cod_occas;
 | ||
| 
 | ||
|   if (_sconto != NULL) delete _sconto;
 | ||
|   if (_esenzione != NULL) delete _esenzione;
 | ||
| }  
 | ||
| 
 | ||
| const TString& TDocumento::codiva_spese() const 
 | ||
| { ((TDocumento *)this)->test_firm(); return _codiva_spese;} 
 | ||
| 
 | ||
| const TString& TDocumento::codiva_bolli() const 
 | ||
| { ((TDocumento *)this)->test_firm(); return _codiva_bolli;} 
 | ||
| 
 | ||
| void TDocumento::check_modules()
 | ||
| { 
 | ||
|   if (_has_mag == 3)
 | ||
|   {               
 | ||
|     _has_mag = dongle().active(MGAUT);
 | ||
|     _has_stat_ven = dongle().active(SVAUT);
 | ||
|     _has_provv = dongle().active(PRAUT);
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| void TDocumento::set_variables(TExpression * e) const
 | ||
| { 
 | ||
|   CHECK(e, "Null expression");
 | ||
|   const int items = e->numvar();
 | ||
|   for  (int i = 0; i < items; i++)
 | ||
|   {                          
 | ||
|     const TFieldref field(e->varname(i), LF_DOC);
 | ||
| 
 | ||
|     switch (field.file())
 | ||
|     {
 | ||
|       case LF_CLIFO :
 | ||
|         e->setvar(i, clifor().get(field.name()));
 | ||
|         break;
 | ||
|       case LF_CFVEN :
 | ||
|         e->setvar(i, clifor().vendite().get(field.name()));
 | ||
|         break;
 | ||
|       default:
 | ||
|         e->setvar(i, get(field.name()));
 | ||
|         break;
 | ||
|     }   
 | ||
|   }
 | ||
| }  
 | ||
| 
 | ||
| void TDocumento::test_firm()
 | ||
| {                
 | ||
|   const long new_firm = prefix().get_codditta();
 | ||
|   
 | ||
|   if (_firm != new_firm)
 | ||
|   {
 | ||
|     TConfig conf(CONFIG_DITTA, "ve");        
 | ||
|     _codiva_spese = conf.get("SPINCODIVA");
 | ||
|     _codiva_bolli = conf.get("SPBOCODIVA");
 | ||
|     _firm = new_firm;
 | ||
|   }
 | ||
| }
 | ||
|                     
 | ||
| real TDocumento::spese_incasso(real & imp, int ndec, TTipo_importo t) const
 | ||
| {        
 | ||
|   static TArray spese_inc;
 | ||
| 	static real maxadd, spadd;
 | ||
| 
 | ||
|   real imp_spese;   
 | ||
|   const real percentuale = get(DOC_PERCSPINC);
 | ||
|   
 | ||
|   if (percentuale > ZERO)
 | ||
|   {
 | ||
|     if (ndec == AUTO_DECIMALS)
 | ||
|       ndec = decimals();
 | ||
|     if (spese_inc.objptr(_rim_dir) == NULL) // Inizializzo le spese d'incasso se necessario
 | ||
|     {
 | ||
|       TConfig conf(CONFIG_STUDIO, "ve");
 | ||
|       for (TTipo_pag p = _rim_dir; p < _nessun_pag; p = TTipo_pag((int)p + 1)) 
 | ||
|       {
 | ||
|         const real r(conf.get("IMPSPINC", "ve", p));
 | ||
|         spese_inc.add(r, p);
 | ||
|       }
 | ||
| 			maxadd = (real)conf.get("MAXADD");
 | ||
| 			spadd = (real)conf.get("SPADD");
 | ||
|     }   
 | ||
| 
 | ||
|     // Calcola l'eventuale importo minimo per effetti (solitamente zero)
 | ||
|     const TRectype& cfven = clifor().vendite();
 | ||
|     const real impmineff = cfven.get_real(CFV_IMPMINEFF);
 | ||
| 
 | ||
|     // Somma le spese di ogni singola rata
 | ||
|     const TPagamento& pag = ((TDocumento *)this)->pagamento();  
 | ||
|     const int nrate = pag.n_rate();
 | ||
| 
 | ||
|     for (int i = 0; i < nrate; i++)
 | ||
|     {
 | ||
|       if (pag.importo_rata(i) >= impmineff)  // Se la rata supera il minimo contrattuale
 | ||
|       {
 | ||
|         const TTipo_pag tp = (TTipo_pag)pag.tipo_rata(i);
 | ||
| 
 | ||
| 				if (spese_inc.objptr(tp) != NULL)
 | ||
|         imp_spese += (const real&)spese_inc[tp];
 | ||
|       }
 | ||
|     }
 | ||
| 		
 | ||
| 		if (imp_spese > ZERO && imp < maxadd)
 | ||
| 			imp_spese += spadd;
 | ||
|     imp_spese = imp_spese * percentuale / CENTO;
 | ||
|     
 | ||
|     if (t == _lordo || t == _imposta)
 | ||
|     {
 | ||
|       TString4 codiva_es; iva_esente(codiva_es);                       
 | ||
|       const real iva_spese(TRiga_documento::iva(codiva_es.full() ? (const TString &)codiva_es : codiva_spese()).imposta(imp_spese, ndec));                      
 | ||
|       if (t == _lordo)
 | ||
|         imp_spese += iva_spese;
 | ||
|       else
 | ||
|         if (t == _imposta)
 | ||
|           imp_spese = iva_spese;
 | ||
|     }         
 | ||
| 
 | ||
|     const real cambio = get(DOC_CAMBIO);
 | ||
|     if (!cambio.is_zero())
 | ||
|     {                      
 | ||
|       // Converte le spese nella valuta del documento
 | ||
|       const exchange_type ce = get_bool(DOC_CONTROEURO) ? _exchange_contro : _exchange_base;
 | ||
|       imp_spese = change_currency(imp_spese, "", ZERO, _exchange_undefined,
 | ||
|                                   get(DOC_CODVAL), cambio, ce, -1);
 | ||
|     }
 | ||
|     
 | ||
|     imp_spese.round(ndec);
 | ||
|   }
 | ||
| 	
 | ||
|   return imp_spese;
 | ||
| }
 | ||
|                                       
 | ||
| void TDocumento::iva_esente(TString& codiva_es) const                                     
 | ||
| {
 | ||
|   codiva_es.cut(0);
 | ||
| 
 | ||
|   const int rows = physical_rows();    
 | ||
|   for (int r = 1; codiva_es.empty() && r <= rows; r++)
 | ||
|   {
 | ||
|     const TRiga_documento& riga = ((TDocumento*)this)->row(r); 
 | ||
|     const TString4 str_codiva(riga.get(RDOC_CODIVA));
 | ||
|     
 | ||
|     if (str_codiva.full())
 | ||
|     {
 | ||
|       const TCodiceIVA codiva(str_codiva);
 | ||
|       const TString& tipoiva = codiva.tipo();      
 | ||
|       if (tipoiva.empty())
 | ||
|         break;
 | ||
|       if (tipoiva == "NI")
 | ||
|         codiva_es = str_codiva;
 | ||
|     }     
 | ||
|   }                                    
 | ||
| }
 | ||
| 
 | ||
| real TDocumento::bolli(real & imp, int ndec, TTipo_importo t) const
 | ||
| {                         
 | ||
|   real tot_bolli;
 | ||
|   static TArray sca_bolli;
 | ||
|   static TArray imp_bolli;
 | ||
|   static real bolli_es;
 | ||
|   static real impmin_bolli;
 | ||
|   static int nscagl;
 | ||
| 
 | ||
|   if (get_bool("ADDBOLLI"))
 | ||
|   {
 | ||
|     if (sca_bolli.objptr(0) == NULL)
 | ||
|     {
 | ||
|       TConfig conf(CONFIG_STUDIO, "ve");
 | ||
|       
 | ||
|       bolli_es = (real) conf.get("BOLLIES", "ve");
 | ||
|       impmin_bolli = (real) conf.get("IMPMINBOLLI", "ve");
 | ||
|       for (nscagl = 0; nscagl < 7; nscagl++) 
 | ||
|       {
 | ||
|         real s(conf.get("SPBOSCA", "ve", nscagl + 1));
 | ||
|         real i(conf.get("SPBOIMP", "ve", nscagl + 1));
 | ||
|                                                       
 | ||
|         if (s == ZERO && i == ZERO)
 | ||
|           break;
 | ||
|         sca_bolli.add(s, nscagl);
 | ||
|         imp_bolli.add(i, nscagl);
 | ||
|       }
 | ||
|     } 
 | ||
|     if (ndec == AUTO_DECIMALS)
 | ||
|       ndec = decimals();
 | ||
|     
 | ||
|     TCurrency_documento imp_val(imp);
 | ||
|     imp_val.change_to_firm_val();
 | ||
|     real importo = imp_val.get_num();
 | ||
|     
 | ||
|     TPagamento & pag = ((TDocumento*)this)->pagamento();  
 | ||
|     const int nrate = pag.n_rate();
 | ||
|     real old_bolli = -1.00;
 | ||
|     real iva_bolli;    
 | ||
|     
 | ||
|     TCurrency_documento imp_orig_val(imposta());
 | ||
|     imp_orig_val.change_to_firm_val();
 | ||
|     const real imp_orig = imp_orig_val.get_num();
 | ||
|     
 | ||
|     TCurrency_documento spese_val(spese());
 | ||
|     spese_val.change_to_firm_val();
 | ||
|     const real sp_orig = spese_val.get_num();
 | ||
|     bool estero = FALSE; // Assumiamo per ora non estero
 | ||
| 
 | ||
|     TString4 codiva_es;
 | ||
|     iva_esente(codiva_es);                       
 | ||
| 
 | ||
|     for (int j = 0; j < 5 && tot_bolli+iva_bolli != old_bolli; j++)
 | ||
|     {
 | ||
|       old_bolli = tot_bolli + iva_bolli;  
 | ||
|       const real imposte = imp_orig + iva_bolli;
 | ||
|       const real imp_spese = sp_orig + tot_bolli - iva_bolli;
 | ||
|       const real imponibile = importo - imposte - imp_spese;
 | ||
|       tot_bolli = ZERO;      
 | ||
|       if (!tipo().nota_credito())
 | ||
|       {
 | ||
|         real imponibile_esente;
 | ||
|         for (int r = physical_rows(); r > 0; r--)
 | ||
|         {
 | ||
|           const TRiga_documento& riga = ((TDocumento*)this)->row(r); 
 | ||
|           const TCodiceIVA codiva(riga.get(RDOC_CODIVA));
 | ||
|                 
 | ||
|           if (codiva.tipo().not_empty())
 | ||
|             imponibile_esente += riga.imponibile();
 | ||
|         }
 | ||
|         if (imponibile_esente >= impmin_bolli)
 | ||
|           tot_bolli = bolli_es;
 | ||
|       }    
 | ||
|       pag.set_total(imponibile, imposte, imp_spese);  
 | ||
|       pag.set_rate_auto();
 | ||
|   
 | ||
|       for (int i = 0; i < nrate; i++)
 | ||
|       {
 | ||
|         const TTipo_pag p = (TTipo_pag) pag.tipo_rata(i);
 | ||
|         real imp = pag.importo_rata(i);
 | ||
|         
 | ||
|         switch (p)
 | ||
|         {         
 | ||
|           case _ric_ban: 
 | ||
|             {
 | ||
|             	int i;
 | ||
|             	
 | ||
|               for (i = 0; i < nscagl - 1; i++)
 | ||
|                 if ((real &) sca_bolli[i] >= imp)
 | ||
|                   break;
 | ||
|               if (imp_bolli.items() > 0)
 | ||
|                 tot_bolli += (real &) imp_bolli[i];
 | ||
|             }
 | ||
|             break;
 | ||
|           case _tratta:
 | ||
|           case _tratta_acc:
 | ||
|             {             
 | ||
|               if (j == 0) // Dobbiamo inizializzare la variabile 'estero'
 | ||
|               { 
 | ||
|                 TString16 key; 
 | ||
|                 key.format("%c|%ld", get_char(DOC_TIPOCF), get_long(DOC_CODCF));
 | ||
|                 const TRectype& clifo = cache().get(LF_CLIFO, key);
 | ||
| 
 | ||
|                 const TString& stato_iva = clifo.get(CLI_STATOPAIV);
 | ||
|                 estero = stato_iva.not_empty() && stato_iva != "IT";
 | ||
|                 if (!estero)
 | ||
|                 {
 | ||
|                   const TString& stato_cf = clifo.get(CLI_STATOCF);
 | ||
|                   estero = (stato_cf.not_empty() && stato_cf != "IT") || clifo.get_char(CLI_COMCF) == 'Z';
 | ||
|                 }
 | ||
|               }
 | ||
|               real r(imp);
 | ||
|               const int ndec = decimals();
 | ||
|               r.ceil(ndec == 0 ? -3 : 0);
 | ||
|               if (estero)
 | ||
|                 r *= 0.009;
 | ||
|               else
 | ||
|                 r *= 0.012;
 | ||
|               r.round(ndec == 0 ? -2 : ndec);
 | ||
|               tot_bolli += r;
 | ||
|             }
 | ||
|             break;
 | ||
|           case _cessione:
 | ||
|           case _paghero:
 | ||
|           case _let_cred:
 | ||
|           case _rim_dir:
 | ||
|           case _rid:
 | ||
|           case _bonfico:
 | ||
|           default:
 | ||
|             break;
 | ||
|         }
 | ||
|       }
 | ||
|       iva_bolli = TRiga_documento::iva(codiva_bolli()).imposta(tot_bolli, ndec);                      
 | ||
|       importo += (tot_bolli + iva_bolli - old_bolli);
 | ||
|     }        
 | ||
|     if (t == _lordo)
 | ||
|       tot_bolli += iva_bolli;
 | ||
|     else
 | ||
|       if (t == _imposta)
 | ||
|         tot_bolli = iva_bolli;
 | ||
| 
 | ||
|     if (in_valuta())
 | ||
|     {                      
 | ||
|       const real cambio = get_real(DOC_CAMBIO);
 | ||
|       const exchange_type ce = get_bool(DOC_CONTROEURO) ? _exchange_contro : _exchange_base;
 | ||
|       tot_bolli = change_currency(tot_bolli, "", ZERO, _exchange_undefined,
 | ||
|                                   get(DOC_CODVAL), cambio, ce, -1);
 | ||
|     }
 | ||
|     tot_bolli.round(ndec);
 | ||
|   }
 | ||
| 
 | ||
|   return tot_bolli;
 | ||
| }
 | ||
| 
 | ||
| const TString & TDocumento::commessa_principale() const
 | ||
| {
 | ||
| 	if (codice_commessa().blank())
 | ||
| 	{
 | ||
| 		const int row = physical_rows();
 | ||
| 
 | ||
| 		for (int i = 1; i <= rows(); i++)
 | ||
| 		{
 | ||
| 			const TRiga_documento &r = ((TRiga_documento &) ((TDocumento *)this)->row(i));
 | ||
| 
 | ||
| 			if (!r.codice_commessa().blank())
 | ||
| 				return r.codice_commessa();
 | ||
| 		}
 | ||
| 	}
 | ||
| 	return codice_commessa();
 | ||
| }
 | ||
| 
 | ||
| bool TDocumento::modificabile() const
 | ||
| {                     
 | ||
|   const char stato_attuale = stato();
 | ||
| 
 | ||
|   if (stato_attuale <= ' ')
 | ||
|     return true;
 | ||
|   
 | ||
|   const TString& stati_modifica = tipo().stati_iniziali_modifica();
 | ||
|   return stati_modifica.blank() || stati_modifica.find(stato_attuale) >= 0;
 | ||
| }      
 | ||
| 
 | ||
| bool TDocumento::cancellabile() const
 | ||
| {
 | ||
|   const char stato_attuale = stato();
 | ||
| 
 | ||
|   if (stato_attuale <= ' ')
 | ||
|     return true;
 | ||
|   
 | ||
|   const TString& stati_cancellazione = tipo().stati_iniziali_cancellazione();
 | ||
|   return stati_cancellazione.blank() || stati_cancellazione.find(stato_attuale) >= 0;
 | ||
| }      
 | ||
| 
 | ||
| bool TDocumento::stampabile() const
 | ||
| {
 | ||
|   const char stato_attuale = stato();
 | ||
|   if (stato_attuale <= ' ')
 | ||
|     return true;
 | ||
| 
 | ||
|   if (stato_attuale == tipo().stato_finale_stampa())  
 | ||
|     return false;
 | ||
|   
 | ||
|   const TString& stati_stampa = tipo().stati_iniziali_stampa();
 | ||
|   return stati_stampa.blank() || stati_stampa.find(stato_attuale) >= 0;
 | ||
| }      
 | ||
| 
 | ||
| bool TDocumento::bloccato() const
 | ||
| {
 | ||
|   const char stato_attuale = stato();
 | ||
| 
 | ||
|   if (stato_attuale <= ' ')
 | ||
|     return false;
 | ||
|   
 | ||
|   char stato_bloccato = tipo().stato_bloccato();
 | ||
| 
 | ||
|   if (stato_bloccato <= ' ')
 | ||
|     return false;
 | ||
|   
 | ||
|   return stato_attuale >= stato_bloccato;
 | ||
| }      
 | ||
| 
 | ||
| bool TDocumento::chiuso() const
 | ||
| {
 | ||
| 	if (!tipo().is_scontrino())
 | ||
| 		return false;
 | ||
| 
 | ||
|   const char stato_attuale = stato();
 | ||
| 
 | ||
|   if (stato_attuale <= ' ')
 | ||
|     return false;
 | ||
|   
 | ||
|   char stato_chiuso = tipo().stato_chiuso();
 | ||
| 
 | ||
|   if (stato_chiuso <= ' ')
 | ||
|     return false;
 | ||
|   
 | ||
|   return stato_attuale >= stato_chiuso;
 | ||
| }      
 | ||
| 
 | ||
| // Funzione statica utile a tutti gli utenti di LF_DOC e LF_RIGHEDOC
 | ||
| void TDocumento::set_key(TRectype& rec, char provv, int anno, const char* codnum, long numdoc)
 | ||
| {
 | ||
|   CHECK(provv == 'D' || provv == 'P', "Provvisorio o Definitivo?");
 | ||
|   CHECKD(anno > 1900, "Anno non valido: ", anno);
 | ||
|   CHECK(codnum && *codnum, "Codice numerazione nullo");
 | ||
|   CHECKD(numdoc >= 0, "Numero documento non valido ", numdoc);
 | ||
| 
 | ||
|   rec.put(DOC_PROVV,  provv); 
 | ||
|   rec.put(DOC_ANNO,   anno);
 | ||
|   rec.put(DOC_CODNUM, codnum);  
 | ||
|   rec.put(DOC_NDOC,   numdoc);
 | ||
| }
 | ||
| 
 | ||
| // Funzione statica utile a tutti gli utenti di LF_DOC e LF_RIGHEDOC
 | ||
| void TDocumento::copy_data(TRectype& dst, const TRectype& src)
 | ||
| {                           
 | ||
|   const bool is_riga = dst.num() == LF_RIGHEDOC;
 | ||
| 
 | ||
|   // Memorizza tutti i campi chiave
 | ||
|   const char provv       = dst.get_char(RDOC_PROVV);
 | ||
|   const int anno         = dst.get_int(RDOC_ANNO);  
 | ||
|   const TString4 codnum  = dst.get(RDOC_CODNUM);
 | ||
| 
 | ||
|   const long numdoc      = dst.get_long(RDOC_NDOC);  
 | ||
|   const int nriga        = is_riga ? dst.get_int(RDOC_NRIGA) : 0;
 | ||
|   const long idriga      = is_riga ? dst.get_long(RDOC_IDRIGA) : 0;  
 | ||
|   // Copia tutto il record     
 | ||
|   dst = src;                          
 | ||
|   // Ripristina tutti i campi chiave
 | ||
|   set_key(dst, provv, anno, codnum, numdoc);
 | ||
|  	dst.init_memo(RECORD_NON_FISICO);
 | ||
|   if (is_riga)
 | ||
|   {
 | ||
|     dst.put(RDOC_NRIGA, nriga);
 | ||
|     dst.put(RDOC_IDRIGA, idriga);
 | ||
|     dst.zero(RDOC_MOVMAG);
 | ||
|     const TString memo = src.get(RDOC_DESCEST);
 | ||
|     dst.put(RDOC_DESCEST, memo);
 | ||
|     const TString g1 = src.get(RDOC_RG1);
 | ||
|     dst.put(RDOC_RG1, g1);
 | ||
| 		((TRiga_documento & )dst).load_memo();
 | ||
| 	}
 | ||
|   else
 | ||
|   {
 | ||
|     dst.zero(DOC_MOVMAG);
 | ||
|     dst.zero(DOC_NUMREG);
 | ||
|     dst.zero(DOC_NUMREGCA);
 | ||
| 		dst.put(DOC_NOTE, src.get(DOC_NOTE));
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| // Funzione statica utile a tutti gli utenti di LF_RIGHEDOC
 | ||
| void TDocumento::copy_data(TRiga_documento& dst, const TRiga_documento& src)
 | ||
| {                           
 | ||
|   copy_data((TRectype&)dst, (const TRectype&)src);
 | ||
|   dst.put(RDOC_CODCMS, src.codice_commessa());
 | ||
|   dst.put(RDOC_FASCMS, src.fase_commessa());
 | ||
|   dst.put(RDOC_CODCOSTO, src.codice_costo());
 | ||
| }
 | ||
|   
 | ||
| void TDocumento::copy_contents(const TDocumento& src, bool copy_header)
 | ||
| {
 | ||
| 	if (copy_header)
 | ||
| 		copy_data(head(), src.head()); 
 | ||
|   destroy_rows();  
 | ||
|   const int rows = src.physical_rows(); 
 | ||
|   for (int i = 1; i <= rows ; i++)
 | ||
|   {
 | ||
|     const TRiga_documento& s = src[i];
 | ||
|     TRiga_documento & r = new_row(s.tipo().codice());
 | ||
|     copy_data(r, s);
 | ||
|     r.set_original_rdoc_key(s);
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| TRiga_documento& TDocumento::insert_row(int row, const char *tipo)
 | ||
| {       
 | ||
|   TRiga_documento& r = (TRiga_documento&)TMultiple_rectype::insert_row(row);
 | ||
|   if (tipo && *tipo)
 | ||
|     r.set_tipo(tipo);
 | ||
|   return r;
 | ||
| }
 | ||
| 
 | ||
| TRiga_documento& TDocumento::new_row(const char *tipo)
 | ||
| {
 | ||
|   TRiga_documento& r = (TRiga_documento&)TMultiple_rectype::new_row();
 | ||
| 
 | ||
| 	r.set_doc(this);
 | ||
|   if (tipo && *tipo)
 | ||
|     r.set_tipo(tipo);
 | ||
|   return r;
 | ||
| }
 | ||
| 
 | ||
| int TDocumento::read(TBaseisamfile& f, word op, word lockop)
 | ||
| { 
 | ||
|   int err = TMultiple_rectype::read(f, op ,lockop); 
 | ||
| 
 | ||
|   _cli_for.zero();
 | ||
|   _occas.zero();
 | ||
| 
 | ||
|   set_riga_sconto();
 | ||
|   if (is_fattura())
 | ||
|     set_riga_esenzione();
 | ||
|   _stato_originale = stato();
 | ||
|   
 | ||
|   if (err == NOERR && tipo_valido() && tipo().statistiche() && _has_stat_ven)
 | ||
|   {       
 | ||
|     TString80 key(get(DOC_PROVV)); key << get(DOC_ANNO); key << get(DOC_CODNUM); key << get(DOC_NDOC);
 | ||
|     TObject* o = _docs_to_agg.objptr(key);
 | ||
| 
 | ||
|     const bool is_nota_credito = tipo().nota_credito();
 | ||
| 
 | ||
|     if ( lockop >= _lock && o == NULL)
 | ||
|     {          
 | ||
|       TStats_agg * st_agg = new TStats_agg;
 | ||
|       for (int i = physical_rows(); i > 0; i--)
 | ||
|         if (is_nota_credito)
 | ||
|           st_agg->add(row(i));
 | ||
|         else
 | ||
|           st_agg->sub(row(i));
 | ||
|       _docs_to_agg.add(key, st_agg, true);
 | ||
|     }
 | ||
|     else 
 | ||
|       if (lockop == _unlock && o != NULL)
 | ||
|         _docs_to_agg.remove(key);
 | ||
|   }
 | ||
|   
 | ||
|   _old_agente.cut(0);
 | ||
|   _old_agente1.cut(0);
 | ||
| 	if (err == NOERR && _has_provv)
 | ||
| 	{
 | ||
|     _old_agente = get(DOC_CODAG);
 | ||
|     _old_agente1 = get(DOC_CODAGVIS);
 | ||
| 	}
 | ||
| 
 | ||
|   return err;
 | ||
| }
 | ||
| 
 | ||
| int TDocumento::read(char provv, int anno, const char* codnum, long numdoc, word op, word lockop)
 | ||
| {                           
 | ||
|   CHECK(numdoc > 0, "Numero documento nullo."); 
 | ||
|   zero();
 | ||
|   set_key(*this, provv, anno, codnum, numdoc);
 | ||
|   return read(op, lockop);
 | ||
| }
 | ||
| 
 | ||
| long TDocumento::renum_ndoc(long numdoc)
 | ||
| {
 | ||
|   if (numdoc <= 0)
 | ||
|   {
 | ||
|     const char     tn = tipo_numerazione();
 | ||
|     const int      an = anno();
 | ||
|     const TString4 nu = numerazione();
 | ||
|     numdoc  = get_next_key(tn, an, nu);
 | ||
|   }   
 | ||
|   put(DOC_NDOC, numdoc);          // Aggiorna testata
 | ||
|   TMultiple_rectype::renum_key(); // Aggiorna righe  ok
 | ||
|   return numdoc;
 | ||
| }
 | ||
| 
 | ||
| void TDocumento::set_riga_sconto()
 | ||
| {                                 
 | ||
|   const TString80 sconto(get(DOC_SCONTOPERC)); 
 | ||
|   
 | ||
|   if (!is_real_discount(sconto))
 | ||
|   {        
 | ||
|     if(_sconto != NULL)
 | ||
|       delete _sconto;
 | ||
|     _sconto = NULL;
 | ||
|   }
 | ||
|   else
 | ||
|   {                
 | ||
|     if (_sconto == NULL)
 | ||
|     {                   
 | ||
|       static TString4 _tipo_riga_sc;
 | ||
|       if (_tipo_riga_sc.empty())
 | ||
|       {
 | ||
|         TConfig conf(CONFIG_STUDIO, "ve");
 | ||
|         _tipo_riga_sc = conf.get("TRSCONTI", "ve");
 | ||
|         // Se non esiste il tipo riga lo cerca, lo setta di default ed avvisa        
 | ||
|         if (_tipo_riga_sc.empty())
 | ||
|         {
 | ||
|           _tipo_riga_sc = "08";
 | ||
|           conf.set("TRSCONTI", _tipo_riga_sc);
 | ||
|           warning_box(FR("Il tipo riga sconti di testa non risultava impostato.\n L'applicazione usera' automaticamente il tipo %s"), (const char*) _tipo_riga_sc);
 | ||
|         }
 | ||
|       }
 | ||
|       _sconto = new TRiga_documento(this, _tipo_riga_sc); 
 | ||
|       _sconto->put(RDOC_DESCR, TR("Sconto"));
 | ||
|     }
 | ||
|     _sconto->put(RDOC_SCONTO, sconto);
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| void TDocumento::update_esenzione()
 | ||
| {   
 | ||
|   if (clifor().use_lettere())
 | ||
|   {
 | ||
|     bool to_update = false;
 | ||
|     const TString8 codiva = codesiva();
 | ||
|     for (int i = physical_rows(); !to_update && i > 0; i--)
 | ||
|     {
 | ||
|       const TString & cod = row(i).get(RDOC_CODIVA);
 | ||
| 
 | ||
|       to_update = cod.full() && cod != codiva;
 | ||
|     }
 | ||
|     if (to_update)
 | ||
|      for (int i = physical_rows(); i > 0; i--)
 | ||
|     {
 | ||
|       TRiga_documento & rdoc = row(i);
 | ||
|       const TString & cod = rdoc.get(RDOC_CODIVA);
 | ||
| 
 | ||
|       if (cod.full())
 | ||
|       {
 | ||
|         if (codiva.full())
 | ||
|           rdoc.put(RDOC_CODIVA, codiva);
 | ||
|         else
 | ||
|         {
 | ||
|           TCodiceIVA i(cod);
 | ||
|           const bool plafond = i.get_int("S3") > 0;
 | ||
|           
 | ||
|           if (plafond)
 | ||
|           {
 | ||
|             TString codivarow;
 | ||
| 
 | ||
|             if (rdoc.is_merce())
 | ||
|               codivarow =cached_article(rdoc.get(RDOC_CODARTMAG)).get(ANAMAG_CODIVA);
 | ||
|             else
 | ||
|               if (rdoc.is_spese())
 | ||
|               {
 | ||
|                 TSpesa_prest s(rdoc.get(RDOC_CODART));
 | ||
|                 
 | ||
|                 codivarow = s.cod_iva();
 | ||
|               }
 | ||
|               else
 | ||
|                 if (rdoc.is_prestazione())
 | ||
|                 {
 | ||
|                   TSpesa_prest p(rdoc.get(RDOC_CODART), 'P');
 | ||
|                   
 | ||
|                   codivarow = p.cod_iva();
 | ||
|                 }
 | ||
|                 else
 | ||
|                   if (rdoc.is_risorsa())
 | ||
|                   {
 | ||
|                     TSpesa_prest r(rdoc.get(RDOC_CODART), 'R');
 | ||
|                   
 | ||
|                     codivarow = r.cod_iva();
 | ||
|                   }
 | ||
|                   else
 | ||
|                     if (rdoc.is_attrezzatura())
 | ||
|                     {
 | ||
|                       TSpesa_prest a(rdoc.get(RDOC_CODART), 'A');
 | ||
|                   
 | ||
|                       codivarow = a.cod_iva();
 | ||
|                     }
 | ||
|             if (codivarow.full())
 | ||
|               rdoc.put(RDOC_CODIVA, codivarow);
 | ||
|           }
 | ||
|         }
 | ||
|       }
 | ||
|      }
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| void TDocumento::set_riga_esenzione()
 | ||
| {                                  
 | ||
|   TCli_for & c = clifor();   
 | ||
|   const TCodiceIVA codes(c.vendite().get(CFV_ASSFIS));
 | ||
|   TString16 v_esenzione;
 | ||
|   TString16 v_data_esenzione;
 | ||
|   TString16 n_registrazione; 
 | ||
|   TString16 n_data_registrazione;
 | ||
| 
 | ||
| 	if (codes.codice().full())
 | ||
| 		get_protocolli_esenzione(v_esenzione, v_data_esenzione, n_registrazione, n_data_registrazione);
 | ||
|   bool esente = codes.tipo().not_empty() && v_esenzione.not_empty() &&
 | ||
|                 v_data_esenzione.not_empty() && n_registrazione.not_empty() &&  
 | ||
|                 n_data_registrazione.not_empty();
 | ||
|   if (esente)                         
 | ||
|   {
 | ||
|     esente = false;
 | ||
|     const TString8 codiva = codes.codice();
 | ||
|     for (int i = physical_rows(); !esente && i > 0; i--)
 | ||
|       esente = row(i).get(RDOC_CODIVA) == codiva;
 | ||
|   }
 | ||
|   
 | ||
|   if (!esente)
 | ||
|   {        
 | ||
|     if(_esenzione != NULL)
 | ||
|       delete _esenzione;
 | ||
|     _esenzione = NULL;
 | ||
|   }
 | ||
|   else 
 | ||
|   {
 | ||
|     static TString4 _tipo_riga_es; 
 | ||
|     static TString80 _des_esenz;
 | ||
|     static real _bollo_es;
 | ||
|     if (_tipo_riga_es.empty())
 | ||
|     {
 | ||
|       TConfig conf(CONFIG_STUDIO, "ve");   
 | ||
|       _tipo_riga_es = conf.get("TRESENZ", "ve"); 
 | ||
|       _bollo_es = (real)conf.get("BOLLIES", "ve");
 | ||
|       if (_tipo_riga_es.empty())           
 | ||
|       {
 | ||
|         _tipo_riga_es = "05";
 | ||
|         conf.set("TRESENZ", _tipo_riga_es);
 | ||
|         warning_box("Il tipo riga esenzione non risultava impostato.\n L'applicazione usera' automaticamente il tipo %s", (const char*) _tipo_riga_es);
 | ||
|       }                         
 | ||
|       _des_esenz = conf.get("DESESENZ", "ve"); 
 | ||
|       if (_des_esenz.not_empty())
 | ||
|         _des_esenz.insert(" ");
 | ||
|       _des_esenz.insert("Fattura non imponibile");
 | ||
|     }
 | ||
|     if (_esenzione == NULL)
 | ||
|       _esenzione = new TRiga_documento(this, _tipo_riga_es); 
 | ||
|     TString d(256); d = _des_esenz;
 | ||
| 
 | ||
|     d << format(" come da vostra dichiarazione n. %s del %s da noi annotata al n. %s il %s.",
 | ||
|                 (const char *) v_esenzione, (const char *) v_data_esenzione, 
 | ||
|                 (const char *) n_registrazione, (const char *) n_data_registrazione);
 | ||
|     
 | ||
|     _esenzione->put(RDOC_DESCR, d.left(50));                                                     
 | ||
|     _esenzione->put(RDOC_DESCLUNGA, "X");
 | ||
|     _esenzione->put(RDOC_DESCEST, d.mid(50));
 | ||
|   }
 | ||
| }
 | ||
|                                  
 | ||
| void TDocumento::dirty_fields()
 | ||
| {
 | ||
|   if (!_dirty_deny)
 | ||
|   {
 | ||
|     for (TDocumento_variable_field * f = (TDocumento_variable_field *) first_variable_field(); 
 | ||
|          f != NULL; f = (TDocumento_variable_field *) succ_variable_field()) 
 | ||
|       f->set_dirty();   
 | ||
|     dirty_tabella_iva();
 | ||
| 
 | ||
|     if (loaded_rows(LF_RIGHEDOC)) // Se ho gia' caricato delle righe in memoria
 | ||
|     {
 | ||
| 		  TRecord_array& righe = body(LF_RIGHEDOC);
 | ||
|       for (int i = righe.last_row(); i > 0; i = righe.pred_row(i))
 | ||
|       {
 | ||
|         TRiga_documento & r = (TRiga_documento &) righe[i];     
 | ||
|         r.dirty_fields(FALSE);
 | ||
|       }  
 | ||
|     }
 | ||
|     _dirty_deny = true;
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| static TToken_string * __key;
 | ||
| 
 | ||
| HIDDEN int sort_doc_rows(const TObject** r0, const TObject** r1)
 | ||
| {
 | ||
| 	TRiga_documento* row0 = (TRiga_documento*)*r0;
 | ||
| 	TRiga_documento* row1 = (TRiga_documento*)*r1;
 | ||
| 	int res = 0;
 | ||
| 
 | ||
|   TString val0, val1;
 | ||
|   TToken_string valist(50,',');
 | ||
| 
 | ||
| 	FOR_EACH_STR_TOKEN(*__key, fldname)
 | ||
| 	{
 | ||
|     int direction = +1;
 | ||
|     if (fldname[0] == '-')
 | ||
|     {
 | ||
|       direction = -1;
 | ||
|       fldname.ltrim(1);
 | ||
|     }
 | ||
|     const int par = fldname.find('(');
 | ||
|     if (par > 0)
 | ||
|     {
 | ||
|       valist = fldname.mid(par+1);
 | ||
|       valist.strip("()");
 | ||
|       fldname.cut(par);
 | ||
|     }
 | ||
|     else
 | ||
|       valist.cut(0);
 | ||
| 
 | ||
| 		const TFieldref fld(fldname, 0);
 | ||
| 		val0 = fld.read(*row0);
 | ||
| 		val1 = fld.read(*row1);
 | ||
| 
 | ||
| 		switch (row0->type(fld.name()))
 | ||
| 		{
 | ||
| 			case _intfld :
 | ||
| 			case _longfld :
 | ||
| 			case _realfld :
 | ||
| 			case _wordfld :
 | ||
| 				{
 | ||
| 					const real r0 = val0;
 | ||
| 					const real r1 = val1;
 | ||
| 
 | ||
| 					if (r0 != r1)
 | ||
| 						res = (r0 < r1 ? -1 : 1) * direction;
 | ||
| 				}
 | ||
| 				break;
 | ||
| 			case _datefld :
 | ||
| 				{
 | ||
| 					const TDate d0 = val0;
 | ||
| 					const TDate d1 = val1;
 | ||
| 
 | ||
| 					if (d0 != d1)
 | ||
| 						res = (d0 < d1 ? -1 : 1) * direction;
 | ||
| 				}
 | ||
| 				break;
 | ||
| 			default:
 | ||
| 				if (val0 != val1)
 | ||
|         {
 | ||
|           if (valist.full())
 | ||
|           {
 | ||
|             int pos0 = valist.get_pos(val0); if (pos0 < 0) pos0 = valist.items();
 | ||
|             int pos1 = valist.get_pos(val1); if (pos1 < 0) pos1 = valist.items();
 | ||
|             res = (pos0 - pos1) * direction;
 | ||
|           }
 | ||
|           else
 | ||
|   			    res = xvt_str_compare_ignoring_case(val0, val1) * direction;
 | ||
|         }
 | ||
| 				break;
 | ||
| 		}
 | ||
| 		if (res != 0)
 | ||
| 			break;
 | ||
| 	}
 | ||
| 	return res;
 | ||
| }
 | ||
| 
 | ||
| void TDocumento::sort_rows(const char* key)
 | ||
| {
 | ||
| 	__key = new TToken_string(key);
 | ||
| 	body().sort(sort_doc_rows);
 | ||
| 	delete __key;
 | ||
| 	__key = NULL;
 | ||
| }
 | ||
| 
 | ||
| static real doc_inventory_qta(const TCausale_magazzino & cau, const TString & codart, const TString & codmag,
 | ||
| 															const TString & livello, int anno, const real & qta)
 | ||
| {
 | ||
| 	const real giac = cached_article_balances(codart).giacenza_anno(codmag, livello, anno);
 | ||
|  
 | ||
| 	real q = qta - giac;
 | ||
| 	switch (cau.sgn(s_giac))
 | ||
| 	{
 | ||
| 		case  1: break;
 | ||
| 		case -1: q = -q; break;
 | ||
| 		default: break;
 | ||
| 	}
 | ||
| 	return q;
 | ||
| }
 | ||
| 
 | ||
| int TDocumento::write_rewrite(TBaseisamfile & f, bool re) const
 | ||
| { 
 | ||
|   TDocumento& myself = *((TDocumento *)this);
 | ||
|   const bool new_doc = nuovo() || numero() <= 0;  // E' nuovo di zecca!       
 | ||
| 
 | ||
|   if (new_doc)
 | ||
|   {
 | ||
|     char stato_finale = tipo().stato_finale_inserimento();
 | ||
|     if (stato() == '\0' && stato_finale > ' ')
 | ||
|       myself.stato(stato_finale);
 | ||
|   }                       
 | ||
|   else
 | ||
|     myself._stato_originale = stato();    
 | ||
| 
 | ||
|   const bool doc_bloccato = bloccato();
 | ||
|   const char stato_doc(stato());
 | ||
| 
 | ||
|   int err = NOERR;
 | ||
| 
 | ||
|   if (!doc_bloccato)
 | ||
|   {
 | ||
|     if (tipo().spese_aut() && !get_bool(DOC_SPESEUPD))
 | ||
|     {
 | ||
|       char name[8] = "CODSP0";
 | ||
|       TString_array spese;        
 | ||
|       const TRectype & ven_rec = clifor().vendite();
 | ||
|       for (int i = 1; i <= 4; i++)
 | ||
|       {                     
 | ||
|         name[5] = '0' + i;
 | ||
|         const TString& s = ven_rec.get(name);   
 | ||
|         if (s.full()) 
 | ||
|           spese.add(s);
 | ||
|       }               
 | ||
|       myself.update_spese_aut(spese);
 | ||
|     }
 | ||
|     myself.update_conai();
 | ||
| 		myself.update_raee();
 | ||
|     myself.set_row_ids();
 | ||
|   
 | ||
|     const bool check_movmag = dongle().active(MGAUT) && tipo().mov_mag();
 | ||
|     if (check_movmag)
 | ||
|     {           
 | ||
|       const bool do_movmag = tipo().stato_with_mov_mag(stato_doc) && get(DOC_CAUSMAG).not_empty();
 | ||
|       long num_movmag = get_long(DOC_MOVMAG);            
 | ||
| 			bool diff_inv = get_bool("DIFFINV");
 | ||
| 
 | ||
|       TMov_mag_doc mov;
 | ||
|       TLocalisamfile m(LF_MOVMAG);
 | ||
|       mov.zero();
 | ||
|       if (!new_doc && do_movmag && num_movmag <= 0)
 | ||
|       {
 | ||
| 				m.setkey(6);
 | ||
| 				m.zero();
 | ||
| 				m.put(MOVMAG_DOCPROVV, myself.get(DOC_PROVV));
 | ||
| 				m.put(MOVMAG_ANNODOC, myself.anno());
 | ||
| 				m.put(MOVMAG_CODNUM, myself.numerazione());
 | ||
| 				m.put(MOVMAG_NUMDOC, myself.numero());
 | ||
| 				if (m.read(_isequal) == NOERR)
 | ||
| 				{
 | ||
| 					num_movmag = m.get_long(MOVMAG_NUMREG);
 | ||
| 	        myself.put(DOC_MOVMAG, num_movmag);
 | ||
| 				}
 | ||
| 				m.setkey(1);
 | ||
| 				m.zero();
 | ||
| 			}
 | ||
| 			if (do_movmag && num_movmag <= 0)
 | ||
|       {
 | ||
|         err = mov.write(m);
 | ||
|         if (err != NOERR)
 | ||
|           return err;
 | ||
|         num_movmag = mov.get_long(MOVMAG_NUMREG);
 | ||
|         myself.put(DOC_MOVMAG, num_movmag);
 | ||
|       }                          
 | ||
|       if (num_movmag > 0)
 | ||
|       {                                
 | ||
|         const bool scarica_residuo = tipo().scarica_residuo();
 | ||
|       
 | ||
|         mov.put(MOVMAG_NUMREG, num_movmag);   
 | ||
|         while (mov.read(m, _isequal, _testandlock) == _islocked)
 | ||
|           message_box("Movimento di magazzino n. %ld in uso da parte di un'altro utente", num_movmag);
 | ||
|         if (do_movmag)
 | ||
|         {
 | ||
|           TRecord_array & b = mov.body();
 | ||
|           const int mag_rows = mov.rows();
 | ||
|           int i;
 | ||
|           for (i = mag_rows; i > 0; i--)
 | ||
|           { 
 | ||
|             TRectype & r = b[i];
 | ||
|             if (r.get_char(RMOVMAG_TIPORIGA) == riga_dadocumento)
 | ||
|             {
 | ||
|               b.destroy_row(i);             
 | ||
|               if (b.exist(i + 1) &&
 | ||
|                   b[i + 1].get_char(RMOVMAG_TIPORIGA) == riga_automatica)
 | ||
|                 b.destroy_row(i + 1);             
 | ||
|             }
 | ||
|             else
 | ||
|               if (r.get_bool(RMOVMAG_ESPLOSA))
 | ||
|                 b.destroy_row(i);             
 | ||
|           }
 | ||
|           b.pack();
 | ||
|           
 | ||
|           const TDate d(get(DOC_DATADOC));
 | ||
|           TString4 codes; codes.format("%04d", mov.codice_esercizio(d));
 | ||
|           mov.put(MOVMAG_ANNOES, codes);
 | ||
|           mov.put(MOVMAG_DATAREG, d);
 | ||
|           mov.put(MOVMAG_DATACOMP, d);
 | ||
|           mov.put(MOVMAG_DOCPROVV, get(DOC_PROVV));
 | ||
|           mov.put(MOVMAG_ANNODOC, get(DOC_ANNO));       
 | ||
|           mov.put(MOVMAG_CODNUM, get(DOC_CODNUM));          
 | ||
|           long numdoc = get_long(DOC_NDOC);
 | ||
|           if (numdoc <= 0L)
 | ||
|             numdoc = myself.renum_ndoc(numdoc);
 | ||
|           
 | ||
|           mov.put(MOVMAG_NUMDOC, numdoc);     
 | ||
|           const long ex_numdoc = get_long(DOC_NUMDOCRIF);
 | ||
|           if (ex_numdoc == 0)
 | ||
|           {
 | ||
|             mov.put(MOVMAG_EXNUMDOC, numdoc);     
 | ||
|             mov.put(MOVMAG_EXDATADOC, d);     
 | ||
|           }
 | ||
|           else
 | ||
|           {
 | ||
|             mov.put(MOVMAG_EXNUMDOC, ex_numdoc);     
 | ||
|             const TDate ex_d(get("DATADOCRIF"));
 | ||
|             mov.put(MOVMAG_EXDATADOC, ex_d);     
 | ||
|           }
 | ||
|           mov.put(MOVMAG_CATVEN, get("CATVEN"));
 | ||
|           mov.put(MOVMAG_CODLIST, get("CODLIST"));
 | ||
|           mov.put(MOVMAG_CODCONT, get("CODCONT"));
 | ||
|           mov.put(MOVMAG_CODCAMP, get("CODCAMP"));
 | ||
|           mov.put(MOVMAG_CODCAUS, get("CAUSMAG")); 
 | ||
|           const TString4 codnum(numerazione());
 | ||
| 
 | ||
|           mov.put(MOVMAG_DESCR, format("%s %s n. %ld del %s", (const char *) tipo().get("S1"),(const char *)codnum, numdoc, (const char *) d.string()));
 | ||
|           mov.put(MOVMAG_TIPOCF, get("TIPOCF"));
 | ||
|           mov.put(MOVMAG_CODCF, get("CODCF"));
 | ||
| 					if (ini_get_bool(CONFIG_DITTA, "mg", "MOV_INDSPED"))
 | ||
| 						mov.put(MOVMAG_CODINDSP, get(DOC_CODINDSP));          
 | ||
| 
 | ||
|           int j = 1;
 | ||
|           real cambio = ZERO;
 | ||
| 
 | ||
|           if (get(DOC_CODVAL).not_empty())
 | ||
|             cambio = get_real(DOC_CAMBIO);
 | ||
|           if (cambio == ZERO)
 | ||
|             cambio = 1.0;
 | ||
| 					const TString8 cod_caus(mov.get(MOVMAG_CODCAUS));
 | ||
| 					const TCausale_magazzino & caus = cached_causale_magazzino(cod_caus);
 | ||
|           const bool esplodente = caus.esplodente();
 | ||
|           const bool scarica_alt = caus.scarica_alternativi();
 | ||
|           TString8 cod_caus_riga;
 | ||
|           TDistinta_tree dist;
 | ||
|           TCodice_articolo codart;
 | ||
| 					const int anno = get_int(DOC_ANNO);
 | ||
|       
 | ||
|           for (i = 1; i <= physical_rows(); i++)
 | ||
|           {            
 | ||
|             TRiga_documento & r = myself.row(i);
 | ||
|             const bool articolo = r.is_articolo();
 | ||
|             bool valid_row = articolo;
 | ||
| 
 | ||
|             cod_caus_riga = r.get(RDOC_CAUSMAG);
 | ||
|             if (articolo)
 | ||
| 	            codart = r.get(RDOC_CODARTMAG);
 | ||
| 						else
 | ||
| 						{
 | ||
|               codart = r.get(RDOC_CODART);
 | ||
| 	            if (codart.full() && (cod_caus_riga.full() ? cached_causale_magazzino(cod_caus_riga).esplodente() : esplodente))
 | ||
| 	              valid_row = dist.set_root(codart);
 | ||
| 						}
 | ||
|             if (valid_row)
 | ||
|             {                  
 | ||
|               long r_num = r.get_long(RDOC_MOVMAG);
 | ||
|               if (r_num == 0)
 | ||
|               {
 | ||
|                 r_num = num_movmag;
 | ||
|                 r.put(RDOC_MOVMAG, r_num);
 | ||
|               }
 | ||
|   
 | ||
|               real qta = scarica_residuo ? r.qtaresidua_mag(): r.quantita_mag();
 | ||
|     
 | ||
|               if (r_num == num_movmag && !qta.is_zero())
 | ||
|               {
 | ||
|                 TRectype & rm = mov.insert_row(j++);
 | ||
|               
 | ||
|                 mov.add_magc(r.get(RDOC_CODMAGC));
 | ||
|               
 | ||
|                 rm.put(RMOVMAG_IMPIANTO, r.get(RDOC_IMPIANTO));
 | ||
|                 rm.put(RMOVMAG_LINEA, r.get(RDOC_LINEA));
 | ||
| 								const TString8 codmag = r.get(RDOC_CODMAG);
 | ||
|                 rm.put(RMOVMAG_CODMAG, codmag);
 | ||
| 								if (articolo && (cod_caus_riga.full() ? cached_causale_magazzino(cod_caus_riga).scarica_alternativi() : scarica_alt))
 | ||
| 								{
 | ||
| 									const TRectype art = cache().get(LF_ANAMAG, codart);
 | ||
| 									const TString & alt = art.get(ANAMAG_CODARTALT);
 | ||
| 
 | ||
| 									if (alt.full())
 | ||
| 										codart = alt;
 | ||
| 								}
 | ||
|                 rm.put(RMOVMAG_CODART, codart);
 | ||
| 								const TString livello = r.get(RDOC_LIVELLO);
 | ||
|                 rm.put(RMOVMAG_LIVGIAC, livello);
 | ||
|                 rm.put(RMOVMAG_UM, r.get(RDOC_UMQTA));
 | ||
|               
 | ||
| 								if (diff_inv)
 | ||
| 									qta = doc_inventory_qta((cod_caus_riga.full() ? cached_causale_magazzino(cod_caus_riga) : caus), codart,
 | ||
| 																					codmag, livello, anno, qta);
 | ||
| 
 | ||
|                 rm.put(RMOVMAG_QUANT, qta);
 | ||
|     
 | ||
|                 TCurrency_documento prezzo(r.prezzo(true, FALSE), *this, true);
 | ||
|   
 | ||
|                 prezzo.change_to_firm_val();
 | ||
|                 rm.put(RMOVMAG_PREZZO, prezzo.get_num());
 | ||
|                 rm.put(RMOVMAG_CODCAUS, cod_caus_riga);
 | ||
|                 rm.put(RMOVMAG_TIPORIGA, (char) riga_dadocumento);   
 | ||
|               }
 | ||
| 							
 | ||
| 							if (main_app().has_module(LVAUT))
 | ||
| 							{
 | ||
| 								const TString & codcauslav = r.get(RDOC_CODAGG1);
 | ||
| 								const TRectype & caulav = cache().get("&LVCAU", codcauslav);
 | ||
| 								if (!caulav.empty())
 | ||
| 								{
 | ||
| 									if (!qta.is_zero() && (j > 1))
 | ||
| 									{
 | ||
| 										const TString & causcons = caulav.get("S2");
 | ||
| 									
 | ||
| 											if (causcons.full())
 | ||
| 											{
 | ||
| 												mov[LF_RMOVMAG][j - 1].put(RMOVMAG_CODCAUS, causcons);
 | ||
| 												mov[LF_RMOVMAG][j - 1].put(RMOVMAG_CODMAG, r.get(RDOC_CODMAGC));
 | ||
| 												mov.reset_magc(j - 1);
 | ||
| 											}
 | ||
| 											else
 | ||
| 											{
 | ||
| 												mov.destroy_row(--j, true);
 | ||
| 												mov.destroy_magc(j);
 | ||
| 											}
 | ||
| 									}
 | ||
| 		    
 | ||
| 									const real qtarit = r.get(RDOC_QTAGG1);
 | ||
| 									const TString & causrit = caulav.get("S1");
 | ||
| 
 | ||
| 									if (r_num == num_movmag && !qtarit.is_zero() && causrit.full())
 | ||
| 									{
 | ||
| 										TRectype & rm = mov.insert_row(j++);
 | ||
| 		              
 | ||
| 										mov.add_magc("");
 | ||
| 										rm.put(RMOVMAG_IMPIANTO, r.get(RDOC_IMPIANTO));
 | ||
| 										rm.put(RMOVMAG_LINEA, r.get(RDOC_LINEA));
 | ||
| 										rm.put(RMOVMAG_CODMAG, r.get(RDOC_CODMAG));
 | ||
| 										if (articolo && (causrit.full() ? cached_causale_magazzino(causrit).scarica_alternativi() : scarica_alt))
 | ||
| 										{
 | ||
| 											const TRectype art = cache().get(LF_ANAMAG, codart);
 | ||
| 											const TString & alt = art.get(ANAMAG_CODARTALT);
 | ||
| 
 | ||
| 											if (alt.full())
 | ||
| 												codart = alt;
 | ||
| 										}
 | ||
| 										rm.put(RMOVMAG_CODART, codart);
 | ||
| 										rm.put(RMOVMAG_LIVGIAC, r.get(RDOC_LIVELLO));
 | ||
| 										rm.put(RMOVMAG_UM, r.get(RDOC_UMQTA));
 | ||
| 										rm.put(RMOVMAG_QUANT, qtarit);
 | ||
| 										rm.put(RMOVMAG_CODCAUS, causrit);
 | ||
| 										rm.put(RMOVMAG_TIPORIGA, (char) riga_dadocumento);   
 | ||
| 									}
 | ||
| 								}
 | ||
| 							}
 | ||
| 						}
 | ||
| 
 | ||
| 						const TString & indetr = r.get(RDOC_TIPODET);
 | ||
| 
 | ||
| 						if (indetr.full())
 | ||
| 						{
 | ||
| 							const TRectype & det = cache().get("%DET", indetr);
 | ||
| 
 | ||
| 							if (!det.empty() && !det.get_bool("FPC"))
 | ||
| 							{
 | ||
| 								TTable tab("%DET");
 | ||
| 
 | ||
| 								tab.curr() = det;
 | ||
| 								tab.curr().put("FPC", "X");
 | ||
| 								tab.rewrite();
 | ||
| 							}
 | ||
| 						}
 | ||
| 
 | ||
|           }
 | ||
|           mov.rewrite(m);
 | ||
|         }
 | ||
|         else
 | ||
|         {
 | ||
|           mov.remove(m);
 | ||
|           for (int i = physical_rows(); i > 0; i--)
 | ||
|           {
 | ||
|             TRiga_documento & r = myself.row(i);
 | ||
|             r.zero(RDOC_MOVMAG);
 | ||
|           }
 | ||
|           myself.zero(DOC_MOVMAG);
 | ||
|         }
 | ||
|       } 
 | ||
|     }
 | ||
|   } 
 | ||
| 
 | ||
|   {
 | ||
|     TLocalisamfile anamag(LF_ANAMAG);
 | ||
|     TLocalisamfile codalt(LF_CODCORR);
 | ||
|     codalt.setkey(2);
 | ||
|     bool docevaso = true;
 | ||
|     const TDate datacons(get_date(DOC_DATACONS));
 | ||
|     const TString80 codcms(get(DOC_CODCMS));
 | ||
|     const TString80 fascms(get(DOC_FASCMS));
 | ||
|     const TString80 codcos(get(DOC_CODCOSTO));
 | ||
|     
 | ||
|     for (int i = physical_rows(); i > 0; i--)
 | ||
|     {
 | ||
|       TRiga_documento& r = myself.row(i);
 | ||
|       if ((r.is_merce() || r.is_omaggio()) && !r.is_checked())
 | ||
|       { 
 | ||
| 				if (r.get(RDOC_CODARTMAG) == NULL_CODART)
 | ||
| 					r.put(RDOC_CODARTMAG, "");
 | ||
| 				else
 | ||
| 				{
 | ||
| 					const TString & codart = r.get("CODART");
 | ||
| 					anamag.put("CODART", codart);
 | ||
| 					if (anamag.read() == NOERR)
 | ||
| 						r.put("CODARTMAG", codart);
 | ||
| 					 else
 | ||
| 					{
 | ||
| 						codalt.put("CODARTALT", codart);
 | ||
| 						if (codalt.read() == NOERR)
 | ||
| 							r.put("CODARTMAG", codalt.get("CODART"));
 | ||
| 					}
 | ||
| 					r.checked();
 | ||
| 				}
 | ||
|       }
 | ||
|       if (r.is_evadibile() && is_ordine())
 | ||
|       {
 | ||
|         docevaso &= r.is_evasa();
 | ||
|         const TDate dcons = r.get_date(RDOC_DATACONS);
 | ||
|         if (!dcons.ok())
 | ||
|           r.put(RDOC_DATACONS, datacons);
 | ||
|       }               
 | ||
|                         
 | ||
|       if (r.get(RDOC_CODCMS).blank() && r.get(RDOC_FASCMS).blank() && r.get(RDOC_CODCOSTO).blank())
 | ||
|       {
 | ||
|         r.put(RDOC_CODCMS, codcms);
 | ||
|         r.put(RDOC_FASCMS, fascms);
 | ||
|         r.put(RDOC_CODCOSTO, codcos);
 | ||
|       }
 | ||
|     }
 | ||
|     if (is_ordine())
 | ||
|       ((TDocumento *)this)->put(DOC_DOCEVASO, docevaso); // Tutte le righe evase   -> doc evaso
 | ||
|   }                            // Almeno una riga aperta -> doc aperto
 | ||
| 
 | ||
|   err = TMultiple_rectype::write_rewrite(f, re);
 | ||
|   
 | ||
|   if (!doc_bloccato && err == NOERR)
 | ||
|   {
 | ||
|     if (clifor().occasionale())
 | ||
|     {
 | ||
|       if (get("OCFPI").not_empty())
 | ||
|       {
 | ||
|         TLocalisamfile o(LF_OCCAS);
 | ||
|         TOccasionale & occ = occas();
 | ||
|         
 | ||
|         err = occ.write(o);
 | ||
|         if (err == _isreinsert)
 | ||
|           err = occ.rewrite(o);
 | ||
|       }
 | ||
|     }
 | ||
|     if (_has_provv && tipo().provvigioni() && tipo().stato_provvigioni() <= stato()) 
 | ||
| 			myself.update_provvigioni(false);
 | ||
|     if (tipo().statistiche() && _has_stat_ven)
 | ||
|     {
 | ||
|       TString80 key(get(DOC_PROVV)); key << get(DOC_ANNO); key << get(DOC_CODNUM); key << get(DOC_NDOC);
 | ||
|       TStats_agg * st_agg = (TStats_agg *) _docs_to_agg.objptr(key);
 | ||
|       const bool is_nota_credito = tipo().nota_credito();
 | ||
|      
 | ||
|       if (st_agg == NULL)       
 | ||
|       {
 | ||
|         st_agg = new TStats_agg;
 | ||
|         _docs_to_agg.add(key, st_agg, true);
 | ||
|       }
 | ||
|       int i;
 | ||
|       
 | ||
|       for (i = physical_rows(); i > 0; i--)
 | ||
|         if (is_nota_credito)
 | ||
|           st_agg->sub(myself.row(i));
 | ||
|         else
 | ||
|           st_agg->add(myself.row(i));
 | ||
|       st_agg->update();
 | ||
|       for (i = physical_rows(); i > 0; i--)
 | ||
|         if (is_nota_credito)
 | ||
|           st_agg->add(myself.row(i));
 | ||
|         else
 | ||
|           st_agg->sub(myself.row(i));
 | ||
|     }
 | ||
|   }
 | ||
|   return err;  
 | ||
| }
 | ||
|                     // eliminare anche il mov di mag. ??????
 | ||
| int TDocumento::remove(TBaseisamfile& f) const
 | ||
| {
 | ||
|   if (!cancellabile() && !yesno_box("Documento non cancellabile,\nContinuare ugualmente"))
 | ||
|     return NOERR;
 | ||
|   const bool check_movmag = dongle().active(MGAUT) && tipo().mov_mag();
 | ||
| 	const bool doc_bloccato = bloccato();
 | ||
|     
 | ||
|   if (check_movmag)
 | ||
|   {
 | ||
|     const long num = get_long("MOVMAG");            
 | ||
|   
 | ||
|     if (num > 0)
 | ||
|     {
 | ||
|       TMov_mag_doc mov;
 | ||
|       TLocalisamfile m(LF_MOVMAG);
 | ||
|       mov.put(MOVMAG_NUMREG, num);   
 | ||
|       while (mov.read(m, _isequal, _testandlock) == _islocked)
 | ||
|         message_box("Movimento di magazzino in uso da parte di un'altro utente");
 | ||
| 			if (doc_bloccato)
 | ||
| 			{
 | ||
| 				const int rows = mov.rows();
 | ||
| 
 | ||
| 				for (int i= 1; i <= rows; i++)
 | ||
| 					mov.body()[i].zero(RMOVMAG_TIPORIGA);
 | ||
| 				mov.rewrite(m);
 | ||
| 			}
 | ||
| 			else
 | ||
| 				mov.remove(m);
 | ||
|     }
 | ||
|   }
 | ||
| 	if (!doc_bloccato)
 | ||
| 	{
 | ||
| 		if (tipo().statistiche() && _has_stat_ven)
 | ||
| 		{
 | ||
| 			TString80 key(get(DOC_PROVV)); key << get(DOC_ANNO); key << get(DOC_CODNUM); key << get(DOC_NDOC);
 | ||
| 			TStats_agg * st_agg = (TStats_agg *) _docs_to_agg.objptr(key);
 | ||
|      
 | ||
| 			if (st_agg != NULL)
 | ||
| 			{
 | ||
| 				st_agg->update();
 | ||
| 				_docs_to_agg.remove(key);
 | ||
| 			}
 | ||
| 		}
 | ||
| 		if (_has_provv && tipo().provvigioni()) 
 | ||
| 		{
 | ||
| 		  TDocumento& myself = *((TDocumento *)this);
 | ||
| 
 | ||
| 			myself.update_provvigioni(true);
 | ||
| 		}
 | ||
| 	}
 | ||
|   return TMultiple_rectype::remove(f);
 | ||
| }
 | ||
| 
 | ||
| int TDocumento::decimals(bool price) const
 | ||
| {                               
 | ||
|   const TString4 codval(get(DOC_CODVAL));
 | ||
|   const TExchange exc(codval);
 | ||
|   const int ndec = exc.decimals(price);
 | ||
|   return ndec;
 | ||
| }
 | ||
| 
 | ||
| void TDocumento::flush_rows()
 | ||
| {
 | ||
|   remove_body(LF_RIGHEDOC);
 | ||
| }
 | ||
| 
 | ||
| void TDocumento::calc_provvigione(TProvvigioni_agente & provv, const TString & key, bool first, bool generata)
 | ||
| {
 | ||
|   const int  anno = TDocumento::anno();
 | ||
|   const TString4 codnum = numerazione();
 | ||
|   const long ndoc = numero();
 | ||
|   const TDate datadoc(data());
 | ||
| 
 | ||
|   while (provv.read(key, anno, codnum, ndoc) == _islocked) // Legge le provvigioni per questo documento
 | ||
|     if (!yesno_box("Dati agente %s in uso da un altro utente. Riprovare?", (const char *) key))
 | ||
|       return ;
 | ||
| 
 | ||
|   const real change(cambio());
 | ||
|   const real perc = provv.perc_fatt(); 
 | ||
|   TCurrency_documento  tot_doc(totale_doc(), *this);
 | ||
|   TCurrency_documento  tot_netto(totale_netto(), *this);
 | ||
|   TCurrency_documento  tot_provv(provvigione(first), *this);
 | ||
|   TCurrency_documento  provv_fat((tot_provv.get_num() / 100.0) * perc, *this); // Provvigione sul fatturato (rata 0)
 | ||
|   TCurrency_documento provv_pag = tot_provv - provv_fat;       // Provvigione sul pagato (da suddivere secondo il pagamento)
 | ||
|   const bool valuta = in_valuta();
 | ||
|               
 | ||
|   // Calcolo rate per provvigioni e documento
 | ||
|   TPagamento& pag1 = pagamento(); // Per rate documento
 | ||
|   TPagamento* pag2 = new TPagamento(pag1.code(), datadoc.string()); // Per rate documento
 | ||
|   
 | ||
|   // Rilegge il pagamento, nel caso in cui venga chiamata la scrittura del documento
 | ||
|   // corrente dopo che <20> stata effettuata una contabilizzazione; la contabilizzazione
 | ||
|   // nel caso di anticipo aggiunge una rata in pi<70>
 | ||
|   if (pag1.n_rate() > pag2->n_rate())
 | ||
|     pag1.read();
 | ||
|     
 | ||
|   TCurrency_documento totspese(spese(), *this);
 | ||
|   TCurrency_documento totimposte(imposta(), *this);
 | ||
|   TCurrency_documento totimponibili(tot_doc - totimposte - totspese);
 | ||
|   TCurrency_documento anticipo(get_real(DOC_IMPPAGATO), *this);
 | ||
|   
 | ||
|   if (is_nota_credito()) // Se il documento e' una nota di credito, cambia segno
 | ||
|   {                    
 | ||
|     tot_doc = -tot_doc;
 | ||
|     tot_netto = -tot_netto;
 | ||
|     tot_provv = -tot_provv;
 | ||
|     provv_fat = -provv_fat;
 | ||
|     provv_pag = -provv_pag;
 | ||
|     totspese = -totspese;
 | ||
|     totimposte = -totimposte;
 | ||
|     totimponibili = -totimponibili;
 | ||
|   }
 | ||
|   
 | ||
|   // Considera l'anticipo, come in contabilizzazione ed in generazione effetti
 | ||
|   //
 | ||
|   // Un anticipo su di una nota di credito non dovrebbe comunque mai esistere, non ha senso.
 | ||
|   // Se esiste <20> un errore in inserimento da parte del cliente.
 | ||
|   if (anticipo.get_num() < abs(tot_doc.get_num()))
 | ||
|   {
 | ||
|     TGeneric_distrib d(anticipo.get_num(), decimals());
 | ||
| 
 | ||
|     d.add(totimponibili.get_num());
 | ||
|     d.add(totimposte.get_num());
 | ||
|     d.add(totspese.get_num());
 | ||
|     
 | ||
|     const TCurrency_documento pagtotimponibili(totimponibili.get_num() - d.get(), *this);
 | ||
|     const TCurrency_documento pagtotimposte(totimposte.get_num() - d.get(), *this);
 | ||
|     const TCurrency_documento pagtotspese(totspese.get_num() - d.get(), *this);
 | ||
| 
 | ||
|     TCurrency zero(ZERO);
 | ||
|     if (valuta)
 | ||
|     {
 | ||
|       TCurrency_documento val2(pagtotimposte); val2.change_to_firm_val();
 | ||
|       TCurrency_documento val3(pagtotspese); val3.change_to_firm_val();
 | ||
|       TCurrency_documento val1(tot_doc); val1.change_to_firm_val(); val1 -= val2 - val3;
 | ||
|       pag1.set_total_valuta(pagtotimponibili, pagtotimposte, pagtotspese, val1, val2, val3);
 | ||
|       TCurrency_documento provv_pag_base(provv_pag) ; provv_pag_base.change_to_firm_val();
 | ||
|       pag2->set_total_valuta(provv_pag, zero, zero, provv_pag_base, zero, zero);
 | ||
|     }
 | ||
|     else
 | ||
|     {
 | ||
|       pag1.set_total(pagtotimponibili, pagtotimposte, pagtotspese);
 | ||
|       pag2->set_total(provv_pag, zero, zero);
 | ||
|     }
 | ||
|     pag1.set_rate_auto();
 | ||
|     pag2->set_rate_auto();
 | ||
|   }
 | ||
|   else
 | ||
|   {
 | ||
|     pag1.zap_rate();
 | ||
|     pag2->zap_rate();
 | ||
|   }
 | ||
|   
 | ||
|   const bool is_anticipo = anticipo.get_num() > ZERO;
 | ||
|   
 | ||
|   if (is_anticipo)
 | ||
|   {
 | ||
|     pag1.add_rata();
 | ||
|     TDate first_scad(pag1.data_rata(0));
 | ||
|         
 | ||
|     if (datadoc == first_scad)
 | ||
|       pag1.set_datarata(0, ++first_scad);
 | ||
|     for (int k=pag1.n_rate()-1; k>0; k--)
 | ||
|       pag1.rata(k) = pag1.rata(k-1);
 | ||
| 
 | ||
|     if (anticipo >= tot_doc)
 | ||
|       anticipo = tot_doc;
 | ||
| 
 | ||
|     TCurrency_documento anticipo_base(anticipo); anticipo_base.change_to_firm_val();
 | ||
|           
 | ||
|     pag1.set_rata(0, valuta ? anticipo.get_num() : ZERO, anticipo_base.get_num(), datadoc, 1, "", FALSE);
 | ||
|   }
 | ||
|     
 | ||
|   // Crea le nuove rate provvigionali
 | ||
|   const bool isnew = provv.items() == 0; // Il documento non ha righe provvigionali
 | ||
|   TRate_doc& rd = provv.rate(anno, codnum, ndoc, isnew ? true : FALSE);
 | ||
|   
 | ||
|   // A questo punto rd e' vuoto: settiamo i dati del documento:
 | ||
|   TToken_string t;
 | ||
|   t.add(anno); t.add(codnum);t.add(ndoc);
 | ||
|   t.add(datadoc.string()); t.add(tot_doc.string());
 | ||
|   t.add(tot_provv.string());t.add(tot_netto.string());
 | ||
|   t.add(codcf());
 | ||
|   t.add(TDocumento::valuta());t.add(change.string());
 | ||
|   t.add(get(DOC_DATACAMBIO));
 | ||
|   rd.set(t);
 | ||
|   
 | ||
|   // Adesso si possono aggiungere le rate (per quelle gia' esistenti sostituisce solo alcuni valori)
 | ||
|   // - Rata 0 : importo rata = 0; importo provvigione = provvigione all'atto della fattura (percentuale sugli agenti)
 | ||
|   //   data scadenza viene settata uguale alla data documento
 | ||
|   //   la provvigione rimanente va suddivisa in rate a seconda del codice pagamento
 | ||
|   // Nel caso si ha un anticipo documento, l'importo della rata non sar<61> 0 ma eguale all'anticipo stesso
 | ||
|   // Se poi abbiamo il caso in cui l'anticipo paga completamente il documento
 | ||
|   // non avremo alcuna rata e tutto l'importo della provvigione del doc. andr<64> comunque
 | ||
|   // sulla rata 0, anche se la provvigione sul fatturato <20> 0 (% a 0)
 | ||
|   
 | ||
|   const int nrate = pag1.n_rate();
 | ||
| 
 | ||
|   if (nrate == 1 && is_anticipo) // significa che l'anticipo paga tutto ora, quindi provv_fat vale tutta la provvigione del documento
 | ||
|     provv_fat = tot_provv;
 | ||
|   
 | ||
|   const bool first_rata_ok = provv_fat.get_num() != ZERO;
 | ||
|   
 | ||
|   // Impostazione prima rata solo se la provvigione sul fatturato <20> diversa da 0
 | ||
|   if (first_rata_ok)
 | ||
|   {    
 | ||
|     TRata& rt = rd.row(0,true);
 | ||
|     rt.set_rata(0);  rt.set_datascad(datadoc);  rt.set_tipopag(1);
 | ||
|     rt.set_imprata(anticipo.get_num());  rt.set_impprovv(provv_fat.get_num());
 | ||
|     rt.set_generata(generata);
 | ||
|   }
 | ||
|   
 | ||
|   // Setta le rate rimanenti
 | ||
|   int i;
 | ||
|   
 | ||
|   for (i = 1; i <= nrate; i++)
 | ||
|   {
 | ||
|     if (i == nrate && is_anticipo)
 | ||
|       break;
 | ||
|       
 | ||
|     const int index = is_anticipo ? i : i - 1;
 | ||
|     TRata& rt = rd.row(first_rata_ok ? i : i - 1, true);
 | ||
|     rt.set_rata(i);
 | ||
|     rt.set_datascad(pag1.data_rata(index));
 | ||
|     rt.set_tipopag(pag1.tipo_rata(index));
 | ||
|     rt.set_imprata(pag1.importo_rata(index,valuta ? true : FALSE));
 | ||
|     rt.set_impprovv(pag2->importo_rata(i-1,valuta ? true : FALSE));
 | ||
|     rt.set_generata(generata);
 | ||
|   }
 | ||
|   
 | ||
|   // Rimuove eventuali righe in eccesso
 | ||
|   const int rd_items = rd.items(); // Rate precedenti
 | ||
|   for (i = first_rata_ok ? nrate+1 : nrate; i < rd_items; i++)
 | ||
|     rd.remove_rata(i);
 | ||
|   delete pag2;
 | ||
| }
 | ||
| 
 | ||
| int TDocumento::update_provvigione(bool remove, const bool first)
 | ||
| {
 | ||
| 	TProvvigioni_agente provv;
 | ||
| 	const TString8 old = first ? _old_agente : _old_agente1;
 | ||
| 	const TString8 agente = first ? get(DOC_CODAG) : get(DOC_CODAGVIS);
 | ||
|   const int  anno = TDocumento::anno();
 | ||
|   const TString & codnum = numerazione();
 | ||
|   const long ndoc = numero();
 | ||
|   const TDate datadoc(data());
 | ||
| 	int err = NOERR;
 | ||
| 
 | ||
| 	if (remove || old != agente)
 | ||
| 	{
 | ||
| 		while (provv.read(old, anno, codnum, ndoc) == _islocked) // Legge le provvigioni per questo documento
 | ||
| 			if (!yesno_box("Dati agente %s in uso da un altro utente. Riprovare?", (const char *) old))
 | ||
| 				return err;
 | ||
| 		if (err != NOERR)
 | ||
| 			return err;
 | ||
| 		err = provv.remove();
 | ||
| 		if (remove)
 | ||
| 			return err;
 | ||
| 	}
 | ||
| 
 | ||
| 	if (agente.blank())
 | ||
| 		return NOERR;
 | ||
| 	calc_provvigione(provv, agente, first);
 | ||
| 	return provv.write();
 | ||
| }
 | ||
| 
 | ||
| int TDocumento::update_provvigioni(bool remove) 
 | ||
| { 
 | ||
| 	int err;
 | ||
| 	
 | ||
| 	if ((err = update_provvigione(remove)) == NOERR)
 | ||
| 		err = update_provvigione(remove, false);
 | ||
| 	return err;
 | ||
| }
 | ||
| 
 | ||
| bool TDocumento::in_valuta() const
 | ||
| {
 | ||
|   const TString& val = valuta();
 | ||
|   return is_true_value(val);
 | ||
| }
 | ||
| 
 | ||
| TCodgiac_livelli & TDocumento::livelli() const 
 | ||
| {
 | ||
|   if (_livelli == NULL) 
 | ||
|     _livelli = new TCodgiac_livelli();
 | ||
|   return *_livelli;
 | ||
| }
 | ||
| 
 | ||
| TRiga_documento & TDocumento::row(int index)
 | ||
| {                                   
 | ||
|   TRecord_array & b = body();
 | ||
|   const int nrows = b.last_row();
 | ||
|   TRiga_documento * r = NULL;
 | ||
|   
 | ||
|   if (index <= nrows)
 | ||
|   {
 | ||
| #ifdef DBG  	
 | ||
|   if (!b.exist(index))
 | ||
|   {
 | ||
|     const long ndoc = get_long(DOC_NDOC);
 | ||
|     const int anno = get_int(DOC_ANNO);
 | ||
|     const char* codnum = get(DOC_CODNUM);
 | ||
|     error_box("Riga documento %d non esistente nel documento %d %s %ld", index, anno, codnum, ndoc);
 | ||
|     insert_row(index, "05");
 | ||
|   }
 | ||
| #endif    
 | ||
|     r = &((TRiga_documento &) b.row(index, FALSE));
 | ||
|   }         
 | ||
|   else
 | ||
|   {                                           
 | ||
|     CHECKD((index == nrows + 1 && (_sconto != NULL || _esenzione != NULL)) ||    (index == nrows + 2 && _sconto != NULL && _esenzione != NULL),
 | ||
|            "Riga documento non esistente ", index);
 | ||
|     if (index == nrows + 1)
 | ||
|     {
 | ||
|       r = _sconto != NULL ? _sconto : _esenzione;
 | ||
|     } else
 | ||
|     if (index == nrows + 2)
 | ||
|       r = _esenzione;
 | ||
|   }       
 | ||
|   return *r;
 | ||
| }
 | ||
| 
 | ||
| const TRiga_documento& TDocumento::physical_row(int index) const 
 | ||
| {                                   
 | ||
|   TRecord_array & b = body();
 | ||
|   return (TRiga_documento&)b.row(index, FALSE);
 | ||
| }
 | ||
| 
 | ||
| long TDocumento::get_next_key(char provv, int anno, const char* codnum) const
 | ||
| {               
 | ||
|   long n = 0;
 | ||
|   
 | ||
|   TLocalisamfile doc(LF_DOC);
 | ||
|   TRectype& curr = doc.curr();
 | ||
|   set_key(curr, provv, anno, codnum, 9999999L);
 | ||
| 
 | ||
|   const int err = doc.read(_isgreat);
 | ||
|               
 | ||
|   if (err != _isemptyfile)
 | ||
|   {
 | ||
|     if (err == NOERR)
 | ||
|       doc.prev();
 | ||
|     if (curr.get_char("PROVV") == provv && 
 | ||
|         curr.get_int("ANNO") == anno && 
 | ||
|         curr.get("CODNUM") == codnum)
 | ||
|        n = curr.get_long("NDOC");
 | ||
|   }     
 | ||
|   
 | ||
|   n++;
 | ||
|   return n;   
 | ||
| }
 | ||
| 
 | ||
| const TTipo_documento& TDocumento::tipo() const
 | ||
| {
 | ||
|   TString4 tipodoc(get(DOC_TIPODOC));
 | ||
| #ifdef DBG
 | ||
|   if (tipodoc.blank())   // Test necessario per lavorare anche su dati rovinati
 | ||
|   {
 | ||
|     const TCodice_numerazione& codnum = codice_numerazione();
 | ||
|     tipodoc = codnum.tipo_doc(0);
 | ||
|     yesnofatal_box("Tipo documento nullo su %d %s %ld\nforzato a %s", 
 | ||
|                    get_int(DOC_ANNO), (const char*)get(DOC_CODNUM), get_long(DOC_NDOC), (const char*)tipodoc);
 | ||
|     ((TDocumento*)this)->set_tipo(tipodoc);
 | ||
|   }
 | ||
| #endif
 | ||
| 	return cached_tipodoc(tipodoc);
 | ||
| }  
 | ||
| 
 | ||
| const TCodice_numerazione& TDocumento::codice_numerazione(const char * numerazione)
 | ||
| {                         
 | ||
|   return cached_numerazione(numerazione);
 | ||
| }  
 | ||
| 
 | ||
| 
 | ||
| const TCodice_numerazione& TDocumento::codice_numerazione() const
 | ||
| {                         
 | ||
|   return cached_numerazione(numerazione());
 | ||
| }  
 | ||
| 
 | ||
| bool TDocumento::raggruppabile(const TDocumento& doc, TToken_string& campi) const
 | ||
| {                
 | ||
|   bool ok = raggruppabile() && doc.raggruppabile();
 | ||
|   if (ok)
 | ||
|   {
 | ||
|     TString campo;
 | ||
|     for (const char* c = campi.get(0); c && ok; c = campi.get())
 | ||
|     {
 | ||
|       if (strncmp(c, "CODABI", 6) == 0 || strncmp(c, "CODCAB", 6) == 0)
 | ||
| 			{
 | ||
| 				long cod = get_long(c);
 | ||
| 				ok &= (cod == doc.get_long(c));
 | ||
| 			}
 | ||
| 			else
 | ||
| 			{
 | ||
| 				campo = get(c);
 | ||
| 				ok &= campo == doc.get(c);
 | ||
| 			}
 | ||
|     }
 | ||
|   }  
 | ||
|   return ok;
 | ||
| } 
 | ||
| 
 | ||
| void TDocumento::set_fields(TAuto_variable_rectype & rec)
 | ||
| {                                                        
 | ||
|   if (tipo_valido())
 | ||
|   {          
 | ||
|     TTipo_documento& tipo_doc = (TTipo_documento&)tipo(); // first_formula() is NOT const
 | ||
|     const TString& tot_doc = tipo_doc.totale_doc();
 | ||
|     
 | ||
|     for (const TFormula_documento* f = tipo_doc.first_formula(); f; f = tipo_doc.succ_formula())
 | ||
|     {     
 | ||
|       TExpr_documento* exp = f->expr(); 
 | ||
|       if (exp != NULL) // Puo' succedere che sia NULL con dati incoerenti
 | ||
|       {
 | ||
|         if (tot_doc == f->name())
 | ||
|         {   
 | ||
|           TString16 tot_doc_netto(tot_doc);
 | ||
|           tot_doc_netto.insert("_");                          
 | ||
| 
 | ||
|           const TFixed_string netto_def(exp->string());              
 | ||
|           TExpr_documento netto_exp(netto_def, _numexpr, this);
 | ||
|                                            
 | ||
|           add_field(new TDocumento_variable_field(tot_doc_netto, netto_exp));
 | ||
|         
 | ||
|           if (netto_def == "IMPONIBILI()+IMPOSTE()")
 | ||
|           {
 | ||
|             TExpr_documento tot_exp("IMPONIBILI(1)+IMPOSTE(1)", _numexpr, this);
 | ||
|             add_field(new TDocumento_variable_field(tot_doc, tot_exp));
 | ||
|           }
 | ||
|           else
 | ||
|           {
 | ||
|             TExpr_documento tot_exp(format("%s + _BOLLI(%s)", (const char *) tot_doc_netto,
 | ||
|                                            (const char*)tot_doc_netto), _numexpr, this);
 | ||
|             add_field(new TDocumento_variable_field(tot_doc, tot_exp));
 | ||
|           }
 | ||
|         }
 | ||
|         else
 | ||
|         {
 | ||
|           exp->set_doc(this);     
 | ||
|           add_field(new TDocumento_variable_field(f->name(), *exp));
 | ||
|         }
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
| 		for (TVariable_field* src_field = rec.first_variable_field();
 | ||
| 				 src_field != NULL; src_field = rec.succ_variable_field()) 
 | ||
| 		{
 | ||
| 			const char* fieldname = src_field->name();
 | ||
| 			if (src_field->expression() == NULL)
 | ||
| 				put(fieldname, rec.get(fieldname));
 | ||
| 		}
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| real TDocumento::imponibile(bool spese, int ndec) const
 | ||
| {
 | ||
|   real val;                      
 | ||
|   if (physical_rows() > 0)
 | ||
|   {
 | ||
|     TAssoc_array& table = ((TDocumento*)this)->tabella_iva();
 | ||
|     table.restart();
 | ||
|     for (TRiepilogo_iva* ri = (TRiepilogo_iva*)table.get(); ri != NULL; ri = (TRiepilogo_iva*)table.get())
 | ||
|       val +=  ri->imponibile(spese);
 | ||
|     if (ndec == AUTO_DECIMALS)
 | ||
|       ndec = decimals();
 | ||
|     val.round(ndec);
 | ||
|   }
 | ||
|   return val;
 | ||
| }
 | ||
| 
 | ||
| void TDocumento::calc_iva_fattura_commerciale()
 | ||
| {
 | ||
|   // Calcolo iva per fatture commerciali:
 | ||
|   // 1) effettua la sommatoria di tutti i real per ogni elementi di _tabella_iva in un TRiepilogo_iva unico
 | ||
|   // 2) azzera _tabella_iva
 | ||
|   // 3) scorpora in % a seconda di cio' che e' indicato in configurazione, e mette i nuovi elementi in _tabella_iva
 | ||
|   // 4) per ogni nuovo elemento di _tabella_iva, ricalcola la relativa imposta.
 | ||
|   TAssoc_array & table = _tabella_iva;
 | ||
|   TRiepilogo_iva t;
 | ||
|   static TString_array tabella_ripartizione;
 | ||
|   const int ndec = decimals();
 | ||
|   
 | ||
|   if (tabella_ripartizione.items() == 0)
 | ||
|   {
 | ||
|     TConfig cnf(CONFIG_STUDIO, "ve");
 | ||
|     for (int k = 1; k <= MAX_IVA_SLICES; k++)
 | ||
|     { 
 | ||
|       TToken_string* tt = new TToken_string();
 | ||
|       tt->add(cnf.get("EXCLUDE_PERC", NULL, k));
 | ||
|       tt->add(cnf.get("EXCLUDE_IVA", NULL, k));
 | ||
|       tabella_ripartizione.add(tt);
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   // 1)
 | ||
|   table.restart();
 | ||
|   for (TRiepilogo_iva * ri = (TRiepilogo_iva *) table.get(); ri != NULL;
 | ||
|        ri = (TRiepilogo_iva *) table.get())
 | ||
|   {
 | ||
|     t.imp()           += ri->imp();
 | ||
|     t.imp_spese()     += ri->imp_spese();
 | ||
|     t.imp_spese_row() += ri->imp_spese_row();
 | ||
|     t.iva_spese()     += ri->iva_spese();
 | ||
|     t.iva_sconto()    += ri->iva_sconto();
 | ||
|     t.sconto_perc()   += ri->sconto_perc();
 | ||
|     t.sconto_imp()    += ri->sconto_imp();
 | ||
|   }
 | ||
|   // 2)
 | ||
|   table.destroy();
 | ||
|     
 | ||
|   // 3)
 | ||
|   TArray tda;
 | ||
|     
 | ||
|   tda.add(new TDistrib(t.imp(), ndec));
 | ||
|   tda.add(new TDistrib(t.imp_spese(), ndec));
 | ||
|   tda.add(new TDistrib(t.imp_spese_row(), ndec));
 | ||
|   tda.add(new TDistrib(t.iva_spese(), ndec));
 | ||
|   tda.add(new TDistrib(t.iva_sconto(), ndec));
 | ||
|   tda.add(new TDistrib(t.sconto_perc(), ndec));
 | ||
|   tda.add(new TDistrib(t.sconto_imp(), ndec));
 | ||
|   
 | ||
|   int k;
 | ||
|     
 | ||
|   for (k = 0; k < MAX_IVA_SLICES; k++)
 | ||
|     for (int j = 0; j < 7; j++)
 | ||
|     {
 | ||
|       const real p (tabella_ripartizione.row(k).get(0));
 | ||
|       TDistrib& td = (TDistrib&) tda[j];
 | ||
|       td.add(p);
 | ||
|     }
 | ||
| 
 | ||
|   // 4)
 | ||
|   for (k = 0; k < MAX_IVA_SLICES; k++)
 | ||
|   {
 | ||
|     TString16 cod(tabella_ripartizione.row(k).get(1));
 | ||
|     cod.trim();
 | ||
|     
 | ||
|     if (cod.empty())
 | ||
|       continue;
 | ||
|         
 | ||
|     const TCodiceIVA civa(cod);
 | ||
|     TRiepilogo_iva * rp = (TRiepilogo_iva *) table.objptr(cod);
 | ||
|     if (rp == NULL)
 | ||
|     {
 | ||
|       rp = new TRiepilogo_iva(civa);
 | ||
|       table.add(cod, rp); 
 | ||
|     }
 | ||
|       
 | ||
|     for (int j = 0; j < 7; j++)
 | ||
|     {
 | ||
|       TDistrib& td  = (TDistrib&) tda[j];
 | ||
|       const real rr = td.get();
 | ||
|         
 | ||
|       switch (j)
 | ||
|       {
 | ||
|       case 0:
 | ||
|         rp->imp() = rr;
 | ||
|         rp->iva() = civa.imposta(rr, ndec);
 | ||
|         break;
 | ||
|       case 1:
 | ||
|         rp->imp_spese() = rr;
 | ||
|         break;
 | ||
|       case 2:
 | ||
|         rp->imp_spese_row() = rr;
 | ||
|         break;
 | ||
|       case 3:
 | ||
|         rp->iva_spese() = rr;
 | ||
|         break;
 | ||
|       case 4:
 | ||
|         rp->iva_sconto() = rr;
 | ||
|         break;
 | ||
|       case 5:
 | ||
|         rp->sconto_perc() = rr;
 | ||
|         break;
 | ||
|       case 6:
 | ||
|         rp->sconto_imp() = rr;
 | ||
|         break;
 | ||
|       default: 
 | ||
|         break;
 | ||
|       }        
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| void TDocumento::update_tabella_iva(bool solo_imponibili)
 | ||
| {
 | ||
| 	static bool __solo_imponibili = false;
 | ||
|   const int items = rows();
 | ||
|   TAssoc_array & table = _tabella_iva;
 | ||
| 
 | ||
|   if (items == 0)
 | ||
| 	{
 | ||
| 	  table.destroy();
 | ||
|     return;                  
 | ||
| 	}
 | ||
| 	if (__solo_imponibili != solo_imponibili)
 | ||
| 	{
 | ||
| 		table.destroy();
 | ||
| 		__solo_imponibili = solo_imponibili;
 | ||
| 	}
 | ||
| 
 | ||
|   if (table.items() > 0)
 | ||
|   {
 | ||
|     if (items == 0)
 | ||
|       table.destroy();
 | ||
|     return;                  
 | ||
|   }
 | ||
| 
 | ||
|   const bool doc_al_lordo = tipo().calcolo_lordo();
 | ||
|   const int ndec = decimals();
 | ||
| 
 | ||
|   const TRecord_array& righe = body(LF_RIGHEDOC);
 | ||
|   
 | ||
|   for (int j = righe.last_row(); j > 0; j = righe.pred_row(j))
 | ||
|   {
 | ||
|     const TRiga_documento& r = row(j);
 | ||
|     
 | ||
|     if (!r.is_sconto() && !r.is_descrizione())
 | ||
|     {
 | ||
|       const TCodiceIVA & iva = r.iva(); 
 | ||
|       if (iva.ok())
 | ||
|       {
 | ||
| 				const TString & cod = iva.codice();
 | ||
|         TRiepilogo_iva* aliquota = (TRiepilogo_iva*)table.objptr(cod);
 | ||
|         if (aliquota == NULL)
 | ||
|         {
 | ||
|           aliquota = new TRiepilogo_iva(iva);
 | ||
|           table.add(cod, aliquota); 
 | ||
|         }
 | ||
| 				const real imponibile = doc_al_lordo ? r.importo(true, true, ndec) : r.imponibile();
 | ||
|     		aliquota->imp_orig() += imponibile;
 | ||
| 			}
 | ||
|     }
 | ||
| 	}
 | ||
| 
 | ||
| 	if (solo_imponibili)
 | ||
| 		return;
 | ||
| 
 | ||
|   real tot_doc;
 | ||
|   real tot_sconti;
 | ||
|   real tot_sconti_perc;
 | ||
| 	TArray imponibili;
 | ||
|   const bool fatt_comm = tipo().fattura_commerciale();
 | ||
|  
 | ||
|   TString4 codiva_es;               
 | ||
| 
 | ||
|   iva_esente(codiva_es);                       
 | ||
|   for (int i = items; i > 0; i--)
 | ||
|   {
 | ||
|     const TRiga_documento& r = row(i);
 | ||
| 		const real imponibile = doc_al_lordo ? r.importo(true, true, ndec) : r.imponibile();
 | ||
| 
 | ||
| 	  tot_doc += imponibile;
 | ||
| 		if (r.is_sconto())         
 | ||
|     {
 | ||
|       tot_sconti += imponibile;    
 | ||
|       if (r.is_sconto_perc())
 | ||
|         tot_sconti_perc += imponibile;
 | ||
|     }
 | ||
|     else
 | ||
|       if (!r.is_descrizione())
 | ||
|       {
 | ||
|         const real imposta = doc_al_lordo ? ZERO :r.imposta(FALSE);
 | ||
| // Aggiorna o aggiunge l'elemento se non esiste    
 | ||
|         const TCodiceIVA & iva = r.iva(); 
 | ||
|         
 | ||
|         if (iva.ok())
 | ||
|         {
 | ||
| 	        const TString & cod = iva.codice();
 | ||
| 
 | ||
|           TRiepilogo_iva* aliquota = (TRiepilogo_iva *) table.objptr(cod);
 | ||
|           if (aliquota == NULL)
 | ||
|           {
 | ||
|             aliquota = new TRiepilogo_iva(iva);
 | ||
|             table.add(cod, aliquota); 
 | ||
| 	        }
 | ||
| 	
 | ||
|           aliquota->imp() += imponibile;
 | ||
|           if (r.is_spese() && iva.tipo().not_empty())
 | ||
|             aliquota->imp_spese_row() += imponibile;
 | ||
|           aliquota->iva() += imposta;
 | ||
|         }  
 | ||
|         tot_doc += imposta;
 | ||
|       }
 | ||
|   }  
 | ||
|   
 | ||
|   if (table.items() == 0)
 | ||
|     return;
 | ||
|     
 | ||
|   if (tot_sconti != ZERO)
 | ||
|   {
 | ||
|     TGeneric_distrib d(tot_sconti, ndec);
 | ||
|     real tot_sconti_imp = tot_sconti - tot_sconti_perc;
 | ||
|     
 | ||
|     if (!table.empty())
 | ||
| 		{
 | ||
| 			FOR_EACH_ASSOC_OBJECT(table, obj, key, o)
 | ||
| 			{
 | ||
| 				TRiepilogo_iva * aliquota = (TRiepilogo_iva *) o;
 | ||
| 
 | ||
| 				d.add(aliquota->imp() - aliquota->imp_spese_row());
 | ||
| 			}
 | ||
| 		}
 | ||
|   
 | ||
| 		FOR_EACH_ASSOC_OBJECT(table, obj, key, o)
 | ||
|     {     
 | ||
| 			TRiepilogo_iva * aliquota = (TRiepilogo_iva *) o;
 | ||
|       const TCodiceIVA & ci = aliquota->cod_iva();    
 | ||
|       const real i(d.get());
 | ||
|       real & imponibile = aliquota->imp();
 | ||
| 
 | ||
|       imponibile += i;
 | ||
|       
 | ||
|       TGeneric_distrib s(i, ndec);
 | ||
|       
 | ||
|       s.add(tot_sconti_imp);
 | ||
|       s.add(tot_sconti_perc);
 | ||
|       
 | ||
|       aliquota->sconto_imp() = s.get();
 | ||
|       aliquota->sconto_perc() = s.get(); 
 | ||
|       
 | ||
|       real & iva = aliquota->iva();   
 | ||
|       
 | ||
| /*      if (doc_al_lordo)
 | ||
|       {
 | ||
|         const real imposta(ci.imposta(i, ndec));
 | ||
| 
 | ||
|         TGeneric_distrib iva(imposta, ndec);
 | ||
|         iva.add(tot_sconti_imp);
 | ||
|         iva.add(tot_sconti_perc);
 | ||
|       
 | ||
|         imponibile += imposta;
 | ||
|         aliquota->sconto_imp() += iva.get();
 | ||
|         aliquota->sconto_perc() += iva.get(); 
 | ||
| 
 | ||
|         tot_doc += imposta;
 | ||
|       }
 | ||
|       else */
 | ||
|       if (!doc_al_lordo)
 | ||
|       {
 | ||
|         const real imposta(ci.imposta(i, ndec));
 | ||
|   
 | ||
|         iva += imposta;
 | ||
|         aliquota->iva_sconto() = imposta;
 | ||
|         tot_doc += imposta;
 | ||
|       } 
 | ||
|     }
 | ||
|   }
 | ||
|                 
 | ||
|   if (fatt_comm)
 | ||
|     calc_iva_fattura_commerciale();
 | ||
| 
 | ||
|   const real rit = ritenute();
 | ||
|   real val = spese_incasso(real(tot_doc - rit), ALL_DECIMALS, doc_al_lordo ? _lordo : _netto);
 | ||
|   
 | ||
|   if (!val.is_zero())
 | ||
|   {
 | ||
|     const TString& codiva = codiva_es.full() ? (const TString &) codiva_es : codiva_spese();
 | ||
|     TRiepilogo_iva* ri = (TRiepilogo_iva*)table.objptr(codiva);
 | ||
|     if (ri == NULL && codiva.full())
 | ||
|     {
 | ||
|       ri = new TRiepilogo_iva(TCodiceIVA(codiva));
 | ||
|       table.add(codiva, ri);
 | ||
|     }
 | ||
|     if (ri != NULL)  
 | ||
|       ri->imp_spese() += val;
 | ||
|     tot_doc += val;
 | ||
|     
 | ||
|     if (!doc_al_lordo)
 | ||
|     {
 | ||
|       val = spese_incasso(real(tot_doc - rit), ALL_DECIMALS, _imposta);
 | ||
|       if (ri != NULL)  
 | ||
|         ri->iva_spese() += val;
 | ||
|       tot_doc += val;
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
| 	val = bolli(real(tot_doc - rit), ALL_DECIMALS, doc_al_lordo ? _lordo : _netto);
 | ||
|   if (val != ZERO)
 | ||
|   {
 | ||
|     const TString& codiva = codiva_bolli();
 | ||
|     if (codiva.full())
 | ||
|     {
 | ||
|       TRiepilogo_iva* ri = (TRiepilogo_iva*)table.objptr(codiva);
 | ||
|       if (ri == NULL)
 | ||
|       {
 | ||
|         ri = new TRiepilogo_iva(TCodiceIVA(codiva));
 | ||
|         table.add(codiva, ri);
 | ||
|       }
 | ||
|       if (!doc_al_lordo)
 | ||
|       {
 | ||
|         real valiva = bolli(real(tot_doc - rit), ALL_DECIMALS, _imposta);
 | ||
|         ri->iva_spese() += valiva;
 | ||
|         tot_doc += valiva;
 | ||
|       }
 | ||
|       ri->imp_spese() += val;
 | ||
|     }
 | ||
| 
 | ||
|     tot_doc += val;
 | ||
|   }                       
 | ||
|   
 | ||
| // SCORPORO
 | ||
|   if (doc_al_lordo)
 | ||
|   {
 | ||
| 		FOR_EACH_ASSOC_OBJECT(table, obj, key, o)
 | ||
|     {     
 | ||
|       TRiepilogo_iva * aliquota = (TRiepilogo_iva*) o;
 | ||
|       const TCodiceIVA& iva = aliquota->cod_iva();
 | ||
| 
 | ||
|       aliquota->iva() = iva.scorpora(aliquota->imp(), ndec);    
 | ||
|       aliquota->iva_spese() = iva.scorpora(aliquota->imp_spese(), ndec);
 | ||
|       iva.scorpora(aliquota->imp_spese_row(), ndec);
 | ||
| 
 | ||
|       aliquota->iva_sconto() = iva.scorpora(aliquota->sconto_imp(), ndec);
 | ||
|       aliquota->iva_sconto() += iva.scorpora(aliquota->sconto_perc(), ndec);
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| real TDocumento::imposta(bool spese, int ndec) const
 | ||
| {                       
 | ||
|   real val = ZERO;     
 | ||
|   if (physical_rows() > 0)
 | ||
|   {
 | ||
|     TAssoc_array& table = ((TDocumento*)this)->tabella_iva();
 | ||
|   
 | ||
|     if (ndec == AUTO_DECIMALS)
 | ||
|       ndec = decimals();
 | ||
|   
 | ||
|     for (TRiepilogo_iva * ri = (TRiepilogo_iva *) table.get(); ri != NULL;
 | ||
|          ri = (TRiepilogo_iva *) table.get())
 | ||
|     {    
 | ||
|       real iva = ri->imposta(spese);
 | ||
| 
 | ||
|       if (ndec == 0)
 | ||
|       {
 | ||
|         if (iva < ZERO)
 | ||
|           iva.floor(ndec);
 | ||
|         else               
 | ||
|           iva.ceil(ndec);
 | ||
|       }
 | ||
|       else
 | ||
|         iva.round(ndec);
 | ||
|       val += iva;
 | ||
|     }
 | ||
|   }
 | ||
|   return val;
 | ||
| }
 | ||
| 
 | ||
| real TDocumento::totale_doc() const
 | ||
| {
 | ||
| /*  A pag.1 c'e' scritto di non fare cosi'
 | ||
|   const TString16 field(tipo().totale_doc());
 | ||
| 
 | ||
|   if (field.not_empty())
 | ||
|     return get_real(field);
 | ||
|   else
 | ||
|   {
 | ||
|     real r = imponibile() + imposta();
 | ||
|     const int ndec = decimals();
 | ||
|     
 | ||
|     r += spese_incasso(r - ritenute()), ndec);
 | ||
|     r += bolli(real(r - ritenute()), ndec);
 | ||
|     return r;
 | ||
|   }
 | ||
| */
 | ||
|   // Cosi' e' piu' ordinato, strutturato e veloce  
 | ||
|   real r;
 | ||
|   const TString& field = tipo().totale_doc();
 | ||
|   if (field.blank())
 | ||
|   {
 | ||
|     const int ndec = decimals();
 | ||
| 		const bool lordo = tipo().calcolo_lordo();
 | ||
| 
 | ||
|     r = imponibile(lordo);
 | ||
| 		if (!lordo)
 | ||
| 			r += imposta();
 | ||
|     r += spese_incasso(real(r - ritenute()), ndec);
 | ||
|     r += bolli(real(r - ritenute()), ndec);
 | ||
|   }
 | ||
|   else
 | ||
|     r = get_real(field);
 | ||
| 
 | ||
|   return r;
 | ||
| }
 | ||
| 
 | ||
| real TDocumento::totale_netto() const
 | ||
| {
 | ||
|   const TString& field = tipo().totale_netto();
 | ||
|   if (field.not_empty())
 | ||
|     return get_real(field);
 | ||
|   else
 | ||
|     return imponibile() + imposta();
 | ||
| }
 | ||
| 
 | ||
| real TDocumento::basesconto() const
 | ||
| {
 | ||
|   const TString& field = tipo().basesconto();
 | ||
| 
 | ||
|   if (field.not_empty())
 | ||
|     return get_real(field);
 | ||
|   else
 | ||
|     return ZERO;
 | ||
| }
 | ||
| 
 | ||
| real TDocumento::spese() const
 | ||
| {
 | ||
|   const TString& field = tipo().spese();
 | ||
|   return field.not_empty() ? get_real(field) : ZERO;
 | ||
| }
 | ||
| 
 | ||
| real TDocumento::ritenute(const char tipo, bool lordo, int ndec) const
 | ||
| {
 | ||
|   real val;
 | ||
|   for (int i = rows() ; i > 0; i--)
 | ||
|   {
 | ||
|     const TRiga_documento& r = operator[](i);
 | ||
|     val += r.ritenuta(tipo, lordo, ndec);
 | ||
| 	}
 | ||
| 	return val;
 | ||
| }
 | ||
| 
 | ||
| TPagamento& TDocumento::pagamento()
 | ||
| { 
 | ||
|   const char tipocf = get_char(DOC_TIPOCF);
 | ||
|   const long codcf = get_long(DOC_CODCF);
 | ||
|   _pag.set_clifo(codcf, tipocf);
 | ||
| 
 | ||
|   TDate data_in = get_date(DOC_DATAINSC);
 | ||
|   if (data_in.empty())     
 | ||
|     data_in = get_date(DOC_DATADOC);
 | ||
| 
 | ||
|   const TString8 codpag(get(DOC_CODPAG));
 | ||
|   if (codpag != _pag.code())
 | ||
|   {                        
 | ||
|     _pag.set_code(codpag);
 | ||
|     _pag.read();
 | ||
|     _pag.set_inizio(data_in); // Perche' rispetta rate true?
 | ||
|   }
 | ||
|   else
 | ||
|   {
 | ||
|     if (data_in != _pag.get_datadoc())
 | ||
|       _pag.set_inizio(data_in); // Perche' rispetta rate true?
 | ||
|   }    
 | ||
| 
 | ||
|   return _pag;                                                        
 | ||
| }                                   
 | ||
| 
 | ||
| real TDocumento::provvigione(bool first, int ndec) const
 | ||
| { 
 | ||
|   TString16 field = agente(first).campoprovv();
 | ||
|   if (field.empty())
 | ||
| 		field = first ? tipo().totprovv() : tipo().totprovv1();
 | ||
| 
 | ||
|   real val;     
 | ||
|   if (field.not_empty())
 | ||
|     val = get_real(field);
 | ||
|   else
 | ||
|   {
 | ||
|     if (ndec == AUTO_DECIMALS)
 | ||
|       ndec = decimals();
 | ||
|     for (int i = physical_rows(); i > 0; i--)
 | ||
|       val += physical_row(i).provvigione(first, ndec);
 | ||
|   }
 | ||
|   return val;
 | ||
| }
 | ||
| 
 | ||
| real TDocumento::valore(bool totale, bool lordo, int ndec) const
 | ||
| {
 | ||
|   real val;
 | ||
|   TDocumento& doc = *(TDocumento*)this;
 | ||
|   FOR_EACH_PHYSICAL_RDOC_BACK(doc, i, r)
 | ||
|   {
 | ||
|     const char t = r->tipo().tipo();
 | ||
|     if (strchr("MSPRA", t) != NULL) // Merce, Spese, Prestazioni, Risorse, Attrezzature
 | ||
|       val += r->valore(totale, lordo, ndec); 
 | ||
|   }
 | ||
|   return val;
 | ||
| }  
 | ||
| 
 | ||
| void TDocumento::put_str(const char* fieldname, const char* val)
 | ||
| {          
 | ||
|   if (strcmp(fieldname, DOC_TIPODOC) == 0)                             
 | ||
|   {                       
 | ||
|     const TString4 v(val);
 | ||
|     if (TRectype::get(DOC_TIPODOC) != v)
 | ||
|     {
 | ||
|       TAuto_variable_rectype::put_str(fieldname, v);
 | ||
|       reset_fields(*this);
 | ||
|       set_fields(*this);
 | ||
|     }
 | ||
|     else
 | ||
|       dirty_fields();                                
 | ||
|   }
 | ||
|   else
 | ||
|     if (strcmp(fieldname, DOC_CODCF) == 0)        
 | ||
|     {
 | ||
|       const TString8 v(val);
 | ||
|       put(DOC_SPESEUPD, TRectype::get(DOC_CODCF) == v);
 | ||
|       TAuto_variable_rectype::put_str(fieldname, v);
 | ||
|       dirty_fields();                                
 | ||
|     }
 | ||
|     else
 | ||
|     {
 | ||
|       TAuto_variable_rectype::put_str(fieldname, val);
 | ||
|       dirty_fields();                                
 | ||
|       if (strcmp(fieldname, DOC_SCONTOPERC) == 0) 
 | ||
|         set_riga_sconto();
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| const TString& TDocumento::get_str(const char* fieldname) const
 | ||
| {
 | ||
|   if (_dirty_deny && variable_field(fieldname) != NULL)
 | ||
|     (bool&) _dirty_deny = false;
 | ||
|   
 | ||
|   return TMultiple_rectype::get_str(fieldname);
 | ||
| }
 | ||
| 
 | ||
| void TDocumento::zero(const char * fieldname)
 | ||
| {
 | ||
|   if (strcmp(fieldname, DOC_TIPODOC) == 0)
 | ||
|     reset_fields(*this);
 | ||
|   TAuto_variable_rectype::zero(fieldname);
 | ||
|   dirty_fields();
 | ||
| }
 | ||
| 
 | ||
| TCli_for& TDocumento::clifor(bool force_reload) const
 | ||
| { 
 | ||
|   const char tipo = tipocf();
 | ||
|   const long codice = codcf();
 | ||
|   TCli_for& cf = (TCli_for&)_cli_for;
 | ||
|   if (force_reload || cf.empty() || cf.tipo() != tipo || cf.codice() != codice)
 | ||
|     cf.read(tipo, codice);
 | ||
|   return cf;
 | ||
| }
 | ||
| 
 | ||
| TOccasionale& TDocumento::occas() const
 | ||
| {
 | ||
|   const TString16 occ_code = cod_occas(); // Codice occasionale in testata
 | ||
| 
 | ||
|   if (occ_code != _occas.codice())
 | ||
|   { 
 | ||
| /* Antidiluvian mode
 | ||
|     TLocalisamfile o(LF_OCCAS);
 | ||
|     ((TDocumento *) this)->_occas.zero();
 | ||
|     ((TDocumento *) this)->_occas.put(OCC_CFPI, occ_code);
 | ||
|     TRectype oc(_occas);
 | ||
|     if (((TDocumento *) this)->_occas.read(o) != NOERR)
 | ||
|       ((TDocumento *) this)->_occas = oc;
 | ||
| */
 | ||
|     // Postdiluvian mode
 | ||
|     TRectype& o = (TRectype&)_occas;     // Inganna const (una volta sola, non 4)
 | ||
|     o = cache().get(LF_OCCAS, occ_code); // Ricerca tramite cache
 | ||
|     if (o.empty())                       // Occasionale cancellato per errore
 | ||
|       o.put(OCC_CFPI, occ_code);         // Ripristina almeno il codice
 | ||
|   }
 | ||
|   return (TOccasionale&)_occas;
 | ||
| }
 | ||
|                                         
 | ||
| const TAgente & TDocumento::agente(bool first) const
 | ||
| {        
 | ||
| 	if (_agenti == NULL)
 | ||
| 		_agenti = new TAgenti_cache;
 | ||
| 	return _agenti->agente(first ? get(DOC_CODAG) : get(DOC_CODAGVIS));
 | ||
| }                                     
 | ||
| 
 | ||
| TDocumento & TDocumento::copy(const TDocumento & d) 
 | ||
| {                                
 | ||
|   TMultiple_rectype::operator=((TMultiple_rectype &)d); 
 | ||
|     reset_fields(*this);
 | ||
| 	set_fields((TAuto_variable_rectype &) d);
 | ||
|   for (int i = physical_rows(); i > 0; i--)
 | ||
|   {
 | ||
|     TRiga_documento& r = row(i);
 | ||
| 
 | ||
| 		r.set_doc(this);
 | ||
| 		r.reset_fields(r);
 | ||
| 		r.set_fields(((TAuto_variable_rectype &)d[i]));
 | ||
|   }
 | ||
|   set_riga_sconto();
 | ||
|   if (is_fattura())
 | ||
|     set_riga_esenzione();
 | ||
|   _occas = d.occas();
 | ||
|   return *this;
 | ||
| }
 | ||
|                                    
 | ||
| TRectype & TDocumento::operator =(const TRectype & r) 
 | ||
| {
 | ||
|   return TMultiple_rectype::operator=(r); 
 | ||
| }
 | ||
|                                    
 | ||
| TRectype & TDocumento::operator =(const char * r) 
 | ||
| {
 | ||
|   return TMultiple_rectype::operator=(r); 
 | ||
| }
 | ||
| 
 | ||
| TRecord_array& TDocumento::body(int logicnum) const
 | ||
| {        
 | ||
|   const bool reset_data_cons = loaded_rows(logicnum) == 0;
 | ||
| 
 | ||
|   if (reset_data_cons)
 | ||
|     ((TDocumento*)this)->_dirty_deny = true;
 | ||
| 
 | ||
|   TRecord_array& r = TMultiple_rectype::body(logicnum);
 | ||
| 
 | ||
|   if (reset_data_cons)
 | ||
|   {
 | ||
|     const TDate datacons(get(DOC_DATACONS));
 | ||
|     const TString80 codcms(get(DOC_CODCMS));
 | ||
|     const TString80 fascms(get(DOC_FASCMS));
 | ||
|     const TString80 codcos(get(DOC_CODCOSTO));
 | ||
|     const bool order = is_ordine();   
 | ||
| 
 | ||
|     for (int i = r.last_row(); i > 0; i = r.pred_row(i))
 | ||
|     {
 | ||
|       TRectype& rec = r[i];
 | ||
|       TRecfield dcons(rec, RDOC_DATACONS);
 | ||
|       if (order && datacons == dcons)
 | ||
|         dcons = "";
 | ||
|       TRecfield ccms(rec, RDOC_CODCMS);
 | ||
|       TRecfield fcms(rec, RDOC_FASCMS);
 | ||
|       TRecfield ccos(rec, RDOC_CODCOSTO);
 | ||
|       if (codcms == ccms && fascms == fcms && codcos == ccos)
 | ||
|       {
 | ||
|         ccms = "";
 | ||
|         fcms = "";
 | ||
|         ccos = "";
 | ||
|       }
 | ||
|     }
 | ||
|     ((TDocumento*)this)->_dirty_deny = false;
 | ||
|   }
 | ||
|   return r;
 | ||
| }
 | ||
| 
 | ||
| void TDocumento::update_raee()
 | ||
| {
 | ||
| 	const TString & r_cod = tipo().raee_cod();
 | ||
| 	const TString & r_fld = tipo().raee_fld();
 | ||
| 
 | ||
| 	if (r_cod.full() && r_fld.full() && tipo().stati_iniziali_modifica().find(stato()) >= 0)
 | ||
| 	{
 | ||
|     TSpesa_prest sp(r_cod);
 | ||
|     TString4 cod_iva_cli;
 | ||
|     TLocalisamfile cfven(LF_CFVEN);
 | ||
|     cfven.put("TIPOCF", get("TIPOCF"));
 | ||
|     cfven.put("CODCF", get("CODCF"));
 | ||
|     if (cfven.read() == NOERR)
 | ||
| 			cod_iva_cli = cfven.get("ASSFIS");
 | ||
|     int nrows = physical_rows();
 | ||
|     int i;
 | ||
|     
 | ||
|     for (i = nrows; i > 0; i--)     
 | ||
|     {
 | ||
|       TRiga_documento & r = row(i);
 | ||
| 
 | ||
|       if (r.tipo().tipo() == RIGA_SPESEDOC && r.is_generata() && r.get("GENTIPO") == "R")
 | ||
|         destroy_row(i, true); 
 | ||
|     }
 | ||
|     nrows = physical_rows();
 | ||
| 		for (i = nrows; i > 0; i--)     
 | ||
|     {
 | ||
|       TRiga_documento & r = row(i);
 | ||
| 
 | ||
| 			if (r.is_articolo())
 | ||
| 			{
 | ||
| 				TArticolo & art = r.articolo();
 | ||
| 				real tax = art.get_real(r_fld);
 | ||
| 
 | ||
| 				if (tax  != ZERO)
 | ||
| 				{
 | ||
| 					const TCurrency_documento val(tax, *this, true);
 | ||
| 					TString16 t(sp.tipo_riga());
 | ||
| 					TRiga_documento & r1 = insert_row(i + 1, t);
 | ||
| 					
 | ||
| 					copy_data(r1, r);
 | ||
| 					r1.set_tipo(t);
 | ||
|           r1.put(RDOC_CODART, r_cod);
 | ||
| 					TString d(sp.descrizione());
 | ||
| 						
 | ||
| 					if (d.full())
 | ||
| 						d << " - ";
 | ||
| 					d << r1.get(RDOC_DESCR);
 | ||
| 					d << r1.get(RDOC_DESCEST);
 | ||
| 			    r1.put(RDOC_DESCR, d.left(50));                                                     
 | ||
| 					if (d.len() > 50)
 | ||
| 					{
 | ||
| 						r1.put(RDOC_DESCLUNGA, "X");
 | ||
| 						r1.put(RDOC_DESCEST, d.mid(50));
 | ||
| 					}
 | ||
| 					else
 | ||
| 					{
 | ||
| 						r1.zero(RDOC_DESCLUNGA);
 | ||
| 						r1.zero(RDOC_DESCEST);
 | ||
| 					}
 | ||
| 					const TString & um = sp.um();
 | ||
| 
 | ||
|           if (um.full())
 | ||
| 						r1.put(RDOC_UMQTA, um);
 | ||
|           if (cod_iva_cli.blank())
 | ||
| 					{
 | ||
| 						const TString & codiva = sp.cod_iva();
 | ||
| 						if (codiva.full())
 | ||
| 							r1.put(RDOC_CODIVA, codiva);
 | ||
| 					}
 | ||
|           else
 | ||
|             r1.put(RDOC_CODIVA, cod_iva_cli);
 | ||
| 					tax = val.get_num();
 | ||
|           r1.put(RDOC_PREZZO, tax);
 | ||
| 					if (tipo().calcolo_lordo())
 | ||
| 					{
 | ||
| 						tax = r1.iva().lordo(tax, ALL_DECIMALS);
 | ||
| 						r1.put(RDOC_PREZZOL, tax);
 | ||
| 					}
 | ||
|           r1.generata();
 | ||
| 					r1.put("GENTIPO", "R");
 | ||
| 				}
 | ||
| 			}
 | ||
| 		}
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| void TDocumento::update_spese_aut(TString_array & spese_aut, bool preserve_old, TSheet_field * sh)
 | ||
| {
 | ||
|   const bool updated = get_bool(DOC_SPESEUPD);
 | ||
|   if (updated)
 | ||
|     return;
 | ||
| 
 | ||
|   const bool interactive = sh != NULL;
 | ||
|     
 | ||
|   if (tipo().spese_aut())
 | ||
|   {                
 | ||
|     const int nrows = physical_rows();
 | ||
|     int i;
 | ||
|     
 | ||
|     for (i = nrows; i > 0; i--)     
 | ||
|     {
 | ||
|       TRiga_documento & r = row(i);
 | ||
|       bool tipo_spese = r.get("GENTIPO").empty();
 | ||
|     
 | ||
|       if (r.tipo().tipo() == RIGA_SPESEDOC && r.is_generata() && tipo_spese)
 | ||
|       { 
 | ||
|         if (preserve_old)
 | ||
|           return;
 | ||
|         destroy_row(i, true); 
 | ||
|         if (interactive)
 | ||
|           sh->destroy(i - 1);
 | ||
|       }
 | ||
|     }
 | ||
|     
 | ||
| 		TString4 cod_iva_cli;
 | ||
|     const int nspese = spese_aut.items();
 | ||
| 
 | ||
|     if (nspese > 0)
 | ||
|     {
 | ||
|       TSpesa_prest sp;
 | ||
|       cod_iva_cli = codesiva();
 | ||
| 
 | ||
|       for (i = 0; i < nspese; i++)
 | ||
|       {                     
 | ||
|         const TString& s = spese_aut.row(i);
 | ||
|         
 | ||
|         if (sp.read(s) != NOERR)
 | ||
|           message_box("Codice spesa  %s  assente", (const char *) s);
 | ||
|         else 
 | ||
|         {
 | ||
|           const TString4 tipo(sp.tipo_riga());
 | ||
|           TRiga_documento& riga = new_row(tipo);
 | ||
|       
 | ||
|           riga.put(RDOC_CODART, s);
 | ||
|           riga.generata();
 | ||
|           riga.put(RDOC_DESCR, sp.descrizione());
 | ||
|           if (cod_iva_cli.blank())
 | ||
|             riga.put(RDOC_CODIVA, sp.cod_iva());
 | ||
|           else
 | ||
|             riga.put(RDOC_CODIVA, cod_iva_cli);          
 | ||
|           switch (sp.tipo())
 | ||
|           {                 
 | ||
|             case 'Q':
 | ||
|               {                              
 | ||
|                 real qta = sp.qta();
 | ||
|                 if (qta == ZERO)
 | ||
|                   qta = UNO;                                       
 | ||
|                 riga.put("QTA", qta);                 
 | ||
|               }
 | ||
|               // Continua perche' e' quantita' e valore
 | ||
|             case 'V':
 | ||
|               {
 | ||
|                 const real cambio = get_real(DOC_CAMBIO);
 | ||
|                 const TString4 valuta = get(DOC_CODVAL);
 | ||
|                 const exchange_type controeuro = get_bool(DOC_CONTROEURO) ? _exchange_contro : _exchange_base;
 | ||
|                 real prezzo = sp.prezzo();
 | ||
|           
 | ||
|                 sppr_calc(sp, valuta, cambio, prezzo, controeuro);
 | ||
| 							if (this->tipo().calcolo_lordo())
 | ||
| 								{
 | ||
| 									prezzo = riga.iva().lordo(prezzo, ALL_DECIMALS);
 | ||
| 									riga.put(RDOC_PREZZOL, prezzo);
 | ||
| 								}
 | ||
|                 riga.put(RDOC_PREZZO, prezzo);
 | ||
|                 riga.put(RDOC_UMQTA, sp.um());
 | ||
|               }
 | ||
|               break;
 | ||
|             case 'P':
 | ||
|             default:
 | ||
|                 riga.put(RDOC_QTA, sp.perc());
 | ||
|               break;
 | ||
|           }
 | ||
|           if (cod_iva_cli.empty())
 | ||
|             riga.put(RDOC_CODIVA, sp.cod_iva());
 | ||
|           else
 | ||
|             riga.put(RDOC_CODIVA, cod_iva_cli);
 | ||
| 
 | ||
|           riga.put(RDOC_CODCOSTO, sp.cdc());
 | ||
|           riga.put(RDOC_CODCMS, sp.cms());
 | ||
|           riga.put(RDOC_FASCMS, sp.fase());
 | ||
| 					riga.cms2tipodet();
 | ||
| 
 | ||
|           if (interactive)
 | ||
|           {              
 | ||
|             const int nrow = sh->insert(-1, FALSE);
 | ||
|             riga.autoload(*sh);        
 | ||
|             sh->check_row(nrow);  
 | ||
|           }
 | ||
|         }         
 | ||
|       }
 | ||
|     }                                                   
 | ||
|   }
 | ||
|   put(DOC_SPESEUPD, true);
 | ||
| }
 | ||
| 
 | ||
| // Calcola il peso in Kg degli imballaggi di una data categoria CONAI
 | ||
| real TDocumento::calc_conai_qta(TCONAI_class cc)
 | ||
| {             
 | ||
| 	real qta;
 | ||
|   if (conai_configured_class(cc))
 | ||
|   {
 | ||
|     FOR_EACH_PHYSICAL_RDOC(*this, i, r) if (r->is_merce() || r->is_omaggio())
 | ||
|     {
 | ||
|       const real rowqty = r->calc_conai_qta(cc);
 | ||
| 	    qta += rowqty;
 | ||
|     }
 | ||
|     qta.round(5); // Arrotondamento al centigrammo
 | ||
|   }
 | ||
|   return qta;
 | ||
| }               
 | ||
| 
 | ||
| void TDocumento::update_conai()
 | ||
| {                   
 | ||
|   if (main_app().has_module(DCAUT, CHK_DONGLE) && tipo().add_conai() && tipo().stati_iniziali_modifica().find(stato()) >= 0)
 | ||
|   {
 | ||
|     const TRectype& cfven = clifor().vendite();
 | ||
|     const bool cli_add_conai = cfven.get_bool("ADDCONAI");
 | ||
| 	  const char * const __conai_cf_names[] = {"ESACC", "ESALL", "ESCAR", "ESPLA", "ESLEG", "ESVET"};
 | ||
|     
 | ||
| 		const TDate datadoc = get(DOC_DATADOC);
 | ||
| 		const TDate dataes = cfven.get(CFV_DATAECONAI);
 | ||
| 		bool esponi_esenti = false;
 | ||
| 	
 | ||
|     TString_array conai_sp(CONAI_CLASSES);   // Codici spesa conai
 | ||
|     {
 | ||
|       const char* const conai_cod[CONAI_CLASSES] = { "CODACC", "CODALL", "CODCAR", "CODPLA", "CODLEG", "CODVET" };
 | ||
|       TConfig c(CONFIG_DITTA, "ve");    
 | ||
|       for (int i = 0; i < CONAI_CLASSES; i++)
 | ||
|         conai_sp.add(c.get(conai_cod[i]));
 | ||
| 			
 | ||
| 			esponi_esenti = c.get_bool("ESPONIESENTI");
 | ||
|     }                          
 | ||
|     
 | ||
|     bool updated[CONAI_CLASSES] = {false,false,false,false,false,false};     
 | ||
|     for (int i = physical_rows(); i > 0; i--)     
 | ||
|     {
 | ||
|       TRiga_documento& r = row(i);   
 | ||
|       const bool tipo_conai = r.get_char("GENTIPO") == 'C';
 | ||
|       
 | ||
|       // Elimina righe generate
 | ||
|       if (tipo_conai)
 | ||
|       {     
 | ||
| 				const TString& cod = r.get(RDOC_CODART);
 | ||
| 				const TCONAI_class pos = (TCONAI_class)conai_sp.find(cod);
 | ||
|    
 | ||
| 				if (pos >= CONAI_FIRST && pos <= CONAI_LAST)
 | ||
| 				{  
 | ||
| 					if (cli_add_conai)
 | ||
| 					{
 | ||
| 						real perc_esenz = cfven.get_real(__conai_cf_names[pos]);
 | ||
| 						real qta = calc_conai_qta(pos);
 | ||
| 						if (dataes.ok() && datadoc > dataes)
 | ||
| 							perc_esenz = ZERO;
 | ||
| 						const bool cli_esente = esponi_esenti && (perc_esenz >= CENTO);
 | ||
|             if (!cli_esente && !perc_esenz.is_zero())
 | ||
| 							qta = qta * (CENTO - perc_esenz) / CENTO;  // More precise
 | ||
| 						if (qta > ZERO) 
 | ||
| 						{
 | ||
| 							r.put(RDOC_QTA, qta);  
 | ||
| 							if (cli_esente)
 | ||
| 								r.zero(RDOC_PREZZO);
 | ||
| 						}
 | ||
| 						else
 | ||
| 							destroy_row(i, true); 
 | ||
| 					}
 | ||
| 					else
 | ||
| 						destroy_row(i, true); 
 | ||
| 					updated[pos] = true;
 | ||
| 				}
 | ||
|       }
 | ||
|     } 
 | ||
|     
 | ||
|     // Genera nuove righe
 | ||
|     if (cli_add_conai)
 | ||
|     {  
 | ||
|       const TString4 cod_iva_cli = codesiva()	;
 | ||
|       TSpesa_prest sp;
 | ||
|   
 | ||
| 			FOR_EACH_CONFIGURED_CONAI_CLASS(ct) if (!updated[ct])
 | ||
| 			{
 | ||
| 				const real perc_esenz = cfven.get_real(__conai_cf_names[ct]);
 | ||
| 			  const bool cli_esente = (esponi_esenti) && (perc_esenz >= CENTO);
 | ||
| 				const real qta_lorda = calc_conai_qta(ct);
 | ||
|         real qta = qta_lorda;
 | ||
|         if (!cli_esente && !qta_lorda.is_zero() && !perc_esenz.is_zero())
 | ||
|         {
 | ||
|           qta = qta_lorda * (CENTO - perc_esenz) / CENTO;
 | ||
|           qta.round(5);
 | ||
|         }
 | ||
| 				
 | ||
|         if (qta > ZERO)
 | ||
| 				{            
 | ||
| 					const TString& s = conai_sp.row(ct);
 | ||
| 
 | ||
| 					if (sp.read(s) != NOERR)
 | ||
| 						message_box(FR("Il codice spesa CONAI %s specificato nei parametri ditta e' assente: '%s'"), 
 | ||
| 												conai_material(ct), (const char*)s);
 | ||
| 					else 
 | ||
| 					{
 | ||
| 						const TString4 tipo = sp.tipo_riga(); 
 | ||
| 						TRiga_documento& riga = new_row(tipo);
 | ||
|       
 | ||
| 						riga.put(RDOC_CODART, s);
 | ||
| 						riga.generata();
 | ||
| 						riga.put(RDOC_GENTIPO, 'C');
 | ||
| 						riga.put(RDOC_DESCR, sp.descrizione());
 | ||
| 						riga.put(RDOC_QTA, qta);                 
 | ||
| 
 | ||
| 						const real cambio = get_real(DOC_CAMBIO);
 | ||
| 						const TString4 valuta = get(DOC_CODVAL);
 | ||
| 						const bool controeuro = get_bool(DOC_CONTROEURO);
 | ||
| 						real prezzo = cli_esente ? ZERO : sp.prezzo();
 | ||
|           
 | ||
| 						sppr_calc(sp, valuta, cambio, prezzo, controeuro ? _exchange_contro : _exchange_base);
 | ||
| 						if (this->tipo().calcolo_lordo())
 | ||
| 							prezzo = riga.iva().lordo(prezzo, ALL_DECIMALS);
 | ||
| 						riga.put(RDOC_PREZZO, prezzo);
 | ||
| 						riga.put(RDOC_UMQTA, sp.um());
 | ||
| 						if (cod_iva_cli.empty())
 | ||
| 							riga.put(RDOC_CODIVA, sp.cod_iva());
 | ||
| 						else
 | ||
| 							riga.put(RDOC_CODIVA, cod_iva_cli);
 | ||
| 					}         
 | ||
| 				}
 | ||
| 			}  
 | ||
| 		}  
 | ||
|   }
 | ||
| }
 | ||
|                                    
 | ||
| bool TDocumento::is_evaso() const
 | ||
| {
 | ||
|   bool ok = is_ordine() || is_bolla() || is_generic();
 | ||
|   for (int r = 1; ok && r <= physical_rows(); r++)
 | ||
|   {
 | ||
|     const TRiga_documento& riga = physical_row(r);
 | ||
|     if (riga.is_evadibile())
 | ||
|       ok = riga.is_evasa();
 | ||
|   }
 | ||
|   return ok;
 | ||
| }
 | ||
| 
 | ||
| bool TDocumento::is_nota_credito() const
 | ||
| { 
 | ||
|   bool swap = false;
 | ||
|   
 | ||
|   // Controlla prima l'esistenza del flag nota-credito sul tipo documento;
 | ||
|   // se non e' settato controlla la causale
 | ||
|   if (tipo().nota_credito())
 | ||
|     swap = true;
 | ||
|   else
 | ||
|   {
 | ||
|     const TString4 codcaus(tipo().causale());
 | ||
|     if (codcaus.full())
 | ||
|     {
 | ||
|       TCausale c(codcaus, data().year());
 | ||
|       const char sez = c.sezione_clifo();
 | ||
|       //controllo ulteriore sull'iva
 | ||
|       TipoIVA tiva = c.reg().iva();
 | ||
|       const char tcf = tipocf();
 | ||
|       if (tiva == nessuna_iva && tcf > ' ')
 | ||
|         tiva = tcf == 'C' ? iva_vendite : iva_acquisti;
 | ||
|       if (tiva != nessuna_iva)
 | ||
|         swap = ((tiva == iva_vendite) ^ (sez == 'D'));
 | ||
|     }
 | ||
|   }
 | ||
|   return swap;
 | ||
| }  
 | ||
| 
 | ||
| TCurrency_documento::TCurrency_documento(const real& num, const TDocumento & doc, bool price)
 | ||
|          : TCurrency(ZERO, "", ZERO, _exchange_base, price)
 | ||
| {           
 | ||
|   const TString4 val = doc.get(DOC_CODVAL);  
 | ||
|   const bool controeuro = doc.get_bool(DOC_CONTROEURO);
 | ||
|   force_value(val, doc.get_real(DOC_CAMBIO), controeuro ? _exchange_contro : _exchange_base);
 | ||
|   set_num(num);
 | ||
| }
 | ||
| 
 | ||
| int TDocumento::set_row_ids()
 | ||
| {
 | ||
|   const int phrw = physical_rows();
 | ||
|   long maxid = 0L;
 | ||
|   int first_needed = 0, r;
 | ||
|   for (r = 1; r <= phrw; r++)
 | ||
|   {
 | ||
|     const TRiga_documento& row = physical_row(r);
 | ||
|     const long id = row.get_long(RDOC_IDRIGA);
 | ||
|     if (id > maxid) 
 | ||
|       maxid = id;
 | ||
|     else
 | ||
|     {
 | ||
|       if (first_needed == 0)
 | ||
|         first_needed = r;
 | ||
|     }
 | ||
|   }
 | ||
|   if (first_needed > 0)
 | ||
|   {
 | ||
|     for (r = first_needed; r <= phrw; r++)
 | ||
|     {
 | ||
|       TRiga_documento& row = (TRiga_documento&)physical_row(r);
 | ||
|       const long id = row.get_long(RDOC_IDRIGA);
 | ||
|       if (id <= 0)
 | ||
|         row.put(RDOC_IDRIGA, ++maxid);
 | ||
|     }
 | ||
|   }  
 | ||
|   return phrw;
 | ||
| }
 | ||
| 
 | ||
| const TRiga_documento* TDocumento::get_row_id(long id) const
 | ||
| {
 | ||
|   TDocumento& doc = *(TDocumento*)this;
 | ||
|   FOR_EACH_PHYSICAL_RDOC_BACK(doc, r, row)
 | ||
|   {
 | ||
|     if (row->get_long(RDOC_IDRIGA) == id)
 | ||
|       return row;
 | ||
|   }
 | ||
|   return NULL;
 | ||
| }
 | ||
| 
 | ||
| int TDocumento::id2rownum(long id) const
 | ||
| {
 | ||
|   const TRiga_documento* rdoc = get_row_id(id);
 | ||
|   return rdoc ? rdoc->get_int(RDOC_NRIGA) : -1;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| int TDocumento::tipo_riclassificato() const
 | ||
| {
 | ||
| 	int tipo_riclassificato = tipo().tipo();
 | ||
| 	if (tipo_riclassificato == TTipo_documento::_altro)
 | ||
| 	{
 | ||
| 		const TCodice_numerazione& num = codice_numerazione();
 | ||
| 		if (num.fattura_emettere_ricevere())
 | ||
| 			tipo_riclassificato = TTipo_documento::_bolla;
 | ||
| 		else
 | ||
| 			tipo_riclassificato = TTipo_documento::_fattura;
 | ||
| 	}
 | ||
| 	return tipo_riclassificato;
 | ||
| }
 | ||
| 
 | ||
| const TString& TDocumento::codesiva() const
 | ||
| {
 | ||
|   TCli_for& c = clifor();   
 | ||
| 	const TString4 codiva(c.vendite().get(CFV_ASSFIS));
 | ||
| 	TCodiceIVA i(codiva);
 | ||
| 	const bool plafond = i.get_int("S3") > 0;
 | ||
| 	
 | ||
| 	if (!c.use_lettere() || c.read_lettera(get_date(DOC_DATADOC)))
 | ||
| 		return c.vendite().get(CFV_ASSFIS);
 | ||
| 	return EMPTY_STRING;
 | ||
| }
 | ||
| 
 | ||
| void TDocumento::get_protocolli_esenzione(TString & esenzione, TString & data_esenzione,
 | ||
| 																					TString & registrazione, TString & data_registrazione) const
 | ||
| {
 | ||
|   TCli_for& c = clifor();
 | ||
| 	if (c.use_lettere())
 | ||
| 	{
 | ||
| 		if (c.read_lettera(get_date(DOC_DATADOC), true))
 | ||
| 		{
 | ||
| 			const TRectype& rec = c.lettera();
 | ||
| 			esenzione = rec.get(LETINT_VSPROT);
 | ||
| 			data_esenzione = rec.get(LETINT_VSDATA);
 | ||
| 			registrazione = rec.get(LETINT_NUMPROT); 
 | ||
| 			data_registrazione = rec.get(LETINT_DATAREG);
 | ||
| 		}
 | ||
| 	}
 | ||
| 	else
 | ||
| 	{
 | ||
| 		esenzione = c.vendite().get(CFV_VSPROT);
 | ||
| 		data_esenzione = c.vendite().get(CFV_VSDATAREG);
 | ||
| 		registrazione = c.vendite().get(CFV_NSPROT); 
 | ||
| 		data_registrazione = c.vendite().get(CFV_NSDATAREG);
 | ||
| 	}
 | ||
| }
 |