From 57525a47ac2c2e72279c397989f8a7f4758b78e3 Mon Sep 17 00:00:00 2001 From: mtollari Date: Tue, 2 May 2017 07:49:23 +0000 Subject: [PATCH] Patch level : 12.0 no-patch Files correlati : tf Commento : Carico il resto del programma per non creare problemi con il progetto git-svn-id: svn://10.65.10.50/branches/R_10_00@23764 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- src/tf/tf0100.cpp | 1425 ++++++++++++++++++++++++++++++++++++++++++++ src/tf/tf0100a.h | 31 + src/tf/tf0100a.uml | 309 ++++++++++ src/tf/tff.ini | 174 ++++++ src/tf/tftbcon.h | 17 + src/tf/tftbcon.uml | 142 +++++ 6 files changed, 2098 insertions(+) create mode 100644 src/tf/tf0100.cpp create mode 100644 src/tf/tf0100a.h create mode 100644 src/tf/tf0100a.uml create mode 100644 src/tf/tff.ini create mode 100644 src/tf/tftbcon.h create mode 100644 src/tf/tftbcon.uml diff --git a/src/tf/tf0100.cpp b/src/tf/tf0100.cpp new file mode 100644 index 000000000..0baf0b49c --- /dev/null +++ b/src/tf/tf0100.cpp @@ -0,0 +1,1425 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../ve/velib05.h" +#include "../cg/cglib03.h" + +#include "tf0.h" +#include "tf0100a.h" + +#include "../fe/felib.h" + +#include +#include +#include +#include +#include +#include +#include +#include + + +///////////////////////////////////////////////////////////////////////////////////// +// Globals +///////////////////////////////////////////////////////////////////////////////////// + +static XVT_SQLDB _db = NULL; // TFF sqlite db +enum return_code +{ + found, // Trovato + movcustom, // Trovato in trasfatt + nextmov, // Trovato ma cambiato movimento + eof, // EOF rmoviva + eofm, // EOF mov + after // File mov su un movimento dopo rispetto a rmoviva +}; + +enum filter_fatt +{ + toSend, // Da inviare + sent, // Inviate + all // Tutte +}; + +///////////////////////////////////////////////////////////////////////////////////// +// Utilities +///////////////////////////////////////////////////////////////////////////////////// + +// Cerca una stringa all'interno di una SLIST (Potrebbe diventare una funzione di XVT.h) +static SLIST_ELT xvt_slist_find_str(SLIST list, const char* str) +{ + SLIST_ELT e = NULL; + for (e = xvt_slist_get_first(list); e; e = xvt_slist_get_next(list, e)) + { + const char* val = xvt_slist_get(list, e, NULL); + if (xvt_str_compare_ignoring_case(str, val) == 0) + break; + } + return e; +} + +static bool haveRFSO(TString& codrfso) +{ + codrfso = cache().get(LF_NDITTE, prefix().firm().codice(), "CODRFSO"); + if(codrfso == "") return false; + return true; +} + +static bool hasRFSO(TString tipocf, TString codcli, TString& codrfso) +{ + codrfso = cache().get(LF_CLIFO, tipocf << "|" << codcli, "CODRFSO"); + if(codrfso == "") return false; + return true; +} + +// DA CONTROLLARE!!!!! +static const char* decodTipo(TDocumento& doc) +{ + if(doc.is_fattura()) + return "TD01"; + if(doc.is_nota_credito()) + return "TD04"; + return "TD05"; +} + +///////////////////////////////////////////////////////////////////////////////////// +// TTrFa_record +///////////////////////////////////////////////////////////////////////////////////// + +// Contenitore di campi di un record di database SQLite +class TTrFa_record : public TObject +{ + TString8 _table; + TToken_string _key; + TAssoc_array _fields; + +protected: + void copy(const TTrFa_record& rec) { _table = rec._table; _key = rec._key; _fields = rec._fields; } + const TString& var2str(const TString& fld, const TVariant& var) const; + +public: + void reset() { _fields.destroy(); } + void set(const char* fld, const TVariant& var); + void set(const char* fld, long var); + void set(const char* fld, const char* var); + void set(const char* fld, const real& var); + void set(const char* fld, const TString& var); + void set(const char* fld, const TDate& var); + void set(const char* fld, bool var); + const TVariant& get(const char* fld) const; + + bool insert(); + bool remove(); + bool search(); + bool search(const char* k1, const char* k2, const char* k3 = NULL); + + virtual TObject* dup() const { return new TTrFa_record(*this); } + virtual bool ok() const { return _table.not_empty(); } + + TTrFa_record& operator=(const TTrFa_record& rec) { copy(rec); return *this; } + TTrFa_record(const TTrFa_record& rec) { copy(rec); } + TTrFa_record(const char* table); +}; + +// Imposta il valore di un campo variant +void TTrFa_record::set(const char* fld, const TVariant& var) +{ + CHECK(fld && *fld, "Null field name"); + + if (var.is_null()) + { + _fields.remove(fld); + } + else + { + TVariant* obj = (TVariant*)_fields.objptr(fld); + if (obj != NULL) + *obj = var; + else + _fields.add(fld, new TVariant(var)); + } +} + +// Imposta il valore di un campo intero +void TTrFa_record::set(const char* fld, long val) +{ + const TVariant var(val); + set(fld, var); +} + +// Imposta il valore di un campo stringa +void TTrFa_record::set(const char* fld, const char* val) +{ + if (val == NULL) + set(fld, NULL_VARIANT); + else + { + const TVariant var(val); + set(fld, var); + } +} + +// Imposta il valore di un campo stringa +void TTrFa_record::set(const char* fld, const TString& val) +{ + const TVariant var(val); + set(fld, var); +} + +// Imposta il valore di un campo numerico +void TTrFa_record::set(const char* fld, const real& val) +{ + const TVariant var(val); + set(fld, var); +} + +// Imposta il valore di un campo data in formato ISO +void TTrFa_record::set(const char* fld, const TDate& val) +{ + if (val.ok()) + { + const TVariant var(val); + set(fld, var); + } + else + set(fld, ""); +} + +// Imposta il valore di un campo booleano +void TTrFa_record::set(const char* fld, bool var) +{ + set(fld, var ? "SI" : "NO"); +} + +// Legge il valore di un campo variant +const TVariant& TTrFa_record::get(const char* fld) const +{ + const TVariant* var = (const TVariant*)_fields.objptr(fld); + return var ? *var : NULL_VARIANT; +} + +// Converte un variant in una stringa valida per SQLite +const TString& TTrFa_record::var2str(const TString& fldname, const TVariant& var) const +{ + const TFieldtypes vt = var.type(); + if (vt == _realfld) + { + const TCurrency v(var.as_real(), "", ZERO, fldname.find("PRZ")>0 || fldname.find("PREZZO")>0); + TString& tmp = get_tmp_string(); + tmp << '\'' << v.string() << '\''; tmp.replace(',','.'); + return tmp; + } + if (vt == _datefld) + { + TString& tmp = get_tmp_string(); + tmp << '\'' << var.as_date().string(full, '-', full, full, amg_date) << '\''; + return tmp; + } + + const TString& str = var.as_string(); + + bool apici = vt == _alfafld; + if (apici && str[0] != '0' && real::is_natural(str)) + apici = false; + + if (!apici) + return str; + + TString& tmp = get_tmp_string(); + tmp = str; + for (int a = str.rfind('\''); a >= 0; a--) + { + if (tmp[a] == '\'') + tmp.insert("'", a); + } + tmp.insert("'", 0); + tmp << '\''; + return tmp; +} + +// Elimina il record in base ai campi chiave +bool TTrFa_record::remove() +{ + TString256 query; + query << "DELETE FROM " << _table << " WHERE "; + int nkf = 0; + FOR_EACH_TOKEN(_key, fld) + { + const TVariant& var = get(fld); + if (!var.is_null()) + { + if (nkf++ > 0) + query << " AND "; + query << fld << '=' << var2str(fld, var) ; + } + } + CHECKS(nkf >= 2, "Can't remove partial key on table ", (const char*)_table); + query << ';'; + return xvt_sql_execute(_db, query, NULL, 0L) > 0; +} + +// Callback per la sottostante funzione search() +static int tff_search_record(void* jolly, int cols, char** values, char** names) +{ + TTrFa_record& rec = *(TTrFa_record*)jolly; + for (int i = 0; i < cols; i++) + rec.set(names[i], values[i]); + return 0; +} + +// Carica un record in base ai campi chiave +bool TTrFa_record::search() +{ + CHECKS(_fields.items() >= _key.items(), "Can't search partial key on table ", _table); + TString256 query; + query << "SELECT * FROM " << _table << " WHERE "; + FOR_EACH_TOKEN(_key, fld) + { + const TVariant& var = get(fld); + if (!var.is_null()) + query << fld << '=' << var2str(fld, var) << " AND "; + } + query.rtrim(5); + query << ';'; + return xvt_sql_execute(_db, query, tff_search_record, this) == 1; +} + +// Carica un record in base ad un massimo di 3 campi chiave +bool TTrFa_record::search(const char* k1, const char* k2, const char* k3) +{ + _fields.destroy(); + + set(_key.get(0), k1); + set(_key.get(1), k2); + if (k3 && *k3) + set(_key.get(2), k3); + + return search(); +} + +// Aggiunge un record al db +bool TTrFa_record::insert() +{ + CHECKS(_fields.items() > _key.items(), "Can't insert empty record on table ", _table); + + TString query, values; + query << "INSERT INTO " << _table << "\n("; + FOR_EACH_ASSOC_OBJECT(_fields, obj, fld, itm) + { + const TVariant& var = get(fld); + if (!var.is_null()) + { + query << fld << ','; + values << var2str(fld, var) << ','; + } + } + query.rtrim(1); values.rtrim(1); + query << ")\nVALUES (" << values << ");"; + return xvt_sql_execute(_db, query, NULL, 0L) == 1; +} + +// Crea un record della tabella data ed imposta i nomi dei campi chiave +TTrFa_record::TTrFa_record(const char* table) : _table(table), _key(15, ',') +{ + _key = ini_get_string("./tff.ini", table, "INDEX_1"); + if (_key.empty()) + { + // Cerco di costruire i nomi della chiave cercando la K, come in P1_KEYHEADERFATT + TConfig cfg("tff.ini", table); + TAssoc_array& fields = cfg.list_variables(); + FOR_EACH_ASSOC_STRING(fields, obj, key, str) + { + if (key[3] == 'K') + _key.add(key); + } + } + CHECKS(!_key.empty_items(), "Invalid primary key for table ", table); +} + +///////////////////////////////////////////////////////////////////////////////////// +// TTrFa_cursors +///////////////////////////////////////////////////////////////////////////////////// +/* + * Classe per la gestione dei cursori RMOVIVA e MOV + */ +class TTrFa_cursors : TObject +{ + friend class TCursor; + + TSorted_cursor* c_mov; + TCursor* c_moviva; + TCursor* c_trasfatt; + TRelation* r_mov; + TRelation* r_moviva; + TRelation* r_trasfatt; + + filter_fatt filFat; + + bool filOk(bool s) { return (filFat == all) || (filFat == sent && s) || (filFat == toSend && !s); } + int _next(bool init = false); // Si sposta avanti di un elemento + +public: + TTrFa_cursors(); + ~TTrFa_cursors() { delete c_mov, c_moviva, r_mov, r_moviva, r_trasfatt, c_trasfatt; }; + long int getMovItems() { return c_mov->items(); } + long int getIvaItems() { return c_moviva->items(); } + long int getMovPos() { return c_mov->pos(); } + long int getIvaPos() { return c_moviva->pos(); } + TRectype getMov() { return c_mov->curr(); } + TRectype getIva() { return c_moviva->curr(); } + TRectype getTrasfatt() { return c_trasfatt->curr(); } + int next(TAssoc_array& recimposte); // Legge tutto il prossimo movimento, in importi mette per ogni codiva la somma + + int updateFilters(const char tipocf, const long codcf, TDate dal, TDate al, TAssoc_array& recimposte, int cod = toSend); +}; + +TTrFa_cursors::TTrFa_cursors() : filFat(all) +{ + r_mov = new TRelation(LF_MOV); + r_moviva = new TRelation(LF_RMOVIVA); + r_trasfatt = new TRelation(LF_TRASFATT); + c_mov = new TSorted_cursor(r_mov, "NUMREG"); + c_moviva = new TCursor(r_moviva); + c_trasfatt = new TCursor(r_trasfatt); +}; + +int TTrFa_cursors::next(TAssoc_array& recimposte) +{ + int err = _next(true); + while(err < nextmov) + { + TRectype mov = getMov(), miva = getIva(), cust = getTrasfatt(); + if(recimposte.is_key(miva.get("CODIVA"))) + { + // Prelevo il record salvato + TRectype app = *(TRectype*)recimposte.objptr(miva.get("CODIVA")); + // Aggiorno i valori + app.put("IMPONIBILE", app.get_real("IMPONIBILE") + (err == movcustom ? cust.get_real("IMPONIBILE") : miva.get_real("IMPONIBILE"))); + app.put("IMPOSTA", app.get_real("IMPOSTA") + (err == movcustom ? cust.get_real("IMPOSTA") : miva.get_real("IMPOSTA"))); + // Lo reinserisco + recimposte.add(miva.get("CODIVA"), app, true); + } + else // Inserisco per la prima volta + { + // Creo un record di tipo tabella trasmissione fatture, tanto conterrebbe tutti i dati necessari + TRectype app(LF_TRASFATT); + // Inserisco i dati + if(err == movcustom) + { + app.put("NUMREG", cust.get("NUMREG")); + app.put("TIPO", cust.get("TIPO")); + app.put("COD", cust.get("CODCF")); + app.put("TIPODOC", cust.get("TIPODOC")); + app.put("NUMDOC", cust.get("NUMDOC")); + app.put("DATADOC", cust.get("DATADOC")); + app.put("IMPONIBILE", cust.get("IMPONIBILE")); + app.put("IMPOSTA", cust.get("IMPOSTA")); + app.put("CODIVA", cust.get("CODIVA")); + } + else + { + app.put("NUMREG", mov.get("NUMREG")); + app.put("TIPO", mov.get("TIPO")); + app.put("COD", mov.get("CODCF")); + app.put("TIPODOC", mov.get("TIPODOC")); + app.put("NUMDOC", mov.get("NUMDOC")); + app.put("DATADOC", mov.get("DATADOC")); + app.put("IMPONIBILE", miva.get("IMPONIBILE")); + app.put("IMPOSTA", miva.get("IMPOSTA")); + app.put("CODIVA", miva.get("CODIVA")); + } + // Salvo il record nell'array + recimposte.add(app.get("CODIVA"), app); + } + err = _next(); + } + return err; +} + +/* + * Questa funzione si sposta sui due cursori trovando la prossima riga, se le righe sono finite si posiziona sul prossimo movimento o ritorna EOF + */ +int TTrFa_cursors::_next(bool init) +{ + bool isNextMov = false; + if(c_moviva->pos() == c_moviva->items()) + return eof; // A noi interessa solo rmoviva + else + { + TRectype rigaMov = c_mov->curr(), rigaIva = c_moviva->curr(), rigaTF = c_trasfatt->curr(); + bool first = true; + bool checkOk = false; + // Posso capitare movimenti aggiunti dopo che non rientrano nel periodo che ci interessa, applico un controllino + while(first || rigaMov.get_long("NUMREG") > rigaIva.get_long("NUMREG") || !filOk(checkOk)) + { + first = false; + + // Stratagemma terribile per evitare di saltare il primo record + if(!init) + { + if(!c_moviva->next_match(0)) + return eof; + } + else init = false; + + rigaMov = c_mov->curr(); + rigaIva = c_moviva->curr(); + rigaTF = c_trasfatt->curr(); + + while(rigaMov.get_long("NUMREG") < rigaIva.get_long("NUMREG")) + { + isNextMov = true; // Vale la pena fare un controllo aggiuntivo per questo? Il while verrà eseguito max 2 volte + + if (!c_mov->next_match(0)) + return eofm; + rigaMov = c_mov->curr(); + } + + // Mi muovo finchè le righe non sono le stesse + while(rigaTF.get_long("NUMREG") <= rigaIva.get_long("NUMREG") && rigaTF.get_long("NUMRIG") < rigaIva.get_long("NUMRIG") && c_trasfatt->pos() != c_trasfatt->items()) + { + if(!c_mov->next_match(0)) // Non mi interessa se raggiungo la fine di questa tabella + break; + rigaTF = c_trasfatt->curr(); + } + if(rigaTF.get_long("NUMREG") == rigaIva.get_long("NUMREG") && rigaTF.get_long("NUMRIG") == rigaIva.get_long("NUMRIG")) + checkOk = rigaTF.get_bool("TFINVIO"); + else + checkOk = rigaIva.get_bool("TFINVIO"); + + } + + if(isNextMov) + { + if(rigaTF.get_long("NUMREG") == rigaIva.get_long("NUMREG") && rigaTF.get_long("NUMRIG") == rigaIva.get_long("NUMRIG")) + return movcustom; + else + return nextmov; + } + else + return found; + } +} + +int TTrFa_cursors::updateFilters(const char tipocf, const long codcf, TDate dal, TDate al, TAssoc_array& recimposte, int cod) +{ + filFat = (filter_fatt)cod; + + TRectype filMov(r_mov->curr()); + int movKey = 1; + + TString filter; + + if(dal.empty()) dal = "20170101"; // Data in cui questo modulo è diventato valido + if(al.empty()) al = TODAY; + filter << "&&(BETWEEN(DATADOC," << dal.date2ansi() << ',' << al.date2ansi() << "))"; + + if(tipocf != 'T') + { + movKey = 3; + filMov.put("TIPO", tipocf); + // Se è selezionato un cliente specifico + if(codcf > 0) + filMov.put("CODCF", codcf); + } + else + filMov = 0; + + // Risetto mov + delete c_mov; + c_mov = new TSorted_cursor(r_mov, "NUMREG", TString("REG!=\"\"")<items(); + c_mov->first_item(); + + // Preparo c_moviva + TRectype filIva(r_moviva->curr()); + filIva.put("NUMREG", TRectype(c_mov->curr()).get_long("NUMREG")); + + // Resetto rmoviva + delete c_moviva; + c_moviva = new TCursor(r_moviva, "", 1, &filIva); + c_moviva->first_item(); + + // Preparo c_moviva + TRectype filTF(r_trasfatt->curr()); + filTF.put("NUMREG", TRectype(c_mov->curr()).get_long("NUMREG")); + + // Resetto trasfatt + delete c_trasfatt; + c_trasfatt = new TSorted_cursor(r_trasfatt, "NUMREG", "", 1, &filIva); + c_trasfatt->first_item(); + + + // Mi posiziono sullo stesso Numero di registrazione + if(c_mov->items() > 0 && c_moviva->items() > 0) + { + return next(recimposte); + } + + return eof; +} + +///////////////////////////////////////////////////////////////////////////////////// +// TTrFa_mask +///////////////////////////////////////////////////////////////////////////////////// + +class TTrFa_mask : public TAutomask +{ + friend class TTrFa_cursors; + + TMaskmode _mode; + bool _sheet_dirty; + bool _filter_changed; + +protected: + virtual void next_page(int p); + const char * natura(const TString& codiva) const; + real get_IVA(const TString& codiva) const; + char revCharge(TString codcaus) const; + TString findDetraib(TString codiva) const; + + virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); + //void fill(); + //void init(); + +public: + void setFilterChanged() { _filter_changed = true; } + void load_sheet(); + TTrFa_mask(TString msk) : TAutomask(msk), _filter_changed(true) {} +}; + +void TTrFa_mask::next_page(int p) +{ + TAutomask::next_page(p); + if (_filter_changed) + { + TSheet_field & sf = sfield(F_RIGHE); + if (curr_win() == sf.parent()) + { + load_sheet(); + sf.force_update(); + _filter_changed = false; + } + } +} + +bool TTrFa_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) +{ + + switch (o.dlg()) + { + case F_DATAINI: + if (e == fe_init) + o.set(ini_get_string(CONFIG_DITTA, "tf", "LastSend", "01-01-2017")); + break; + case F_DATAFIN: + if (e == fe_init) + o.set(TDate(TODAY)); + break; + case F_TIPOCF: + if(get(F_TIPOCF) != "T") + { + enable(F_CODCF); + enable(F_RAGSOC); + } + else + { + disable(F_CODCF); + disable(F_RAGSOC); + } + break; + case DLG_ALL: + if (e == fe_button) + { + TSheet_field& docs = sfield(F_RIGHE); + TString_array& sht = docs.rows_array(); + const int items = sht.items(); + + if (items > 0) + { + const TString4 select = *(sht.row(0).get(0)) == 'X' ? "" : "X"; + for (int i = 0; i < items; i++) + sht.row(i).add(select, 0); + docs.force_update(); + } + } + break; + default: + break; + } + + const short id = o.dlg(); + if (e == fe_modify && jolly == 1) + { + if (id >= A_NUMERO && id < A_COFI && id != A_FORZATA) + { + o.mask().set(A_FORZATA, true); + } + } + if (e == fe_modify && jolly == 0) + { + if (id >= F_DATAINI && id <= F_FATTSEL) + { + setFilterChanged(); + } + } + return true; +} + +void TTrFa_mask::load_sheet() +{ + const char tipocf = get(F_TIPOCF)[0]; + const long codcf = get_long(F_CODCF); + TDate dal = get_date(F_DATAINI), al = get_date(F_DATAFIN); + //TString key; key << "TIPOA=" << prefix().firm().get("TIPOA")<< ",CODANAGR=" << prefix().firm().get("CODANAGR"); + TString key; key << prefix().firm().get("TIPOA") << "|" << prefix().firm().get("CODANAGR"); + const TString pivaDitta = cache().get(LF_ANAG, key, "PAIV"); + const TString cofiDitta = cache().get(LF_ANAG, key, "COFI"); + + TTrFa_cursors c; + + TSheet_field& sheet = sfield(F_RIGHE); + TString_array& strarr = sheet.rows_array(); + + sheet.hide(); // Nascondo lo sheet per guadagnare un 20% di velocità di caricamento, le ottimizzazioni da PRO! + sheet.destroy(); + TAssoc_array recimposte; + int next = c.updateFilters(tipocf, codcf, dal, al, recimposte, get_int(F_FATTSEL)); + while(next < eof) + { + TRectype mov(c.getMov()), miva(c.getIva()), mcust(c.getTrasfatt()); + TToken_string* row = new TToken_string; + + // Carico i clienti + TRelation r_cli(LF_CLIFO); + TRectype filCli(r_cli.curr()); + filCli.put("TIPOCF", mov.get("TIPO")); + filCli.put("CODCF", mov.get("CODCF")); + TCursor c_cli(&r_cli, "", 1, &filCli, &filCli); c_cli.items(); + c_cli = 0; + TRectype cli(c_cli.curr()); + + FOR_EACH_ASSOC_OBJECT(recimposte, h, iva, rec) + { + TRectype movimento = *(TRectype*)rec; + row->add(next == movcustom ? mcust.get("TFINVIO") : miva.get("TFINVIO"), 0); //Forzo la posizione + row->add(row[0] == "X"? "" : "X"); // Se è già stata spedita la riga non viene preselezionata + row->add(next == movcustom ? "X" : ""); + row->add(movimento.get_long("NUMREG")); + row->add(miva.get_long("NUMRIG")); + row->add(cli.get("TIPOCF")); + row->add(cli.get("CODCF")); + row->add(cli.get_bool("OCCAS") ? "X" : ""); + row->add(cli.get("RAGSOC")); + row->add(cli.get("CODRFSO")); + + row->add(movimento.get("TIPODOC")); // Tipo documento + row->add(movimento.get_long("NUMDOC")); // Numero documento + row->add(movimento.get_date("DATADOC")); // Data documento + row->add(natura(iva)); // NATURA! + row->add(get_IVA(iva)); // Aliquota! + row->add(findDetraib(iva)); // Detraibilità + row->add(movimento.get_real("IMPONIBILE")); // Imponibile + row->add(movimento.get_real("IMPOSTA")); // Imposta + row->add(revCharge(mov.get("CODCAUS"))); // Rev.Charge + row->add(pivaDitta == cli.get("PAIV") ? 'X' : '\0'); // AutoFatt + if(strcmp(row->get(19), "X") == 0) // Se è un autofattura + { + row->add(pivaDitta); + row->add(cofiDitta); + } + else + { + row->add(cli.get("PAIV")); + row->add(cli.get("COFI")); + } + + strarr.add(row); + } + recimposte.destroy(); + next = c.next(recimposte); + } + sheet.force_update(); + sheet.show(); +} + +TString TTrFa_mask::findDetraib(TString codiva) const +{ + // Mi creo un cursore per i valori di indetraibilità, così facendo mi risparmio operazioni lente dopo + static TRelation r_indetr(LF_TABCOM); + static TRectype f_indetr(r_indetr.curr()); f_indetr.put("COD", "DET"); + static TCursor c_indetr(&r_indetr, "", 1, &f_indetr, &f_indetr); + + TString codtab = cache().get("%IVA", codiva, "S4"); + if(codtab.full()) + { + for(c_indetr = 0; c_indetr.pos() < c_indetr.items(); ++c_indetr) + { + TRectype row = c_indetr.curr(); + if(codtab == row.get("CODTAB")) + return (CENTO - row.get_real("R0")).stringa(6,2); + } + } + return "0.00"; +} + +const char * TTrFa_mask::natura(const TString& codiva) const +{ + const TRectype& ai = cache().get("%IVA", codiva); + TString & natura = get_tmp_string(4); + + natura = ai.get("S12"); + if(natura.blank()) + { + const int tipo_iva11 = ai.get_int("S2"); + const bool revcharge = tipo_iva11 >= 31 && tipo_iva11 <= 38; + const TString& tipo = ai.get("S1"); + const int tipo_vendite = ai.get_int("S7"); + + // N1 escluse ex art 15 + if (tipo_vendite == 5) + natura = "N5"; // regime del margine + else + if (revcharge) + natura = "N6"; // Inversione contabile (REVERSE CHARGE) + else + if (tipo == "NS") + natura = "N2"; // Non soggetto + else + if (tipo == "NI") + natura = "N3"; // Non imponibile + else + if (tipo == "ES") + natura = "N4"; // Esente + } + return natura; +} + +real TTrFa_mask::get_IVA(const TString& codiva) const +{ + const TRectype& ai = cache().get("%IVA", codiva); + return ai.get_real("R0"); +} + +char TTrFa_mask::revCharge(TString codcaus) const +{ + const TRectype& caus = cache().get(LF_CAUSALI, codcaus); + const int reg_spec = caus.get_int(CAU_REGSPIVA); + if (reg_spec == 13 || reg_spec == 50 || reg_spec == 51) // reverse charge + return 'X'; + return '\0'; +} + +///////////////////////////////////////////////////////////////////////////////////// +// TTrFa_app +///////////////////////////////////////////////////////////////////////////////////// + +class TTrFa_app : public TSkeleton_application +{ + TAnagrafica _ditta; + TString16 _cofi; + TFilename _dbname; + TLog_report* _log; + TString _logTFF; + enum { _spedita, _invio, _forzata, _numero, _numriga, _tipocf, _codcf, _ocfpi, _ragsoc, _rfso, _codnum, _numdoc, _datadoc, + _natura, _aliquota, _detraibile, _imponibile, _imposta, _reverse, _autofatt, _paiv, _codfis }; + +private: + int parse_line(const TString& line, TString& var, TString& val) const; + bool create_table(TScanner& TFF, const TString& table); + bool addDT(TString8& hfatt, TString20& bfatt, TToken_string* strarr); + bool setEsportato(TToken_string* strarr); + //const TRectype* find_parent_row(const TRectype& rdoc) const; + //int find_ancestors(const TRiga_documento& rdoc, TArray& ancestors) const; + +protected: + //const char* descrizione(const TRiga_documento& rdoc) const; + //const TRectype& cco(const TRectype& doc) const; // Contratto/Convenzione/Offerta + + void log(int severity, const char* msg); + bool show_log(); + void set_IVA(const TString& codiva, TTrFa_record& TFF) const; + void set_IVA(const TRiga_documento& rdoc, TTrFa_record& TFF) const; + bool syncronizeDB(); + bool createDB(); + +public: + virtual bool create(); + virtual bool destroy(); + virtual void main_loop(); + bool send(TTrFa_mask* msk); + + TTrFa_app() : _log(NULL) {} +}; + +void TTrFa_app::log(int severity, const char* msg) +{ + if (severity < 0) + { + _logTFF = msg; + } else + if (_log == NULL) + { + _log = new TLog_report; + if (_logTFF.full()) + { + TString txt; + txt << _logTFF << ": " << msg; + _log->log(severity, txt); + } + else + _log->log(severity, msg); + } +} + +bool TTrFa_app::show_log() +{ + bool ok = true; + if (_log) + { + _log->preview(); + delete _log; + _log = NULL; + ok = noyes_box(TR("Si desidera procedere con la generazione file xml?")); + } + return ok; +} + +void TTrFa_app::set_IVA(const TString& codiva, TTrFa_record& tff) const +{/* + const TRectype& ai = cache().get("%IVA", codiva); + const real aliquota = ai.get("R0"); + tff.set("PI_ALIQUOTAIVA", aliquota); + if (codiva.full()) + { + if (aliquota.is_zero()) + tff.set("PI_NATURA", natura(codiva)); + else + tff.set("PI_NATURA", ""); + }*/ +} + +void TTrFa_app::set_IVA(const TRiga_documento& rdoc, TTrFa_record& tff) const +{/* + const TString8 codiva(rdoc.get(RDOC_CODIVA)); + const TRectype& ai = cache().get("%IVA", codiva); + const real aliquota = ai.get("R0"); + tff.set("PI_ALIQUOTAIVA", aliquota); + if (codiva.full()) + { + if (aliquota.is_zero()) + tff.set("PI_NATURA", natura(codiva)); + else + tff.set("PI_NATURA", ""); + }*/ +} + + +int TTrFa_app::parse_line(const TString& line, TString& var, TString& val) const +{ + if (line.blank()) + return 0; + + if (line[0] == '[') + { + var = line.mid(1); + var.rtrim(1); + val.cut(0); + return 1; + } + + const int equal = line.find('='); + if (equal < 6) + return 0; + var = line.left(equal); var.trim(); + val = line.mid(equal+1); val.trim(); + return 2; +} + +bool TTrFa_app::create_table(TScanner& tff, const TString& table) +{ + TString query, var, val; + if (xvt_sql_table_exists(_db, table)) + { + SLIST fields = xvt_sql_list_fields(_db, table); + while (!tff.eof()) + { + const TString& line = tff.line(); + const int n = parse_line(line, var, val); + if (n <= 0) + break; + if (var.starts_with("INDEX_")) + break; + if (xvt_slist_find_str(fields, var) == NULL) + { + query.cut(0) << "ALTER TABLE " << table << " ADD COLUMN " << var << ' ' << val << " NOT NULL"; + if (val.find("INT") >= 0 || val.find("NUM") >= 0) + query << " DEFAULT 0"; + else + query << " DEFAULT ''"; + query << ";"; + xvt_sql_execute(_db, query, NULL, NULL); // Create table + } + } + xvt_slist_destroy(fields); + } + else + { + query << "CREATE TABLE " << table << " ("; + while (!tff.eof()) + { + const TString& line = tff.line(); + const int n = parse_line(line, var, val); + if (n <= 0) + break; + if (n == 1) + { + tff.push(line); + break; + } + if (var.starts_with("INDEX_")) + { + query.rtrim(1); // toglie ultima , + query << ");"; + xvt_sql_execute(_db, query, NULL, NULL); // Create table + query.cut(0); + query << "CREATE UNIQUE INDEX " + << table << "_1 ON " << table + << " (" << val << ");"; + xvt_sql_execute(_db, query, NULL, NULL); // Create index + break; + } + else + { + query << "\n " << var << ' ' << val << " NOT NULL"; + if (val.find("INT") >= 0 || val.find("NUM") >= 0) + query << " DEFAULT 0"; + else + query << " DEFAULT ''"; + query << ","; + } + } + } + + return true; +} + +bool TTrFa_app::create() +{ + open_files(LF_MOV, LF_RMOV, LF_RMOVIVA, LF_TABCOM, LF_ANAG, + LF_CLIFO, LF_OCCAS, LF_CFVEN, LF_NDITTE, 0); + + // Controllo preventivo dell'avvenuta conversione del tracciato record + TRectype rmoviva(LF_RMOVIVA); + + //if (rmoviva.type("TFINVIO") != _boolfld) + //return error_box(TR("Database non convertito per il Trasferimento Elettronico")); + + _ditta.init(LF_NDITTE, prefix().get_codditta()); + + _dbname = prefix().get_studio(); // base direcotry + _dbname.add("sql"); make_dir(_dbname); + TString16 d; d.format("TR%05ld.db", prefix().get_codditta()); + _dbname.add(d); + + bool create = !_dbname.exist(); + _db = xvt_sql_open(_dbname, user(), "", _dbname.path()); + if (_db == NULL) + return false; + + if(create) + { + createDB(); + } + return TSkeleton_application::create(); +} + +// Sincronizzo il DB SQL con quello di campo +bool TTrFa_app::syncronizeDB() +{ + //xvt_sql_begin(_db); + + return true; +} + +bool TTrFa_app::createDB() +{ + const TFilename ini = "tff.ini"; + bool ok = ini.exist(); + if (ok) + { + xvt_sql_begin(_db); + TScanner TFF(ini); + while (ok && !TFF.eof()) + { + const TString& p = TFF.line(); + if (p.starts_with("[TF") && p.ends_with("F]")) + { + TString16 table = p; table.strip("[]"); + ok = create_table(TFF, table); + } + } + + if (ok) + xvt_sql_commit(_db); + else + xvt_sql_rollback(_db); + } + else + return cantread_box(ini); + + return true; +} + +bool TTrFa_app::send(TTrFa_mask* msk) +{ + // Mi carico i miei dati + + TSheet_field& sheet = msk->sfield(F_RIGHE); + bool ok; + TProgress_monitor p(sheet.items(),"Esportazione fatture"); + FOR_EACH_SHEET_ROW(sheet, r, strarr) + { + //if(!p.add_status()) + //return false; + if(strcmp(strarr->get(_invio), "X") != 0) continue; // Non mi interessa se non è selezionata + + TString8 hfatt; // Codice univoco di 6 caratteri dell'ufficio P.A. + TString20 bfatt; // Codice univoco di 20 caratteri del documento + + hfatt.cut(0) << strarr->get(_tipocf) << "_" << strarr->get(_codcf); + bfatt.cut(0) << TDate(strarr->get(_datadoc)).year() << "|" << strarr->get(_codnum) << "|" << strarr->get(_numdoc) << "|" << strarr->get(_numriga); + + log(-1, bfatt); + + // Preparo l'esportazione + xvt_sql_begin(_db); + + ok = addDT(hfatt, bfatt, strarr); + + // Controllo in caso di errore + if(!ok) + { + log(-1, "WTF!?"); + xvt_sql_rollback(_db); + //return false; + } + else + { + xvt_sql_commit(_db); + // Imposto l'esportazione + setEsportato(strarr); + } + } + return true; +} + +bool TTrFa_app::addDT(TString8& hfatt, TString20& bfatt, TToken_string* strarr) +{ + const char* const paese = "IT"; + static const TFirm& firm = prefix().firm(); + + // + TTrFa_record tff0100f("TFF0100F"); + tff0100f.set("P1_KEYHEADERFATT", hfatt); + tff0100f.set("P1_KEYBODYFATT", bfatt); + + tff0100f.set("P1_TRASMITTPAESE", paese); + tff0100f.set("P1_TRASMITTCOD", _cofi); + tff0100f.set("P1_PRGINVIO", ""); // Ci pensa SiAggTF + + tff0100f.set("P1_CODDEST", hfatt); + TString80 tel; tel << firm.get(NDT_PTEL) << firm.get(NDT_TEL); + tff0100f.set("P1_TELEFONO", tel); + tff0100f.set("P1_MAIL", firm.get(NDT_MAIL)); + tff0100f.set("P1_GESTIONE", "D"); + tff0100f.insert(); + + // + + /******************************************************************************************************************** + * CessionarioCommit * + ********************************************************************************************************************/ + + // + TTrFa_record tff0200f("TFF0200F"); + tff0200f.set("P2_KEYHEADERFATT", hfatt); + tff0200f.set("P2_KEYBODYFATT", bfatt); + tff0200f.remove(); + + if (_ditta.partita_IVA().full()) + { + tff0200f.set("P2_FISCIVAPAESE", paese); // Sempre IT + tff0200f.set("P2_FISCIVACOD", _ditta.partita_IVA()); + } + tff0200f.set("P2_CODFISCALE", _ditta.codice_fiscale()); + if (_ditta.fisica()) + { + tff0200f.set("P2_ANANOME", _ditta.nome()); + tff0200f.set("P2_ANACOGNOME", _ditta.cognome()); + } + else + { + tff0200f.set("P2_ANADENOMIN", _ditta.ragione_sociale()); + } + + // DatiSede + tff0200f.set("P2_SEDEIND", _ditta.via_residenza()); + tff0200f.set("P2_SEDENRCIVICO", _ditta.civico_residenza()); + tff0200f.set("P2_SEDECAP", _ditta.CAP_residenza()); + tff0200f.set("P2_SEDECOMUNE", _ditta.comune_residenza()); + tff0200f.set("P2_SEDEPROV", _ditta.provincia_residenza()); + tff0200f.set("P2_SEDENAZ", paese); + + TString myrfso; + if(haveRFSO(myrfso)) + { + TRectype r_ana = cache().get(LF_ANAG, TString(myrfso[0]) << myrfso.sub(1)); + + if(r_ana.get_char("TIPORFSO") == 'S') // Stabile Organizzazione + { + tff0200f.set("P2_STABORGIND", r_ana.get("INDRES")); + tff0200f.set("P2_STABORGNRCIVICO", r_ana.get("CIVRES")); + tff0200f.set("P2_STABORGCAP", r_ana.get("CAPRES")); + TRectype r_comune = cache().get(LF_COMUNI, TString("|") << r_ana.get("COMRES")); + tff0200f.set("P2_STABORGCOMUNE", r_comune.get("DENCOM")); + tff0200f.set("P2_STABORGPROV", r_comune.get("PROVCOM")); + tff0200f.set("P2_STABORGNAZ", "IT"); + } + else // Rappresentante Fiscale + { + TTrFa_record tff0300f("TFF0300F"); + tff0300f.set("P3_KEYHEADERFATT", hfatt); + tff0300f.set("P3_KEYBODYFATT", bfatt); + tff0300f.remove(); + tff0300f.set("P3_FISCIVAPAESE", paese); // Io italiano posso avere un rappresentante fiscale italiano + tff0300f.set("P3_FISCIVACODICE", r_ana.get("PAIV")); + + if(r_ana.get_char("TIPOA") == 'G') + { + tff0300f.set("P3_ANADENOMI", r_ana.get("RAGSOC")); + } + else + { + TString nomCom = r_ana.get("RAGSOC"); + tff0300f.set("P3_ANANOME", nomCom.sub(30)); + tff0300f.set("P3_ANACOGNOME", nomCom.sub(0,30)); + } + tff0300f.set("P3_GESTIONE", "D"); + tff0300f.insert(); + } + } + + tff0200f.set("P2_GESTIONE", "D"); + + tff0200f.insert(); + + /******************************************************************************************************************** + * Cedeprest * + ********************************************************************************************************************/ + + // + + TAnagrafica cedeprest(LF_CLIFO, strarr->get_char(_tipocf), strarr->get_long(_codcf)); + TRectype r_cedeprest = cache().get(LF_CLIFO, TString(strarr->get_char(_tipocf)) << "|" << strarr->get_long(_codcf)); + TString statocli = cache().get("%STA", r_cedeprest.get("STATOCF"), "S2"); + // + + TTrFa_record tff0400f("TFF0400F"); + tff0400f.set("P4_KEYHEADERFATT", hfatt); + tff0400f.set("P4_KEYBODYFATT", bfatt); + tff0400f.remove(); + + // Autofattura + if(strcmp(strarr->get(_autofatt),"X") == 0) + { + tff0400f.set("P4_FISCIVAPAESE", paese); + tff0400f.set("P4_FISCIVACOD", _ditta.partita_IVA()); + tff0400f.set("P4_CODFISC", _ditta.codice_fiscale()); + } + else // Fattura normale + { + if (cedeprest.stato_partita_IVA().full() && cedeprest.partita_IVA().full()) + { + tff0400f.set("P4_FISCIVAPAESE", cedeprest.stato_partita_IVA()); + tff0400f.set("P4_FISCIVACOD", cedeprest.partita_IVA()); + } + else + tff0400f.set("P4_CODFISC", cedeprest.codice_fiscale()); + } + + if (cedeprest.fisica()) + { + tff0400f.set("P4_ANANOME", cedeprest.nome()); + tff0400f.set("P4_ANACOGNOME", cedeprest.cognome()); + } + else + { + tff0400f.set("P4_ANADENOM", cedeprest.ragione_sociale()); + } + // DatiSede + tff0400f.set("P4_SEDEIND", cedeprest.via_residenza()); + tff0400f.set("P4_SEDENRCIVICO", cedeprest.civico_residenza()); + tff0400f.set("P4_SEDECAP", cedeprest.CAP_residenza()); + tff0400f.set("P4_SEDECOMUNE", cedeprest.comune_residenza()); + tff0400f.set("P4_SEDEPROV", cedeprest.provincia_residenza()); + tff0400f.set("P4_SEDENAZ", statocli); + tff0400f.set("P4_GESTIONE", "D"); + tff0400f.insert(); + + TString rfso; + if(hasRFSO(strarr->get_char(_tipocf), strarr->get_long(_codcf), rfso)) + { + TRectype r_ana = cache().get(LF_ANAG, TString(myrfso[0]) << rfso.sub(1)); + TTrFa_record tff3100f("TFF3100F"); + tff3100f.set("PH_KEYHEADERFATT", hfatt); + tff3100f.set("PH_KEYBODYFATT", bfatt); + tff3100f.remove(); + + if(r_ana.get_char("TIPORFSO") == 'S') // Stabile Organizzazione + { + tff3100f.set("PH_STABORGIND", r_ana.get("INDRES")); + tff3100f.set("PH_STABORGNRCIVICO", r_ana.get("CIVRES")); + tff3100f.set("PH_STABORGCAP", r_ana.get("CAPRES")); + TRectype r_comune = cache().get(LF_COMUNI, TString("|") << r_ana.get("COMRES")); + tff3100f.set("PH_STABORGCOMUNE", r_comune.get("DENCOM")); + tff3100f.set("PH_STABORGPROV", r_comune.get("PROVCOM")); + tff3100f.set("PH_STABORGNAZ", "IT"); + } + else // Rappresentante Fiscale + { + // La P.IVA del rappresentante fiscale deve essere in AT quindi non faccio alcun controllo, + // se il valore nullo perchè Extra CEE non è un errore di campo (Anche perchè che senso ha un RF extra CEE?) + tff3100f.set("PH_FISCIVAPAESE", r_ana.get("STATOPAIV") == "" ? "IT" : r_ana.get("STATOPAIV")); + tff3100f.set("PH_FISCIVACODICE", r_ana.get("PAIV")); + + if(r_ana.get_char("TIPOA") == 'G') + { + tff3100f.set("PH_ANADENOMI", r_ana.get("RAGSOC")); + } + else + { + TString nomCom = r_ana.get("RAGSOC"); + tff3100f.set("PH_ANANOME", nomCom.sub(30)); + tff3100f.set("PH_ANACOGNOME", nomCom.sub(0,30)); + } + } + tff3100f.set("PH_GESTIONE", "D"); + tff3100f.insert(); + } + + // + + /******************************************************************************************************************** + * Fattura * + ********************************************************************************************************************/ + + // + TTrFa_record tff0700f("TFF0700F"); + tff0700f.set("P7_KEYHEADERFATT", hfatt); + tff0700f.set("P7_KEYBODYFATT", bfatt); + tff0700f.remove(); + + tff0700f.set("P7_GESTIONE", "D"); + tff0700f.insert(); + + TTrFa_record tff2200f("TFF2200F"); + tff2200f.set("PL_KEYHEADERFATT", hfatt); + tff2200f.set("PL_KEYBODYFATT", bfatt); + tff2200f.remove(); + + tff2200f.set("PL_IMPONIBILE", strarr->get(_imponibile)); + tff2200f.set("PL_IMPOSTA", strarr->get(_imposta)); + tff2200f.set("PL_ALIQUOTAIVA", strarr->get(_aliquota)); + tff2200f.set("PL_NATURA", strarr->get(_natura)); + if(strcmp(strarr->get(_detraibile), "0.00") != 0) + { + tff2200f.set("PL_DETRAIBILE", strarr->get(_detraibile)); + } + else if(false) // Sempre disabilitato! + { + tff2200f.set("PL_DEDUCIBILE", "SI"); + } + + tff2200f.set("PL_GESTIONE", "D"); + tff2200f.insert(); + + return true; +} + +bool TTrFa_app::setEsportato(TToken_string* strarr) +{ + if(strcmp(strarr->get(_forzata), "X") == 0) + { + // Devo inserire la riga in trasfatt + TRectype row(LF_TRASFATT); + if(strcmp(strarr->get(_spedita), "X") == 0) // Controllo che non sia già stata spedita prima + { + row = cache().get(LF_TRASFATT, TString(strarr->get(_numero))<<"|"<<(strarr->get(_numriga))); + } + else + { + row.put("NUMREG", strarr->get(_numero)); + row.put("NUMRIG", strarr->get(_numriga)); + } + row.put("TIPODOC", strarr->get(_codnum)); + row.put("NDOC", strarr->get(_numdoc)); + row.put("DATADOC", strarr->get(_datadoc)); + row.put("IMPONIBILE", strarr->get(_imponibile)); + row.put("IMPOSTA", strarr->get(_imposta)); + row.put("REVCHARGE", strarr->get(_reverse)); + row.put("AUTOFATT", strarr->get(_autofatt)); + row.put("TFINVIO", "X"); + row.put("TFDATA", TDate(TODAY)); + + return row.write_rewrite(TLocalisamfile(LF_TRASFATT)) == NOERR; + } + else + { + TRectype row = cache().get(LF_RMOVIVA, TString(strarr->get(_numero))<<"|"<<(strarr->get(_numriga))); + row.put("TFINVIO", "X"); + row.put("TFDATA", TDate(TODAY)); + return row.rewrite(TLocalisamfile(LF_RMOVIVA)) == NOERR; + } +} + +void TTrFa_app::main_loop() +{ + TTrFa_mask msk("tf0100a"); + + while (msk.run() == K_ENTER) + { + TSheet_field& sheet = msk.sfield(F_RIGHE); + TString msg("La tabella dei movimenti è vuota, vuoi caricarla con i filtri selezionati?"); + if(sheet.empty() && yesno_box(msg)) + { + msk.load_sheet(); + } + + send(&msk); + } +} + +bool TTrFa_app::destroy() +{ + if (_cofi.full()) + ini_set_string(CONFIG_DITTA, "pa", "TRASMITTCOD", _cofi); + + xvt_sql_close(_db); _db = NULL; + return TSkeleton_application::destroy(); +} + +int tf0100(int argc, char* argv[]) +{ + TTrFa_app t2t; + t2t.run(argc, argv, TR("Trasferimento Fatture Elettroniche")); + return 0; +} \ No newline at end of file diff --git a/src/tf/tf0100a.h b/src/tf/tf0100a.h new file mode 100644 index 000000000..727732333 --- /dev/null +++ b/src/tf/tf0100a.h @@ -0,0 +1,31 @@ +#define F_DATAINI 401 +#define F_DATAFIN 402 +#define F_TIPOCF 403 +#define F_CODCF 404 +#define F_RAGSOC 405 +#define F_FATTSEL 406 + +#define F_RIGHE 300 + +#define A_SPEDITA 101 +#define A_INVIO 102 +#define A_FORZATA 103 +#define A_NUMERO 104 +#define A_NUMRIGA 105 +#define A_TIPOCF 106 +#define A_CODCF 107 +#define A_OCFPI 108 +#define A_RAGSOC 109 +#define A_RFSO 110 +#define A_TIPODOC 111 +#define A_NUMDOC 112 +#define A_DATADOC 113 +#define A_NATURA 114 +#define A_ALIQUOTA 115 +#define A_DETRAIB 116 +#define A_IMPONIBILE 117 +#define A_IMPOSTA 118 +#define A_REVERSE 119 +#define A_AUTOFATT 120 +#define A_PAIV 121 +#define A_COFI 122 \ No newline at end of file diff --git a/src/tf/tf0100a.uml b/src/tf/tf0100a.uml new file mode 100644 index 000000000..4af536cf6 --- /dev/null +++ b/src/tf/tf0100a.uml @@ -0,0 +1,309 @@ +#include "tf0100a.h" + +TOOLBAR "topbar" 0 0 0 2 +#include +ENDPAGE + +PAGE "Impostazioni" 0 2 0 0 + +DATE F_DATAINI +BEGIN + PROMPT 1 0 "Data iniziale:" + CHECKTYPE REQUIRED +END + +DATE F_DATAFIN +BEGIN + PROMPT 40 0 "Data Finale: " + CHECKTYPE REQUIRED +END + +RADIOBUTTON F_TIPOCF 15 +BEGIN + PROMPT 1 2 "Tipo C/F" + ITEM "T|Tutti" + ITEM "C|Cliente" + ITEM "F|Fornitore" +END + +NUMBER F_CODCF 6 +BEGIN + PROMPT 18 4 "Codice:" + USE LF_CLIFO + INPUT TIPOCF F_TIPOCF SELECT + INPUT CODCF F_CODCF + DISPLAY "Codice" CODCF + DISPLAY "Ragione Sociale@50" RAGSOC + DISPLAY "Occasionale@C" OCCAS + DISPLAY "Codice Fiscale@16" COFI + DISPLAY "Partita IVA@15" PAIV + OUTPUT F_CODCF CODCF + OUTPUT F_RAGSOC RAGSOC + CHEKTYPE NORMAL + GROUP 1 + FLAGS "D" +END + +STRING F_RAGSOC 50 49 +BEGIN + PROMPT 18 5 "R.Soc: " + USE LF_CLIFO KEY 2 + INPUT TIPOCF F_TIPOCF SELECT + INPUT RAGSOC F_RAGSOC + DISPLAY "Ragione Sociale@50" RAGSOC + DISPLAY "Codice" CODCF + DISPLAY "Codice Fiscale@16" COFI + DISPLAY "Partita IVA@15" PAIV + COPY OUTPUT F_CODCF + ADD RUN CG0 -1 + GROUP 1 + FLAGS "D" +END + + +RADIOBUTTON F_FATTSEL 25 +BEGIN + PROMPT 1 7 "Fatture da visualizzare" + ITEM "0|Da inviare" + ITEM "1|Inviate" + ITEM "2|Tutti" +END + +ENDPAGE + +PAGE "Trasferimento Fatture" 0 2 0 0 + +SPREADSHEET F_RIGHE +BEGIN + PROMPT 0 0 "" + ITEM "Spedita@3F" + ITEM "Invio@3F" + ITEM "Mod.@3F" + ITEM "N.\nRegistraz.@7F" + ITEM "N.Riga@3F" + ITEM "C/F@2F" + ITEM "Codice@6F" + ITEM "Occas.@3" + ITEM "Ragione Sociale@35" + ITEM "RF/SO@6" + ITEM "Tipo\nDocum.@2" + ITEM "Numero\nDocum.@5" + ITEM "Data\nDocum.@10" + ITEM "Natura\nIVA@4" + ITEM "Aliquota@4" + ITEM "% Detr.@6" + ITEM "Imponibile@10" + ITEM "Imposta@10" + ITEM "Rev.\nCharge@4" + ITEM "Auto\nfatt.@3" + ITEM "Partita IVA@11" + ITEM "Codice Fiscale@15" + DEFAULT "*" // Impedisce il salvataggio su profilo .ini +END + +ENDPAGE + +ENDMASK + +PAGE "Riga" -1 -1 69 10 + +BOOLEAN A_SPEDITA +BEGIN + PROMPT 40 9 "Gia' spedita" + FIELD SPEDITA + FLAGS "D" +END + +BOOLEAN A_INVIO +BEGIN + PROMPT 40 9 "Da inviare" + FIELD INVIO +END + +BOOLEAN A_FORZATA +BEGIN + PROMPT 40 9 "Forzatura manuale" + FIELD FORZATURA +END + +NUMBER A_NUMERO 7 +BEGIN + PROMPT 1 0 "N.Movimento" + FLAGS "D" + FIELD PROGR +END + +NUMBER A_NUMRIGA 3 +BEGIN + PROMPT 25 0 "N.Riga" + FLAGS "D" + FIELD PROGR +END + +LIST A_TIPOCF 1 10 +BEGIN + PROMPT 1 2 "Tipo C/F" + ITEM "C|Cliente" + ITEM "F|Fornitore" + FIELD TIPOCF + FLAGS "D" +END + +NUMBER A_CODCF 6 +BEGIN + PROMPT 23 2 "Cod. C/F" + USE LF_CLIFO + INPUT TIPOCF A_TIPOCF SELECT + INPUT CODCF A_CODCF + DISPLAY "Codice" CODCF + DISPLAY "Ragione Sociale@50" RAGSOC + DISPLAY "Occasionale@C" OCCAS + DISPLAY "Partita IVA" PAIV + DISPLAY "Codice fiscale@16" COFI + OUTPUT A_CODCF CODCF + CHEKTYPE REQUIRED + ADD RUN cg0 -1 + FIELD CODCF + FLAGS "DG" +END + +STRING A_OCFPI 16 +BEGIN + PROMPT 43 2 "Occas." + USE LF_OCCAS + INPUT CFPI A_OCFPI + DISPLAY "Codice@16" CFPI + DISPLAY "Ragione Sociale@50" RAGSOC + DISPLAY "Partita IVA" PAIV + DISPLAY "Codice fiscale@16" COFI + OUTPUT A_OCFPI CFPI + CHEKTYPE NORMAL + GROUP 3 + ADD RUN cg0 -6 + FIELD OCFPI + FLAGS "DG" +END + +STRING A_RAGSOC 50 47 +BEGIN + FIELD RAGSOC + PROMPT 1 3 "Ragione Sociale " + FLAGS "D" +END + +STRING A_RFSO 6 +BEGIN + FIELD RFSO + PROMPT 30 16 "Codice RF/SO:" + HELP "Codice Rappresentante Fiscale o Stabile Organizzazione" + FLAGS "D" +END + +STRING A_TIPODOC 2 +BEGIN + PROMPT 23 5 "Tipo doc. " + FLAGS "U" + FIELD TIPODOC +END + +STRING A_NUMDOC 7 +BEGIN + PROMPT 23 5 "Num. doc. " + FLAGS "U" + FIELD NUMDOC +END + +DATE A_DATADOC +BEGIN + PROMPT 1 5 "Data doc. " + FIELD DATADOC +END + +LIST A_NATURA 1 35 +BEGIN + PROMPT 1 6 "Natura IVA" + ITEM "|IVA ordinaria" + ITEM "N1|N1 - IVA esclusa ex art 15" + ITEM "N2|N2 - IVA non soggetta" + ITEM "N3|N3 - IVA non imponibile" + ITEM "N4|N4 - IVA esente" + ITEM "N5|N5 - IVA in regime del margine" + ITEM "N6|N6 - IVA in reverse charge" + ITEM "N7|N7 - IVA assolta in altro stato U3" + FIELD S12 +END + +NUMBER A_ALIQUOTA 6 2 +BEGIN + PROMPT 25 7 "Aliquota " + HELP "Percentuale di imposta" + FLAGS "D" +END + +STRING A_DETRAIB 6 +BEGIN + PROMPT 25 7 "% Detraibilita' " + HELP "Percentuale di detraibilita'" + FLAGS "D" +END + + +CURRENCY A_IMPONIBILE 12 +BEGIN + PROMPT 1 7 "Imponibile" + FIELD IMPORTO +END + +CURRENCY A_IMPOSTA 12 +BEGIN + PROMPT 45 7 "Imposta" + FIELD IMPOSTA +END + +BOOLEAN A_REVERSE +BEGIN + PROMPT 1 9 "Reverse charge" + FIELD REVERSE +END + +BOOLEAN A_AUTOFATT +BEGIN + PROMPT 25 9 "Autofattura" + FIELD AUTOFATT +END + +STRING A_PAIV 12 +BEGIN + PROMPT 1 4 "Partita IVA " + FLAGS "D" +END + +STRING A_COFI 16 +BEGIN + PROMPT 33 4 "Codice Fiscale " + FLAGS "D" +END + +ENDPAGE + +TOOLBAR "topbar" 0 0 0 2 + +BUTTON DLG_OK 2 2 +BEGIN + PROMPT 1 1 "" +END + +BUTTON DLG_USER 2 2 +BEGIN + PROMPT 2 1 "Collega" + PICTURE TOOL_LINK +END + +BUTTON DLG_CANCEL 2 2 +BEGIN + PROMPT 4 1 "" +END + +ENDPAGE + +ENDMASK \ No newline at end of file diff --git a/src/tf/tff.ini b/src/tf/tff.ini new file mode 100644 index 000000000..5aa1415f7 --- /dev/null +++ b/src/tf/tff.ini @@ -0,0 +1,174 @@ +[TFF0100F] +P1_KEYHEADERFATT = CHAR(20) +P1_KEYBODYFATT = CHAR(20) + +P1_TRASMITTPAESE = CHAR(2) +P1_TRASMITTCOD = CHAR(28) +P1_PRGINVIO = CHAR(10) +P1_FMTTRASMISS = CHAR(5) +P1_CODDEST = CHAR(6) +P1_TELEFONO = CHAR(12) +P1_MAIL = CHAR(256) + +P1_GESTIONE = CHAR(1) +P1_ERRINT = CHAR(1) +P1_ERREST = CHAR(1) + +INDEX_1 = P1_KEYHEADERFATT,P1_KEYBODYFATT + +[TFF0200F] +P2_KEYHEADERFATT = CHAR(20) +P2_KEYBODYFATT = CHAR(20) + +P2_FISCIVAPAESE = CHAR(2) +P2_FISCIVACOD = CHAR(28) +P2_CODFISCALE = CHAR(16) +P2_ANADENOMIN = CHAR(80) +P2_ANANOME = CHAR(60) +P2_ANACOGNOME = CHAR(60) +P2_ANATITOLO = CHAR(10) +P2_ANACODEORI = CHAR(17) +P2_ALBOPROFESS = CHAR(60) +P2_PROVALBO = CHAR(2) +P2_NRISCRIZALBO = CHAR(60) +P2_DTISCRIZEALBO = DATE +P2_REGFISCALE = CHAR(4) +P2_SEDEIND = CHAR(60) +P2_SEDENRCIVICO = CHAR(8) +P2_SEDECAP = NUMERIC(5, 0) +P2_SEDECOMUNE = CHAR(60) +P2_SEDEPROV = CHAR(2) +P2_SEDENAZ = CHAR(2) +P2_STABORGIND = CHAR(60) +P2_STABORGNRCIVICO = CHAR(8) +P2_STABORGCAP = NUMERIC(5, 0) +P2_STABORGCOMUNE = CHAR(60) +P2_STABORGPROV = CHAR(2) +P2_STABORGNAZ = CHAR(2) +P2_ISCRREAUFF = CHAR(2) +P2_ISCRREANUM = CHAR(20) +P2_ISCRREACAP = VARNUMERIC(15, 2) +P2_ISCRREASOCIOU = CHAR(2) +P2_ISCRREASLIQUID = CHAR(2) +P2_CONTATTITELEF = CHAR(12) +P2_CONTATTIFAX = CHAR(12) +P2_CONTATTIMAIL = CHAR(256) +P2_RIFAMMINISTR = CHAR(20) + +P2_GESTIONE = CHAR(1) +P2_ERRINT = CHAR(1) +P2_ERREST = CHAR(1) + +INDEX_1 = P2_KEYHEADERFATT,P2_KEYBODYFATT + +[TFF0300F] +P3_KEYHEADERFATT = CHAR(20) +P3_KEYBODYFATT = CHAR(20) + +P3_FISCIVAPAESE = CHAR(2) +P3_FISCIVACODICE = CHAR(28) +P3_CODFISC = CHAR(16) +P3_ANADENOMI = CHAR(80) +P3_ANANOME = CHAR(60) +P3_ANACOGNOME = CHAR(60) +P3_ANATITOLO = CHAR(10) +P3_ANACODEORI = CHAR(17) + +P3_GESTIONE = CHAR(1) +P3_ERRINT = CHAR(1) +P3_ERREST = CHAR(1) + +INDEX_1 = P3_KEYHEADERFATT,P3_KEYBODYFATT + +[TFF0400F] +P4_KEYHEADERFATT = CHAR(20) +P4_KEYBODYFATT = CHAR(20) +P4_FISCIVAPAESE = CHAR(2) +P4_FISCIVACOD = CHAR(28) +P4_CODFISC = CHAR(16) +P4_ANADENOM = CHAR(80) +P4_ANANOME = CHAR(60) +P4_ANACOGNOME = CHAR(60) +P4_ANATITOLO = CHAR(10) +P4_ANACODEORI = CHAR(17) + +P4_SEDEIND = CHAR(60) +P4_SEDENRCIVICO = CHAR(8) +P4_SEDECAP = CHAR(5) +P4_SEDECOMUNE = CHAR(60) +P4_SEDEPROV = CHAR(2) +P4_SEDENAZ = CHAR(2) + +P4_GESTIONE = CHAR(1) +P4_ERRINT = CHAR(1) +P4_ERREST = CHAR(1) + +INDEX_1 = P4_KEYHEADERFATT,P4_KEYBODYFATT + +[TFF0700F] +P7_KEYHEADERFATT = CHAR(20) +P7_KEYBODYFATT = CHAR(20) +P7_TIPODOC = CHAR(4) +P7_DIVISA = CHAR(3) +P7_DATA = DATE +P7_NUMERO = CHAR(20) + +P7_TIPORITENUTA = CHAR(4) +P7_IMPORTORIT = NUMERIC(15, 2) +P7_ALIQUOTARIT = NUMERIC(6, 2) +P7_CAUSPAGAM = CHAR(1) +P7_NUMEROBOLLO = CHAR(14) +P7_IMPORTOBOLLO = NUMERIC(15, 2) + +P7_DATAREG = DATE +P7_NUMEROREG = NUMERIC(20, 0) +P7_TIPOREG = CHAR(6) +P7_PROTOCOLLO = CHAR(18) +P7_POSIZIONE = NUMERIC(4, 0) + +P7_GESTIONE = CHAR(1) +P7_ERRINT = CHAR(1) +P7_ERREST = CHAR(1) + +INDEX_1 = P7_KEYHEADERFATT,P7_KEYBODYFATT + +[TFF2200F] +PL_KEYHEADERFATT = CHAR(20) +PL_KEYBODYFATT = CHAR(20) + +PL_ALIQUOTAIVA = NUMERIC(6,2) +PL_NATURA = CHAR(2) +PL_SPESEACCESS = NUMERIC(15,2) +PL_ARROTONDAM = NUMERIC(15,2) +PL_IMPONIBILE = NUMERIC(15,2) +PL_IMPOSTA = NUMERIC(15,2) +PL_ESIGIVA = CHAR(1) +PL_RIFNORMATIVO = CHAR(100) +PL_DETRAIBILE = NUMERIC(6, 2) +PD_DEDUCIBILE = CHAR(2) + +PL_GESTIONE = CHAR(1) +PL_ERRINT = CHAR(1) +PL_ERREST = CHAR(1) + +INDEX_1 = PL_KEYHEADERFATT,PL_KEYBODYFATT + +[TFF3100F] +PH_KEYHEADERFATT = CHAR(20) +PH_KEYBODYFATT = CHAR(20) +PH_STABORGIND = CHAR(60) +PH_STABORGNRCIVICO = CHAR(8) +PH_STABORGCAP = NUMERIC(5) +PH_STABORGCOMUNE = CHAR(60) +PH_STABORGPROV = CHAR(2) +PH_STABORGNAZ = CHAR(2) +PH_FISCIVAPAESE = CHAR(2) +PH_FISCIVACODICE = CHAR(28) +PH_ANADENOMI = CHAR(80) +PH_ANANOME = CHAR(60) +PH_ANACOGNOME = CHAR(60) +PH_GESTIONE = CHAR(1) +PH_ERRINT = CHAR(1) +PH_ERREST = CHAR(1) + +INDEX_1 = PH_KEYHEADERFATT,PH_KEYBODYFATT \ No newline at end of file diff --git a/src/tf/tftbcon.h b/src/tf/tftbcon.h new file mode 100644 index 000000000..8d95a629e --- /dev/null +++ b/src/tf/tftbcon.h @@ -0,0 +1,17 @@ +#ifndef __TFTBCON_H +#define __TFTBCON_H + +#define F_CON_TIPO 101 +#define F_CON_CODCF 102 +#define F_CON_RAGSOC 112 +#define F_CON_CODICE 103 +#define F_CON_DESCRIZIONE 113 +#define F_CON_DATA 104 +#define F_CON_RIFAMM 105 +#define F_CON_CAUS1 121 +#define F_CON_CAUS2 122 +#define F_CON_CAUS3 123 + +#endif + + diff --git a/src/tf/tftbcon.uml b/src/tf/tftbcon.uml new file mode 100644 index 000000000..f041d97ac --- /dev/null +++ b/src/tf/tftbcon.uml @@ -0,0 +1,142 @@ +#include "tftbcon.h" + +TOOLBAR "topbar" 0 0 0 2 +#include +ENDPAGE + +PAGE "Contratti per PA" 0 2 0 0 + +GROUPBOX DLG_NULL 78 5 +BEGIN + PROMPT 1 0 "@bEstremi contratto/convenzione/ordine P.A." +END + +LIST F_CON_TIPO 1 11 +BEGIN + PROMPT 2 1 "Tipo " + ITEM "C|Contratto" + ITEM "V|Convenzione" + ITEM "O|Ordine" + FIELD CODTAB[1,1] + KEY 1 +END + +NUMBER F_CON_CODCF 6 +BEGIN + PROMPT 2 2 "Cliente " + USE LF_CFVEN SELECT PADESTIN!="" + JOIN LF_CLIFO INTO TIPOCF==TIPOCF CODCF==CODCF + INPUT TIPOCF "C" + INPUT CODCF F_CON_CODCF + DISPLAY "Codice" CODCF + DISPLAY "Ragione Sociale@50" LF_CLIFO->RAGSOC + DISPLAY "Destinatario" PADESTIN + DISPLAY "Riferimento amm.@20" PARIFAMM + OUTPUT F_CON_CODCF CODCF + OUTPUT F_CON_RAGSOC LF_CLIFO->RAGSOC + CHECKTYPE REQUIRED + FIELD CODTAB[2,7] + KEY 1 + MESSAGE EMPTY ENABLE,F_CON_RAGSOC + MESSAGE DISABLE,F_CON_RAGSOC +END + +STRING F_CON_RAGSOC 50 +BEGIN + PROMPT 24 2 "" + USE LF_CLIFO KEY 2 SELECT LF_CFVEN->PADESTIN!="" + JOINT LF_CFVEN INTO TIPOCF==TIPOCF CODCF==CODCF + INPUT TIPOCF "C" + INPUT RAGSOC F_CON_RAGSOC + DISPLAY "Ragione Sociale@50" RAGSOC + DISPLAY "Codice" CODCF + DISPLAY "Destinatario" LF_CFVEN->PADESTIN + DISPLAY "Riferimento amm.@20" LF_CFVEN->PARIFAMM + COPY OUTPUT F_CON_CODCF + CHECKTYPE NORMAL +END + +STRING F_CON_CODICE 20 +BEGIN + PROMPT 2 3 "Numero " + FLAGS "U" + FIELD CODTAB[8,27] + USE &CON + JOIN LF_CLIFO INTO TIPOCF="C" CODCF=CODTAB[2,7] + INPUT CODTAB[1,1] F_CON_TIPO SELECT + INPUT CODTAB[2,7] F_CON_CODCF SELECT + INPUT CODTAB[8,27] F_CON_CODICE + DISPLAY "Tipo" CODTAB[1,1] + DISPLAY "Numero@20" CODTAB[8,] + DISPLAY "Descrizione@50" S0 + DISPLAY "Cliente" CODTAB[2,7] + DISPLAY "Ragione Sociale@50" LF_CLIFO->RAGSOC + OUTPUT F_CON_CODCF CODTAB[2,7] + OUTPUT F_CON_CODICE CODTAB[8,] + OUTPUT F_CON_DESCRIZIONE S0 + CHECKTYPE REQUIRED + KEY 1 +END + + +GROUPBOX DLG_NULL 78 5 +BEGIN + PROMPT 1 5 "@bDati contratto/convenzione/ordine P.A." +END + +STRING F_CON_DESCRIZIONE 70 50 +BEGIN + PROMPT 2 6 "Descrizione " + FIELD S0 + USE &CON KEY 2 SELECT (CODTAB[1,1]==#F_CON_TIPO)&&(STR(CODTAB[2,7]=#F_CON_CODCF)) + JOIN LF_CLIFO INTO TIPOCF=CODTAB[1,1] CODCF=CODTAB[2,7] + INPUT S0 F_CON_DESCRIZIONE + DISPLAY "Tipo" CODTAB[1,1] + DISPLAY "Descrizione@50" S0 + DISPLAY "Numero@20" CODTAB[8,] + DISPLAY "Cliente" CODTAB[2,7] + DISPLAY "Ragione Sociale@50" LF_CLIFO->RAGSOC + CHECKTYPE REQUIRED + COPY OUTPUT F_CON_CODICE + KEY 2 +END + +DATA F_CON_DATA +BEGIN + PROMPT 2 7 "Data " + FIELD D0 +END + +STRING F_CON_RIFAMM 20 +BEGIN + PROMPT 24 7 "Riferimento amministrazione " + FIELD S4 +END + +GROUPBOX DLG_NULL 78 5 +BEGIN + PROMPT 1 10 "@bCausale" +END + +STRING F_CON_CAUS1 50 +BEGIN + PROMPT 14 11 "" + FIELD S1 +END + +STRING F_CON_CAUS2 50 +BEGIN + PROMPT 14 12 "" + FIELD S2 +END + +STRING F_CON_CAUS3 50 +BEGIN + PROMPT 14 13 "" + FIELD S3 +END + +ENDPAGE +ENDMASK + +