#include <applicat.h>
#include <tabutil.h>

#include "cg0501.h"

#include <causali.h>


const char* iva2name(TipoIVA iva)
{
  const char* i;
  switch(iva)
  {
  case nessuna_iva : 
    i = "Nessuna IVA"; break;
  case iva_acquisti: 
    i = "IVA Acquisti"; break;
  case iva_vendite : 
    i = "IVA Vendite"; break;
  case iva_generica: 
    i = "IVA Generica"; break;
    default          : 
    i = "IVA ERRATA!"; break;
  }
  
  return i;
}

///////////////////////////////////////////////////////////
// Registro
///////////////////////////////////////////////////////////

TRegistro::TRegistro(const char* cod, int year) : _rec(LF_TAB), _att(LF_ATTIV)
{
  read(cod, year);
}


bool TRegistro::read(const char* cod, int year)
{               
  if (year <= 0) 
  {
    const TDate oggi(TODAY);
    year = oggi.year();
  }

  int err = ~NOERR;
  
  TTable reg("REG");
  if (cod && *cod > ' ')
  {
    TString16 chiave;
    chiave << year << cod;
    reg.put("CODTAB", chiave);
    err = reg.read(); 
  }
  _rec = reg.curr();
  
  if (_att.ok())  
    _att.zero();
  if (err != NOERR)
    _rec.zero();
  return err == NOERR;
}           


int TRegistro::year() const 
{ return ok() ? atoi(_rec.get("CODTAB")) : 0; }



TRegistro& TRegistro::operator =(const TRegistro& r)
{ 
  _rec = r._rec; 
  _att = r._att;
  return *this;
}


int TRegistro::tipo() const
{
  const int t = ok() ? _rec.get_int("I0") : 0;
  return t;
}


bool TRegistro::corrispettivi() const
{
  const bool c = ok() ? _rec.get_bool("B0") : FALSE;
  return c;
}


TipoIVA TRegistro::iva() const
{ 
  TipoIVA i = (TipoIVA)tipo();
  if (i != nessuna_iva && i != iva_vendite && i != iva_acquisti)
  {
    error_box("Il registro '%s' non e' un registro IVA o contabile: tipo %d", 
              (const char*)name(), i);
    i = nessuna_iva;
  }
  return i;     
} 

bool TRegistro::read_att()
{
  if (!_att.empty()) 
    return TRUE;

  TLocalisamfile attiv(LF_ATTIV);
  attiv.put("CODDITTA", MainApp()->get_firm());
  attiv.put("CODATT", attivita());
  const int err = attiv.read();
  _att = attiv.curr();
  if (err != NOERR)
    _att.zero();
  
  return err == NOERR;
}

bool TRegistro::agenzia_viaggi()
{                             
  if (iva() != iva_vendite)
    return FALSE;

  bool av = FALSE;
  if (read_att()) av = _att.get_bool("REG74TER");
  
  return av;
}

const TString& TRegistro::tipo_attivita()
{
  read_att();
  return _att.get("TIPOATT");
}


// Certified 99%                       
bool TRegistro::update(long protiva, const TDate& datareg)
{ 
  bool updated = TRUE;
  
  if (protiva > _rec.get_long("I5"))
  {
    _rec.put("I5", protiva);
    updated = FALSE;
  }  
  if (datareg > _rec.get_date("D2"))
  {
    _rec.put("D2", datareg);
    updated = FALSE;
  }  
  if (!updated)
  { 
    TTable reg("REG");
    updated = reg.rewrite(_rec) == NOERR;
  }  
  
  return updated;
}

///////////////////////////////////////////////////////////
// Libro giornale
///////////////////////////////////////////////////////////

// Legge il libro giornale dell'anno specificato
bool TLibro_giornale::read(int y)
{
  if (y <= 0) 
  {
    const TDate oggi(TODAY);
    y = oggi.year();
  }
  
  TTable reg("REG");
  bool found = FALSE;                 
  
  TString16 anno; anno.format("%-4d", y);
  
  reg.setkey(1);                                  
  reg.put("CODTAB", anno);                    // Cerca il primo registro dell'anno y
  
  for (int err = reg.read(_isgteq); err == NOERR; err = reg.next())
  {
    if (strncmp(reg.get("CODTAB"), anno, 4) != 0) break;
    if (reg.get_int("I0") == libro_giornale)
    {       
      found = TRUE;
      break;
    }  
  }
  
  if (!found) reg.zero();                     // Memorizza record (anche vuoto)
  _rec = reg.curr();
  
  return found;
}

TLibro_giornale::TLibro_giornale(int y)
{
  read(y);
}

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

TCausale::TCausale(const char* cod, int year) 
: TArray(12), _rec(LF_CAUSALI), _iva(iva_errata)
{
  if (*cod) read(cod, year);
}


// Legge le righe della causale attualmente selezionata sulla maschera
bool TCausale::read(const char* cod, int year)
{
  destroy();                                          // Delete all rows

  if (*cod > ' ')
  {
    _iva = iva_errata;

    TLocalisamfile caus(LF_CAUSALI);
    caus.setkey(1);
    caus.zero();
    caus.put(CAU_CODCAUS, cod);

    int err = caus.read();
    _rec = caus.curr();
    if (err != NOERR) return FALSE;

    TLocalisamfile rcaus(LF_RCAUSALI);                        
    rcaus.setkey(1);
    rcaus.zero();
    rcaus.put(CAU_CODCAUS, cod);
    rcaus.put(CAU_NRIGA, 0);          
    
    err = rcaus.read(_isgteq);                         // Find first line
    if (err != NOERR) return FALSE;
    
    while (err == NOERR && rcaus.get(CAU_CODCAUS) == cod)
    {
      const int riga = rcaus.get_int(CAU_NRIGA);
      add(rcaus.curr(), riga);
      err = rcaus.next();                              // Read next line
    } 
    rcaus.zero();                                      
    for (int riga = 1; riga < size(); riga++)          // Fill gaps
      if (objptr(riga) == NULL) add(rcaus.curr(), riga);

    TString16 codreg(caus.get("REG"));
    const bool ok = _reg.read(codreg, year);         // Read register
    if (!ok && codreg.not_empty()) 
      return error_box("Non esiste il registro '%s' per l'anno %d", 
                       (const char*)codreg, year);
  }
  else 
  {
    _iva = nessuna_iva;                                // Clear IVA data
    _reg.read("", year);
  }                            

  return TRUE;
}

const TRectype& TCausale::row(int num) const
{
  const TRectype* rec = (const TRectype*)objptr(num);
  CHECKD(rec, "Manca la riga di causale ", num);
  return *rec;
}


TConto& TCausale::bill(int num, TConto& conto) const
{
  const TRectype& rec = row(num);
  conto.set(rec.get_int("GRUPPO"), rec.get_int("CONTO"),
            rec.get_long("SOTTOCONTO"), rec.get_char("TIPOCF"));
  return conto;
}   

bool TCausale::data_doc() const 
{ return _rec.ok() ? _rec.get_bool("DATADOC") : FALSE; }

bool TCausale::num_doc() const 
{ return _rec.ok() ? _rec.get_bool("NUMDOC") : FALSE; }

bool TCausale::apertura() const 
{ return _rec.ok() ? _rec.get_char("MOVAP") == 'A' : FALSE; }

bool TCausale::sezionale() const 
{ return _rec.ok() ? _rec.get_bool("MOVSEZ") : FALSE; }

bool TCausale::valuta() const 
{ return _rec.ok() ? _rec.get_bool("MOVVAL") : FALSE; }

bool TCausale::intra() const 
{ return _rec.ok() ? _rec.get_bool("INTRACOM") : FALSE; }

bool TCausale::corrval() const 
{ return _rec.ok() ? _rec.get_bool("VALINTRA") : FALSE; }

int TCausale::tipo_mov() const 
{ return _rec.ok() ? _rec.get_int("TIPOMOV") : -1; }

const char* TCausale::cod_reg() const 
{ return _rec.ok() ? _rec.get("REG") : ""; }

const char* TCausale::causale_inc_imm() const 
{ return _rec.ok() ? _rec.get("CODCAUSIM") : ""; }

const char* TCausale::tipo_doc() const 
{ return _rec.ok() ? _rec.get("TIPODOC") : ""; }


bool TCausale::puramentecontabile() const 
{
  const char * codreg = cod_reg();
  return ((codreg == NULL || *codreg == '\0') && tipo_mov() == 0);
}

TipoIVA TCausale::iva() const
{
  if (_iva == iva_errata)
  {      
    TipoIVA i = nessuna_iva;
    
    if (ok())
    {           
      TString tipodoc(_rec.get("TIPODOC"));
      if (tipodoc.not_empty())
      {
        TTable tpd("%TPD");
        tpd.put("CODTAB", tipodoc);
        if (tpd.read() == NOERR)
        {
          i = (TipoIVA)tpd.get_int("I0");               // IVA acquisti, vendite, generica
          if (i == iva_generica)
            i = _reg.iva();
        }
      }
    }
    ((TCausale*)this)->_iva = i;                        // Ricorda IVA per la prossima volta
  }
  return _iva;  
}  


bool TCausale::similar(const TCausale& c) const
{
  return iva() == c.iva() &&
    sezionale() == c.sezionale() &&
      valuta() == c.valuta() &&
        intra() == c.intra();
}

///////////////////////////////////////////////////////////
// Codice IVA
///////////////////////////////////////////////////////////

TCodiceIVA::TCodiceIVA(const char* cod) : TRectype(LF_TABCOM)
{
  read(cod);
}                 

bool TCodiceIVA::read(const char* cod)
{   
  int err = ~NOERR;
  TTable iva("%IVA");
  if (cod && *cod)
  {
    iva.setkey(1);
    iva.put("CODTAB", cod);
    err = iva.read();
  }   
  TRectype::operator=(iva.curr());
  if (err != NOERR) zero();
  return err == NOERR;
}