446 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			446 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
// -----------------------------------------------------------------
 | 
						|
// Calcolo liquidazione
 | 
						|
// part 4: casi particolari
 | 
						|
// fv 2-2-94
 | 
						|
// -----------------------------------------------------------------
 | 
						|
 | 
						|
#include "cg4300.h"
 | 
						|
 | 
						|
void TLiquidazione_app::add_plafond(int month, const char* codatt, int type,
 | 
						|
                                    real& howmuch, bool intra)
 | 
						|
{
 | 
						|
  look_ppa(month,codatt,type);
 | 
						|
  
 | 
						|
  TString att(codatt);
 | 
						|
  
 | 
						|
  real r0 = _ppa_r->get_real("R0");
 | 
						|
  real r1 = _ppa_r->get_real("R1");
 | 
						|
  real r2 = _ppa_r->get_real("R2");
 | 
						|
 | 
						|
  if (intra) r1 += howmuch; 
 | 
						|
  else       r0 += howmuch;
 | 
						|
 | 
						|
  if (r2 < (r0+r1))
 | 
						|
    describe_error("Acquisti in eccesso rispetto al plafond disponibile",
 | 
						|
                   att.cut(5));
 | 
						|
  _ppa_r->put("R0",r0);
 | 
						|
  _ppa_r->put("R1",r1);
 | 
						|
  _ppa->rewrite();
 | 
						|
}    
 | 
						|
 | 
						|
void TLiquidazione_app::zero_plafond (int month, const char* codatt)
 | 
						|
{
 | 
						|
  for (int jj = 1; jj <= 3; jj++) // three types of plafond
 | 
						|
  {
 | 
						|
    real r;
 | 
						|
    look_ppa(month,codatt,jj,TRUE);
 | 
						|
    if (is_first_month(month))
 | 
						|
    {
 | 
						|
      r = (jj == 1 ? _p8 : (jj == 2 ? _p8b : _p9)); 
 | 
						|
    }
 | 
						|
    else 
 | 
						|
    {
 | 
						|
      long rn = _ppa->recno();
 | 
						|
      
 | 
						|
      // se non c'e' quello del mese prima c'e' poco da fare,
 | 
						|
      // si ricalcola tutto
 | 
						|
      if (!look_ppa(previous_month(month),codatt,jj))
 | 
						|
        // mazza che bella chiamata ricorsiva
 | 
						|
      { 
 | 
						|
        if (_recalc != needed)
 | 
						|
        {
 | 
						|
          describe_error("Progressivi plafond non ricalcolati per "
 | 
						|
                         "i mesi precedenti: possibili errori",
 | 
						|
                         codatt);
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
          if (!update_att(previous_month(month),codatt, FALSE))
 | 
						|
            describe_error("Progressivi plafond non ricalcolati per "
 | 
						|
                           "i mesi precedenti: possibili errori",
 | 
						|
                           codatt);
 | 
						|
          look_ppa(previous_month(month),codatt,jj); 
 | 
						|
        }
 | 
						|
      }
 | 
						|
      r = _ppa_r->get_real("R2") - 
 | 
						|
        _ppa_r->get_real("R0") - 
 | 
						|
          _ppa_r->get_real("R1"); 
 | 
						|
      
 | 
						|
      _ppa->readat(rn);
 | 
						|
    }
 | 
						|
    _ppa_r->put("R2",r);
 | 
						|
    _ppa_r->put("R0","");
 | 
						|
    _ppa_r->put("R1","");
 | 
						|
    _ppa->rewrite();
 | 
						|
  } // for tipo esenzione plafond      
 | 
						|
}                                     
 | 
						|
 | 
						|
// ricalcolo dei corrispettivi
 | 
						|
void TLiquidazione_app::recalc_corrispettivi(int month, const char* codatt)
 | 
						|
{
 | 
						|
  if (_corr_arr.items() == 0) return;
 | 
						|
  // ricalcola (solo per il mese in corso!) operando sull'array 
 | 
						|
  for (int i = 0; i < _corr_arr.items(); i++)
 | 
						|
  {
 | 
						|
    _CorrItem* ci = (_CorrItem*)&_corr_arr[i];
 | 
						|
    if (ci->_month != month)
 | 
						|
      continue;
 | 
						|
    
 | 
						|
    real imponibile    = ci->_totale/(1.00 + ci->_aliquota);
 | 
						|
    imponibile.ceil(ROUND_LIRA);
 | 
						|
    real imposta = ci->_totale - imponibile;
 | 
						|
 | 
						|
    // aggiusto l'IVA vendite nei plm
 | 
						|
    look_plm(month, codatt);
 | 
						|
    real ive = _plm->get_real("R0");
 | 
						|
    ive     += imposta;
 | 
						|
    _plm->put("R0",ive);
 | 
						|
    _plm->rewrite();
 | 
						|
 | 
						|
    // Aggiorno i luridi pim
 | 
						|
    look_pim(month, codatt, ci->_codreg, "", ci->_codiva, ci->_tipodet, TRUE);
 | 
						|
    
 | 
						|
    imponibile += _pim->get_real("R0");
 | 
						|
    imposta    += _pim->get_real("R1");
 | 
						|
    _pim->put("R0", imponibile);
 | 
						|
    _pim->put("R1", imposta);  
 | 
						|
    _pim->rewrite();
 | 
						|
  }   
 | 
						|
}
 | 
						|
 | 
						|
// ricalcolo della malefica ventilazione
 | 
						|
void TLiquidazione_app::recalc_ventilation(int month, const char* codatt)
 | 
						|
{
 | 
						|
  if (!_isvent || _vend_arr.items() == 0) return;
 | 
						|
 | 
						|
  TString att(codatt);
 | 
						|
 | 
						|
  // 1) ricalcola i pim dei mesi dal primo al corrente se necessario
 | 
						|
  recalc rcl = _recalc;
 | 
						|
  _recalc = needed;
 | 
						|
  for (int m = 1; m < month; m++)
 | 
						|
    update_att(m,codatt, FALSE);
 | 
						|
  _recalc = rcl;
 | 
						|
  
 | 
						|
  _vent_arr.destroy();
 | 
						|
  
 | 
						|
  for (m = 1; m <= month; m++)
 | 
						|
  {
 | 
						|
    // aggiunge gli acquisti del mese m operando sui pim
 | 
						|
    for (_pim->first(); !_pim->eof(); _pim->next())
 | 
						|
    {
 | 
						|
      // se e' acquisto beni per rivendita
 | 
						|
      int tipocr  = atoi(*_pim_tipocr);
 | 
						|
      int mese    = atoi(*_pim_mese);     
 | 
						|
      int tipodet = atoi(*_pim_tipodet);
 | 
						|
      
 | 
						|
      /*
 | 
						|
       * se non si e' settato il ricalcolo nei parametri ditta
 | 
						|
       * considera soltanto quelli con detraibilita' == 3 
 | 
						|
       * (passaggi interni)
 | 
						|
       * sensu Scudler 1994
 | 
						|
       */ 
 | 
						|
      if (!_isricacq && tipodet != 3) 
 | 
						|
        continue; 
 | 
						|
      
 | 
						|
      /*
 | 
						|
       * caso particolare SENSU Vladimiro (1995) #MI3001   
 | 
						|
       * questi vengono pero' conteggiati nel totale
 | 
						|
       * acquisti per rivendita
 | 
						|
       */
 | 
						|
      if (tipocr == 5 && tipodet == 3)
 | 
						|
        continue;
 | 
						|
      
 | 
						|
      TString att(codatt); 
 | 
						|
      if (tipocr == 1 && mese == m && att == (const char*)(*_pim_codatt))  
 | 
						|
      {
 | 
						|
        look_iva(*_pim_codiva);
 | 
						|
 | 
						|
        // base di riparto solo se non esente, non soggetto, non imponibile
 | 
						|
        TString tipoiva(_iva->get("S1"));                        
 | 
						|
        
 | 
						|
        if (tipoiva != "NS" && tipoiva != "NI" && tipoiva != "ES")   
 | 
						|
        {
 | 
						|
          real lurd     = _pim->get_real("R0");
 | 
						|
          lurd         += _pim->get_real("R1");
 | 
						|
          real perc     = _iva->get_real("R0");
 | 
						|
          TString other = _iva->get("S6");
 | 
						|
          if (!other.empty())
 | 
						|
          {
 | 
						|
            // ventila a un altro codice
 | 
						|
            look_iva(other);
 | 
						|
            perc = _iva->get_real("R0");
 | 
						|
          }
 | 
						|
          add_ventilation(perc / CENTO, lurd, *_pim_codiva, other);
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  // 2) calcola totale acquisti su tutte le aliquote
 | 
						|
  real totacq = 0.0;
 | 
						|
  real totven = 0.0;
 | 
						|
  
 | 
						|
  for (int j = 0; j < _vent_arr.items(); j++)
 | 
						|
  {
 | 
						|
    _VentItem* vv = (_VentItem*)&_vent_arr[j];
 | 
						|
    totacq += vv->_totale;
 | 
						|
  }
 | 
						|
  
 | 
						|
  // 3) ricalcola (solo per il mese in corso!) operando sull'array 
 | 
						|
  for (int i = 0; i < _vend_arr.items(); i++)
 | 
						|
  {
 | 
						|
    _VendItem* vi = (_VendItem*)&_vend_arr[i];
 | 
						|
    if (vi->_month != month)
 | 
						|
      continue;
 | 
						|
    
 | 
						|
    // questo serve solo per il prospettino di m.
 | 
						|
    totven += vi->_totale;
 | 
						|
 | 
						|
    // 3.2) calcola percentuali di ripartizione e prepara l'affettatrice
 | 
						|
    TDistrib dst(vi->_totale,ROUND_LIRA);
 | 
						|
    for (j = 0; j < _vent_arr.items(); j++)
 | 
						|
    {
 | 
						|
      _VentItem* vv = (_VentItem*)&_vent_arr[j];
 | 
						|
      dst.add(vv->_totale/totacq);
 | 
						|
    }
 | 
						|
    
 | 
						|
    // 3.3) affetta l'importo
 | 
						|
    for (j = 0; j < _vent_arr.items(); j++)
 | 
						|
    {
 | 
						|
      _VentItem* vv = (_VentItem*)&_vent_arr[j];
 | 
						|
      real imponibile = dst.get();  
 | 
						|
      real div(1.0); div += vv->_aliquota;
 | 
						|
      real imposta    = imponibile - (imponibile/div);
 | 
						|
      imposta.ceil(ROUND_LIRA);
 | 
						|
      imponibile -= imposta;
 | 
						|
 | 
						|
      // aggiusto l'IVA vendite nei plm
 | 
						|
      look_plm(month, codatt);
 | 
						|
      real ive = _plm->get_real("R0");
 | 
						|
      ive     += imposta;
 | 
						|
      _plm->put("R0",ive);
 | 
						|
      _plm->rewrite();
 | 
						|
 | 
						|
      // Aggiorno i luridi pim
 | 
						|
      look_pim(month, codatt, vi->_codreg, "0", vv->_codiva, vi->_tipodet, TRUE);
 | 
						|
      
 | 
						|
      imponibile += _pim->get_real("R0");
 | 
						|
      imposta    += _pim->get_real("R1");
 | 
						|
      _pim->put("R0", imponibile);
 | 
						|
      _pim->put("R1", imposta);            
 | 
						|
      _pim->put("S4", vv->_other);
 | 
						|
      // segnale per comodita'
 | 
						|
      _pim->put("B1","X");
 | 
						|
      _pim->rewrite();
 | 
						|
    }
 | 
						|
  }   
 | 
						|
  // memorizza totali per il prospettino di m.
 | 
						|
  look_plm(month, codatt);
 | 
						|
 | 
						|
  // TBI PAM e PUM
 | 
						|
  _pam->put("R2",totacq);
 | 
						|
  _pam->put("R3",totven);
 | 
						|
  _pam->rewrite();
 | 
						|
}                               
 | 
						|
 | 
						|
 | 
						|
// questa serve per il rimborso secondo le
 | 
						|
// nuove cazzonorme
 | 
						|
class rObj : public TObject
 | 
						|
{  
 | 
						|
public:
 | 
						|
  real _imp;
 | 
						|
  real _iva;
 | 
						|
  real _perc;       
 | 
						|
  
 | 
						|
  rObj() {}
 | 
						|
  virtual ~rObj() {}
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
_DescrItem* TLiquidazione_app::recalc_rimborso(int month, const char* codatts)
 | 
						|
{
 | 
						|
  // calcola condizioni per il diritto al rimborso infracazzuale
 | 
						|
  // chiamata soltanto per i trimestri anche se annuale
 | 
						|
  // aggiornata a normative per anno liq. > 1994
 | 
						|
  
 | 
						|
  bool rimborsami = FALSE;
 | 
						|
  _DescrItem* d = NULL;
 | 
						|
  TToken_string atts(codatts);
 | 
						|
  const char* tmpatt; 
 | 
						|
  TString att;
 | 
						|
 | 
						|
  real es_ni   = 0.0;
 | 
						|
  real vol_aff = 0.0;;
 | 
						|
 | 
						|
  while ((tmpatt = atts.get()) != NULL)
 | 
						|
  {
 | 
						|
    att = tmpatt;
 | 
						|
    for (int m = month - 2; m <= month; m++)
 | 
						|
    { 
 | 
						|
      if (!look_plm(m,att)) continue;
 | 
						|
      
 | 
						|
      vol_aff   += _pam->get_real("R1");
 | 
						|
      es_ni     += _pum->get_real("R6");
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // condizione 1
 | 
						|
  if (!vol_aff.is_zero() && (es_ni/vol_aff) > MIN_PARTE_ESENTE)
 | 
						|
  {
 | 
						|
    rimborsami = TRUE;
 | 
						|
    d = new _DescrItem(RIMBORSO);
 | 
						|
    d->_f0 = TRUE;
 | 
						|
    d->_r0 = es_ni;
 | 
						|
    d->_r1 = vol_aff;
 | 
						|
  }
 | 
						|
 | 
						|
  
 | 
						|
  // ---------------------- condizione 2
 | 
						|
  // u'casinu pazzescu d'u nuiu guvernu 
 | 
						|
  
 | 
						|
  // due array dove ficcare i totali per 
 | 
						|
  // codiva in ordine di imponibile
 | 
						|
  TArray varr, aarr; 
 | 
						|
  real   vtot = 0.0;
 | 
						|
  real   atot = 0.0;
 | 
						|
  real   ivav = 0.0;
 | 
						|
  real   ivaa = 0.0; 
 | 
						|
  
 | 
						|
  // scorri i bellissimi progressivi mensili rimborso
 | 
						|
  for (_rmb->first(); !_rmb->eof(); _rmb->next()) 
 | 
						|
  {                                   
 | 
						|
    int year  = atoi((const char*)_year);
 | 
						|
    int ryear = atoi((const char*)(*_rmb_anno));
 | 
						|
    int rmese = atoi((const char*)(*_rmb_mese));
 | 
						|
    
 | 
						|
    if (year != ryear  || (rmese < (month - 2) || rmese > month))
 | 
						|
      continue; 
 | 
						|
    
 | 
						|
    real imp = _rmb->get("R0");
 | 
						|
    real iva = _rmb->get("R1");
 | 
						|
    real per = _rmb->get("R2");
 | 
						|
    
 | 
						|
    rObj* rb   = new rObj;
 | 
						|
    rb->_imp  = imp;
 | 
						|
    rb->_iva  = iva;
 | 
						|
    rb->_perc = per;
 | 
						|
    
 | 
						|
    TArray& arr = (tiporeg)atoi((const char*)(*_rmb_tiporeg)) == vendita ? varr : aarr;
 | 
						|
    
 | 
						|
    for (int i = 0; i < arr.items(); i++)
 | 
						|
    {
 | 
						|
      rObj& robj = (rObj&)arr[i];
 | 
						|
      if (robj._imp < imp) 
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    arr.insert(rb, i); 
 | 
						|
    
 | 
						|
    // totali imponibili 
 | 
						|
    if ((tiporeg)atoi((const char*)(*_rmb_tiporeg)) == vendita)
 | 
						|
      vtot += imp; 
 | 
						|
    else
 | 
						|
      atot += imp;
 | 
						|
  }
 | 
						|
  
 | 
						|
  // se ci sono due o piu' imponibili uguali devo
 | 
						|
  // sostituire l'imposta con la media delle aliquote
 | 
						|
  // ciclo uguale sui due array
 | 
						|
  for (int w = 0; w < 2; w++)
 | 
						|
  {               
 | 
						|
    TArray& arr = w == 0 ? varr : aarr;
 | 
						|
    for (int i = 0; i < arr.items(); i++)
 | 
						|
    {
 | 
						|
      rObj& robj  = (rObj&)arr[i];  
 | 
						|
      real impref = robj._imp;
 | 
						|
      real perc   = robj._perc;
 | 
						|
      
 | 
						|
      for (int j = i+1; j < arr.items(); j++)
 | 
						|
      {
 | 
						|
        rObj& rbj = (rObj&)arr[j];
 | 
						|
        if (rbj._imp != impref)
 | 
						|
          break;
 | 
						|
        perc += rbj._perc;
 | 
						|
      }
 | 
						|
      // riaggiustesbimo
 | 
						|
      if (j > i+1)
 | 
						|
      {
 | 
						|
        // funzionerebbe comunque ma risparmiamo una
 | 
						|
        // divisione per 1
 | 
						|
        real ndiv(j-i);
 | 
						|
        perc /= ndiv;
 | 
						|
        for (; i < j; i++)
 | 
						|
        {
 | 
						|
          rObj& rbj = (rObj&)arr[i];
 | 
						|
          rbj._iva  = rbj._imp * (perc/CENTO);
 | 
						|
          rbj._iva.round(ROUND_LIRA);
 | 
						|
        }
 | 
						|
        i --;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  // 51 per  cento
 | 
						|
  vtot *= PERC_IMP_RIMBORSABILE;
 | 
						|
  atot *= PERC_IMP_RIMBORSABILE;  
 | 
						|
  
 | 
						|
  real alv = 0.0;    // aliquota media vendite
 | 
						|
  real ala = 0.0;    // aliquota media acquisti  
 | 
						|
  
 | 
						|
  for (w = 0; w < 2; w++)
 | 
						|
  {               
 | 
						|
    TArray& arr  = w == 0 ? varr : aarr; 
 | 
						|
    real    timp = w == 0 ? vtot : atot; 
 | 
						|
    real    tiva = 0.0;
 | 
						|
    
 | 
						|
    for (int i = 0; i < arr.items(); i++)
 | 
						|
    {
 | 
						|
      rObj& robj  = (rObj&)arr[i]; 
 | 
						|
      if (timp >= robj._imp)
 | 
						|
      {
 | 
						|
        tiva += robj._iva;
 | 
						|
        timp -= robj._imp;
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        real perc = timp/robj._imp;
 | 
						|
        if (!perc.is_zero())
 | 
						|
        {
 | 
						|
          real ttiv = robj._iva * perc;
 | 
						|
          ttiv.round(ROUND_LIRA);
 | 
						|
          tiva += ttiv;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
      } 
 | 
						|
    } 
 | 
						|
    if (w == 0) ivav = tiva;
 | 
						|
    else        ivaa = tiva; 
 | 
						|
  }
 | 
						|
  
 | 
						|
  // finalmente
 | 
						|
  alv = ivav/vtot;  alv.round(2);
 | 
						|
  ala = ivaa/atot;  ala.round(2);
 | 
						|
  
 | 
						|
  if (ala > alv)
 | 
						|
  {
 | 
						|
    rimborsami = TRUE;
 | 
						|
    if (d == NULL) d = new _DescrItem(RIMBORSO);
 | 
						|
    d->_f1 = TRUE;
 | 
						|
    d->_r2 = vtot; 
 | 
						|
    d->_r3 = atot; 
 | 
						|
    d->_r4 = ivav; 
 | 
						|
    d->_r5 = ivaa; 
 | 
						|
    d->_r6 = alv * CENTO; 
 | 
						|
    d->_r7 = ala * CENTO; 
 | 
						|
  } 
 | 
						|
  
 | 
						|
  if (rimborsami)
 | 
						|
  {
 | 
						|
    look_lim(month);
 | 
						|
    _lim->put("B2", "X");
 | 
						|
    _lim->rewrite();
 | 
						|
  }
 | 
						|
  return d;
 | 
						|
}
 |