// -----------------------------------------------------------------
// 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);

  real r0 = _ppa_r->get("R0");
  real r1 = _ppa_r->get("R1");
  real r2 = _ppa_r->get("R2");

  if (intra) r1 += howmuch; else r0 += howmuch;

  if (r2 < (r0+r1))
    describe_error("Acquisti in eccesso rispetto al plafond disponibile",
                   codatt);

  r2 -= (r0+r1);
  if (r2.sign() < 0) r2 = 0.0;

  _ppa_r->put("R0",r0);
  _ppa_r->put("R1",r1);
  _ppa_r->put("R2",r2);
  
  _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 (!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->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, "0", ci->_codiva, TRUE);
    
    imponibile += _pim->get_real("R0");
    imposta    += _pim->get_real("R1");
    _pim->put("R0", imponibile);
    _pim->put("R1", imposta);

    // segnale per comodita'
    _pim->put("B1","X");
    _pim->rewrite();
  }   
}

// ricalcolo della malefica ventilazione
void TLiquidazione_app::recalc_ventilation(int month, const char* codatt)
{
  if (_vend_arr.items() == 0) return;

  TString att(codatt);
  //  look_pla(att);
  //  _pla->put("B0","X");
  //  _pla->rewrite();
  _isvent = TRUE;

  // 1) ricalcola i pim dei mesi dal primo al corrente se necessario
  for (int m = 1; m < month; m++)
    if (is_month_ok(m)) update_att(m,codatt, FALSE);

  _vent_arr.destroy();
  
  for (m = 1; m <= month; m++)
  {
    if (is_month_ok(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);
        TString att(codatt); 
        if (tipocr == 1 && mese == m && 
            att == (const char*)(*_pim_codatt))
          
        {
          look_iva(*_pim_codiva);

          // soltanto normali ed esenti IVA sono base di riparto
          if (_iva->get("S1").empty() ||
              _iva->get("S1") == "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);
          }
        }
      }
    }
  }
  
  // 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/div;
      imposta.round(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, TRUE);
      
      imponibile += _pim->get_real("R0");
      imposta    += _pim->get_real("R1");
      _pim->put("R0", imponibile);
      _pim->put("R1", imposta);
      // segnale per comodita'
      _pim->put("B1","X");
      _pim->rewrite();
    }
  }   
  // memorizza totali per il prospettino di m.
  look_ptm(month, codatt);
  _ptm->put("S4",totacq.string());
  _ptm->put("S5",totven.string());
  _ptm->rewrite();
}











