//********************************
//*  Riepilogo Progressivi IVA   *
//********************************
#include <mask.h>
#include <printapp.h>
#include <tabutil.h>
#include <utility.h>

#include "cg0.h"
#include "cg0400.h"

#include "classpim.h"

#include <anagr.h>
#include <comuni.h>   
#include <attiv.h>   
#include <nditte.h>   


HIDDEN TString80 TMP;

enum liste {
  visualizza=1,
  stampa=2,
};

struct Importi {
  real imponibile;
  real imposta;
};

struct TRiga_gen : public TArray
{
  TString16 _codiva;
  real      _impoven, _imposven;    //imponibile e imposta vendite
  real      _impoacq, _imposacq;    //imponibile e imposta acquisti
  real      _impobd, _imposbd;      //imponibile e imposta importazioni (ovvero bolle doganali)
  
  TRiga_gen (const char* codiva, const real& impov, const real& imposv, const real& impoa, const real& imposa, const real& impobd, const real& imposbd):
  _codiva(codiva),_impoven(impov),_imposven(imposv),_impoacq(impoa),_imposacq(imposa),_impobd(impobd),_imposbd(imposbd) {} 
};

class TGen_array : public TArray
{
public:
  bool add_riga(const char* codiva, const real& imponibilev, const real& impostav, const real& imponibilea, const real& impostaa, const real& imponibilebd, const real& impostabd); 
  TRiga_gen& riga(int i) { return (TRiga_gen&)(*this)[i]; }
};  

bool TGen_array::add_riga(const char* codiva, const real& imponibilev, const real& impostav, const real& imponibilea, const real& impostaa, const real& imponibilebd, const real& impostabd)
{
  bool found = FALSE;
  for (int i = 0; i < items(); i++)
  {
    TRiga_gen& r = riga(i);
    if (r._codiva==codiva)
    {
      found = TRUE;
      r._impoven  += imponibilev;
      r._imposven += impostav;
      r._impoacq  += imponibilea;
      r._imposacq += impostaa;
      r._impobd   += imponibilebd;
      r._imposbd  += impostabd;
    }
  }
  if (!found)
  {
    TRiga_gen* r = new TRiga_gen(codiva,imponibilev,impostav,imponibilea,impostaa,imponibilebd,impostabd);
    add(r);
  }
  return found;
};

struct TRiga_iva : public TArray
{
  tiporec _tipo;
  real    _imponibile, _imposta, _detrazione;
  
  TRiga_iva (const tiporec& tipo, const real& impo, const real& impos, const real& detr):
  _tipo(tipo),_imponibile(impo),_imposta(impos), _detrazione(detr) {}
};                            

class TIva_array : public TArray
{
public:
  bool add_riga(const tiporec& tipo, const real& imponibile, 
                const real& imposta, const real& detr); 
  TRiga_iva& riga(int i) { return (TRiga_iva&)(*this)[i]; }
};

bool TIva_array::add_riga(const tiporec& tipo, const real& imponibile, 
                          const real& imposta, const real& detr)
{
  bool found = FALSE;
  for (int i = 0; i < items(); i++)
  {
    TRiga_iva& r = riga(i);
    if (r._tipo == tipo)
    {
      found = TRUE;
      r._imponibile += imponibile;
      r._imposta    += imposta;
      r._detrazione += detr;
    }
  }
  if (!found)
  {
    TRiga_iva* r = new TRiga_iva(tipo,imponibile,imposta,detr);
    add(r);
  }
  return found;
};

class CG0400_application : public TPrintapp
{
  TTable*         _tabpim, * _tabreg, * _tabais, * _tablia;
  TLocalisamfile* _nditte, * _anag, * _com, * _attiv;
  TMask*          _msk;
  TDate           _data;
  int             _sospmsk, _tipoprog, _livelloprog, _tipo_aliq, _tipo_attiv, _annoiva, _i;
  int             _mese, _anno;
  long            _codditta;
  bool            _st_inizio_anno, _prima_pagina;
  TIva_array      _iva_array,_iva1_array;
  TGen_array      _gen_array,_gen1_array;
  TString         _cap,_cofi,_paiva,_ragsoc,_comunefis,_provfis,_viafis,_codivamsk,_codattmsk;
  TString         _datast, _cod_att;
  Importi         _mesi[13];          
  liste           _tipo_lista;
  
public:            

  virtual bool user_create();
  virtual bool user_destroy();
  virtual bool set_print(int);
  virtual void preprocess_header();
  virtual bool preprocess_page(int,int);
  virtual print_action postprocess_page(int,int);

  void        cerca_i_pim();
  void        azzera_mesi();
  void        get_dati_ditta();
  void        setta_intestazione();
  void        calcola_totali(real&,real&);
  void        cerca_tipo(TIva_array&, tiporec, real&, real&, real&);
  void        prospetto_pagina(TGen_array&, TIva_array&);
  int         stampa_intestazione_ditta(); 
  const char* desc_attivita(const char*);
  const char* desc_iva(const char*);
  char        look_lia(long ditta = 0l);
  void        look_pim();

  CG0400_application(){};
};

HIDDEN int compare_rows(const TObject** o1, const TObject** o2)
{
  TRiga_gen* r1 = (TRiga_gen*)*o1;
  TRiga_gen* r2 = (TRiga_gen*)*o2;
  
  return (strcmp((const char*)r1->_codiva, (const char*)r2->_codiva));
}

const char* CG0400_application::desc_attivita(const char* codatt)
{
  TTable attiv ("%AIS");
  attiv.zero();
  attiv.put("CODTAB", codatt);
  if (attiv.read()==NOERR)
    TMP = attiv.get("S0");
  else
    TMP = "";
  return TMP;
}

const char* CG0400_application::desc_iva(const char* cod)
{
  TTable  tab_iva("%IVA");
  TString codtab(format("%-4s", cod));
  
  tab_iva.zero();
  tab_iva.put("CODTAB", codtab);
  if (tab_iva.read()==NOERR)
    TMP = tab_iva.get("S0");
  else
    TMP = "";

  return TMP;
} 

char CG0400_application::look_lia(long ditta)
{
  if (ditta == 0l) ditta = get_firm();
  
  TString16 y; y.format("%05ld%04d", ditta, _anno);
  
  _tablia->zero();
  _tablia->put("CODTAB", y);
  
  if (_tablia->read() != NOERR)
    _tablia->zero();

  return _tablia->get_char("S7");
}

bool CG0400_application::user_create()
{
  _tabpim = new TTable(TAB_PIM);
  _tabreg = new TTable(TAB_REG);
  _tabais = new TTable("%AIS"); 
  _tablia = new TTable("%LIA");
  _anag   = new TLocalisamfile(LF_ANAG);
  _nditte = new TLocalisamfile(LF_NDITTE);
  _com    = new TLocalisamfile(LF_COMUNI);
  _attiv  = new TLocalisamfile(LF_ATTIV);     
  
  set_real_picture("###.###.###.###");
  set_print_zero(FALSE);
  printer().footerlen(5);
  
  return TRUE;
}

bool CG0400_application::user_destroy()
{
  delete _tabpim;
  delete _tabreg;
  delete _tabais;
  delete _tablia;
  delete _anag;
  delete _nditte;
  delete _com;
  delete _attiv;
  
  return TRUE;
}

void CG0400_application::azzera_mesi()
{
  for (int i=0; i<=12; i++)
  {
    _mesi[i].imponibile = ZERO; 
    _mesi[i].imposta = ZERO;
  }   
}

void CG0400_application::look_pim()
{
  TTable pim("PIM");
  for (pim.first(); !pim.eof(); pim.next())
  {
    real imponibile, imposta;
    tiporec tipo;

    TString80 codtab = pim.get("CODTAB");
    int anno = atoi(codtab.mid(0,4));
    int mese = atoi(codtab.mid(13,2)); 
    TString16 codatt = codtab.mid(4,5);
    TString16 codiva = codtab.mid(16,4);         
    TString16 tipoiva = pim.get("S5");    
    codiva = codiva.trim();
    codatt = codatt.trim();

    if (anno != _anno) continue; 
    
    if (_st_inizio_anno)
      if (mese > _mese)
        continue;
    
    if (!_st_inizio_anno)
      if (mese != _mese)
        continue;
    
    if (codatt != _cod_att) continue;
    
    //Modifica del 12/07/1995
    if (tipoiva == "VE") continue; //i codici iva di tipo "VE"
    //Fine                         //non devono essere stampati
    
    while (classify_pim(pim.curr(), imponibile, imposta, tipo, TRUE))
    {
      switch(tipo)
      { 
      case acq_norm:
        _gen_array.add_riga(codiva,ZERO,ZERO,imponibile,imposta,ZERO,ZERO);
        if (_st_inizio_anno && mese == _mese) //lo metto in un array a parte
          _gen1_array.add_riga(codiva,ZERO,ZERO,imponibile,imposta,ZERO,ZERO);
        break;
      case vend_norm:
        _gen_array.add_riga(codiva,imponibile,imposta,ZERO,ZERO,ZERO,ZERO);
        if (_st_inizio_anno && mese == _mese) //lo metto in un array a parte
          _gen1_array.add_riga(codiva,imponibile,imposta,ZERO,ZERO,ZERO,ZERO);
        break;
      case bolle_doganali:
        _gen_array.add_riga(codiva,ZERO,ZERO,ZERO,ZERO,imponibile,imposta);
        if (_st_inizio_anno && mese == _mese)
          _gen1_array.add_riga(codiva,ZERO,ZERO,ZERO,ZERO,imponibile,imposta);
        break;
      case acq_amm_ultdetr:  
      {  
        real detr = imponibile * real(0.06); 
        _iva_array.add_riga(tipo,imponibile,imposta,detr);
        if (_st_inizio_anno && mese == _mese) 
          _iva1_array.add_riga(tipo,imponibile,imposta,detr);
      }
        break;
      default: 
        _iva_array.add_riga(tipo,imponibile,imposta,ZERO); 
        if (_st_inizio_anno && mese == _mese) 
          _iva1_array.add_riga(tipo,imponibile,imposta,ZERO);
        break;    
      }
    } 
  }
  _gen_array.sort(compare_rows);  // ordinamento per codice iva
  _gen1_array.sort(compare_rows); // ordinamento per codice iva
}                

void CG0400_application::cerca_i_pim()
{
  TTable pim("PIM");
  for (pim.first(); !pim.eof(); pim.next())
  {
    real imponibile, imposta, impo, impos;
    tiporec tipo;

    TString80 codtab = pim.get("CODTAB");
    int anno = atoi(codtab.mid(0,4));
    TString16 codatt = codtab.mid(4,5); 
    int mese = atoi(codtab.mid(13,2)); 
    TString16 codiva = codtab.mid(16,4);         
    TString16 tipoiva = pim.get("S5");
    
    if (anno != _annoiva) continue; 
    
    //Modifica del 12/07/1995
    if (tipoiva == "VE") continue;
    //Fine                         
    
    if (_livelloprog == 1) //riepilogo per aliquota 
    { 
      codiva = codiva.trim();
      if (codiva != _codivamsk) continue;
    }
    
    if (_livelloprog == 2) //riepilogo per attivita'
    {
      codatt = codatt.trim();
      if (codatt != _codattmsk) continue;
    }
    
    impo = impos = ZERO;
    
    while (classify_pim(pim.curr(), imponibile, imposta, tipo, FALSE))
    {
      switch(tipo)
      { 
      case acq_norm:
        if (_tipoprog == 1) break;  //vendite
        if (_tipo_aliq == 1)        //nella maschera e' stato richiesto 
        {                           //acquisti in genere
          impo  += imponibile;
          impos += imposta;
        }  
        break;
      case vend_norm:
        if (_tipoprog == 2) break;  //acquisti
        if (_sospmsk == 1)          //nella maschera e' stato richiesto 
        {                           //vendite in genere
          impo  += imponibile;
          impos += imposta;
        }  
        break;
      case vend_simp:
        if (_tipoprog == 2) break;  //acquisti
        if (_sospmsk == 2)          //nella maschera e' stato richiesto 
        {                           //vendite in sospensione d'imposta
          impo  += imponibile;
          impos += imposta;
        }  
        break;
      case acq_ind_op_es:
        if (_tipoprog == 1) break;  
        if (_tipo_aliq == 2) 
        {
          impo  += imponibile;
          impos += imposta;
        }  
        break;
      case acq_ind_pass_int:
        if (_tipoprog == 1) break;  
        if (_tipo_aliq == 3) 
        {
          impo  += imponibile;
          impos += imposta;
        }  
        break;     
      case acq_ind_art_19:
        if (_tipoprog == 1) break;  
        if (_tipo_aliq == 4) 
        {
          impo  += imponibile;
          impos += imposta;
        }  
        break; 
      case base_ventilazione:
        if (_tipoprog == 1) break;  
        if (_tipo_aliq == 5) 
        {
          impo  += imponibile;
          impos += imposta;
        }  
        break;              
      case bolle_doganali:
        if (_tipoprog == 1) break;  
        if (_tipo_aliq == 6) 
        {
          impo  += imponibile;
          impos += imposta;
        }  
        break;
      case acq_simp:
        if (_tipoprog == 1) break;  
        if (_tipo_aliq == 7) 
        {
          impo  += imponibile;
          impos += imposta;
        }  
        break;  
      case acq_beni_riv:
        if (_tipoprog == 1) break;  
        if (_tipo_attiv == 1) 
        {
          impo  += imponibile;
          impos += imposta;
        }  
        break;
      case acq_beni_ammort:
        if (_tipoprog == 1) break;  
        if (_tipo_attiv == 2) 
        {
          impo  += imponibile;
          impos += imposta;
        }  
        break;              
      case acq_beni_ammort_nd:
        if (_tipoprog == 1) break;  
        if (_tipo_attiv == 3) 
        {
          impo  += imponibile;
          impos += imposta;
        }  
        break;      
      case acq_beni_leasing:
        if (_tipoprog == 1) break;  
        if (_tipo_attiv == 4) 
        {
          impo  += imponibile;
          impos += imposta;
        }  
        break;              
      case acq_amm_ultdetr:
        if (_tipoprog == 1) break;  
        if (_tipo_attiv == 5) 
        {
          impo  += imponibile;
          impos += imposta;
        }  
        break;
      case cess_amm:
        if (_tipoprog == 2) break;
        if (_livelloprog == 2)  //Nel caso di vendite per attivita' il tipo costo/ricavo
        {                       //viene forzato a 4 => cessione beni ammortizzabili
          impo  += imponibile;
          impos += imposta; 
        }  
      default:
        break;    
      }
    } //fine while
    _mesi[mese].imponibile += impo;
    _mesi[mese].imposta    += impos; 
    impo = impos = ZERO;
  }  
}                  


bool CG0400_application::set_print(int m)
{
  TString16 masc = "";
  
  switch(m)
  {
  case 1: 
    masc = "cg0400a";
    _tipo_lista = visualizza;
    break;
  case 2:
    masc = "cg0400b";
    _tipo_lista = stampa;
    break;
  default:
    break;
  }   
  
  TMask msk(masc);
  
  if (msk.run() != K_ENTER) return FALSE;

  switch (_tipo_lista)
  {
  case visualizza:
  {
    _sospmsk = _tipo_aliq = _tipo_attiv = 0;
    _codditta = msk.get_long(F_CODDITTA);
    _annoiva = msk.get_int(F_ANNO);
    _tipoprog = msk.get_int(F_TIPO);       // 1 <=> vendite; 2 <=> acquisti 
    _livelloprog = msk.get_int(F_LIVELLO); // 1 <=> aliquota; 2 <=> attivita'
    _codivamsk  = msk.get(F_CODIVA);
    _codattmsk  = msk.get(F_ATTIVITA);
    if (_livelloprog == 1 && _tipoprog == 2) 
      _tipo_aliq  = msk.get_int(F_TIPOTABE);
    if (_livelloprog == 2 && _tipoprog == 2) 
      _tipo_attiv = msk.get_int(F_TIPOTABEL);
    if (_tipoprog == 1 && _livelloprog == 1)
      _sospmsk = msk.get_int(F_TIPOTAB);  //vendite in genere; vendite in sospensione d'imposta
    
    setta_intestazione();
    azzera_mesi();
    cerca_i_pim();
  }  
  break;
 case stampa:
{ 
  _codditta = msk.get_long(F_CODDITTA);
  _anno = msk.get_int(F_ANNO);
  _datast = msk.get(F_DATASTAMPA);
  _mese   = msk.get_int(F_MESE);
  _st_inizio_anno = msk.get_bool(F_STAMPA);
  
  TLocalisamfile attiv(LF_ATTIV); 
  attiv.zero();
  attiv.put(ATT_CODDITTA, _codditta);   
  TRectype r(attiv.curr());
  //prospetto per ogni codice attivita' della ditta
  for(attiv.read(_isgteq); !attiv.eof(); attiv.next())
  {
    if (attiv.curr() != r) break;
    
    _cod_att = attiv.get("CODATT"); 
    _prima_pagina = TRUE;

    _iva_array.destroy();
    _iva1_array.destroy();
    _gen_array.destroy(); 
    _gen1_array.destroy(); 
    
    look_pim();
    
    print();
  } 
  return FALSE; 
}
break;
default:
break;
}  

//set_real_picture("###.###.###.###");
//set_print_zero(FALSE);
//printer().footerlen(5);

return TRUE;
}

void CG0400_application::calcola_totali(real& imp, real& imps)
{
  for (int i=0; i<=12; i++)
  {
    imp  += _mesi[i].imponibile;
    imps += _mesi[i].imposta;
  }
}

void CG0400_application::cerca_tipo(TIva_array& iva_array,tiporec t, 
                                    real& imp, real& imps, real& det)
{
  int k = 0;
  bool trovato = FALSE;
  imp = imps = det = ZERO;
  while ( k < iva_array.items() && !trovato)
  {
    TRiga_iva& riga = (TRiga_iva&)iva_array[k];
    if (t == riga._tipo)
      trovato = TRUE;
    else k++;  
  }
  if (trovato)            
  {
    TRiga_iva& riga = (TRiga_iva&)iva_array[k];
    imp = riga._imponibile; 
    imps = riga._imposta;
    det = riga._detrazione; 
  }     
}

bool CG0400_application::preprocess_page(int file, int counter)
{
  reset_print();
  
  switch (_tipo_lista)
  {
  case stampa:
  {
    if (!_st_inizio_anno)
      prospetto_pagina(_gen_array,_iva_array);
    else 
    {
      if (_prima_pagina)
        prospetto_pagina(_gen1_array,_iva1_array);
      else
      {
        printer().formfeed();
        prospetto_pagina(_gen_array,_iva_array);
      }
    }  
  }
  break;
 case visualizza:
{
  if (counter)
    _i++;
  else
    _i = 1;
  
  const char* mese = itom(_i);
  set_row(1,"%s", mese);
  set_row(1,"@26g%r", &_mesi[_i].imponibile);
  set_row(1,"@56g%r", &_mesi[_i].imposta);
  if (_i == 12)
  {
    real tot_impo = ZERO;
    real tot_imposta = ZERO;
    calcola_totali(tot_impo, tot_imposta);
    TString dep = "";
    set_row(2,(const char*) dep);   
    set_row(3,"@8gTotale");
    set_row(3,"@26g%r", &tot_impo);
    set_row(3,"@56g%r", &tot_imposta);
  }
}
break;
default:
break;
}
return TRUE;
}

void CG0400_application::prospetto_pagina(TGen_array& gen, TIva_array& iva)
{ 
  real t_impov,t_imposv,t_impoa,t_imposa,t_impobd,t_imposbd;
  t_impov = t_imposv = t_impoa = t_imposa = t_impobd = t_imposbd = ZERO;
  int r = 1;
  
  set_row(++r, "Cod.@40gVENDITE@77gACQUISTI@113gIMPORTAZIONI");
  set_row(++r, "IVA  Descrizione@29gImponibile@48gImposta@67gImponibile@86gImposta@105gImponibile@124gImposta");
  r+=2; 

  for (int k = 0; k < gen.items(); k++)
  {       
    TRiga_gen& riga = (TRiga_gen&)gen[k];
    TString80 descr = desc_iva(riga._codiva);
    if (riga._impoven != ZERO)
      set_row(r, "@24g%r", &riga._impoven);
    if (riga._imposven != ZERO)
      set_row(r, "@40g%r", &riga._imposven);
    if (riga._impoacq != ZERO)
      set_row(r, "@62g%r", &riga._impoacq);
    if (riga._imposacq != ZERO)
      set_row(r, "@78g%r", &riga._imposacq);
    if (riga._impobd != ZERO)
      set_row(r, "@100g%r", &riga._impobd);
    if (riga._imposbd != ZERO)
      set_row(r, "@116g%r", &riga._imposbd); 
    if (riga._impoven != ZERO || riga._imposven != ZERO || riga._impoacq != ZERO
        || riga._imposacq != ZERO || riga._impobd != ZERO || riga._imposbd != ZERO)  
    {
      set_row(r, "@0g%-4s", (const char*)riga._codiva);
      set_row(r, "@5g%-.18s", (const char*)descr);
      r++;
    } 
    
    t_impov   += riga._impoven;
    t_imposv  += riga._imposven;
    t_impoa   += riga._impoacq;
    t_imposa  += riga._imposacq;
    t_impobd  += riga._impobd;
    t_imposbd += riga._imposbd;
  }
  
  gen.destroy();
  
  r+=2;
  set_row(r++, "Totale@24g%r@40g%r@62g%r@78g%r@100g%r@116g%r", 
          &t_impov,&t_imposv,&t_impoa,&t_imposa,&t_impobd,&t_imposbd);
  r++;
  real im, is, d; //inizializzati in cerca_tipo()
  cerca_tipo(iva,acq_ind_op_es,im,is,d); 
  t_impoa  += im;
  t_imposa += is;
  bool st_riga = FALSE;
  if (im != ZERO || is != ZERO) 
  {
    set_row(r++, "Totali acquisti indeducibili su ricavi esenti@62g%r@78g%r", &im, &is); 
    st_riga = TRUE;
  }
  cerca_tipo(iva,acq_ind_art_19,im,is,d);
  t_impoa  += im;
  t_imposa += is; 
  if (im != ZERO || is != ZERO) 
  {
    set_row(r++, "Totali acquisti indeducibili per ART.19@62g%r@78g%r", &im, &is);
    st_riga = TRUE;
  }
  cerca_tipo(iva,acq_ind_pass_int,im,is,d);
  t_impoa  += im;
  t_imposa += is;    
  if (im != ZERO || is != ZERO)
  {
    set_row(r++, "Totali acquisti indeducibili per passaggi interni@62g%r@78g%r", &im, &is);
    st_riga = TRUE;
  }
  r+=2;
  if (st_riga)  
    set_row(r++, "Totale generale IVA@24g%r@40g%r@62g%r@78g%r@100g%r@116g%r",
            &t_impov,&t_imposv,&t_impoa,&t_imposa,&t_impobd,&t_imposbd);
  r+=3;
  int kk = r;
  /*
     set_row(r++, "ALTRI DATI RELATIVI ALLA DICHIARAZIONE@54gImponibile@74gImposta@91gDetrazione");             
     r++;
     */
  r+=2; 
  
  st_riga = FALSE;
  cerca_tipo(iva,acq_simp,im,is,d);   
  if (im != ZERO || is != ZERO)
  {
    set_row(r++, "Acquisti in sospensione d'imposta@49g%r@66g%r", &im, &is);
    st_riga = TRUE;
  }
  cerca_tipo(iva,vend_simp,im,is,d);   
  if (im != ZERO || is != ZERO)  
  {
    set_row(r++, "Vendite in sospensione d'imposta@49g%r@66g%r", &im, &is);
    st_riga = TRUE;
  }
  cerca_tipo(iva,cess_amm,im,is,d);   
  if (im != ZERO || is != ZERO)
  {
    set_row(r++, "Cessione beni ammortizzabili@49g%r@66g%r", &im, &is);
    st_riga = TRUE;
  }
  cerca_tipo(iva,acq_beni_riv,im,is,d);   
  if (im != ZERO || is != ZERO)
  {
    set_row(r++, "Acquisto beni destinati alla rivendita@49g%r@66g%r", &im, &is);
    st_riga = TRUE;
  }
  cerca_tipo(iva,acq_beni_ammort,im,is,d);   
  if (im != ZERO || is != ZERO)
  {
    set_row(r++, "Acquisto beni ammortizzabili iva detraibile@49g%r@66g%r", &im, &is);
    st_riga = TRUE;
  }
  cerca_tipo(iva,acq_beni_ammort_nd,im,is,d);   
  if (im != ZERO || is != ZERO) 
  {
    set_row(r++, "Acquisto beni ammortizzabili iva non detraibile@49g%r@66g%r", &im, &is);
    st_riga = TRUE;
  }
  cerca_tipo(iva,acq_beni_leasing,im,is,d);   
  if (im != ZERO || is != ZERO)
  {
    set_row(r++, "Altri beni strumentali acquisiti in leasing@49g%r@66g%r", &im, &is);
    st_riga = TRUE;
  }
  cerca_tipo(iva,acq_amm_ultdetr,im,is,d);   
  if (im != ZERO || is != ZERO)
  {
    set_row(r++, "Acquisto beni soggetti a detrazione (6%%)@49g%r@66g%r@86g%r", &im, &is, &d);
    st_riga = TRUE;
  }  
  if (st_riga) 
    set_row(kk, "ALTRI DATI RELATIVI ALLA DICHIARAZIONE@54gImponibile@74gImposta@91gDetrazione");             
  
  iva.destroy();
}

TRectype& look_com (const char* cod, TLocalisamfile *comuni)
{
  comuni->zero();
  comuni->put(COM_COM, cod);
  comuni->read();
  if (comuni->bad())
    comuni->zero();
  
  return comuni->curr();
}

void CG0400_application::get_dati_ditta()
{
  TLocalisamfile nditte(LF_NDITTE); 
  TLocalisamfile anag(LF_ANAG); 
  TString        codanagr;
  TString        tipoa;

  nditte.zero();
  nditte.put(NDT_CODDITTA, _codditta);   
  nditte.read();

  if (nditte.bad()) nditte.zero();

  codanagr = nditte.get(NDT_CODANAGR);
  tipoa    = nditte.get(NDT_TIPOA);
  _ragsoc  = nditte.get(NDT_RAGSOC);

  anag.setkey(1);
  anag.zero();
  anag.put (ANA_TIPOA, tipoa);
  anag.put (ANA_CODANAGR, codanagr);
  anag.read();
  if (anag.bad()) anag.zero();
  
  _cofi      = anag.get(ANA_COFI);
  _paiva     = anag.get(ANA_PAIV);
  _comunefis = anag.get(ANA_COMRF);

  if (_comunefis.empty()) 
    _comunefis = anag.get(ANA_COMRES);

  TRectype dep = look_com (_comunefis, _com);

  _comunefis   = dep.get(COM_DENCOM);
  _provfis     = dep.get(COM_PROVCOM);
  _cap         = dep.get(COM_CAPCOM);
  if (_comunefis.empty()) 
  {
    _viafis    = anag.get(ANA_INDRF);
    _viafis.rtrim();
    _viafis << " " << anag.get (ANA_CIVRF); 
  }
  else
  {
    _viafis    = anag.get(ANA_INDRES);
    _viafis.rtrim();
    _viafis << " " << anag.get (ANA_CIVRES); 
  }
}

int CG0400_application::stampa_intestazione_ditta()
{
  int r = 1;
  TString riga(132);

  get_dati_ditta();

  set_header (r, "Ditta %ld %s %s %s %s %s", _codditta,
              (const char*)_ragsoc, (const char*)_viafis,
              (const char*)_cap, (const char*)_comunefis,
              (const char*)_provfis);
  r++;
  riga = "Data @<  Pag. @#";
  riga.right_just(127);
  riga.overwrite (format ("Partita iva %s Codice fiscale %s", (const char*)_paiva, (const char*)_cofi));
  set_header (r, "%s", (const char*) riga);
  r+=3;
  
  return r; 
}

void CG0400_application::setta_intestazione()
{
  int r = 1;

  reset_header();

  r = stampa_intestazione_ditta();
  
  if (_livelloprog == 1)
    set_header(r++, "Gestione Iva@b@50gPROGRESSIVI IVA PER ALIQUOTA");
  else set_header(r++, "Gestione Iva@b@50gPROGRESSIVI IVA PER ATTIVITA'");
  r++;
  set_header(r++, "Anno liquidazione %d", _annoiva);
  if (_tipoprog == 1) //vendite
  { 
    if (_livelloprog == 1)
    {
      if (_sospmsk == 1)
        set_header(r, "Vendite in genere");
      else set_header(r, "Vendite in sospensione d'imposta");
    } 
    else set_header(r, "Cessione beni da ammortizzare");
  }
  else  //acquisti
  {
    if (_livelloprog == 1) //per codice iva
      switch (_tipo_aliq)
      {
      case 1:
        set_header(r, "Acquisti in genere");
        break;
      case 2:
        set_header(r, "Acquisti indetraibili su operazioni esenti");
        break;
      case 3:
        set_header(r, "Acquisti indetraibili passaggi interni");
        break;
      case 4:
        set_header(r, "Acquisti indetraibili art.19");
        break;
      case 5:
        set_header(r, "Acquisti base di calcolo per la ventilazione");
        break;
      case 6:
        set_header(r, "Bolle doganali");
        break;
      case 7:
        set_header(r, "Acquisti in sospensione d'imposta");
        break;
      default:
        break;            
      }
    else //per attivita'
      switch (_tipo_attiv)
      {
      case 1:
        set_header(r, "Acquisti beni per rivendita");
        break;
      case 2:
        set_header(r, "Acquisti beni da ammortizzare detraibili");
        break;
      case 3:
        set_header(r, "Acquisti beni da ammortizzare non detraibili");
        break;
      case 4:
        set_header(r, "Altri beni strumentali acquisiti in leasing");
        break;
      case 5:
        set_header(r, "Acquisti beni da ammortizzare ult.detr. 6%");
        break;
      default:
        break;            
      }  
  }
  r++;
  if (_livelloprog == 1)
    set_header(r++, "IVA %s",(const char*) _codivamsk);
  else set_header(r++, "ATTIVITA' %s",(const char*)_codattmsk);
  set_header(++r, "@29gImponibile@60gImposta");
}

void CG0400_application::preprocess_header()
{
  if (_tipo_lista == stampa)
  {
    int soh = 1;       
    TString sep(132);
    TString ragsoc(50);
    //TString attprev(5);
    TString16 descf; 
    
    TLocalisamfile nditte(LF_NDITTE); 
    nditte.zero();
    nditte.put(NDT_CODDITTA, _codditta);   
    if (nditte.read() == NOERR)
    { 
      ragsoc  = nditte.get(NDT_RAGSOC); 
      //attprev = nditte.get(NDT_CODATTPREV);
    }
    
    //TString80 descr = desc_attivita(attprev);

    TString80 descr = desc_attivita(_cod_att);
    
    reset_header();
    
    char f = look_lia(_codditta);
    if (f == 'T')
      descf = " TRIMESTRALE";
    else if (f == 'M')
      descf = " MENSILE";
    else descf = "";
    
    sep << "Ditta  " << _codditta;
    sep << " " << ragsoc;
    sep << " " << descf;

    sep.left_just(132);
    
    set_header (soh++, (const char*) sep);
    
    sep = "";
    sep << "Data " << _datast;
    sep << "  Pag. @#";

    sep.right_just(127);    
    
    sep.overwrite ("RIEPILOGO PROGRESSIVI");
    set_header (soh++, (const char*)sep);
    sep.fill('-');
    set_header (soh++, (const char *) sep);      
    /*
       set_header (soh++, "Riepilogo progressivi IVA del periodo  %s  %d  Cod. Att. %s %s", itom(_mese), _anno, (const char*) _cod_att, (const char*) descr);
       set_header (soh++, (const char *) sep);
    */ 
    if (_st_inizio_anno)
    {
      if (_prima_pagina)
        set_header(soh++, "Riepilogo progressivi IVA del periodo  %s  %d  Cod. Att. %s %s", itom(_mese), _anno, (const char*) _cod_att, (const char*) descr);
      else set_header(soh++, "Riepilogo progressivi IVA al Mese di:  %s  %d  Cod. Att. %s %s", itom(_mese), _anno, (const char*) _cod_att, (const char*) descr);
    }
    else set_header (soh++, "Riepilogo progressivi IVA del periodo  %s  %d  Cod. Att. %s %s", itom(_mese), _anno, (const char*) _cod_att, (const char*) descr);
    set_header (soh, (const char *) sep);
  } 
}

print_action CG0400_application::postprocess_page(int file, int counter)
{
  switch (_tipo_lista)
  {
  case stampa:
  {
    if (_st_inizio_anno) 
      if (_prima_pagina)
      {
        _prima_pagina = FALSE; 
        return REPEAT_PAGE;  
      } 
      else return NEXT_PAGE; 
  }
  break;
 case visualizza:
{
  if (_i < 12) return REPEAT_PAGE;
  else return NEXT_PAGE;
}
break;

default:
break;
}
return NEXT_PAGE;  
}

int cg0400(int argc,char* argv[])
{
  CG0400_application a;
  a.run(argc, argv, "Riepilogo progressivi IVA");
  return 0;
}

