#include <applicat.h>
#include <config.h>
#include <form.h>
#include <mask.h>   
#include <printer.h>
#include <relation.h>
#include <sheet.h>
#include <tabutil.h>
#include <urldefid.h>
#include <utility.h>

#include "ba2500.h"

class TStampa_deleghe_IVA : public TApplication
{
  TRelation *_nditte;
  TTable* _banche;

  TArray_sheet* _ditte;

  int _mese, _anno, _tipo;
  TString16 _azienda, _dipendenza, _concessione;

  TString16 _profilo;     // Profilo base
  long      _codice;      // Codice profilo

  bool _stampa_distinte, _aggiorna_codici, _definitiva;
  TDate _pd;
  
protected:
  virtual bool create();
  virtual bool destroy();
  virtual bool menu(MENU_TAG);
  virtual void print();

  char frequenza_versamenti(long firm, int year) const;
  int select();
  bool print_deleghe();
  void print_distinta();

public:
  TStampa_deleghe_IVA() : _ditte(NULL) {}
};


bool TStampa_deleghe_IVA::create()
{
  TApplication::create();

  _nditte = new TRelation(LF_NDITTE);
  _nditte->add(LF_ANAG, "TIPOA=TIPOA|CODANAGR=CODANAGR");
  _nditte->add(LF_COMUNI, "COM=COMRF(COMRES)", 1, LF_ANAG);
  
  _banche = new TTable("%BAN");

  _ditte  = new TArray_sheet(-1, -1, 0, 0, "Selezione Deleghe da stampare",
                             "@1|Cod.@5|Ragione Sociale@30|Importo@15r|Interessi@15r|ABI@5|CAB@5|Concessione|Tit. Conto Fis.");
  
  _azienda = "" ;
  _dipendenza = "" ;
  
  dispatch_e_menu(BAR_ITEM(1));
  return TRUE;
}

bool TStampa_deleghe_IVA::destroy()
{
  delete _ditte;
  delete _banche;
  delete _nditte;
  return TApplication::destroy();
}


int TStampa_deleghe_IVA::select()
{
  TMask m("ba2500a");

  m.set(F_CONCESSIONE, _concessione);
  m.set(F_ABI, _azienda);
  m.set(F_CAB, _dipendenza);
  if (m.run() != K_ENTER) 
    return 0;
  
  _azienda    = m.get(F_ABI);
  _dipendenza = m.get(F_CAB);

  _mese = m.get_int(F_MESE);
  _anno = m.get_int(F_ANNO);
  _tipo = m.get_int(F_TIPO);

  _definitiva      = m.get_bool(F_DEFINITIVA);
  _stampa_distinte = m.get_bool(F_DISTINTA);
  _aggiorna_codici = m.get_bool(F_AGGIORNA);
  
  _profilo = m.get(F_PROFILO);
  _codice = m.get_long(F_CODICE);
  const bool contofis = _profilo.right(2) == "CF";
  
  int del_dis_bol=0;
  if (_profilo.left(3) == "DIS") del_dis_bol = 2;
  else 
    if (_profilo.left(3) == "BOL") del_dis_bol = 1;
  //const TDate pd(m.get(F_DATA));
  //printer().setdate(pd);
  
  _pd = m.get(F_DATA);
  printer().setdate(_pd);
  
  _concessione = m.get(F_CONCESSIONE);
  const long soloabi = m.get_long(F_SOLO_ABI);
  const long solocab = m.get_long(F_SOLO_CAB);

  TTable deleghe("%DEL");

  TString16 chiave;
  TToken_string d(80);

  _ditte->destroy();
  begin_wait();
  for (_nditte->first(); _nditte->good(); _nditte->next())
  {
    TLocalisamfile& anag = _nditte->lfile(LF_ANAG);
    TLocalisamfile& com  = _nditte->lfile(LF_COMUNI); // Comune residenza fiscale
    
    const TString16 con = com.get("UFFCONC");
    if (_concessione.not_empty() && _concessione != con) continue;

    const bool cf = anag.get_bool("TITCF");
    if (contofis != cf) continue;
    
    const int tstdel = anag.get_int("TIPOSTDEL");
    if (tstdel != del_dis_bol) continue;
    
    const long dit = _nditte->lfile().get_long("CODDITTA");
    chiave.format("%05ld%04d%02d%d", dit, _anno, _mese, _tipo);
    deleghe.put("CODTAB", chiave);

    if (deleghe.read() == NOERR && deleghe.get_bool("B0") == FALSE) // Da stampare
    {
      const long abi = deleghe.get_long("S7");
      const long cab = deleghe.get_long("S8");
      if ((soloabi == 0 || soloabi == abi) && (solocab == 0 || solocab == cab))
      {  
        d = " ";                                        // Selezione
        d.add(dit);                                     // Codice ditta
        d.add(_nditte->lfile().get("RAGSOC").left(30)); // Cognome
        d.add(deleghe.get_real("R0").string("."));      // Importo
        d.add(deleghe.get_real("R1").string("."));      // Interesse
        d.add(abi ? format("%05ld", abi) : "");         // Azienda
        d.add(cab ? format("%05ld", cab) : "");         // Dipendenza
        d.add(con);                                     // Concessione
        d.add(cf ? "X" : " ");                          // Conto fiscale
        _ditte->add(d);
      }  
    }
  }
  end_wait();

  int res = 1;     
  if (_ditte->items() > 0)
  {
    const bool ok = _ditte->run() == K_ENTER && _ditte->one_checked();
    if (!ok) res = 2; 
  }
  else
  {
    warning_box("Nessuna ditta ha deleghe del tipo specificato");
    res = 2;
  }
  
  enable_menu_item(M_FILE_PRINT, res == 1);
  return res;
}

bool TStampa_deleghe_IVA::menu(MENU_TAG)
{
  int s;
  while ((s = select()) != 0)
    if (s == 1) print();
  return FALSE;
}

void TStampa_deleghe_IVA::print()
{
  bool ok = yesno_box("Inserire il modulo prefincato nella stampante "
                      "e confermare la stampa delle deleghe");
  if (ok)                    
  {
    print_deleghe();
    if (_stampa_distinte)
    {
      ok = yesno_box("Inserire il modulo in carta bianca nella stampante "
                     "e confermare la stampa della distinta");
      if (ok) print_distinta();
    }  
  }
}

void TStampa_deleghe_IVA::print_distinta()
{
  enum Tabulatori { TAB_DITTA = 0, TAB_SEDE = 52, TAB_PROV = 78,
                    TAB_IMPORTO = 82, TAB_NOTE = 100 };

  printer().open();

  TString16 codban;
  if (_azienda.not_empty())
  {
    codban = _azienda; codban << _dipendenza;
    _banche->put("CODTAB", codban);
    _banche->read();
    CHECK(_banche->status() == NOERR, "E' sparita nel nulla la banca");
  }

  TPrintrow row;

  if (atol(_azienda))
    row.put(_banche->get("S0"), 0);
  row.put("@bDISTINTA DELEGHE DI VERSAMENTO", TAB_SEDE);
  row.put("Data @>", 106);
  row.put("Pag.@#", 124);
  printer().setheaderline(0, row);

  row.reset();
  if (atol(_dipendenza))
    row.put(_banche->get("S1"), 0);

  TString256 t("Dichiarazione ");
  switch (_tipo)
  {
  case 2: 
    t << "annuale :"; break;
  case 3: 
    t << "articolo 74 : " << itom(_mese); break;
  case 4: 
    t << "cessazione attivita' : " << itom(_mese); break;
  case 5: 
    t << "integrativa : " << itom(_mese); break;
  default: 
    t << "periodica : " << itom(_mese);  break;
  }
  t << ' ' << _anno;
  row.put(t, TAB_SEDE);
  printer().setheaderline(1, row);

  t.fill('-', 130);
  row.reset();
  row.put(t, 0);
  printer().setheaderline(2, row);
  printer().setheaderline(4, row);

  row.reset();
  row.put("Ditta",   TAB_DITTA);
  row.put("Sede" ,   TAB_SEDE);
  row.put("Importo", TAB_IMPORTO+8);
  row.put("Note",    TAB_NOTE);
  printer().setheaderline(3, row);

  real totale;

  TLocalisamfile& com = _nditte->lfile(LF_COMUNI);

  for (int i = 0; i < _ditte->items(); i++)
    if (_ditte->checked(i))
    {                          
      TToken_string& riga = _ditte->row(i);
      const TString16 cod(riga.get(1));
      _nditte->lfile().put("CODDITTA", cod);
      _nditte->read();                    

      TParagraph_string dencom(com.get("DENCOM"), 18);

      row.reset();
      row.put(_nditte->lfile().get("RAGSOC"), TAB_DITTA);
      row.put(dencom.get(), TAB_SEDE);
      row.put(com.get("PROVCOM"), TAB_PROV);

      const real imp(real::ita2eng(riga.get(3)));
      row.put(imp.string("###.###.###.###"), TAB_IMPORTO);
      printer().print(row);
      totale += imp;

      const char* r;
      while ((r = dencom.get()) != NULL)
      {
        row.reset();
        row.put(r, TAB_SEDE);
        printer().print(row);
      }
    }

  row.reset();
  printer().print(row);
  row.put("@bTotale versamenti :", TAB_SEDE);
  row.put(totale.string("###.###.###.###"), TAB_IMPORTO);
  printer().print(row);

  printer().close();
}


// Calcola frequenza dei versamenti IVA di una ditta
// Certified 99%
char TStampa_deleghe_IVA::frequenza_versamenti(long firm, int year) const
{        
  char freq = 'M';
  
  TString16 key; key.format("%05ld%d", firm, year);
  TTable lia("%LIA");
  lia.put("CODTAB", key);
  if (lia.read() != NOERR)
  { 
    TLocalisamfile nditte(LF_NDITTE);
    nditte.put("CODDITTA", firm);
    nditte.read();
    freq = nditte.get_char("FREQVIVA");
  }
  else 
    freq = lia.get_char("S7");
  CHECK(freq == 'M' || freq == 'T', "Frequenza versamenti IVA assurda");
  
  return freq;
}  


bool TStampa_deleghe_IVA::print_deleghe()
{
  bool ok = printer().open();
  bool arng = FALSE;
  TForm f(_profilo, (_codice != 0) ? format("%05ld",_codice) : "");

  TCursor& cur = *f.cursor();
  TLocalisamfile& delega = cur.file();
  TString16 chiave; 

  for (int i = 0; ok && i < _ditte->items(); i++)
    if (_ditte->checked(i))
    {                                        
      TToken_string& r = _ditte->row(i);

      const long firm = r.get_long(1);
      chiave.format("%05ld%04d%02d%d", firm, _anno, _mese, _tipo);
      delega.put("CODTAB", chiave);

      cur.read();                     // Posiziona il cursore
      
      if (_pd.ok())
        delega.put("D0",_pd);
      
      const bool cera_abi = _azienda.empty() || _dipendenza.empty();
      if (!cera_abi)
      {
        delega.put("S7", _azienda);
        delega.put("S8", _dipendenza);
        delega.rewrite();
        cur.read();
      }
      const bool cera_conc = (*r.get(7) <= ' ') || delega.get("S9").not_empty();
      if (!cera_conc)
        delega.put("S9", r.get(7));   // Concessione
      
      const bool cera_tribu = delega.get("S6").not_empty();
      if (!cera_tribu)   // Metti codice tributo
      {                
        TString16 tributo;
        switch(_tipo) 
        {
        case 1:
          if (frequenza_versamenti(firm, _anno) == 'T')
            tributo << "603" << ((_mese-1)/3+1);
          else
            tributo << "60" << format("%02d", _mese);
          break;  
        case 2:
          tributo = "6099";              // Annuale
          break;
        case 7:
          if (frequenza_versamenti(firm, _anno) == 'T')
            tributo = "6035";
          else
            tributo = "6013";
          break;  
        default:
          tributo = "";   
          break;
        }  
        delega.put("S6", tributo);
      }
      
      ok = f.print(-1);               // Stampa solo il record corrente
      if (!arng)
      {                               // Scopo di cio' e' far si' che esegua il
        f.set_arrange(arng);          // posizionamento solo la prima volta che chiama
        arng = TRUE;                  // f.print()
      }
      if (!ok) break;

      bool scrivi = _aggiorna_codici && (!cera_abi || !cera_conc || !cera_tribu);

      if (_definitiva)
      {
        delega.put("B0", "X");        // Stampato
        delega.put("D0", _pd);
        scrivi = TRUE;
      }
      if (!_aggiorna_codici)          // Cancella codici se non richiesti
      {       
        if (!cera_abi)
        {
          delega.zero("S7");
          delega.zero("S8");
          scrivi = TRUE;
        }  
        if (!cera_conc)
        {
          delega.zero("S9");
          scrivi = TRUE;
        }  
        if (!cera_tribu)
        {
          delega.zero("S6");
          scrivi = TRUE;
        }  
      }
      if (scrivi)
        delega.rewrite();
    }
  printer().close();

  return ok;
}


int ba2500(int argc, char* argv[])
{
  TStampa_deleghe_IVA a;
  a.run(argc, argv, "Stampa Deleghe IVA");
  return 0;
}