// cg0500.cpp  - Tabella causali

#include <applicat.h>
#include <config.h>
#include <msksheet.h>
#include <relapp.h>
#include <tabutil.h>
#include <utility.h>

#include <causali.h>
#include <rcausali.h>
#include <clifo.h>
#include <pconti.h>

#include "cglib.h"
#include "cg2103.h"
#include "cg0500.h"

typedef enum { no_descr, acquisto, vendita, incasso_pagamento, 
               ritenuta_occas } tipo_descr;

               class TCaus_app : public TRelation_application
{
  TRelation* _rel;           // Relazione principale
  TLocalisamfile * _rcaus;
  TTable  * _dpn;
  TMask* _msk;               // Maschera principale

  
  int _filtro;        // tipo di filtro su tab. reg.
  // 1 vendite senza corrisp
  // 2 vendite con corrisp
  // 3 acquisti
  // 4 sia acquisti che vendite
  
  TSheet_field* _sheet;
  TRecord_array * _rcaus_rec;

  // Parametri ditta 
  bool _valuta, _saldaconto;    
  int _anno_iva;             
  tipo_descr _last_descr;

protected:
  
  static bool filtra_reg(const TRelation * r);
  int calc_filter(const TString& tpd);
  void set_reg_filter(int filtro);

  static bool tipocf_hndl (TMask_field& f, KEY k);
  static bool cod_reg_hndl (TMask_field& f, KEY k);
  static bool tipodoc_hndl (TMask_field& f, KEY k);
  static bool tipomov_hndl (TMask_field& f, KEY k);

  static bool sezione_hndl (TMask_field& f, KEY k);
  static bool conto_hndl (TMask_field& f, KEY k);
  static bool sottoconto_hndl (TMask_field& f, KEY k);
  static bool codcausim_hndl (TMask_field& f, KEY k);
  static bool m770_hndl (TMask_field& f, KEY k);
  static bool ss_notify (TSheet_field& s, int r, KEY k);

  bool   fill_sheet(TMask&);

  void set_descr (int numrig, const char* descr);
  void clear(int riga);  
  void clear_descr();    
  void carica_righe_libere(int from = -1);
  void causale_inc_pag();
  void causale_ritenute ();
  void causale_vendite ();
  void causale_acquisti();
  
  virtual bool user_create();
  virtual bool user_destroy();

  virtual TRelation*   get_relation() const { return _rel; }
  virtual TMask*       get_mask(int mode)   { return _msk; }
  virtual bool         changing_mask(int mode) {return FALSE; }
  virtual bool         remove();
  
  void init_mask(TMask&);
  virtual void on_config_change();
  virtual void init_query_mode(TMask&);
  virtual void init_insert_mode(TMask&);
  virtual void init_modify_mode(TMask&);
  virtual int rewrite(const TMask& m);
  virtual int write(const TMask& m);
  virtual int read(TMask& m);
  void load_rcaus(TMask& m);
  int re_write(const TMask& m, bool re);

public:
  tipo_descr _tipo_des;        // Il tipo di causale corrente

  void compila_array (const TString&, int, int, int);

  TSheet_field& ss() const { return *_sheet; }
  TMask& ss_mask()   const { return _sheet->sheet_mask(); }

  void add_riga (int numrig, char sz, TConto& tc, const TString& d, const TString& da); 
  bool mostra_campi();           
  
  bool valuta() const { return _valuta; }
  bool saldaconto() const { return _saldaconto; }
  int anno_iva() const { return _anno_iva; }
  
  TCaus_app() : _last_descr(no_descr) {}
};

HIDDEN TCaus_app& app() { return (TCaus_app&) main_app(); }

bool TCaus_app::filtra_reg(const TRelation * r)
{           
  bool ok = TRUE;
  
  const TRectype& rec = r->lfile().curr();
  const int anno = atoi(rec.get("CODTAB").left(4));
  
  if (anno == app().anno_iva())
  {
    const TipoIVA tiporeg = (TipoIVA)rec.get_int("I0");
    const bool corrisp = rec.get_bool("B0");

    switch (app()._filtro)
    {
    case 1:
      ok = tiporeg == iva_vendite; break;
    case 2:
      ok = (tiporeg == iva_vendite && corrisp); break;
    case 3:
      ok = tiporeg == iva_acquisti; break;
    case 4:  // tiporeg 1 senza corrisp OPPURE 2 (NC ST ND AF)
      ok = tiporeg == iva_acquisti || (tiporeg == iva_vendite && !corrisp) ; break;
    default:
      break;
    }
  }  
  return ok;
}


////////////////////////////////////////////////////////////////////////////
// Funzioni che caricano le varie descrizioni fisse nell'array
////////////////////////////////////////////////////////////////////////////

// Cancella tutta la riga tranne la descrizione
void TCaus_app::clear(int riga) 
{
  TToken_string& r = ss().row(riga);
  r = r.get(0);   
  ss().force_update(riga);
}

// Setta la descrizione di una riga senza cmbiare il resto
void TCaus_app::set_descr(int i, const char * dfi)
{
  TToken_string& r = ss().row(i);
  r.add(dfi, 0);
}

void TCaus_app::carica_righe_libere(int from)
{
  if (from < 0) from = ss().items();
  for (int i = from; i < 20; i++)
    set_descr(i, "");
  if (_last_descr != _tipo_des)
  {
    ss().force_update();  
    _last_descr = _tipo_des;
  }
}

// Cancella tutte le descrizioni delle righe
void TCaus_app::clear_descr() 
{          
  if (_tipo_des != no_descr)
  {
    TArray& a = ss().rows_array();
    for (int i = 0; i < a.items(); i++) 
    {
      TToken_string& r = (TToken_string&)a[i];
      r.add("", 0);
    }
    _tipo_des = no_descr;
    carica_righe_libere();  
  }  
}

void TCaus_app::causale_vendite()
{ 
  if (_tipo_des != vendita)
  {
    int i = 0;
    set_descr(i++, "C Clienti"); 
    set_descr(i++, "C Di ricavo");
    set_descr(i++, "C Iva vendite");
    set_descr(i++, "C Iva non detraibile");
    set_descr(i++, "C Imp. esenti");
    set_descr(i++, "C Imp. non imponibili");
    set_descr(i++, "C Imp. non soggetti");
    set_descr(i++, "C Ritenute fiscali");
    set_descr(i++, "C Ritenute soc.");
    _tipo_des = vendita;
    carica_righe_libere(i);  
  }  
}


void TCaus_app::causale_acquisti()
{
  if (_tipo_des != acquisto)
  {
    int i = 0;
    set_descr( i++, "C Fornitori");
    set_descr(i++, "C Di costo");
    set_descr(i++, "C Iva acquisti");
    set_descr(i++, "C Iva non detraibile");
    set_descr(i++, "C Imp. esenti");
    set_descr(i++, "C Imp. non imponibili");
    set_descr(i++, "C Imp. non soggetti");
    set_descr(i++, "C Ritenute fiscali");
    set_descr(i++, "C Ritenute soc.");
    _tipo_des = acquisto;
    carica_righe_libere(i);  
  }
}

void TCaus_app::causale_ritenute()
{
  if (_tipo_des != ritenuta_occas)
  {
    int i = 0;
    set_descr (i++, "Costo");
    set_descr (i++, "Cassa/banca");
    set_descr (i++, "Erario");
    _tipo_des = ritenuta_occas;
    carica_righe_libere(i);  
  }  
}

void TCaus_app::causale_inc_pag()
{
  if (_tipo_des != incasso_pagamento)
  {
    int i = 0;
    set_descr ( i++, "C Clienti/Fornitori");
    set_descr ( i++, "C Cassa o banca");
    set_descr ( i++, "C Tratta");
    set_descr ( i++, "C Ricevuta bancaria");
    set_descr ( i++, "C Cessione");
    set_descr ( i++, "C Paghero'");
    set_descr ( i++, "C Lettera di credito");
    set_descr ( i++, "C Abbuoni pass./sc.");
    set_descr ( i++, "C Abbuoni att./sc.");
    set_descr ( i++, "C Spese e rimborsi");
    set_descr ( i++, "C Ritenute fiscali");
    set_descr ( i++, "C Differenza cambio");
    _tipo_des = incasso_pagamento;
    carica_righe_libere(i);  
  }  
}

////////////////////////////////////////////////////////////////////////////
// Handler della maschera principale
////////////////////////////////////////////////////////////////////////////
/************
  se m770==6 le descrizioni devono essere
  1. conto
  2. cassa/banca
  3. erario
  ************/
bool TCaus_app::m770_hndl (TMask_field& f, KEY k)
{
  if (k == K_TAB && f.focusdirty())
    app().fill_sheet(f.mask());  
  return TRUE;
}

void TCaus_app::set_reg_filter(int f)
{                                   
  _filtro = f;

  TEdit_field& reg = _msk->efield(F_COD_REG);
  reg.browse()->cursor()->set_filterfunction(filtra_reg);
  
  TEdit_field& des = _msk->efield(F_DES_REG);
  des.browse()->cursor()->set_filterfunction(filtra_reg);
}


int TCaus_app::calc_filter(const TString& tpd)
{
  TTable tabtpd("%TPD");
  tabtpd.put("CODTAB", tpd);

  int filtro = 0;          
  
  if (tabtpd.read() == NOERR)
  {
    const TipoIVA i = (TipoIVA)tabtpd.get_int("I0"); // IVA acquisti, vendite, generica
    const bool corrisp = tabtpd.get_bool("B0");
    
    if (i == iva_vendite)        // vendite
    {
      if (corrisp)     // vendite con corrispettivi
        filtro = 2;
      else             // vendite senza corrispettivi
        filtro = 1;
    } else      
      if ( i == iva_acquisti )    // acquisti
        filtro = 3;
      else 
        if ( i == 9 )  // sia acquisti che vendite
          filtro = 4;
  }
  
  set_reg_filter(filtro);
  
  return filtro;        
}


bool TCaus_app::tipodoc_hndl (TMask_field& f, KEY k)
{
  // Testo K_TAB perche' il controllo deve scattare anche all'inizio
  // per vedere, per es., se il registro scritto nella causale esiste ancora
  if (k == K_TAB)
  {
    const TString16 val(f.get());
    TMask& m = f.mask();
    TEdit_field& field_reg = m.efield(F_COD_REG);

    if (val.not_empty() && val != "IN" && val != "PG" && val != "AN")
    { 
      m.hide(F_TIPO_MOV_2);      
      m.show(F_TIPO_MOV_1);
      m.enable(F_TIPO_MOV_1, app().saldaconto());
      
      field_reg.enable();
      m.enable(F_DES_REG);
      app().calc_filter(val);
    }
    else         // TIPODOC vuoto || IN || PG || AN
    {
      field_reg.reset();
      field_reg.enable(m.query_mode());
      m.reset(F_DES_REG);
      m.enable(F_DES_REG, m.query_mode());
      
      m.hide(F_TIPO_MOV_1);
      m.show(F_TIPO_MOV_2);      
      m.enable(F_TIPO_MOV_2, app().saldaconto());      
    }
    
    // Ma davvero esiste il registro ?
    const TString16 codreg(field_reg.get());
    if (codreg.not_empty())
    {
      TRegistro registro(codreg, app().anno_iva());  
      if (registro.name().empty())
        return f.error_box("Non esiste il registro %s per l'anno %d", 
                           (const char *)codreg, app().anno_iva());
    }    
    
    app().mostra_campi();  
    app().fill_sheet(m);
  }
  return TRUE;
}

bool TCaus_app::tipomov_hndl (TMask_field& f, KEY k)
{
  if (k == K_SPACE) 
  {
    app().mostra_campi();
    if (f.focusdirty()) 
      app().fill_sheet(f.mask());
  }
  return TRUE;
}

// Il codice causale per incasso immediato, se specificato, deve
// essere puramente contabile (= codreg vuoto e tpm = Nessuno
bool TCaus_app::codcausim_hndl (TMask_field& f, KEY k)
{
  if (f.to_check(k)) 
  {                           
    TEdit_field& e = (TEdit_field&)f;
    const TString& causim = e.get();
    
    TLocalisamfile& caus = e.browse()->cursor()->file();
    caus.zero();
    caus.put(CAU_CODCAUS, causim);
    if (caus.read() == NOERR)
    {
//      const int tpm = caus.get_int(CAU_TIPOMOV);
      const TString& codreg = caus.get(CAU_REG);
      if (codreg.not_empty() /* || tpm != 0 */)
        return f.warning_box("La causale per l'incasso/pagamento immediato deve essere puramente contabile"); 
    }
  }
  return TRUE;
}


bool TCaus_app::mostra_campi()
{
  TMask& m = curr_mask();
  
  const TString& codreg = m.get(F_COD_REG);
  if (codreg.empty()) 
  {      
    m.hide(F_AUTO_FAT);        
    m.hide(F_ALLEGAT);        
    m.hide(F_FAT_RITARDO);        
    m.hide(F_OP_INTRACOM);                    
    m.hide(F_VALINTRA);                    

    m.hide(F_COD_CAUS_IM);                    

    const int tpm = m.get_int(F_TIPO_MOV);
    switch (tpm) 
    {
    case 0:
      m.enable(F_OP_FINE_ANNO, m.insert_mode());
      m.enable(F_MOV_VALU, valuta());    
      m.hide(F_MOV_SEZ);                    
      m.show(F_M_770);
      m.show(F_OP_FINE_ANNO);
      m.show(F_COLL_CESP);
      break;
    case 3:
    case 5:
    case 6:
      m.enable(F_MOV_VALU, valuta());    
      m.show(F_MOV_SEZ, saldaconto());            
      m.show(F_M_770);
      m.hide(F_OP_FINE_ANNO);
      m.hide(F_COLL_CESP);        
      break;
    default:
      break;
    }
  }
  else 
  {      // codreg non vuoto   
    m.hide(F_OP_FINE_ANNO);    
    m.hide(F_MOV_SEZ);                          

    m.enable(F_MOV_VALU, valuta());            
    m.show(F_COD_CAUS_IM);                    
    m.enable(F_COD_CAUS_IM, !saldaconto());                    
    
    m.show(F_AUTO_FAT);        
    m.show(F_ALLEGAT);        
    m.show(F_FAT_RITARDO);        
    m.show(F_COLL_CESP);        
    m.show(F_OP_INTRACOM);                    
    m.show(F_VALINTRA);                    
  }
  return TRUE;
}

bool TCaus_app::cod_reg_hndl (TMask_field& f, KEY k)
{
  if (k == K_TAB)  
  {
    app().mostra_campi();
    if (f.focusdirty()) app().fill_sheet(f.mask());
    return TRUE;
  }

  // controllo di consistenza tra codice (tipo) registro e tipo documento
  if (k == K_ENTER)
  {
    //    bool ok = TRUE;
    const TString16 tpd    = f.mask().get(F_TIPO_DOC);
    const TString16 codreg = f.mask().get(F_COD_REG);
    
    if (tpd.not_empty())
    {
      TipoIVA i = nessuna_iva;
      TRegistro grog(codreg, app().anno_iva());
      TTable tabtpd("%TPD");
      tabtpd.put("CODTAB", tpd);
      if (tabtpd.read() == NOERR)
      {
        i = (TipoIVA)tabtpd.get_int("I0");   // IVA acquisti, vendite, generica
        const TipoIVA ri = grog.iva();
        if (i == iva_generica) i = ri;
        if (i != ri) 
        {
          return f.warning_box("Tipo documento incompatibile con tipo registro");
          i = iva_errata;
        }  
      }
    }
  } 
  return TRUE;
}


////////////////////////////////////////////////////////////////////////////
// Handler della maschera dello spreadsheet
////////////////////////////////////////////////////////////////////////////

bool TCaus_app::ss_notify(TSheet_field& s, int r, KEY k)
{
  if (k == K_ENTER)
  {
    TToken_string &riga = s.row(r);
    const int g  = riga.get_int(3); 
    if (g == 0)        // riga azzerata  
      app().clear(r);  // pulisco la riga anche nell'array
  } 
  return TRUE;
}


// Handler della sezione D/A: e' obbligatoria se si specifica un gruppo sulla riga
bool TCaus_app::sezione_hndl(TMask_field& f, KEY k)
{
  if (k == K_ENTER)
  {
    if (f.mask().get(SS_GRUPPO).not_empty())
    {
      const char sez = f.get()[0];
      if (sez != 'A' && sez != 'D')
        return f.error_box("E' necessario specificare la sezione D/A");
    }  
    else
      f.reset();
  }
  
  return TRUE;
}

bool TCaus_app::conto_hndl (TMask_field& f, KEY k)
{
  if (k == K_ENTER)
  {
    char scarta = 'Z';
    int ultima  = 8;

    const TipoIVA tpr = (TipoIVA)app().curr_mask().get_int(F_TIPO_REG);  
    
    switch (tpr)
    {
    case iva_vendite: 
      scarta = 'F'; break;          // Scarta vendite a fornitori
    case iva_acquisti: 
      scarta = 'C'; break;          // Scarta acquisti da clienti
    default:
      scarta = 'Z';                 // Accetta tutto
      switch (app()._tipo_des)
      {
      case incasso_pagamento:         
        ultima = 12; break;
      default: 
        ultima = 8; break;
      }
    }

    TMask_field& sez = f.mask().field(SS_SEZIONE);
    char sezione = toupper(sez.get()[0]);
    if (sezione != 'A' && sezione != 'D') sezione = ' ';
    char sezione_consigliata = ' ';
    
    const bool full = f.mask().get(SS_GRUPPO).not_empty();

    const int riga = app().ss().selected();
    if (tpr != nessuna_iva && riga <= ultima)
    {                
      TMask_field& cfld = f.mask().field(SS_TIPOCF);
      const char cf = toupper(cfld.get()[0]);
      
      bool ok = TRUE;
      if (riga == 0 || riga == 8) 
      {
        ok = cf != scarta;
        if (full && sezione == ' ')
        {
          if (riga == 0)
            sezione_consigliata = cf == 'C' ? 'D' : 'A';
          else  
            sezione_consigliata = app().ss().row(0).get_char(1);
        }  
      }  
      else 
      {
        ok = cf != 'C' && cf != 'F';
        if (full && sezione == ' ')
          sezione_consigliata = app().ss().row(0).get_char(1) == 'D' ? 'A' : 'D';
      }  
      
      if (!ok)
        return cfld.error_box(
          "%s non valido con registro %s", cf == 'C' ? "Cliente" : "Fornitore", iva2name(tpr));
    }
    
    if (sezione == ' ' && sezione_consigliata != ' ') 
    {
      const char sc[2] = { sezione_consigliata, '\0' };
      sez.set(sc);
    }  
  }
  
  return TRUE;
}

// 1. Se specifico il sottoconto devono essere non vuoti gruppo e conto
// 2. g-c-s devono esistere
bool TCaus_app::sottoconto_hndl(TMask_field& f, KEY k)     
{
  if (k == K_ENTER && f.get().not_empty())
  {          
    const TMask& m = f.mask();
    const bool ok = m.get(SS_GRUPPO).not_empty() && m.get(SS_CONTO).not_empty();
    if (!ok) return f.error_box("Conto incompleto");
  }
  return TRUE;
}


void TCaus_app::compila_array(const TString& tpd, int tpm, int tpr, int m770)
{
  if (tpd.empty() || tpd == "IN" || tpd == "AN" || tpd == "PG")
  {
    bool canc = TRUE;
    switch (tpm) 
    {
    case 0: 
      if (m770 == 6)
      {
        causale_ritenute();  
        canc = FALSE;
      }  
      break;  
    case 3:
    case 5:
    case 6:
      if (saldaconto())
      {
        causale_inc_pag();  
        canc = FALSE;
      };
      break;
    default:
      break;
    }
    if (canc)
      clear_descr();    
  }
  else    // C'e' il tipodoc.
  {
    switch (tpr)
    {
    case 1:
      causale_vendite(); break;
    case 2:  
      causale_acquisti(); break;
    default:
      clear_descr(); break;
    }      
  }
}


///////////////////////////////////////////////////////////
// Relapp functions
///////////////////////////////////////////////////////////

int TCaus_app::read(TMask& m)
{                    
  int err = TRelation_application::read(m);
  if (err == NOERR)
  {  
    TRectype r = _rcaus->curr();
    
    r.zero();
    r.put(RCA_CODCAUS, m.get(F_COD_CAUS));
    _rcaus_rec->read(r);
    load_rcaus(m);
    fill_sheet(m);

    const TString16 tpd = m.get(F_TIPO_DOC);
    calc_filter(tpd);
  }
  return err;
}

void TCaus_app::add_riga(int numrig, char sz, TConto& tc, const TString& d, const TString& da)
{
  TToken_string& riga = ss().row(numrig);
  riga = riga.get(0);                        // Lascia invariata la descrizione ...
  if (riga.empty()) riga = " ";              // ... se esiste gia'
  riga.add(sz);
  riga.add(tc.string(0x3)); 
  riga.add(d); 
  riga.add(da); 
}

void TCaus_app::load_rcaus(TMask& m)
{
  const TString16 cod(_rel->lfile().get(RCA_CODCAUS));
  TString16 d;
  TString80 da; 
  const int last = _rcaus_rec->last_row();
  
  for (int i = 1; i <= last; i++)
  {         
    TRectype & r = _rcaus_rec->row(i, TRUE);
    const char sz = r.get_char(RCA_SEZIONE); 
    const char cf = r.get_char(RCA_TIPOCF);
    const int g   = r.get_int(RCA_GRUPPO);
    const int c   = r.get_int(RCA_CONTO);
    const long s  = r.get_long(RCA_SOTTOCONTO);
    d = r.get(RCA_CODDESC);
    
    if (d.not_empty())
    {
      _dpn->put("CODTAB", d);
      _dpn->read() ;
      da = _dpn->get("S0");
    } else da.cut(0);  

    TConto tc(g,c,s,cf);
    add_riga(i-1, sz, tc, d, da);

  }
}


bool TCaus_app::fill_sheet(TMask& m)
{              
  const TString16 codreg = m.get(F_COD_REG);
  const TString16 tpd    = m.get(F_TIPO_DOC);
  const int       tpm    = m.get_int(F_TIPO_MOV);
  const int       m770   = m.get_int(F_M_770);
  int       tpr    = m.get_int(F_TIPO_REG);    
  
  if (!m.is_running())
  {
    TString16 chiave; chiave << anno_iva() << codreg;      
    TTable reg("REG");
    reg.put("CODTAB", chiave);
    if (reg.read() == NOERR)
      tpr = reg.get_int("I0");
  }
  
  // carico le descrizioni fisse nell'array Righe_rcaus  
  compila_array(tpd,tpm,tpr,m770);

  return TRUE;
}

int TCaus_app::write(const TMask& m)
{
  int err = TRelation_application::write(m);
  if (err == NOERR)
    err = re_write(m, FALSE);
  return err;
}

int TCaus_app::rewrite(const TMask& m)
{
  int err =  re_write(m, TRUE);
  int err1 = TRelation_application::rewrite(m);
  return err == NOERR ? err1 : err;
}

int TCaus_app::re_write(const TMask& m, bool re)
{
  _rcaus_rec->destroy_rows();
  if (m.insert_mode())
    _rcaus_rec->renum_key(RCA_CODCAUS, m.get(F_COD_CAUS));
  
  for (int i = 0;  i < ss().items(); i++)
  {
    TToken_string &riga = ss().row(i);
    const char sezione = riga.get_char(1);
    const char tipo_cf = riga.get_char();
    const int  g       = riga.get_int();

    if (g > 0)
    {                         
      const int row = i + 1 ;
      TRectype & r = _rcaus_rec->row(row, TRUE);
      const int  c       = riga.get_int();
      const long s       = riga.get_long();
      riga.get();                                     // Salta descrizione conto
      const TString80 coddesc(riga.get());
      
      r.put (RCA_SEZIONE, sezione);
      r.put (RCA_TIPOCF, tipo_cf);
      r.put (RCA_GRUPPO , g);
      r.put (RCA_CONTO  , c);
      r.put (RCA_SOTTOCONTO, s);
      r.put (RCA_CODDESC, coddesc);
    }
  } 
  return _rcaus_rec->write(re);                   
}


bool TCaus_app::remove()
{
  return TRelation_application::remove() && _rcaus_rec->remove() == NOERR;
}

void TCaus_app::init_mask(TMask& m)
{
  m.set(F_ANNOES, _anno_iva);
  carica_righe_libere();
}

void TCaus_app::init_query_mode(TMask& m)
{
  ss().reset();
  init_mask(m);
}

void TCaus_app::init_insert_mode(TMask& m)
{
  init_mask(m);
}

void TCaus_app::init_modify_mode(TMask& m)
{
  init_mask(m);
}


void TCaus_app::on_config_change()
{                                
  TConfig conf(CONFIG_DITTA);
  
  _saldaconto = conf.get_bool("GesSal");
  _valuta = conf.get_bool("GesVal"); 
  _anno_iva = (int)conf.get_long("AnLiIv", NULL, -1, TDate(TODAY).year()); 

  _msk->show(F_TIPO_MOV_1, saldaconto());
  _msk->show(F_TIPO_MOV_2, saldaconto());
  _msk->show (F_MOV_SEZ, saldaconto());
  
  _msk->enable(F_COD_CAUS_IM, !saldaconto());  
  _msk->enable(F_MOV_VALU, valuta());        
  
  if (saldaconto()) 
  {
    _msk->set_handler(F_TIPO_MOV_1, tipomov_hndl);
    _msk->set_handler(F_TIPO_MOV_2, tipomov_hndl);
  }
  else
  {
    _msk->set_handler(F_TIPO_MOV_1, NULL);
    _msk->set_handler(F_TIPO_MOV_2, NULL);
  }
}


bool TCaus_app::user_create()
{
  _rel = new TRelation (LF_CAUSALI);
  //  _rel->add(LF_RCAUSALI, "CODCAUS=CODCAUS");
  _rcaus = new TLocalisamfile(LF_RCAUSALI);
  _dpn = new TTable("%DPN");

  _rcaus_rec = new TRecord_array(LF_RCAUSALI, RCA_NRIGA);

  _msk = new TMask("cg0500a");
  _sheet = &(TSheet_field&)_msk->field(F_SHEET_GCS);
  
  _msk->set_handler(F_TIPO_DOC, tipodoc_hndl);
  _msk->set_handler(F_COD_REG, cod_reg_hndl);
  _msk->set_handler(F_COD_CAUS_IM, codcausim_hndl);
  _msk->set_handler(F_M_770, m770_hndl);

  TSheet_field& cs = ss();
  cs.set_notify(ss_notify);
  cs.sheet_mask().set_handler(SS_SEZIONE, sezione_hndl);
  cs.sheet_mask().set_handler(SS_CONTO, conto_hndl);
  cs.sheet_mask().set_handler(SS_SOTTOCONTO, sottoconto_hndl);  
  cs.sheet_mask().set_handler(SS_SOTTOCONTO+100, sottoconto_hndl); 
  cs.sheet_mask().set_handler(SS_SOTTOCONTO+200, sottoconto_hndl);
  
  return TRUE;
}

bool TCaus_app::user_destroy()
{
  delete _msk;
  delete _rel;
  delete _rcaus;    
  delete _dpn;
  delete _rcaus_rec;
  return TRUE;
}

#ifdef MAIN
int main(int argc, char** argv)
#else                                 
  int cg0500(int argc, char* argv[])
#endif
{
  TCaus_app a;
  a.run(argc, argv, "Tabella causali");
  return 0;
}

