Files correlati : Ricompilazione Demo : [ ] Commento : Riportate le patch fino alla 172 git-svn-id: svn://10.65.10.50/trunk@12526 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			2422 lines
		
	
	
		
			69 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			2422 lines
		
	
	
		
			69 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <dongle.h>
 | 
						||
#include <modaut.h>
 | 
						||
#include <prefix.h>
 | 
						||
#include <tabutil.h>
 | 
						||
#include <utility.h>
 | 
						||
 | 
						||
#include "veini.h"
 | 
						||
#include "velib.h"
 | 
						||
#include "sconti.h"             
 | 
						||
#include "vepriv.h"
 | 
						||
#include "veuml.h"
 | 
						||
 | 
						||
#include "../cg/cg2103.h"
 | 
						||
#include "../cg/cglib01.h"
 | 
						||
#include "../mg/mglib.h"
 | 
						||
#include "../mg/movmag.h"
 | 
						||
#include "../pr/prlib.h"
 | 
						||
#include "../sv/svlib01.h"
 | 
						||
#include "../db/dblib.h"
 | 
						||
 | 
						||
#include <clifo.h>
 | 
						||
 | 
						||
// 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 TString16 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) { _codmagc.add(magc); }
 | 
						||
  TMov_mag_doc() { }
 | 
						||
  virtual ~TMov_mag_doc() {}
 | 
						||
};
 | 
						||
 | 
						||
const char* TMov_mag_doc::codmag_rauto(int r) const
 | 
						||
{
 | 
						||
  TRecord_array & b = body();
 | 
						||
 | 
						||
  if (r > b.rows()) // Can't check non-existent rows
 | 
						||
    return NULL;
 | 
						||
 | 
						||
  TRectype & row = b[r];
 | 
						||
  const char tr = row.get_char(RMOVMAG_TIPORIGA);
 | 
						||
 | 
						||
  if (tr != 'D' && tr != 'A') // These are customer's added rows
 | 
						||
    return NULL;
 | 
						||
  
 | 
						||
  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)
 | 
						||
  	return _codmagc.row(j);
 | 
						||
  else
 | 
						||
  	return NULL;
 | 
						||
}
 | 
						||
 | 
						||
/////////////////////////////////////////////////////////////
 | 
						||
// TRiepilogo IVA
 | 
						||
/////////////////////////////////////////////////////////////
 | 
						||
TRiepilogo_iva& TRiepilogo_iva::copy(const TRiepilogo_iva& a)
 | 
						||
{ 
 | 
						||
  (TRectype &) _codiva = (TRectype &) a._codiva;
 | 
						||
  _imp = a._imp;
 | 
						||
  _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;
 | 
						||
TAssoc_array TDocumento::_tipi;
 | 
						||
TAssoc_array TDocumento::_numerazioni;
 | 
						||
TString16 TDocumento::_codiva_spese;
 | 
						||
TString16 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, "NRIGA");
 | 
						||
  set_memo_fld("G1");
 | 
						||
 | 
						||
  _tipocf = new TRecfield(*this, "TIPOCF");
 | 
						||
  _codcf = new TRecfield(*this, "CODCF");
 | 
						||
  _cod_occas = new TRecfield(*this, "OCFPI");
 | 
						||
  _provv_agente = new TProvvigioni_agente;
 | 
						||
  
 | 
						||
  _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 (_provv_agente != NULL) delete _provv_agente;
 | 
						||
  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
 | 
						||
{ 
 | 
						||
  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(int ndec, TTipo_importo t) const
 | 
						||
{        
 | 
						||
  real imp_spese;   
 | 
						||
  const real percentuale = get_real("PERCSPINC");
 | 
						||
  static TArray spese_inc;
 | 
						||
  
 | 
						||
  if (percentuale > ZERO)
 | 
						||
  {
 | 
						||
    if (ndec == AUTO_DECIMALS)
 | 
						||
      ndec = decimals();
 | 
						||
    if (spese_inc.objptr(_rim_dir) == NULL)
 | 
						||
    {
 | 
						||
      TConfig conf(CONFIG_STUDIO, "ve");
 | 
						||
      for (TTipo_pag p = _rim_dir; p < _nessun_pag; p = (TTipo_pag) ((int)p + 1)) 
 | 
						||
      {
 | 
						||
        real r(conf.get("IMPSPINC", "ve", p));
 | 
						||
        spese_inc.add(r, p);
 | 
						||
      }
 | 
						||
    }   
 | 
						||
    TPagamento & pag = ((TDocumento *)this)->pagamento();  
 | 
						||
    const int nrate = pag.n_rate();
 | 
						||
    
 | 
						||
    for (int i = 0; i < nrate; i++)
 | 
						||
    {
 | 
						||
      const TTipo_pag p = (TTipo_pag) pag.tipo_rata(i);
 | 
						||
      imp_spese += (real &) spese_inc[p];
 | 
						||
    }              
 | 
						||
    imp_spese *= percentuale / 100.0;
 | 
						||
    
 | 
						||
    if (t == _lordo || t == _imposta)
 | 
						||
    {
 | 
						||
      TString16 codiva_es;
 | 
						||
    
 | 
						||
      iva_esente(codiva_es);                       
 | 
						||
      real iva_spese(TRiga_documento::iva(codiva_es.not_empty() ? (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_real("CAMBIO");
 | 
						||
    if (!cambio.is_zero())
 | 
						||
    {                      
 | 
						||
      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                                     
 | 
						||
 | 
						||
{
 | 
						||
  int rows = physical_rows();
 | 
						||
      
 | 
						||
  codiva_es.cut(0);
 | 
						||
  for (int r = 1; codiva_es.empty() && r <= rows; r++)
 | 
						||
  {
 | 
						||
    const TRiga_documento& riga = ((TDocumento*)this)->row(r); 
 | 
						||
    const TString16 str_codiva(riga.get(RDOC_CODIVA));
 | 
						||
    
 | 
						||
    if (str_codiva.not_empty())
 | 
						||
    {
 | 
						||
      const TCodiceIVA codiva(str_codiva);
 | 
						||
      const TString & tipoiva = codiva.tipo();
 | 
						||
                
 | 
						||
      if (tipoiva.empty())
 | 
						||
        break;
 | 
						||
      if (tipoiva == "NI")
 | 
						||
        codiva_es = codiva.codice();
 | 
						||
    }     
 | 
						||
  }                                    
 | 
						||
}
 | 
						||
 | 
						||
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);
 | 
						||
      
 | 
						||
      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
 | 
						||
    TString16 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_es.not_empty() ? (const TString &) codiva_es : 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("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;
 | 
						||
}
 | 
						||
 | 
						||
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;
 | 
						||
}      
 | 
						||
 | 
						||
// 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("PROVV",  provv); 
 | 
						||
  rec.put("ANNO",   anno);
 | 
						||
  rec.put("CODNUM", codnum);  
 | 
						||
  rec.put("NDOC",   numdoc);
 | 
						||
}
 | 
						||
 | 
						||
// Funzione statica utile a tutti gli utenti di LF_DOC e LF_RIGHEDOC
 | 
						||
void TDocumento::copy_data(TRectype& dst, const TRectype& src)
 | 
						||
{                           
 | 
						||
  // 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        = dst.num() == LF_RIGHEDOC ? dst.get_int(RDOC_NRIGA) : 0;
 | 
						||
  const long idriga      = dst.num() == LF_RIGHEDOC ? dst.get_long(RDOC_IDRIGA) : 0;  
 | 
						||
  // Copia tutto il record     
 | 
						||
  dst = src;                          
 | 
						||
  // Ripristina tutti i campi chiave
 | 
						||
  set_key(dst, provv, anno, codnum, numdoc);
 | 
						||
  if (nriga > 0)
 | 
						||
  {
 | 
						||
    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);
 | 
						||
  }
 | 
						||
  else
 | 
						||
    dst.zero(DOC_MOVMAG); 
 | 
						||
}
 | 
						||
 | 
						||
// 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());
 | 
						||
}
 | 
						||
  
 | 
						||
void TDocumento::copy_contents(const TDocumento& src)
 | 
						||
{
 | 
						||
  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); // ok
 | 
						||
  if (tipo)
 | 
						||
    r.set_tipo(tipo);
 | 
						||
  return r;
 | 
						||
}
 | 
						||
 | 
						||
TRiga_documento& TDocumento::new_row(const char *tipo)
 | 
						||
{
 | 
						||
  TRiga_documento & r = (TRiga_documento&)TMultiple_rectype::new_row(); // ok
 | 
						||
  if (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);
 | 
						||
  }
 | 
						||
  
 | 
						||
  if (err == NOERR && _has_provv)
 | 
						||
    _old_agente = get(DOC_CODAG);
 | 
						||
  else
 | 
						||
    _old_agente.cut(0);
 | 
						||
 | 
						||
  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("SCONTOPERC"));  
 | 
						||
  
 | 
						||
  if (sconto.empty())
 | 
						||
  {        
 | 
						||
    if(_sconto != NULL)
 | 
						||
      delete _sconto;
 | 
						||
    _sconto = NULL;
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {                
 | 
						||
    if (_sconto == NULL)
 | 
						||
    {                   
 | 
						||
      static TString16 _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("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("DESCR","Sconto");
 | 
						||
    }
 | 
						||
    _sconto->put("SCONTO", sconto);
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
void TDocumento::set_riga_esenzione()
 | 
						||
{                                  
 | 
						||
  TCli_for & c = clifor();   
 | 
						||
  const TCodiceIVA codes(c.vendite().get(CFV_ASSFIS));
 | 
						||
  const TString16 v_esenzione(c.vendite().get(CFV_VSPROT));
 | 
						||
  const TString16 v_data_esenzione(c.vendite().get(CFV_VSDATAREG));
 | 
						||
  const TString16 n_registrazione(c.vendite().get(CFV_NSPROT)); 
 | 
						||
  const TString16 n_data_registrazione(c.vendite().get(CFV_NSDATAREG));
 | 
						||
  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();
 | 
						||
    for (int i = loaded_rows(); i > 0; i--)
 | 
						||
    {
 | 
						||
      TRiga_documento & r = (TRiga_documento &) row(i);     
 | 
						||
      r.dirty_fields(FALSE);
 | 
						||
    }  
 | 
						||
    _dirty_deny = TRUE;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
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());
 | 
						||
  const int rows = physical_rows();
 | 
						||
 | 
						||
  int err = NOERR;
 | 
						||
 | 
						||
  if (!doc_bloccato)
 | 
						||
  {
 | 
						||
    if(tipo().spese_aut() && !get_bool("SPESEUPD"))
 | 
						||
    {
 | 
						||
      TString16 name("CODSP0");
 | 
						||
      TString_array spese;        
 | 
						||
      TRectype & ven_rec = clifor().vendite();
 | 
						||
      for (int i = 1; i <= 4; i++)
 | 
						||
      {                     
 | 
						||
        name.rtrim(1); name << i;
 | 
						||
        const TString16 s(ven_rec.get(name));
 | 
						||
        
 | 
						||
        if (s.not_empty()) 
 | 
						||
          spese.add(s);
 | 
						||
      }               
 | 
						||
      myself.update_spese_aut(spese);
 | 
						||
    }
 | 
						||
  
 | 
						||
    myself.update_conai();
 | 
						||
    myself.set_row_ids();
 | 
						||
  
 | 
						||
    long num = get_long("MOVMAG");            
 | 
						||
  
 | 
						||
    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();
 | 
						||
 | 
						||
      TMov_mag_doc mov;
 | 
						||
      TLocalisamfile m(LF_MOVMAG);
 | 
						||
      mov.zero();
 | 
						||
      if (num == 0 && do_movmag)
 | 
						||
      {
 | 
						||
        err = mov.write(m);
 | 
						||
        if (err != NOERR)
 | 
						||
          return err;
 | 
						||
        num = mov.get_long(MOVMAG_NUMREG);
 | 
						||
        myself.put("MOVMAG", num);
 | 
						||
      }                          
 | 
						||
      if (num > 0)
 | 
						||
      {                                
 | 
						||
        const bool scarica_residuo = tipo().scarica_residuo();
 | 
						||
      
 | 
						||
        mov.put(MOVMAG_NUMREG, num);   
 | 
						||
        while (mov.read(m, _isequal, _testandlock) == _islocked)
 | 
						||
          message_box("Movimento di magazzino n. %ld in uso da parte di un'altro utente", num);
 | 
						||
        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("DATADOC"));
 | 
						||
          TString8 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("PROVV"));
 | 
						||
          mov.put(MOVMAG_ANNODOC, get("ANNO"));;       
 | 
						||
          mov.put(MOVMAG_CODNUM, get("CODNUM"));          
 | 
						||
          long numdoc = get_long("NDOC");
 | 
						||
          if (numdoc <= 0L)
 | 
						||
            numdoc = myself.renum_ndoc(numdoc);
 | 
						||
          
 | 
						||
          mov.put(MOVMAG_NUMDOC, numdoc);     
 | 
						||
          const long ex_numdoc = get_long("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")); 
 | 
						||
          TString8 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"));
 | 
						||
 | 
						||
          int j = 1;
 | 
						||
          real cambio = ZERO;
 | 
						||
 | 
						||
          if (get(DOC_CODVAL).not_empty())
 | 
						||
            cambio = get_real(DOC_CAMBIO);
 | 
						||
          if (cambio == ZERO)
 | 
						||
            cambio = 1.0;
 | 
						||
          const bool esplodente = TCausale_magazzino(mov.get(DOC_CAUSMAG)).esplodente();
 | 
						||
          TString80 codice_riga;
 | 
						||
          TString16 caus_riga;
 | 
						||
          TDistinta_tree dist;
 | 
						||
          TString80 codart;
 | 
						||
      
 | 
						||
          for (i = 1; i <= rows; i++)
 | 
						||
          {            
 | 
						||
            TRiga_documento & r = myself.row(i);
 | 
						||
            const bool articolo = r.is_articolo();
 | 
						||
            codart = r.get("CODARTMAG");
 | 
						||
            codice_riga = r.get("CODART");
 | 
						||
            if (codart.empty())
 | 
						||
              codart = codice_riga;
 | 
						||
            caus_riga = r.get("CAUSMAG");
 | 
						||
            bool distinta_da_esplodere = FALSE;
 | 
						||
            if (!articolo &&
 | 
						||
                (codice_riga.not_empty() &&
 | 
						||
                (caus_riga.not_empty() ? TCausale_magazzino(caus_riga).esplodente() : esplodente)))
 | 
						||
              distinta_da_esplodere = dist.set_root(TCodice_articolo(codice_riga));
 | 
						||
            if (articolo || distinta_da_esplodere)
 | 
						||
            {                  
 | 
						||
              long r_num = r.get_long("MOVMAG");
 | 
						||
              if (r_num == 0)
 | 
						||
              {
 | 
						||
                r_num = num;
 | 
						||
                r.put("MOVMAG", r_num);
 | 
						||
              }
 | 
						||
  
 | 
						||
              const real qta = scarica_residuo ? r.qtaresidua(): r.quantita();
 | 
						||
    
 | 
						||
              if (r_num == num && qta != ZERO)
 | 
						||
              {
 | 
						||
                TRectype & rm = mov.insert_row(j++);
 | 
						||
              
 | 
						||
                mov.add_magc(r.get("CODMAGC"));
 | 
						||
              
 | 
						||
                rm.put(RMOVMAG_IMPIANTO, r.get("IMPIANTO"));;       
 | 
						||
                rm.put(RMOVMAG_LINEA, r.get("LINEA"));          
 | 
						||
                rm.put(RMOVMAG_CODMAG, r.get("CODMAG"));
 | 
						||
                rm.put(RMOVMAG_CODART, codart);
 | 
						||
                rm.put(RMOVMAG_LIVGIAC, r.get("LIVELLO"));
 | 
						||
                rm.put(RMOVMAG_UM, r.get("UMQTA"));
 | 
						||
              
 | 
						||
                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, caus_riga);
 | 
						||
                rm.put(RMOVMAG_TIPORIGA, (char) riga_dadocumento);   
 | 
						||
              }
 | 
						||
            }
 | 
						||
          }
 | 
						||
          mov.rewrite(m);
 | 
						||
        }
 | 
						||
        else
 | 
						||
        {
 | 
						||
          mov.remove(m);
 | 
						||
          for (int i = rows; i > 0; i--)
 | 
						||
          {
 | 
						||
            TRiga_documento & r = myself.row(i);
 | 
						||
 | 
						||
            r.zero("MOVMAG");
 | 
						||
          }
 | 
						||
          myself.zero("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));
 | 
						||
    
 | 
						||
    for (int i = rows; i > 0; i--)
 | 
						||
    {
 | 
						||
      TRiga_documento& r = myself.row(i);
 | 
						||
      if ((r.is_merce() || r.is_omaggio()) && !r.is_checked() && r.get("CODARTMAG") != NULL_CODART)
 | 
						||
      {                         
 | 
						||
        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).empty())
 | 
						||
        r.put(RDOC_CODCMS, codcms);
 | 
						||
      if (r.get(RDOC_FASCMS).empty())
 | 
						||
        r.put(RDOC_FASCMS, fascms);
 | 
						||
 | 
						||
    }
 | 
						||
    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()) 
 | 
						||
    {
 | 
						||
      const TString16 agente = get(DOC_CODAG);
 | 
						||
      if (agente != _old_agente)
 | 
						||
      {   
 | 
						||
        if (_old_agente.not_empty())                                   
 | 
						||
        {
 | 
						||
          const int anno = get_int(DOC_ANNO);
 | 
						||
          const TString16 codnum = get(DOC_CODNUM);
 | 
						||
          const long numdoc = get_long(DOC_NDOC);
 | 
						||
          TProvvigioni_agente provv;
 | 
						||
          if (provv.read(_old_agente, anno, codnum, numdoc) == NOERR)
 | 
						||
            provv.remove();
 | 
						||
        }    
 | 
						||
        myself._old_agente = agente;
 | 
						||
      }
 | 
						||
      if (agente.not_empty())
 | 
						||
        myself.write_provvigioni();
 | 
						||
    }
 | 
						||
    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();
 | 
						||
    
 | 
						||
  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");
 | 
						||
      mov.remove(m);
 | 
						||
    }
 | 
						||
  }
 | 
						||
  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()) 
 | 
						||
  {
 | 
						||
    const TString8 agente(get(DOC_CODAG));
 | 
						||
    const int anno = TDocumento::anno();
 | 
						||
    const TString4 codnum(numerazione());
 | 
						||
    const long ndoc = numero();
 | 
						||
    
 | 
						||
    // Legge le provvigioni per questo documento
 | 
						||
    _provv_agente->read(agente, anno,codnum,ndoc); 
 | 
						||
    // Le rimuove
 | 
						||
    _provv_agente->remove();
 | 
						||
  }
 | 
						||
  return TMultiple_rectype::remove(f);
 | 
						||
}
 | 
						||
 | 
						||
int TDocumento::decimals(bool price) const
 | 
						||
{                               
 | 
						||
  const TString& codval = get(DOC_CODVAL);
 | 
						||
  const TExchange exc(codval);
 | 
						||
  const int ndec = exc.decimals(price);
 | 
						||
  return ndec;
 | 
						||
}
 | 
						||
 | 
						||
void TDocumento::flush_rows()
 | 
						||
{
 | 
						||
  remove_body(LF_RIGHEDOC);
 | 
						||
}
 | 
						||
 | 
						||
TProvvigioni_agente& TDocumento::calc_provvigioni(const bool generata)
 | 
						||
{
 | 
						||
  CHECK (_provv_agente, "Bad TProvvigione_agente object");
 | 
						||
 | 
						||
  TString16  agente(get(DOC_CODAG));
 | 
						||
  const int  anno = TDocumento::anno();
 | 
						||
  TString16  codnum(numerazione());
 | 
						||
  const long ndoc = numero();
 | 
						||
  TDate      datadoc(data());
 | 
						||
 | 
						||
  while (_provv_agente->read(agente, 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*) agente))
 | 
						||
      return *_provv_agente;
 | 
						||
 | 
						||
  const TString16 codval(TDocumento::valuta());
 | 
						||
  const real change(cambio());
 | 
						||
  const real perc = _provv_agente->perc_fatt(); 
 | 
						||
  TCurrency_documento  tot_doc(totale_doc(), *this);
 | 
						||
  TCurrency_documento  tot_netto(totale_netto(), *this);
 | 
						||
  TCurrency_documento  tot_provv(provvigione(), *this);
 | 
						||
  TCurrency_documento  provv_fat((tot_provv.get_num() / 100.0) * perc, *this); // Provvigione sul fatturato (rata 0)
 | 
						||
//  const int ndec = decimals();
 | 
						||
//  provv_fat.round(ndec);
 | 
						||
  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)
 | 
						||
    {
 | 
						||
      //real val1 = totimponibili * change;
 | 
						||
      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_agente->items() == 0; // Il documento non ha righe provvigionali
 | 
						||
  TRate_doc& rd = _provv_agente->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());
 | 
						||
    if (generata)
 | 
						||
      rt.set_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));
 | 
						||
    if (generata)
 | 
						||
      rt.set_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;
 | 
						||
  return *_provv_agente;
 | 
						||
}
 | 
						||
 | 
						||
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.rows();
 | 
						||
  TRiga_documento * r = NULL;
 | 
						||
  
 | 
						||
  if (index <= nrows)
 | 
						||
  {
 | 
						||
    r = &((TRiga_documento &) b.row(index, FALSE));
 | 
						||
    CHECKD(r, "Riga documento non esistente ", index);
 | 
						||
  }         
 | 
						||
  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;
 | 
						||
    }
 | 
						||
    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 char * tipodoc)
 | 
						||
{
 | 
						||
  CHECK(tipodoc && *tipodoc, "Tipo documento nullo");
 | 
						||
  TTipo_documento * o = (TTipo_documento*)_tipi.objptr(tipodoc);
 | 
						||
  if (o == NULL)
 | 
						||
  {
 | 
						||
    o = new TTipo_documento(tipodoc);
 | 
						||
    _tipi.add(tipodoc, o);
 | 
						||
  }
 | 
						||
  return *o;
 | 
						||
}  
 | 
						||
 | 
						||
const TTipo_documento& TDocumento::tipo() const
 | 
						||
{
 | 
						||
  const TString16 tipodoc(get("TIPODOC"));
 | 
						||
  return tipo(tipodoc);
 | 
						||
}  
 | 
						||
 | 
						||
const TCodice_numerazione& TDocumento::codice_numerazione(const char * numerazione)
 | 
						||
{                         
 | 
						||
  TCodice_numerazione* o = (TCodice_numerazione*)_numerazioni.objptr(numerazione);
 | 
						||
  if (o == NULL)
 | 
						||
  {
 | 
						||
    o = new TCodice_numerazione(numerazione);
 | 
						||
    _numerazioni.add(numerazione, o);
 | 
						||
  }
 | 
						||
  return *o;
 | 
						||
}  
 | 
						||
 | 
						||
const TCodice_numerazione& TDocumento::codice_numerazione() const
 | 
						||
{                         
 | 
						||
  return codice_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(); 
 | 
						||
    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 (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
 | 
						||
        if (exp)
 | 
						||
        {
 | 
						||
          exp->set_doc(this);     
 | 
						||
          add_field(new TDocumento_variable_field(f->name(), *exp));
 | 
						||
        }
 | 
						||
    }                      
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
real TDocumento::imponibile(bool spese, int ndec) const
 | 
						||
{
 | 
						||
  real val;                      
 | 
						||
  if (physical_rows() > 0)
 | 
						||
  {
 | 
						||
    TAssoc_array & table = ((TDocumento *)this)->tabella_iva();
 | 
						||
    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()
 | 
						||
{
 | 
						||
  const int items = rows();
 | 
						||
  TAssoc_array & table = _tabella_iva;
 | 
						||
 | 
						||
  if (table.items() > 0 || items == 0)
 | 
						||
  {
 | 
						||
   if (items == 0)
 | 
						||
     table.destroy();
 | 
						||
   return;                  
 | 
						||
  }
 | 
						||
 | 
						||
  real tot_doc;
 | 
						||
  real tot_sconti;
 | 
						||
  real tot_sconti_perc;
 | 
						||
  const bool doc_al_lordo = tipo().calcolo_lordo();
 | 
						||
  const int ndec = decimals();
 | 
						||
  const bool fatt_comm = tipo().fattura_commerciale();
 | 
						||
  TString16 codiva_es;
 | 
						||
                       
 | 
						||
  iva_esente(codiva_es);                       
 | 
						||
  for (int i = items; i > 0; i--)
 | 
						||
  {
 | 
						||
    const TRiga_documento& r = row(i);
 | 
						||
    const real imponibile = r.imponibile(doc_al_lordo);
 | 
						||
    
 | 
						||
    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(); 
 | 
						||
        const TString16 cod(iva.codice());
 | 
						||
        if (cod.not_empty())
 | 
						||
        {
 | 
						||
          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;
 | 
						||
    
 | 
						||
    table.restart();
 | 
						||
    
 | 
						||
    TRiepilogo_iva * ri;
 | 
						||
    
 | 
						||
    for (ri = (TRiepilogo_iva *) table.get(); ri != NULL;
 | 
						||
         ri = (TRiepilogo_iva *) table.get())
 | 
						||
     d.add(ri->imp() - ri->imp_spese_row());
 | 
						||
  
 | 
						||
    table.restart();
 | 
						||
    for (ri = (TRiepilogo_iva *) table.get(); ri != NULL;
 | 
						||
         ri = (TRiepilogo_iva *) table.get())
 | 
						||
    {     
 | 
						||
      const TCodiceIVA & ci = ri->cod_iva();    
 | 
						||
      const real i(d.get());
 | 
						||
      real & imponibile = ri->imp();
 | 
						||
      imponibile += i;
 | 
						||
      
 | 
						||
      TGeneric_distrib s(i, ndec);
 | 
						||
      
 | 
						||
      s.add(tot_sconti_imp);
 | 
						||
      s.add(tot_sconti_perc);
 | 
						||
      
 | 
						||
      ri->sconto_imp() = s.get();
 | 
						||
      ri->sconto_perc() = s.get(); 
 | 
						||
      
 | 
						||
      real & iva = ri->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;
 | 
						||
        ri->sconto_imp() += iva.get();
 | 
						||
        ri->sconto_perc() += iva.get(); 
 | 
						||
 | 
						||
        tot_doc += imposta;
 | 
						||
      }
 | 
						||
      else
 | 
						||
      {
 | 
						||
        const real imposta(ci.imposta(i, ALL_DECIMALS));
 | 
						||
  
 | 
						||
        iva += imposta;
 | 
						||
        ri->iva_sconto() = ci.imposta(i, ndec);
 | 
						||
        tot_doc += imposta;
 | 
						||
      } 
 | 
						||
    }
 | 
						||
  }
 | 
						||
                
 | 
						||
  if (fatt_comm)
 | 
						||
    calc_iva_fattura_commerciale();
 | 
						||
 | 
						||
  real val = spese_incasso(ALL_DECIMALS, doc_al_lordo ? _lordo : _netto);
 | 
						||
  
 | 
						||
  if (val != ZERO)
 | 
						||
  {
 | 
						||
    const TString16 codiva = codiva_es.not_empty() ? (const TString &) codiva_es : codiva_spese();
 | 
						||
    TRiepilogo_iva* ri = (TRiepilogo_iva*)table.objptr(codiva);
 | 
						||
    if (ri == NULL)
 | 
						||
    {
 | 
						||
      ri = new TRiepilogo_iva(TCodiceIVA(codiva));
 | 
						||
      table.add(codiva, ri);
 | 
						||
    }
 | 
						||
      
 | 
						||
    ri->imp_spese() += val;
 | 
						||
    tot_doc += val;
 | 
						||
    
 | 
						||
    if (!doc_al_lordo)
 | 
						||
    {
 | 
						||
      val = spese_incasso(ALL_DECIMALS, _imposta);
 | 
						||
      ri->iva_spese() += val;
 | 
						||
      tot_doc += val;
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  const real rit = ritenute();
 | 
						||
	val = bolli(real(tot_doc - rit), ALL_DECIMALS, doc_al_lordo ? _lordo : _netto);
 | 
						||
  if (val != ZERO)
 | 
						||
  {
 | 
						||
    const TString16 codiva = codiva_bolli();
 | 
						||
    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)
 | 
						||
  {
 | 
						||
    table.restart();
 | 
						||
    for (TRiepilogo_iva* ri = (TRiepilogo_iva*)table.get(); ri != NULL; ri = (TRiepilogo_iva*)table.get())
 | 
						||
    {                               
 | 
						||
      const TCodiceIVA& iva = ri->cod_iva();
 | 
						||
 | 
						||
      ri->iva() = iva.scorpora(ri->imp(), ndec);    
 | 
						||
      ri->iva_spese() = iva.scorpora(ri->imp_spese(), ndec);
 | 
						||
      iva.scorpora(ri->imp_spese_row(), ndec);
 | 
						||
 | 
						||
      ri->iva_sconto() = iva.scorpora(ri->sconto_imp(), ndec);
 | 
						||
      ri->iva_sconto() += iva.scorpora(ri->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
 | 
						||
{
 | 
						||
  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(ndec);
 | 
						||
    r += bolli(real(r - ritenute()), ndec);
 | 
						||
    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();
 | 
						||
  if (field.not_empty())
 | 
						||
    return get_real(field);
 | 
						||
  else
 | 
						||
    return ZERO;
 | 
						||
}
 | 
						||
 | 
						||
real TDocumento::ritenute(const char tipo, bool lordo, int ndec) const
 | 
						||
{
 | 
						||
  real val;
 | 
						||
  for (int i = rows() ; i > 0; i--)
 | 
						||
  {
 | 
						||
    TRiga_documento &r = ((TRiga_documento &) ((TDocumento *)this)->row(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(int ndec) const
 | 
						||
{ 
 | 
						||
  TString16 field = agente().campoprovv();
 | 
						||
  if (field.empty())
 | 
						||
    field = tipo().totprovv();
 | 
						||
 | 
						||
  real val;     
 | 
						||
  if (field.not_empty())
 | 
						||
    val = get_real(field);
 | 
						||
  else
 | 
						||
  {
 | 
						||
    if (ndec == AUTO_DECIMALS)
 | 
						||
      ndec = decimals();
 | 
						||
    for (int i = rows(); i > 0; i--)
 | 
						||
      val += ((TRiga_documento &) ((TDocumento *)this)->row(i)).provvigione(ndec);
 | 
						||
  }
 | 
						||
  return val;
 | 
						||
}
 | 
						||
 | 
						||
real TDocumento::valore(bool totale, int ndec) const
 | 
						||
{
 | 
						||
  real val;
 | 
						||
  for (int i=rows(); i>0; i--)
 | 
						||
  {
 | 
						||
    TRiga_documento &r = ((TRiga_documento &) ((TDocumento *)this)->row(i));
 | 
						||
    if (r.is_merce() || r.is_spese() || r.is_prestazione())
 | 
						||
      val += r.valore(totale, ndec); 
 | 
						||
  }
 | 
						||
  return val;
 | 
						||
}  
 | 
						||
 | 
						||
void TDocumento::put_str(const char* fieldname, const char* val)
 | 
						||
{          
 | 
						||
  if (strcmp(fieldname, "TIPODOC") == 0)                             
 | 
						||
  {                       
 | 
						||
    const TString16 v(val);
 | 
						||
    if (TRectype::get("TIPODOC") != v)
 | 
						||
    {
 | 
						||
      TAuto_variable_rectype::put_str(fieldname, v);
 | 
						||
      reset_fields(*this);
 | 
						||
      set_fields(*this);
 | 
						||
    }
 | 
						||
    else
 | 
						||
      dirty_fields();                                
 | 
						||
  }
 | 
						||
  else
 | 
						||
    if (strcmp(fieldname, "CODCF") == 0)        
 | 
						||
    {
 | 
						||
      const TString16 v(val);
 | 
						||
      put("SPESEUPD", TRectype::get("CODCF") == v);
 | 
						||
      TAuto_variable_rectype::put_str(fieldname, v);
 | 
						||
      dirty_fields();                                
 | 
						||
    }
 | 
						||
    else
 | 
						||
    {
 | 
						||
      TAuto_variable_rectype::put_str(fieldname, val);
 | 
						||
      dirty_fields();                                
 | 
						||
      if (strcmp(fieldname, "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, "TIPODOC") == 0)
 | 
						||
    reset_fields(*this);
 | 
						||
  TRectype::zero(fieldname);
 | 
						||
  dirty_fields();
 | 
						||
}
 | 
						||
 | 
						||
TCli_for & TDocumento::clifor() const
 | 
						||
{ 
 | 
						||
  const char tipo = tipocf();
 | 
						||
  const long codice = codcf();
 | 
						||
  if (_cli_for.empty() || _cli_for.tipo() != tipo || _cli_for.codice() != codice)
 | 
						||
    ((TDocumento *) this)->_cli_for.read(tipo, codice);
 | 
						||
  return (TCli_for &)_cli_for;
 | 
						||
}
 | 
						||
 | 
						||
TOccasionale & TDocumento::occas() const
 | 
						||
{
 | 
						||
  const TString80 occ_code(cod_occas());
 | 
						||
 | 
						||
  if (_occas.empty() || occ_code != _occas.codice())
 | 
						||
  { 
 | 
						||
    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;
 | 
						||
  }
 | 
						||
  return (TOccasionale &) _occas;
 | 
						||
}
 | 
						||
                                        
 | 
						||
const TAgente & TDocumento::agente() const
 | 
						||
{        
 | 
						||
	if (_agenti == NULL)
 | 
						||
		_agenti = new TAgenti_cache;
 | 
						||
  return _agenti->agente(get(DOC_CODAG));
 | 
						||
}                                     
 | 
						||
 | 
						||
TDocumento & TDocumento::copy(const TDocumento & d) 
 | 
						||
{                                
 | 
						||
  TMultiple_rectype::operator=((TMultiple_rectype &)d); 
 | 
						||
  reset_fields(*this);
 | 
						||
  set_fields(*this);
 | 
						||
  for (int i = physical_rows(); i > 0; i--)
 | 
						||
  {
 | 
						||
    TRiga_documento & r = row(i);
 | 
						||
    r.set_doc(this);
 | 
						||
    r.set_fields(r);
 | 
						||
  }
 | 
						||
  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;
 | 
						||
 | 
						||
  TRecord_array& r = TMultiple_rectype::body(logicnum);
 | 
						||
 | 
						||
  if (reset_data_cons)
 | 
						||
  {
 | 
						||
    const TDate datacons(get_date(DOC_DATACONS));
 | 
						||
    const TString80 codcms(get(DOC_CODCMS));
 | 
						||
    const TString80 fascms(get(DOC_FASCMS));
 | 
						||
    
 | 
						||
    for (int i = r.rows(); i > 0; i--)
 | 
						||
    {
 | 
						||
      TRectype & rec = r[i];
 | 
						||
      TRecfield dcons(rec, RDOC_DATACONS);
 | 
						||
      if (is_ordine() && datacons == dcons)
 | 
						||
        dcons = "";
 | 
						||
      TRecfield ccms(rec, RDOC_CODCMS);
 | 
						||
      TRecfield fcms(rec, RDOC_FASCMS);
 | 
						||
      if (codcms == ccms)
 | 
						||
        ccms = "";
 | 
						||
      if (fascms == fcms)
 | 
						||
        fcms = "";
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return r;
 | 
						||
}
 | 
						||
 | 
						||
void TDocumento::update_spese_aut(TString_array & spese_aut, bool preserve_old, TSheet_field * sh)
 | 
						||
{
 | 
						||
  const bool updated = get_bool("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);
 | 
						||
      }
 | 
						||
    }
 | 
						||
    TString16 cod_iva_cli;
 | 
						||
    const int nspese = spese_aut.items();
 | 
						||
    if (nspese > 0)
 | 
						||
    {
 | 
						||
      TLocalisamfile cfven(LF_CFVEN);
 | 
						||
      TSpesa_prest sp;
 | 
						||
      cfven.put("TIPOCF", get("TIPOCF"));
 | 
						||
      cfven.put("CODCF", get("CODCF"));
 | 
						||
      if (cfven.read() == NOERR)
 | 
						||
        cod_iva_cli = cfven.get("ASSFIS");
 | 
						||
      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 
 | 
						||
        {
 | 
						||
          TString16 tipo(sp.tipo_riga());
 | 
						||
          TRiga_documento & riga = new_row(tipo);
 | 
						||
      
 | 
						||
          riga.put("CODART", s);
 | 
						||
          riga.generata();
 | 
						||
          riga.put("DESCR", sp.descrizione());
 | 
						||
          switch (sp.tipo())
 | 
						||
          {                 
 | 
						||
            case 'Q':
 | 
						||
              {                              
 | 
						||
                real qta = sp.qta();
 | 
						||
                if (qta == ZERO)
 | 
						||
                  qta = 1.0;                                       
 | 
						||
                riga.put("QTA", qta);                 
 | 
						||
              }
 | 
						||
            case 'V':
 | 
						||
              {
 | 
						||
                const real cambio = get_real(DOC_CAMBIO);
 | 
						||
                const TString16 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);
 | 
						||
                riga.put("PREZZO", prezzo);
 | 
						||
                riga.put("UMQTA", sp.um());
 | 
						||
              }
 | 
						||
              break;
 | 
						||
            case 'P':
 | 
						||
            default:
 | 
						||
                riga.put("QTA", sp.perc());
 | 
						||
              break;
 | 
						||
          }
 | 
						||
          if (cod_iva_cli.empty())
 | 
						||
            riga.put("CODIVA", sp.cod_iva());
 | 
						||
          else
 | 
						||
            riga.put("CODIVA", cod_iva_cli);
 | 
						||
          if (interactive)
 | 
						||
          {              
 | 
						||
            const int nrow = sh->insert(-1, FALSE);
 | 
						||
            riga.autoload(*sh);        
 | 
						||
            sh->check_row(nrow);  
 | 
						||
          }
 | 
						||
        }         
 | 
						||
      }
 | 
						||
    }                                                   
 | 
						||
  }
 | 
						||
  put("SPESEUPD", true);
 | 
						||
}
 | 
						||
                                   
 | 
						||
real TDocumento::calc_conai_qta(int type)
 | 
						||
{                                     
 | 
						||
  const char * const __conai_art_names[] = {"CONACC", "CONALL", "CONCAR", "CONPLA", "CONLEG", "CONVET"};
 | 
						||
  const char * const __conai_cf_names[] = {"ESACC", "ESALL", "ESCAR", "ESPLA", "ESLEG", "ESVET"};
 | 
						||
  const real perc_esenz = clifor().vendite().get_real(__conai_cf_names[type]);
 | 
						||
  real qta = ZERO;
 | 
						||
 
 | 
						||
  if (perc_esenz < 100.0)
 | 
						||
  {
 | 
						||
    const int nrows = physical_rows();
 | 
						||
    for (int i = nrows; i > 0; i--)     
 | 
						||
    {
 | 
						||
      TRiga_documento & r = row(i);
 | 
						||
      TArticolo_giacenza * art = r.articolo();
 | 
						||
      if (art != NULL)
 | 
						||
      {
 | 
						||
        const real row_qta = r.get_real(RDOC_QTA);
 | 
						||
        qta += row_qta*art->get_real(__conai_art_names[type]);
 | 
						||
      }
 | 
						||
    }
 | 
						||
    if (qta > ZERO) 
 | 
						||
    {
 | 
						||
      // qta *= (1 - perc_esenz/100.0);
 | 
						||
      qta = qta * (100 - perc_esenz) / 100.0;  // More precise!
 | 
						||
    }  
 | 
						||
  }  
 | 
						||
  return qta;
 | 
						||
}               
 | 
						||
 | 
						||
void TDocumento::update_conai()
 | 
						||
{                   
 | 
						||
  if (tipo().add_conai())
 | 
						||
  {
 | 
						||
    const bool cli_add_conai = clifor().vendite().get_bool("ADDCONAI");
 | 
						||
    
 | 
						||
    const char* conai_cod[6] = { "CODACC", "CODALL", "CODCAR", "CODPLA", "CODLEG", "CODVET" };
 | 
						||
    const char* conai_mat[6] = { "Acciaio", "Alluminio", "Carta", "Plastica", "Legno", "Vetro" };
 | 
						||
    TString_array conai_sp(6);   // Codici spesa conai
 | 
						||
    {
 | 
						||
      TConfig c(CONFIG_DITTA, "ve");    
 | 
						||
      for (int i = 0; i < 6; i++)
 | 
						||
        conai_sp.add(c.get(conai_cod[i]));
 | 
						||
    }                          
 | 
						||
    bool updated[6] = {FALSE,FALSE,FALSE,FALSE,FALSE,FALSE}; 
 | 
						||
    
 | 
						||
    const int nrows = physical_rows();
 | 
						||
    int i;
 | 
						||
    
 | 
						||
    for (i = nrows; i > 0; i--)     
 | 
						||
    {
 | 
						||
      TRiga_documento& r = row(i);   
 | 
						||
      const bool tipo_conai = r.get_char("GENTIPO") == 'C';
 | 
						||
      
 | 
						||
      // Elimina righe generate
 | 
						||
      if (tipo_conai && r.tipo().tipo() == RIGA_SPESEDOC && r.is_generata())
 | 
						||
      {     
 | 
						||
        const TString16 cod(r.get("CODART"));
 | 
						||
        const int pos = conai_sp.find(cod);
 | 
						||
        
 | 
						||
        if (pos >= 0)
 | 
						||
        {  
 | 
						||
          if (cli_add_conai)
 | 
						||
          {
 | 
						||
            real qta = calc_conai_qta(pos);
 | 
						||
            if (qta > ZERO) 
 | 
						||
              r.put("QTA", qta);  
 | 
						||
            else
 | 
						||
              destroy_row(i, TRUE); 
 | 
						||
          }
 | 
						||
          else
 | 
						||
            destroy_row(i, TRUE); 
 | 
						||
          updated[pos] = TRUE;
 | 
						||
        }
 | 
						||
      }
 | 
						||
    } 
 | 
						||
    
 | 
						||
    // Genera nuove righe
 | 
						||
    if (cli_add_conai)
 | 
						||
    {  
 | 
						||
      const TString16 cod_iva_cli = clifor().vendite().get("ASSFIS");
 | 
						||
      TSpesa_prest sp;
 | 
						||
  
 | 
						||
      for (i = 0; i < 6; i++)
 | 
						||
      {
 | 
						||
        if (!updated[i])
 | 
						||
        {            
 | 
						||
          const real qta = calc_conai_qta(i);
 | 
						||
          if (qta > ZERO)
 | 
						||
          {            
 | 
						||
            const TString & s = conai_sp.row(i);
 | 
						||
            if (sp.read(s) != NOERR)
 | 
						||
              message_box("Il codice spesa CONAI %s specificato nei parametri ditta e' assente: '%s'", 
 | 
						||
                          conai_mat[i], (const char*)s);
 | 
						||
            else 
 | 
						||
            {
 | 
						||
              TString16 tipo(sp.tipo_riga()); 
 | 
						||
              TRiga_documento & riga = new_row(tipo);
 | 
						||
            
 | 
						||
              riga.put("CODART", s);
 | 
						||
              riga.generata();
 | 
						||
              riga.put("GENTIPO", "C");
 | 
						||
              riga.put("DESCR", sp.descrizione());
 | 
						||
              riga.put("QTA", qta);                 
 | 
						||
    
 | 
						||
              const real cambio = get_real(DOC_CAMBIO);
 | 
						||
              const TString16 valuta = get(DOC_CODVAL);
 | 
						||
              const bool controeuro = get_bool(DOC_CONTROEURO);
 | 
						||
              real prezzo = sp.prezzo();
 | 
						||
                
 | 
						||
              sppr_calc(sp, valuta, cambio, prezzo, controeuro ? _exchange_contro : _exchange_base);
 | 
						||
              riga.put("PREZZO", prezzo);
 | 
						||
              riga.put("UMQTA", sp.um());
 | 
						||
              if (cod_iva_cli.empty())
 | 
						||
                riga.put("CODIVA", sp.cod_iva());
 | 
						||
              else
 | 
						||
                riga.put("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 TString16 codcaus(tipo().causale());
 | 
						||
    if (codcaus.not_empty())
 | 
						||
    {
 | 
						||
      TLocalisamfile caus(LF_CAUSALI);
 | 
						||
      TLocalisamfile rcaus(LF_RCAUSALI);
 | 
						||
      TCausale c(codcaus, data().year());
 | 
						||
      const char sez = c.sezione_clifo();
 | 
						||
      swap = ((c.reg().iva() == 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 TString16 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
 | 
						||
{
 | 
						||
  for (int r = physical_rows(); r > 0; r--)
 | 
						||
  {
 | 
						||
    const TRiga_documento& row = physical_row(r);
 | 
						||
    if (row.get_long(RDOC_IDRIGA) == id)
 | 
						||
      return &row;
 | 
						||
  }
 | 
						||
  return NULL;
 | 
						||
}
 |