// cg0500.cpp - Tabella causali #include #include #include #include #include #include #include #include #include #include "cglib01.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 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 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& m) { init_query_mode(m); } virtual void init_modify_mode(TMask& m) { init_query_mode(m); } virtual int rewrite(const TMask& m); virtual int write(const TMask& m); virtual int read(TMask& m); virtual void ini2sheet(TConfig& ini, TSheet_field &sheet); virtual void sheet2ini(TSheet_field &sheet,TConfig& ini); void load_rcaus(TMask& m); int re_write(const TMask& m, bool re); public: // @cmember Disabilita la verifica del modulo : essendo una anagrafica, va sempre abilitata virtual bool check_autorization() const { return false; } 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, const TBill& 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) { const TRectype& rec = r->curr(); const int anno = atoi(rec.get("CODTAB").left(4)); bool ok = anno == app().anno_iva(); if (ok) { 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) { if (curr_mask().is_running()) ss().force_update(); ss().select(0); _last_descr = _tipo_des; } } // Cancella tutte le descrizioni delle righe void TCaus_app::clear_descr() { if (_tipo_des != no_descr) { TString_array& a = ss().rows_array(); for (int i = 0; i < a.items(); i++) { TToken_string& r = a.row(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++, TR("C Clienti")); set_descr(i++, TR("C Di ricavo")); set_descr(i++, TR("C Iva vendite")); set_descr(i++, TR("C Iva non detraibile")); set_descr(i++, TR("C Imp. esenti")); set_descr(i++, TR("C Imp. non imponibili")); set_descr(i++, TR("C Imp. non soggetti")); set_descr(i++, TR("C Ritenute fiscali")); set_descr(i++, TR("C Ritenute soc.")); set_descr(i++, TR("C Iva ad esig.diff.")); _tipo_des = vendita; carica_righe_libere(i); } } void TCaus_app::causale_acquisti() { if (_tipo_des != acquisto) { int i = 0; set_descr(i++, TR("C Fornitori")); set_descr(i++, TR("C Di costo")); set_descr(i++, TR("C Iva acquisti")); set_descr(i++, TR("C Iva non detraibile")); set_descr(i++, TR("C Imp. esenti")); set_descr(i++, TR("C Imp. non imponibili")); set_descr(i++, TR("C Imp. non soggetti")); set_descr(i++, TR("C Ritenute fiscali")); set_descr(i++, TR("C Ritenute soc.")); set_descr(i++, TR("C Iva ad esig.diff.")); _tipo_des = acquisto; carica_righe_libere(i); } } void TCaus_app::causale_ritenute() { if (_tipo_des != ritenuta_occas) { int i = 0; set_descr (i++, TR("Costo")); set_descr (i++, TR("Cassa/banca")); set_descr (i++, TR("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++, TR("C Clienti/Fornitori")); // 2 set_descr(i++, TR("C Cassa o banca")); set_descr(i++, TR("C Tratta")); // 4 set_descr(i++, TR("C Ricevuta bancaria")); set_descr(i++, TR("C Cessione")); // 6 set_descr(i++, TR("C Paghero'")); set_descr(i++, TR("C Lettera di credito"));// 8 set_descr(i++, TR("C Tratta accettata")); set_descr(i++, TR("C Abbuoni pass./sc.")); set_descr(i++, TR("C Abbuoni att./sc.")); // 10 set_descr(i++, TR("C Spese e rimborsi")); set_descr(i++, TR("C Ritenute fiscali")); // 12 set_descr(i++, TR("C Differenza cambio")); set_descr(i++, TR("C Ritenute sociali")); // 14 _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) { int filtro = 0; if (tpd.full()) { const TRectype& tpd_rec = cache().get("%TPD", tpd); if (!tpd_rec.empty()) { const TipoIVA i = (TipoIVA)tpd_rec.get_int("I0"); // IVA acquisti, vendite, generica if (i == iva_vendite) // vendite { const bool corrisp = tpd_rec.get_bool("B0"); // vendite con corrispettivi? filtro = corrisp ? 2 : 1; } else { if (i == iva_acquisti) // acquisti filtro = 3; else if (i == iva_generica) // sia acquisti sia 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 TString& 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 TString& codreg = field_reg.get(); if (codreg.full()) { TRegistro registro(codreg, app().anno_iva()); if (registro.name().empty()) return f.error_box(FR("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_TAB && f.mask().is_running()) { app().mostra_campi(); if (f.focusdirty()) app().fill_sheet(f.mask()); } return true; } bool TCaus_app::mostra_campi() { TMask& m = curr_mask(); const TString& codreg = m.get(F_COD_REG); if (codreg.blank()) { 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); m.hide(F_CODCAUREG); 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.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_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.enable(F_MOV_VALU, valuta()); // m.show(F_COD_CAUS_IM); // m.enable(F_COD_CAUS_IM, !saldaconto()); m.show(F_CODCAUREG); 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) { const TMask& m = f.mask(); const TString& tpd = m.get(F_TIPO_DOC); if (tpd.not_empty()) { const TRectype& tabtpd = cache().get("%TPD", tpd); if (!tabtpd.empty()) { const TipoIVA i = (TipoIVA)tabtpd.get_int("I0"); // IVA acquisti, vendite, generica if (i != iva_generica) // iva_generica = 9 { const TString& codreg = m.get(F_COD_REG); const TRegistro grog(codreg, app().anno_iva()); const TipoIVA ri = grog.iva(); if (i != ri) return f.error_box(TR("Tipo documento incompatibile con tipo registro")); } } } } return true; } //////////////////////////////////////////////////////////////////////////// // Handler della maschera dello spreadsheet //////////////////////////////////////////////////////////////////////////// bool TCaus_app::ss_notify(TSheet_field& s, int r, KEY k) { static bool selecting = false; switch(k) { case K_TAB: if (!selecting && s.row(r).get_char(1) <= ' ') // riga azzerata { selecting = true; s.select(r, 1, false); // Vado alla prima colonna delle righe vuote selecting = false; } break; case K_ENTER: if (s.row(r).get_int(3) == 0 && s.row(r).get_char(1) <= ' ') // riga azzerata app().clear(r); // pulisco la riga anche nell'array break; default: break; } 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(TR("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( FR("%s non valido con registro %s"), cf == 'C' ? TR("Cliente") : TR("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(TR("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(LF_RCAUSALI); r.put(RCA_CODCAUS, m.get(F_COD_CAUS)); _rcaus_rec->read(r); load_rcaus(m); _tipo_des = no_descr; //assegnazione necessaria per forzare il ricaricamento delle descrizioni fill_sheet(m); const TString& tpd = m.get(F_TIPO_DOC); calc_filter(tpd); } return err; } void TCaus_app::add_riga(int numrig, char sz, const TBill& 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 TString4 cod(_rel->curr().get(RCA_CODCAUS)); TString d, da(50); ss().destroy(); const int last = _rcaus_rec->last_row(); for (int i = 1; i <= last; i++) { const 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); da = cache().get("%DPN", d, "S0"); const TBill tc(g,c,s,cf); add_riga(i-1, sz, tc, d, da); } } bool TCaus_app::fill_sheet(TMask& m) { const TString& codreg = m.get(F_COD_REG); const TString& 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() && codreg.full()) { TString8 chiave; chiave << anno_iva() << codreg; const TRectype& reg = cache().get("REG", chiave); 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 int g = riga.get_int(3); const char sezione = riga.get_char(1); if (g > 0 || sezione > ' ') { TRectype & r = _rcaus_rec->row(i+1, true); const char sezione = riga.get_char(1); const char tipo_cf = riga.get_char(); const int c = riga.get_int(4); const long s = riga.get_long(); riga.get(); // Salta descrizione conto const TString80 coddesc(riga.get()); r.put (RCA_CODDESC, coddesc); 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); } } return _rcaus_rec->write(re); } bool TCaus_app::remove() { return TRelation_application::remove() && _rcaus_rec->remove() == NOERR; } void TCaus_app::ini2sheet(TConfig& ini, TSheet_field& sheet) { TMask& m = sheet.mask(); fill_sheet(m); const TString& tpd = m.get(F_TIPO_DOC); calc_filter(tpd); TString16 defpar, d; TString da; for (int i = 0; i < ss().items(); i++) { defpar.format("%d,%d", LF_RCAUSALI, i+1); if (ini.set_paragraph(defpar)) { const char sz = ini.get(RCA_SEZIONE)[0]; const char cf = ini.get(RCA_TIPOCF)[0]; const int g = ini.get_int(RCA_GRUPPO); const int c = ini.get_int(RCA_CONTO); const long s = ini.get_long(RCA_SOTTOCONTO); d = ini.get(RCA_CODDESC); da = cache().get("%DPN", d, "S0"); TBill tc(g,c,s,cf); add_riga(i, sz, tc, d, da); } } } void TCaus_app::sheet2ini(TSheet_field& sheet,TConfig& ini) { TString16 defpar; for (int i = 0; i < ss().items(); i++) { defpar.format("%d,%d", LF_RCAUSALI, i+1); ini.set_paragraph(defpar); TToken_string &riga = ss().row(i); const int g = riga.get_int(3); if (g > 0) { const TString4 sezione = riga.get_char(1); const TString4 tipo_cf = riga.get_char(); const int c = riga.get_int(4); // Salta al conto const long s = riga.get_long(); const char* coddesc = riga.get(7); // Salta alla descrizione conto ini.set(RCA_CODDESC, coddesc); ini.set(RCA_SEZIONE, sezione); ini.set(RCA_TIPOCF, tipo_cf); ini.set(RCA_GRUPPO, g); ini.set(RCA_CONTO, c); ini.set(RCA_SOTTOCONTO, s); } else ini.remove_all(); } } void TCaus_app::init_mask(TMask& m) { m.set(F_ANNOES, anno_iva()); carica_righe_libere(); } void TCaus_app::init_query_mode(TMask& m) { init_mask(m); } void TCaus_app::on_config_change() { TConfig conf(CONFIG_DITTA, "cg"); _saldaconto = conf.get_bool("GesSal"); _valuta = conf.get_bool("GesVal"); _anno_iva = 0; TTable reg("REG"); if (reg.last() == NOERR) _anno_iva = atoi(reg.get("CODTAB").left(4)); if (_anno_iva <= 0) { _anno_iva = conf.get_int("AnLiIv"); if (_anno_iva <= 0) _anno_iva = TDate(TODAY).year(); } _msk->show(F_TIPO_MOV_1, saldaconto()); _msk->show(F_TIPO_MOV_2, 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() { open_files(LF_CAUSALI, LF_RCAUSALI, LF_TABCOM, LF_TAB, 0); _rel = new TRelation (LF_CAUSALI); _rcaus_rec = new TRecord_array(LF_RCAUSALI, RCA_NRIGA); _msk = new TMask("cg0500a"); _sheet = &_msk->sfield(F_SHEET_GCS); _msk->set_handler(F_TIPO_DOC, tipodoc_hndl); _msk->set_handler(F_COD_REG, cod_reg_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 _rcaus_rec; delete _rel; return true; } int cg0500(int argc, char* argv[]) { TCaus_app a; a.run(argc, argv, TR("Tabella causali")); return 0; }