// cg3301.cpp
//
// classi di supporto per cg3300_application
//

#include <lffiles.h>
#include <isam.h>
#include <tabutil.h>
#include <strings.h>
#include <scanner.h>

#include <comuni.h>
#include <clifo.h>
#include <alleg.h>
#include <nditte.h>
#include <anagr.h>
#include <anafis.h>
#include <anagiu.h>

#include "cg3300.h"

const int CODTABLEN = 15;

#define MAXSTR 128
static char __tmp[MAXSTR];
static TFixed_string tmp(__tmp, MAXSTR);

//
// SortRecord
//

SortRecord::SortRecord()
{
  _all      = new struct alleg_sort;
  _clifo    = new TLocalisamfile(LF_CLIFO);
  _comuni   = new TLocalisamfile(LF_COMUNI);
  _anagfis  = new TLocalisamfile(LF_ANAGFIS); 
  _anaggiu  = new TLocalisamfile(LF_ANAGGIU); 
  _anag     = new TLocalisamfile(LF_ANAG); 
  _attiv    = new TTable("%AIS");
  _tpd      = new TTable("%TPD");
  azzera_struttura();
}

SortRecord::~SortRecord()
{
  delete _clifo; delete _comuni; delete _attiv; delete _tpd;
  delete _anagfis; delete _anaggiu; delete _anag;
  delete _all;
}

long SortRecord::cerca_codice_all(TString tipo, long codcf) 
{
  TLocalisamfile& clifo = *_clifo;

  clifo.zero();
  clifo.put (CLI_TIPOCF, tipo);
  clifo.put (CLI_CODCF,  codcf);
  clifo.read();

  if (clifo.good()) 
  {
    long codice_all = clifo.get_long (CLI_CODALLEG);
    return codice_all;
  }

  return 0L;
}

const char * SortRecord::decodifica_desc_att (TString & codatt)
{
  TTable& attivita = * _attiv;

  attivita.zero();
  attivita.put ("CODTAB", codatt);

  attivita.read();

  if (attivita.bad())
    attivita.zero();
  
  tmp = attivita.get ("S0");

  return __tmp;
}

bool SortRecord::corrispettivo (const char * tipodoc)
{
  TTable& tpd = * _tpd;
  TString natura_doc;
  bool    corrisp;

  tpd.zero();
  tpd.put ("CODTAB", tipodoc);
  tpd.read();
  if (tpd.bad())
    tpd.zero();

  natura_doc = tpd.get("I0");
  corrisp    = tpd.get_bool ("B0");
  
  if ((natura_doc == "1") || (natura_doc == "9"))
    if (corrisp)
      return TRUE;  

  return FALSE;
}

TRectype& SortRecord::look_com (const char * cod)
{
  TLocalisamfile&  com = *_comuni;

  com.zero();
  com.put (COM_COM, cod);

  com.read();

  if (com.bad())
    com.zero();

  return com.curr();
}

//
// Ricerca la ragione sociale in clifo
// Controlla il tipo di persona , se fisica scrive nome e cognome 
// e tipo di persona nella struttura puntata da _RecordSort->Strutt 
// Se e' persona fisica mette a '\0' il campo ragsoc_dett
//
// Ritorna la ragione sociale oppure NULL
//
const char * SortRecord::fill_dati_dettaglio (const char * tipocf, long codcf)
{
  TLocalisamfile& clifo = *_clifo;
  static char _rag[51];
  TString tipop, cog, nom, rag;
  TString indcf, comcf;
  TString stato, paiva;

  clifo.zero();
  clifo.put (CLI_TIPOCF, tipocf);
  clifo.put (CLI_CODCF,  codcf); 
  clifo.read();

  if ((clifo.good()))
  {
    tipop = clifo.get (CLI_TIPOPERS); 
    rag   = clifo.get (CLI_RAGSOC); 

    indcf = clifo.curr().get (CLI_INDCF); 
    indcf << ", " << clifo.curr().get (CLI_CIVCF);
    comcf  = clifo.curr().get (CLI_COMCF); 
    
    TRectype dep = look_com ((const char *)comcf);
    strcpy (_all->comune_dett , dep.get(COM_DENCOM));
    strcpy (_all->prov_dett   , dep.get(COM_PROVCOM));

    strcpy (_all->via_dett     , indcf);

    paiva = clifo.curr().get (CLI_PAIV);
    stato = clifo.curr().get (CLI_STATOPAIV);

    strcpy (_all->paiva_dett  , paiva);
    strcpy (_all->statopaiva_dett  , stato);

    strcpy (_all->ragsoc_dett  , rag);

    if (tipop == "F")
    {
      cog    = rag.left(30); 
      nom    = rag.mid (31);
      strcpy (_all->cognome_dett , cog.trim());
      strcpy (_all->nome_dett   , nom.trim());
      //
      // N.B.
      // Azzero la ragione sociale se persona fisica. 
      // 
      strcpy (_all->ragsoc_dett , "\0");
    }
    strcpy (_rag, (const char*) rag);
    return _rag;
  }
  return NULL;
}

//
// SortRecord::somma
//
// Somma gli importi dal record corrente di alleg nella struttura
// corrente.
// Incrementa SOLO i totali di riga (che sono nella struttura)
// NON i totali e i riporti in fondo alla pagina
//
void SortRecord::somma (TLocalisamfile * alleg, stampe tipo_stampa)
{
  switch (tipo_stampa)
  {
  case fornitori:
  case clienti:
    _all->impesc  += alleg->curr().get_real (ALL_IMPESC);
    _all->ivaesc  += alleg->curr().get_real (ALL_IVAESC);
    _all->niesc   += alleg->curr().get_real (ALL_NIESC);
    _all->e8esc   += alleg->curr().get_real (ALL_E8ESC);
    _all->ndocesc += alleg->curr().get_int  (ALL_NDOCESC);

    _all->impesp  += alleg->curr().get_real (ALL_IMPESP);
    _all->ivaesp  += alleg->curr().get_real (ALL_IVAESP);
    _all->niesp   += alleg->curr().get_real (ALL_NIESP);
    _all->e8esp   += alleg->curr().get_real (ALL_E8ESP);
    _all->ndocesp += alleg->curr().get_int  (ALL_NDOCESP);

    // Incremento totali di riga
    _all->tot_rigac += _all->impesc + _all->ivaesc + _all->niesc + _all->e8esc;
    _all->tot_rigap += _all->impesp + _all->ivaesp + _all->niesp + _all->e8esp;

    break;

  case modulo101:
  case modulo102:
    _all->prog101102 += alleg->get_real("ALL_PROG101102");
    break;

  default:
    break;
  }
}

void SortRecord::azzera_struttura()
{
  _all->codditta_dic = -1;
  strcpy (_all->tipopers_dic,   "\0");
  strcpy (_all->paiva_dic,      "\0");
  strcpy (_all->cognome_dic,    "\0");
  strcpy (_all->nome_dic,       "\0");
  strcpy (_all->ragsoc_dic,     "\0");
  _all->datana_dic = "";
  strcpy (_all->sesso_dic, "\0");
  strcpy (_all->comunena_dic, "\0");
  strcpy (_all->provna_dic, "\0");
  strcpy (_all->viafis_dic, "\0");  // via + numero civico
  strcpy (_all->comunefis_dic, "\0");
  strcpy (_all->provfis_dic , "\0");
  strcpy (_all->attivita_dic , "\0");
  strcpy (_all->codatt_dic , "\0");

  _all->natgiu_dic = 0;

  strcpy (_all->codatt_dett, "\0");
  strcpy (_all->tipopers_dett, "\0");

  _all->codcf_dett = -1;      // usato in da_sommare() per distinguere 
  // il primo record

  strcpy (_all->ragsoc_dett , "\0");
  strcpy (_all->cognome_dett , "\0");
  strcpy (_all->nome_dett    , "\0");
  strcpy (_all->via_dett     , "\0");
  strcpy (_all->comune_dett  , "\0");
  strcpy (_all->prov_dett    , "\0");
  strcpy (_all->statopaiva_dett    , "\0");
  strcpy (_all->paiva_dett    , "\0");

  _all->anno    = 0;
  _all->immesso = FALSE;

  _all->impesc  = 0.00;
  _all->ivaesc  = 0.00;
  _all->niesc   = 0.00;
  _all->e8esc   = 0.00;
  _all->ndocesc = 0;

  _all->impesp  = 0.00;
  _all->ivaesp  = 0.00;
  _all->niesp   = 0.00;
  _all->e8esp   = 0.00;
  _all->ndocesp = 0;

  _all->tot_rigac   = 0.00;
  _all->tot_rigap   = 0.00;

  _all->prog101102  = 0.00;

}

// -----------------------------------------------------------------
// COMPILA
// 
// Compila la struttura _RecordSort->Strutt leggendo da _alleg
// Scarta i record con l'anno diverso da quello specificato 
// nella maschera.
//
void SortRecord::compila(TLocalisamfile * _alleg)
{
  TString tipoa; 
  long    codcf;

  //  azzera_struttura();
  
  tipoa = _alleg->curr().get (ALL_TIPOCF);
  strcpy (_all->tipopers_dett, tipoa);

  //  strcpy (_all->tipopers_dett, _alleg->curr().get (ALL_TIPOCF));

  codcf = _alleg->curr().get_long (ALL_CODCF);
  _all->codcf_dett   = codcf;

  //  _RecordSort->Strutt()->codcf_dett   = _alleg->curr().get_long (ALL_CODCF);

  //  strcpy (_RecordSort->Strutt()->paiva_dett, get_paiva_cf (tipoa, codcf));

  //
  // QUI CAMBIA IL CODICE ATTIVITA
  //
  strcpy (_all->codatt_dett, _alleg->curr().get (ALL_CODATT));

  _all->immesso = _alleg->curr().get_bool (ALL_IMMESSO);

  _all->impesc  = _alleg->curr().get_real (ALL_IMPESC);
  _all->ivaesc  = _alleg->curr().get_real (ALL_IVAESC);
  _all->niesc   = _alleg->curr().get_real (ALL_NIESC);
  _all->e8esc   = _alleg->curr().get_real (ALL_E8ESC);
  _all->ndocesc = _alleg->curr().get_int  (ALL_NDOCESC);

  _all->impesp  = _alleg->curr().get_real (ALL_IMPESP);
  _all->ivaesp  = _alleg->curr().get_real (ALL_IVAESP);
  _all->niesp   = _alleg->curr().get_real (ALL_NIESP);
  _all->e8esp   = _alleg->curr().get_real (ALL_E8ESP);
  _all->ndocesp = _alleg->curr().get_int  (ALL_NDOCESP);

  _all->prog101102 = _alleg->curr().get_real (ALL_PROG101102);

  fill_dati_dettaglio (tipoa, codcf);
}

bool SortRecord::fill_dati_anag_dic (TLocalisamfile * nditte)
{
  TLocalisamfile& anagfis = *_anagfis; 
  TLocalisamfile& anaggiu = *_anaggiu; 
  TLocalisamfile& anag    = *_anag; 
  TString         codanagr;
  TString         tipoa;
  TString         comodo;

  _all->codditta_dic        = nditte->get_long(NDT_CODDITTA);
  comodo                    = nditte->get(NDT_CODATTPREV);

  strcpy (_all->codatt_dic,   comodo);
  if (comodo.not_empty())
    comodo = decodifica_desc_att (comodo); 

  if (comodo.not_empty())
    strcpy (_all->attivita_dic, comodo);
  else
    strcpy (_all->attivita_dic, "\0");

  codanagr = nditte->curr().get(NDT_CODANAGR);
  tipoa    = nditte->curr().get(NDT_TIPOA);

  strcpy (_all->tipopers_dic, tipoa);

  anag.setkey(1);
  anag.curr().zero();
  anag.curr().put (ANA_TIPOA, tipoa);
  anag.curr().put (ANA_CODANAGR, codanagr);
  if (anag.read() == NOERR)
  { 
    strcpy (_all->paiva_dic,     anag.curr().get (ANA_PAIV));
    strcpy (_all->ragsoc_dic   , anag.curr().get(ANA_RAGSOC));
    strcpy (_all->comunefis_dic, anag.curr().get(ANA_COMRF));
  }
  else
  { 
    strcpy (_all->paiva_dic,     "\0");
    strcpy (_all->ragsoc_dic   , "\0");
    strcpy (_all->comunefis_dic, "\0");
  }

  if (_all->comunefis_dic[0] == '\0') 
  {
    strcpy (_all->comunefis_dic, anag.curr().get(ANF_COMRES));

    TRectype dep = look_com (_all->comunefis_dic);

    strcpy (_all->comunefis_dic , dep.get(COM_DENCOM));
    strcpy (_all->provfis_dic   , dep.get(COM_PROVCOM));
    comodo = anag.curr().get(ANA_INDRES);
    comodo.rtrim();
    comodo << " " << anag.curr().get (ANA_CIVRES); 
    strcpy (_all->viafis_dic , (const char *) comodo);
  }
  else
  {
    TRectype dep = look_com (_all->comunefis_dic);
    strcpy (_all->comunefis_dic, dep.get(COM_DENCOM));
    strcpy (_all->provfis_dic  , dep.get(COM_PROVCOM));
    comodo = anag.curr().get(ANA_INDRF);
    comodo.rtrim();
    comodo << " " << anag.curr().get (ANA_CIVRF); 
    
    strcpy (_all->viafis_dic, comodo);
  }

  if (tipoa[0] == 'F')
  {
    TString cognome, nome;

    comodo = _all->ragsoc_dic;
    cognome = comodo.sub(0,29);
    cognome.trim();
    strcpy (_all->cognome_dic, cognome);

    comodo = _all->ragsoc_dic;
    nome = comodo.mid(30);
    nome.trim();
    strcpy (_all->nome_dic, nome);

    anagfis.setkey(1);
    anagfis.curr().zero();
    anagfis.curr().put (ANF_CODANAGR, codanagr);
    anagfis.read();
    
    _all->datana_dic        =  anagfis.curr().get_date(ANF_DATANASC);
    strcpy (_all->sesso_dic  , anagfis.curr().get(ANF_SESSO));

    TRectype dep = look_com (anagfis.curr().get(ANF_COMNASC));

    strcpy (_all->comunena_dic, dep.get(COM_DENCOM));
    strcpy (_all->provna_dic  , dep.get(COM_PROVCOM));
  }
  else 
    if (tipoa[0] == 'G')
    {
      // Leggo natura giuridica dal anagrafe giuridiche
      anaggiu.setkey(1);
      anaggiu.curr().zero();
      anaggiu.curr().put (ANG_CODANAGR, codanagr);
      if (anaggiu.read() == NOERR)
        _all->natgiu_dic = anaggiu.curr().get_int (ANG_NATGIU);
      else
        _all->natgiu_dic = 0;
    }

  return TRUE;
}

//
// Totali
//

// 
// I riporti sono i totali della pagina precedente..
//
void Totali::compila_riporti()
{
  _rip_tot_es    = _tot_esc;
  _rip_tot_impes = _tot_impesc;
  _rip_tot_ivaes = _tot_ivaesc;
  _rip_tot_nies  = _tot_niesc;
  _rip_tot_e8es  = _tot_e8esc;
}

void Totali::azzera_totali()
{
  _rip_tot_es        = 0;
  _rip_tot_impes     = 0.00;
  _rip_tot_ivaes     = 0.00;
  _rip_tot_nies      = 0.00;
  _rip_tot_e8es      = 0.00;

  _tot_esc           = 0;
  _tot_impesc        = 0.00;
  _tot_ivaesc        = 0.00;
  _tot_niesc         = 0.00;
  _tot_e8esc         = 0.00;

  _tot_esp           = 0;
  _tot_impesp        = 0.00;
  _tot_ivaesp        = 0.00;
  _tot_niesp         = 0.00;
  _tot_e8esp         = 0.00;
}

//
// Incrementa i totali in fondo alla pagina
//
void Totali::incrementa_totali(struct alleg_sort* buf, stampe tipo_stampa)
{
  switch (tipo_stampa)
  {
  case fornitori:
  case clienti:
    _tot_tot_rigac  += buf->tot_rigac;
    _tot_tot_rigap  += buf->tot_rigap;

    _tot_esc        += buf->ndocesc;
    _tot_impesc     += buf->impesc + buf->impesp;
    _tot_ivaesc     += buf->ivaesc + buf->ivaesp;
    _tot_niesc      += buf->niesc + buf->niesp;
    _tot_e8esc      += buf->e8esc + buf->e8esp;

    _tot_esp        += buf->ndocesp;
    _tot_impesp     += buf->impesp;
    _tot_ivaesp     += buf->ivaesp;
    _tot_niesp      += buf->niesp;
    _tot_e8esp      += buf->e8esp;
    
    break;

  case modulo101:
  case modulo102:
    _tot_col_101102 += buf->prog101102;
    
  default:
    break;
  }
}

//
// Array_desc_campi
//

void Array_desc_campi::leggi_modulo (const char * file, const char *modulo)
{
  TScanner s(file);

  s.paragraph (modulo);

  s.equal();
  _passo = s.integer();

  s.equal();
  _righe_modulo = s.integer();

  int riga;
  TString formato;

  while (s.ok())
  {
    riga    = s.integer();
    formato = s.string();

    add (riga, formato);
  }
}

void Array_desc_campi::add(int r, const char * f)
{
  desc_campo * descr = new desc_campo;

  descr->_riga    = r;
  descr->_formato = f;
  
  _campi.add (descr);
}

//
// Record_B
//

void Record_B::compila(TLocalisamfile *all)
{
  esc    = all->get_int  (ALL_NDOCESC);
  impesc = all->get_real (ALL_IMPESC);
  ivaesc = all->get_real (ALL_IVAESC);
  tot    = impesc + ivaesc;
}

void Record_B::azzera()
{
  tot    = 0.00;
  esc    = 0; 
  impesc = 0.00;
  ivaesc = 0.00;
}

void Record_B::somma()
{
  tot = impesc + ivaesc;
}