// 774100.cpp - Generazione quadro L        
//
// 774 -0 S (livello di studio)    oppure      
// 774 -0 D (livello di ditta)
//
// Lista modifiche
//
// 21.12.95 Azzera solo i record con AP=anno dichiarazione (nf)
//  8.01.96 Scambiate nel quadrol la chiave 2 con la 1 (nf)
//
#include <applicat.h>                  
#include <mask.h>              
#include <printapp.h>
#include <progind.h>
#include <relation.h>
#include <tabutil.h>
#include <utility.h>
#include <config.h>
#include <urldefid.h> 
#include <execp.h>
#include "rpag.h"
#include "rver.h"
#include "scperc.h"
#include "quadrol.h"
#include "774100.h"
#include "77lib.h"

// inizializzato in TGenera::set() - usato in filter_func()
HIDDEN TGenera* this_genera = NULL;
// Possibili esiti della dialog-box di configurazione parametri di gen.
HIDDEN const int UNCHANGED = 0;
HIDDEN const int CHANGED   = 1;
HIDDEN const int ESCI      = 2;

void TVersamenti::set (TSchedaP& sc, const long numvers)
{
  _key.format("%4ld%c%4ld%4d%4ld", sc.codditta(),sc.tipoa(),sc.codanagr(),sc.nprog(),numvers);
  add(_key);
}

bool TVersamenti::find (TSchedaP& sc, const long numvers)
{
  _key.format("%4ld%c%4ld%4d%4ld", sc.codditta(),sc.tipoa(),sc.codanagr(),sc.nprog(),numvers);
  return is_key(_key);
}

// Accetta un record solo se:
//   l'anno della data-pagamento == annodic  E
//   il pagamento e' collegato ad un versamento (non importa quale)
bool filter_func (const TRelation * rel)
{ 
  TDate datapag;
  int   anno,annod;
  long	nvers;
    
  annod = this_genera->_annodic;
  datapag = rel->lfile().get(PAG_DATAPAG); 
  nvers   = rel->lfile().get_long(PAG_NUMVERS); 
  anno    = datapag.year();
  
  return anno == annod && nvers > 0L;
}

bool TGenera::causale1015(int causale)
{     
  TTable ca7("%CA7");
  TString dep; 
  int artbil = 0;

  ca7.zero();   
  dep = format("%02d", causale);
  ca7.put("CODTAB", dep);
  const bool ok = ca7.read() == NOERR;
  
  if (!ok) ca7.zero();
  
  _ab1015 = ca7.get_int("I3"); 
  _ct1015 = ca7.get_int("I0");
  _cq1015 = ca7.get    ("S1");
  
  return ok;
}     

void TGenera::causale(int causale)
{     
  TTable ca7("%CA7");
  TString dep; 
  
  _codqua = "";
  
  ca7.zero();   
  dep = format("%02d", causale);
  ca7.put("CODTAB", dep);
  if (ca7.read() == NOERR)   
  {
    _codqua  = ca7.get    ("S1");
    _artbil  = ca7.get_int("I3");
    _codtrib = ca7.get_int("I0");
  }
}     

bool TGenera::set(const long codditta, TConfig* cnf, const char* section)
{ 
  TString16     filt; 
  int           causale;
  TRelation*    rel;
  TCursor*      cur;
  
  if (!yesno_box("Conferma la generazione dei versamenti?"))
    return FALSE;
    
  _codditta = codditta;
  _annodic  = (int)cnf->get_long(ANNO_SEL, section);

  this_genera = this;
    
  rel = new TRelation (LF_RPAG);
  filt.format("CODDITTA=%ld", codditta);
  
  cur   = new TCursor(rel,filt,1);              
  cur->set_filterfunction (filter_func);
  
  causale  = atoi(cnf->get("CoCa1015", section));

  if (causale) 
  {
    if (!causale1015(causale))
      return warning_box("Manca la causale 1015 nella tabella causali");
  }
  else
    return warning_box("Manca la causale 1015 nei parametri di studio");
  
  azzera_quadroL();
  genera_riga(cur);
  arrotonda();
                 
  delete cur;                 
  delete rel;    
    
  return FALSE;
}                

int TGenera::controllo_parametri()
{
  TLocalisamfile base (LF_BASE);
  base.setkey(1);
  base.zero();
  base.put("CODDITTA", _codditta);
  const int rc = base.read();
  if (rc == NOERR)
  {
    TDate   dv (base.get_date("DATAVERS"));
    char    lv = base.get_char("LUOVERS");
    char    tv = base.get_char("TIPOVERS");
    TString s(base.get("SERIE"));
    TString n(base.get("NUMERO"));
    
    if (!dv.ok() || lv == '\0' || tv == '\0' || n == "" || (s == "" && tv != 'C') )
    {
      TString appname("776mod -4 d");
      TExternal_app a (appname);
      a.run();
      
      TMailbox m;
      TMessage* msg = m.next_s("");
      int subj;
// 1 => uscito con Registra
// 0 => uscito con Quit
      if (msg != NULL)
      {
        subj = atoi(msg->body());
        if (subj) 
          return CHANGED;
        else
          return ESCI;
      }
    }
  }
#ifdef DBG             
  if (rc != NOERR)
    return warning_box("Errore di lettura su base cod. %d", rc);
#endif
  return UNCHANGED;  
}
                           
bool TGenera::azzera_quadroL()
{ 
  TString quadro(3); 
  const long dittafirm = get_firm_770();
  TLocalisamfile ql(LF_QUAL);
  TProgind  progn(ql.items(), "Azzeramento quadro L", FALSE, TRUE);
  
  for (ql.first(_lock); !ql.eof(); ql.next(_lock))
  {                                              
    progn.addstatus(1);
    const long codditta = ql.get_long(QUL_CODDITTA);
    if (codditta != dittafirm) continue;

// 21.12.95 Azzera solo quelli dell'anno dichiarazione 
    const int ap = ql.get_int(QUL_QLAP);    
    if (ap != _annodic) 
    {
      ql.reread(_unlock);
      continue;
    }
    
    quadro = ql.get(QUL_QLCODQUA);
    if (quadro == "C" || quadro == "D" || quadro == "D1"
        || quadro == "E" || quadro == "E1")
      ql.remove();
  }                    
  progn.addstatus(1);
  return TRUE;
}                           

void TGenera::dati_rver(TLocalisamfile& rver,TSchedaP& sch, long numvers)
{  
  rver.zero(); 
  rver.put(VER_CODDITTA, sch.codditta());  
  rver.put(VER_TIPOA,    sch.tipoa());
  rver.put(VER_CODANAGR, sch.codanagr());
  rver.put(VER_NPROG,    sch.nprog());
  rver.put(VER_NRIGA,  (long)numvers);
  rver.read();
  if (rver.bad())
    rver.zero();
  
  _ver1015 = rver.get_bool(VER_VERS1015);  
  _ritver  = rver.get_real(VER_IMPVERS);
  
  if (_ver1015)
  {         
    //Prendo i dati su flags LF_BASE 
    TLocalisamfile base(LF_BASE);
    
    base.setkey(1);
    base.zero();
    base.put("CODDITTA", _codditta);
    if (base.read(_isequal) == NOERR)
    {
      _datavers = base.get_date("DATAVERS"); 
      _mesepag  = 12;
      _luovers  = base.get_char("LUOVERS");
      _tipover  = base.get_char("TIPOVERS");
      _serie    = base.get     ("SERIE");
      _numero   = base.get     ("NUMERO");
      if (_tipover == DELEGA_BANCARIA)
        _sNprog   = _numero.mid(6);
              
      rver.reread(_testandlock);
      rver.put("DATAVERS", _datavers);
      rver.put("TIPOVERS", _tipover);
      rver.put("SERIE",    _serie);
      rver.put("NUMERO",   _numero);
      rver.put("LUOVERS",  _luovers);
      rver.rewrite();
      rver.reread(_unlock);
    }
  }
  else
  {
    _datavers = rver.get_date(VER_DATAVERS);
    _luovers  = rver.get_char(VER_LUOVERS);
    _tipover  = rver.get_char(VER_TIPOVERS);
    _serie    = rver.get     (VER_SERIE);
    _numero   = rver.get     (VER_NUMERO);
    _sNprog   = rver.get     (VER_PROGBANC);
    _sNprog.trim();
    if (_sNprog.not_empty())
      _numero << _sNprog;
  }    
}                                    

void TGenera::dati_scperc(TSchedaP& sch)
{
  TLocalisamfile scperc(LF_SCPERC);
  int codtrib = 0;
  
  scperc.setkey(1);
  scperc.zero();
  scperc.put(SPR_CODDITTA, sch.codditta());
  scperc.put(SPR_TIPOA,    sch.tipoa());
  scperc.put(SPR_CODANAGR, sch.codanagr());
  scperc.put(SPR_NPROG,    sch.nprog());      
  if (scperc.read(_isequal) == NOERR) 
    _causale = scperc.get_int(SPR_CODCAUS);
}

void TGenera::arrotonda()
{ 
  TLocalisamfile qual (LF_QUAL);
  TRecnotype items_qual = qual.items();
  real importo; importo = ZERO;                                 
  TProgind  progn(items_qual, "Arrotondamento ritenute versate in corso... Prego attendere", FALSE, TRUE);  
  
  qual.setkey(1);
  qual.zero();
  for (qual.first(); !qual.eof(); qual.next())
  {                                          
    progn.addstatus(1);
    const long codditta = qual.get_long(QUL_CODDITTA);
    if (codditta != _codditta) 
    {                
      progn.addstatus(1); // per far andare fino alla fine il "termometro" (sic)
      continue;
    }
    importo = qual.get_real(QUL_QLRITVER);
    importo = round_770(importo);
    qual.reread(_testandlock);
    qual.put(QUL_QLRITVER, importo);
    qual.rewrite();           
    qual.reread(_unlock);
  }  
  progn.addstatus(1);
}

void TGenera::genera_riga(TCursor* cur)
{ 
  TLocalisamfile ql  (LF_QUAL);
  TLocalisamfile rver(LF_RVER); 
  real      riteff,ritver;  
  long      numvers,codanagr,codp;  
  char      tipoa,tipop;
  int       nprog,nprogp;   
  bool      prima_volta = TRUE;
  bool      gia_fatto   = FALSE;
  TString   perc,percp;             
                                
  (*cur) = 0L;
  TRecnotype items_rpag  = cur->items();        
  TString   scritta(60); 
  scritta.format("Generazione versamenti per la ditta %ld", _codditta);
  TProgind  progn(items_rpag, scritta, FALSE, TRUE);

  riteff = ZERO;  
  ritver = ZERO; 
  
  _righe_gia_presenti = new TVersamenti;
  _righe_gia_presenti->destroy();
  
  tipop  = 'Z';
  codp   = 99999;      
  nprogp = 9999;

  TSchedaP scheda_prec;
  for (int i = 0; i < items_rpag; i++, ++(*cur), progn.addstatus(1))
  { 
// Leggo i dati su RPAG                                   
    TDate datapag(cur->curr().get(PAG_DATAPAG));    
    _mesepag = datapag.month();;
    _annopag = datapag.year();
    riteff   = cur->curr().get_real(PAG_RITENUTA);
    numvers  = cur->curr().get_long(PAG_NUMVERS); 
    tipoa    = cur->curr().get_char(PAG_TIPOA);
    codanagr = cur->curr().get_long(PAG_CODANAGR);
    nprog    = cur->curr().get_int (PAG_NPROG);

    TSchedaP scheda_corr(_codditta, tipoa, codanagr, nprog);    
    dati_rver(rver,scheda_corr,numvers);
    
    if (scheda_corr != scheda_prec)
    {
      dati_scperc(scheda_corr);          
      causale(_causale);
    }
    scheda_prec.set(_codditta,tipoa,codanagr,nprog);    

// Se e' tributo1015 posso evitare di controllare il codice quadro      
    if (!_ver1015) 
    {
      if (_codqua != "C" && _codqua != "D" && _codqua != "D1" &&
          _codqua != "E" && _codqua != "E1") 
        continue;
    }      
    else                        
      if (!gia_fatto)
      { 
        gia_fatto = TRUE;
        const int cp = controllo_parametri();
        if (cp == CHANGED)
          dati_rver(rver,scheda_corr,numvers);  
        else
          if (cp == ESCI)
            break;  // ho premuto il bottone FINE
      }
          
    ql.setkey(1);
    ql.zero(); 
    ql.put(QUL_CODDITTA, _codditta);
    ql.put(QUL_QLMP,     _mesepag);
    ql.put(QUL_QLAP,     _annopag);
    ql.put(QUL_QLDV,     _datavers);
    ql.put(QUL_QLLV,     _luovers);
    ql.put(QUL_QLTV,     _tipover); 
    
    if (_ver1015)
    {
      ql.put(QUL_QLCT,     _ct1015);
      ql.put(QUL_QLAB,     _ab1015);  
      ql.put(QUL_QLCODQUA, _cq1015);
    }  
    else    
    {                 
      ql.put(QUL_QLCT,     _codtrib);
      ql.put(QUL_QLAB,     _artbil);  
      ql.put(QUL_QLCODQUA, _codqua);
    }  
    ql.put(QUL_QLSERIE,  _serie);
    ql.put(QUL_QLNUMERO, _numero);

    TRectype dep(ql.curr());
        
    if (ql.read(_isequal, _lock) == NOERR)
    {
      _riteff = ql.get_real(QUL_QLRITEFF);
      _riteff += riteff; 
      ql.put(QUL_QLRITEFF, _riteff);

      if (!_righe_gia_presenti->find(scheda_corr,numvers))
      {
        ritver  = ql.get_real(QUL_QLRITVER);
        ritver += _ritver;
        ql.put(QUL_QLRITVER, ritver);
      }
      ql.rewrite();
    }
    else
    { 
      ql.zero();
      ql.curr() = dep;
      ql.put(QUL_QLRITEFF, riteff);
      ql.put(QUL_QLRITVER, _ritver);
      ql.write();                  
    }                                   
    _righe_gia_presenti->set(scheda_corr,numvers);
  }          
}
                           

class TGenera_versamenti : public TApplication
{
    char        _liv;
    TString16   _section;
    TConfig*    _cnf;
  public:
    TGenera*    _genera;
    TLocalisamfile  *_rver, *_rpag, *_base, *_scperc, *_ql;
  public:
    virtual bool create();        
    virtual bool menu(MENU_TAG m);
    virtual bool destroy();

    TGenera&    genera() { return *_genera; }
    
  public:
    TGenera_versamenti(char livello) : _liv(toupper(livello)) {}
    ~TGenera_versamenti() {}
};

TGenera_versamenti& app() { return (TGenera_versamenti&)main_app(); }

bool TGenera_versamenti::menu(MENU_TAG m)
{
  long  codditta, codditta_prec;
  int   i = 0;
  
  if (m == BAR_ITEM(1))
    if (_liv == 'S')
    {
      codditta_prec = get_firm_770();
      while ((codditta = _cnf->get_long(DITTE_SEL, _section, i++)) != 0L) 
      {
        set_firm_770(codditta);
        _genera->set(codditta, _cnf, _section);
      }
      set_firm_770(codditta_prec); 
      
      return FALSE;
    }
    else
      return _genera->set(get_firm_770(), _cnf, _section); 
      
  return FALSE;
}

bool TGenera_versamenti::create()
{
  TApplication::create();
  _rver     = new TLocalisamfile(LF_RVER);
  _rpag     = new TLocalisamfile(LF_RPAG);
  _scperc   = new TLocalisamfile(LF_SCPERC);
  _base     = new TLocalisamfile(LF_BASE);    
  _ql       = new TLocalisamfile(LF_QUAL);    
  _genera   = new TGenera;  
  _cnf      = new TConfig(_liv == 'S' ? CONFIG_USER : CONFIG_STUDIO);

  _section = name();
  _section.cut(2);

  dispatch_e_menu (BAR_ITEM(1));  
  return TRUE;
}

bool TGenera_versamenti::destroy()
{
  delete _rver;
  delete _rpag;
  delete _scperc;
  delete _base;
  delete _ql;
  delete _genera;
  delete _cnf;
  return TApplication::destroy();  
}  

int m74100 (int argc, char* argv[])
{
  TGenera_versamenti a(*argv[2]);
  a.run(argc, argv, "Generazione versamenti");
  return 0;
}            

