#include "cg2103.h"

#include <diction.h>
#include <recarray.h>
#include <tabutil.h>

#include <causali.h>
#include <rcausali.h>

///////////////////////////////////////////////////////////
// Causale
///////////////////////////////////////////////////////////

TCausale::TCausale(const char* cod, int year) 
        : TArray(12), _rec(LF_CAUSALI), 
          _iva(iva_errata), _corrisp(false),
          _sezione_clifo(' '), _sezione_ritsoc(' '), _sezione_ritfis(' '),
          _provvisorio(' ')

{
  if (cod && *cod) 
    read(cod, year);

}


// Legge le righe della causale attualmente selezionata sulla maschera
bool TCausale::read(const char* cod, int year)
{
  _rec.zero();                                        // Delete header
  destroy();                                          // Delete all rows
  _iva = iva_errata;                                  // Delete misc info
  _sezione_clifo = _sezione_ritsoc = _provvisorio = ' ';
  _corrisp = false;

  if (cod && *cod > ' ')
  { 
    _rec = cache().get(LF_CAUSALI, cod);
    if (_rec.empty())
      return false;
    
		_provvisorio = _rec.get_char(CAU_PROVV);
    TLocalisamfile rcaus(LF_RCAUSALI);                        
    rcaus.put(CAU_CODCAUS, cod);
    rcaus.put(CAU_NRIGA, 0);          
    
    int err;
    for (err = rcaus.read(_isgteq);                       // Find first line
         err == NOERR && rcaus.get(CAU_CODCAUS) == cod;
         err = rcaus.next())                              // Read next line
    {
      const int riga = rcaus.get_int(CAU_NRIGA);
      add(rcaus.curr(), riga);
    } 
    
    const TString4 codreg(_rec.get(CAU_REG));
    const bool ok = _reg.read(codreg, year);         // Read register
    if (!ok && codreg.not_empty()) 
      return error_box(FR("Non esiste il registro '%s' del %d"), 
                       (const char*)codreg, year);
    calcIVA();
  }
  else 
  {
    _iva = nessuna_iva;                                // Clear IVA data
    _corrisp = false;
    _reg.read("", year);
  }                            

  return true;
}


TBill& TCausale::bill(int num, TBill& conto) const
{
  const TRectype* rec = row(num);
  if (rec != NULL)
    conto.set(rec->get_int(RCA_GRUPPO), rec->get_int(RCA_CONTO),
              rec->get_long(RCA_SOTTOCONTO), rec->get_char(RCA_TIPOCF));
  return conto;
}   

const char* TCausale::desc_agg(int num) const
{         
  const char* deag = "";
  
  const TRectype* rec = row(num);
  if (rec != NULL)
  {  
    const TString& cod = rec->get(RCA_CODDESC);
    if (cod.not_empty())
    {
      const TRectype& da = cache().get("%DPN", cod);
      deag = da.get("S0");
    }
  }    
  
  return deag;
}   

const char* TCausale::descrizione() const
{ return _rec.get(CAU_DESCR); }

const char* TCausale::codice() const
{ return _rec.get(CAU_CODCAUS); }


bool TCausale::data_doc() const 
{ return _rec.get_bool(CAU_DATADOC); }

bool TCausale::num_doc() const 
{ return _rec.get_bool(CAU_NUMDOC); }

bool TCausale::apertura() const 
{ return _rec.get_char(CAU_MOVAP) == 'A'; }

bool TCausale::chiusura() const 
{ return _rec.get_char(CAU_MOVAP) == 'C'; }

bool TCausale::sezionale() const 
{ return _rec.get_bool(CAU_MOVSEZ); }

bool TCausale::valuta() const 
{ return _rec.get_bool(CAU_MOVVAL); }

bool TCausale::intra() const 
{ return _rec.get_bool(CAU_INTRACOM); }

bool TCausale::valintra() const 
{ return _rec.get_bool(CAU_VALINTRA); }

bool TCausale::soloiva() const 
{ return _rec.get_bool(CAU_SOLOIVA); }

int TCausale::regime_speciale() const 
{ return _rec.get_int(CAU_REGSPIVA); }

bool TCausale::esclusione_allegati() const
{ return _rec.get_bool(CAU_ALLEG); }

const TString& TCausale::causale_collegata() const 
{ return _rec.get(CAU_CODCAUSIM); }

const TString& TCausale::causale_reg_iva() const 
{ return _rec.get(CAU_CODCAUREG); }

const TString& TCausale::tipo_doc() const 
{ return _rec.get(CAU_TIPODOC); }

int TCausale::tipomov() const
{ return _rec.get_int(CAU_TIPOMOV); }

const TString& TCausale::tipodoc() const
{ return _rec.get(CAU_TIPODOC); }

bool TCausale::saldaconto(const TDate& datareg) const
{ 
  bool yes = tipomov() > 0;
  if (yes && datareg.ok())
  {
    static TDate _data_sal = ini_get_string(CONFIG_DITTA, "cg", "DatSal");
    yes = datareg >= _data_sal;
  }
  return yes; 
}

int TCausale::link_m770() const
{ return _rec.get_int(CAU_M770); }

char TCausale::link_cespiti() const
{ return _rec.get_char(CAU_COLLCESP); }

bool TCausale::link_analitica() const
{ return _rec.get_bool(CAU_MOVIND); }

bool TCausale::ok() const
{
  return iva() != iva_errata;
}

char TCausale::sezione(int riga) const
{ 
  const TRectype* rec = row(riga);
  char sez = rec ? toupper(rec->get_char(RCA_SEZIONE)) : ' ';
  if (sez <= ' ')                                  // Guess section on tipocf
  {
    const TRectype* uno = row(1);
    char tipocf = uno ? toupper(uno->get_char(RCA_TIPOCF)) : ' ';
    if (tipocf <= ' ') 
      tipocf = (iva() == iva_vendite) ? 'C' : 'F'; // Guess tipocf on IVA
    sez = (tipocf == 'C') ? 'D' : 'A';
  }  
  return sez;
}

char TCausale::sezione_clifo() const
{
  if (_sezione_clifo <= ' ')
    (char&)_sezione_clifo = sezione(1);
  return _sezione_clifo;
}

char TCausale::sezione_ritsoc() const
{
  if (_sezione_ritsoc <= ' ')
  {
    // Fatture o Pagamenti?
    const int tm = _rec.get_int(CAU_TIPOMOV);
    (char&)_sezione_ritsoc = sezione(tm <= 2 ? 9 : 14);
  }
  return _sezione_ritsoc;
}

char TCausale::sezione_ritfis()

{
  if (_sezione_ritfis == ' ')

  {
    if (_rec.get_int(CAU_TIPOMOV) <= 2)
      _sezione_ritfis = sezione(8);  // Fatture
    else
      _sezione_ritfis = sezione(12); // Pagamenti

  }
  return _sezione_ritfis;
}

void TCausale::calcIVA()
{
  TipoIVA i = nessuna_iva;                          // Tipo IVA di default
  bool c = false;                                   // Corrispettivi di default
    
  const TString& td = tipo_doc();
  if (td.full())
  {
    const TRectype& tpd = cache().get("%TPD", td);
    if (!tpd.empty())
    {
      i = (TipoIVA)tpd.get_int("I0");               // IVA acquisti, vendite, generica
      const TipoIVA ri = _reg.iva();
      if (i == iva_generica)
        i = ri;
      if (i != ri) 
      {
        error_box(FR("Tipo documento '%s' incompatibile con tipo registro"), (const char*)td);
        i = iva_errata;
      }  
      c = tpd.get_bool("B0");                       // B0 flag corrispettivi
    }
    else 
      error_box(FR("Tipo documento sconosciuto: '%s'"), (const char*)td);
  }
  _iva = i;                    
  _corrisp = c;          
}  

const TString& TCausale::compatible(const TCausale& c) const
{                                         
  const char* err = NULL;
  if (sezionale() != c.sezionale()) 
    err = TR("il segnale di sezionale");
  if (intra() != c.intra()) 
    err = TR("la gestione dei movimenti intra");
  if (valuta() != c.valuta()) 
    err = TR("la gestione valuta");
  if (valintra() != c.valintra()) 
    err = TR("la gestione valuta intracomunitaria");
  if (corrispettivi() != c.corrispettivi()) 
    err = TR("la gestione dei corrispettivi");
  if (iva() != c.iva()) 
    err = TR("il tipo di IVA"); 
  if (tipomov() != c.tipomov()) 
    err = TR("il tipo di movimento");
  
  if (err != NULL)  
  {
    TString& msg = get_tmp_string();
    msg.format(FR("La causale e' incompatibile per %s"), err);
    return msg;
  }

  return EMPTY_STRING;
}
 
bool TCausale::IVA2bill(const TCodiceIVA& iva, TBill& c) const
{
  const TString& tipo = iva.tipo();
  
  if (tipo.not_empty())
  {
    if (tipo == "ES") bill(5, c); else
      if (tipo == "NI") bill(6, c); else
        if (tipo == "NS") bill(7, c);
  }  

  if (!c.ok()) 
    bill(2, c);
  
  const int spric = c.tipo_cr();
  if (spric == 2 || spric == 3)
  {
    const TString& td = tipo_doc();
    if (td == "FV" || td == "NC") 
      c.tipo_cr(4);
  } 
  
  return c.ok();  
}