From b3b982eb70cc54d90feb7ef410bb356a196576aa Mon Sep 17 00:00:00 2001 From: Mattia Tollari Date: Wed, 25 Jul 2018 15:53:29 +0200 Subject: [PATCH] =?UTF-8?q?Patch=20level=20=20=20=20=20=20=20=20=20:=2012.?= =?UTF-8?q?0=20no-patch=20Files=20correlati=20=20=20=20=20:=20fp=20Comment?= =?UTF-8?q?o=20=20=20=20=20=20=20=20=20=20=20=20:=20-=20Spostato=20codice?= =?UTF-8?q?=20trasmittente=20nel=20programma=20di=20configurazione=20-=20S?= =?UTF-8?q?vuotato=20file=20fp0200=20che=20dava=20solo=20problemi=20-=20Po?= =?UTF-8?q?rtato=20tutto=20il=20procedimento=20di=20esportazione=20in=20fp?= =?UTF-8?q?lib=20cos=C3=AC=20da=20poter=20utilizzare=20il=20tutto=20anche?= =?UTF-8?q?=20da=20altre=20applicazioni?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/fp0.vcxproj | 12 +- build/fplib.vcxproj.filters | 21 + src/fp/fp0100.cpp | 32 +- src/fp/fp0100a.h | 1 + src/fp/fp0100a.uml | 19 +- src/fp/fp0200.cpp | 1751 ----------------------------------- src/fp/fp0300.cpp | 1472 +---------------------------- src/fp/fp0300a.h | 5 +- src/fp/fp0300a.uml | 6 - src/fp/fplib01.cpp | 1366 ++++++++++++++++++++++++++- src/fp/fplib01.h | 105 +++ 11 files changed, 1549 insertions(+), 3241 deletions(-) create mode 100644 build/fplib.vcxproj.filters diff --git a/build/fp0.vcxproj b/build/fp0.vcxproj index c6c09dddb..937c2ac40 100644 --- a/build/fp0.vcxproj +++ b/build/fp0.vcxproj @@ -12,8 +12,8 @@ {9C91BACF-9A70-4973-B8CC-FA3D2AF9867C} - tf0 - 10.0.17134.0 + fp + 10.0.16299.0 @@ -186,7 +186,6 @@ true - @@ -197,7 +196,6 @@ true - @@ -216,6 +214,12 @@ Document + + + + + + diff --git a/build/fplib.vcxproj.filters b/build/fplib.vcxproj.filters new file mode 100644 index 000000000..e6b867b3a --- /dev/null +++ b/build/fplib.vcxproj.filters @@ -0,0 +1,21 @@ + + + + + {72a9ea2f-8fbe-4546-96f3-21a4de35bf0e} + + + {afa0f493-bfe6-4bd2-add2-3256306ed9c5} + + + + + Headers + + + + + Sources + + + \ No newline at end of file diff --git a/src/fp/fp0100.cpp b/src/fp/fp0100.cpp index 7ceb34419..cb8817737 100644 --- a/src/fp/fp0100.cpp +++ b/src/fp/fp0100.cpp @@ -14,6 +14,8 @@ class TParametri_mask : public TAutomask { +private: + void load_all(); protected: void tipi_import(); static TMask& get_tmp_msk(const char* title); @@ -22,18 +24,34 @@ protected: public: TParametri_mask(const char* n); + void save_all() const; }; TParametri_mask::TParametri_mask(const char * n) : TAutomask(n) +{ + load_all(); +} + +void TParametri_mask::save_all() const +{ + ini_set_string(CONFIG_DITTA, "fp", "ip", get(F_INDIRIZZO)); + ini_set_string(CONFIG_DITTA, "fp", "db", get(F_DATABASE)); + ini_set_string(CONFIG_DITTA, "fp", "usr", get(F_USER)); + ini_set_string(CONFIG_DITTA, "fp", "psw", encode(get(F_PASSWORD))); + ini_set_string(CONFIG_DITTA, "fp", "flddest", get(F_FLDDEST)); + ini_set_string(CONFIG_DITTA, "fp", "fldusrdest", get(F_FLDUSRDEST)); + ini_set_string(CONFIG_DITTA, "fp", "cofitras", get(F_COFI)); +} + +void TParametri_mask::load_all() { set(F_INDIRIZZO, ini_get_string(CONFIG_DITTA, "fp", "ip")); set(F_DATABASE, ini_get_string(CONFIG_DITTA, "fp", "db")); set(F_USER, ini_get_string(CONFIG_DITTA, "fp", "usr")); - set(F_PASSWORD, decode(ini_get_string(CONFIG_DITTA, "fp", "psw") )); + set(F_PASSWORD, decode(ini_get_string(CONFIG_DITTA, "fp", "psw"))); set(F_FLDDEST, ini_get_string(CONFIG_DITTA, "fp", "flddest")); set(F_FLDUSRDEST, ini_get_string(CONFIG_DITTA, "fp", "fldusrdest")); - - + set(F_COFI, ini_get_string(CONFIG_DITTA, "fp", "cofitras")); } void TParametri_mask::tipi_import() @@ -210,13 +228,7 @@ void TParametri_ditta::main_loop() SSimple_query s(ad, usr, psw, TSDB_MSSQL); if (s.sq_is_connect()) { - - ini_set_string(CONFIG_DITTA, "fp", "ip", ip); - ini_set_string(CONFIG_DITTA, "fp", "db", db); - ini_set_string(CONFIG_DITTA, "fp", "usr", usr); - ini_set_string(CONFIG_DITTA, "fp", "psw", encode(psw)); - ini_set_string(CONFIG_DITTA, "fp", "flddest", pm.get(F_FLDDEST)); - ini_set_string(CONFIG_DITTA, "fp", "fldusrdest", pm.get(F_FLDUSRDEST)); + pm.save_all(); message_box("Dati salvati correttamente!"); } else diff --git a/src/fp/fp0100a.h b/src/fp/fp0100a.h index 0205a7f81..e05cea82d 100644 --- a/src/fp/fp0100a.h +++ b/src/fp/fp0100a.h @@ -4,6 +4,7 @@ #define F_PASSWORD 104 #define F_FLDDEST 105 #define F_FLDUSRDEST 106 +#define F_COFI 107 #define F_SETPATCH 201 #define F_ENPTYTABLE 202 diff --git a/src/fp/fp0100a.uml b/src/fp/fp0100a.uml index 352e7e53c..66f4f8ad6 100644 --- a/src/fp/fp0100a.uml +++ b/src/fp/fp0100a.uml @@ -13,7 +13,7 @@ ENDPAGE PAGE "Configurazione FP" 0 2 0 0 -GROUPBOX DLG_NULL 78 10 +GROUPBOX DLG_NULL 78 8 BEGIN PROMPT 1 1 "@BDatabase" END @@ -47,19 +47,28 @@ BEGIN CHECKTYPE REQUIRED END +GROUPBOX DLG_NULL 78 3 +BEGIN + PROMPT 1 9 "@BTrasmittente" +END + +STRING F_COFI 16 +BEGIN + PROMPT 2 10 "Codice fiscale trasmittente " + CHECKTYPE REQUIRED +END + STRING F_FLDDEST 300 50 BEGIN PROMPT 2 6 "Destinazione Server " - CHECKTYPE REQUIRED - FLAGS "M" + FLAGS "" END STRING F_FLDUSRDEST 300 50 BEGIN PROMPT 2 7 "Destinazione User " DSELECT - CHECKTYPE REQUIRED - FLAGS "M" + FLAGS "" END ENDPAGE diff --git a/src/fp/fp0200.cpp b/src/fp/fp0200.cpp index 73c5add88..e1eb8ad53 100644 --- a/src/fp/fp0200.cpp +++ b/src/fp/fp0200.cpp @@ -1,1757 +1,6 @@ #include "fp0.h" -#include "fp0200b.h" - -#include -#include -#include -#include - -#include "../ve/velib05.h" -#include "../cg/cglib03.h" - -#include "../fe/felib.h" - -#include -#include -#include -#include -#include -#include -#include "../cg/cfban.h" - -///////////////////////////////////////////////////////////////////////////////////// -// Utilities -///////////////////////////////////////////////////////////////////////////////////// - -SSimple_query& db() -{ - static SSimple_query* db = new SSimple_query(); - return *db; -} - -// Crea la coppia di chiavi per il db PAF a partire da un documento vero e proprio -static bool chiave_paf(const TDocumento& doc, TString& cess, TString& numdoc) -{ - cess = doc.clifor().vendite().get(CFV_PADESTIN); - CHECK(cess.full(), "Destinatario fattura P.A. non valido"); - - const TCodice_numerazione& codnum = doc.codice_numerazione(); - const long ndoc = doc.numero(); - TString16 fullnumdoc; codnum.complete_num(ndoc, fullnumdoc); - - numdoc.cut(0) << doc.get(DOC_ANNO) << '/' << codnum.codice() << '/' << fullnumdoc; - return cess.full(); -} - -// Crea la coppia di chiavi per il db PAF a partire da un semplice record di testata documento -static bool chiave_paf(const TRectype& doc, TString& cess, TString& numdoc) -{ - const long codcf = doc.get_long(DOC_CODCF); - TString8 key; key.format("C|%ld", codcf); - cess = cache().get(LF_CFVEN, key, CFV_PADESTIN); - CHECK(cess.full(), "Destinatario fattura P.A. non valido"); - - const TCodice_numerazione& codnum = cached_numerazione(doc.get(DOC_CODNUM)); - const long ndoc = doc.get_long(DOC_NDOC); - TString16 fullnumdoc; codnum.complete_num(ndoc, fullnumdoc); - numdoc.cut(0) << doc.get(DOC_ANNO) << '/' << codnum.codice() << '/' << fullnumdoc; - - return cess.full(); -} - - -///////////////////////////////////////////////////////////////////////////////////// -// TAncestor -///////////////////////////////////////////////////////////////////////////////////// - -struct TAncestor : public TObject -{ - TString20 _numdoc; - TDate _datadoc; - - TAncestor(const TRectype& rdoc); -}; - -TAncestor::TAncestor(const TRectype& rdoc) -{ - const int anno = rdoc.get_int(RDOC_ANNO); - const TString4 codnum = rdoc.get(RDOC_CODNUM); - const long ndoc = rdoc.get_long(RDOC_NDOC); - const TCodice_numerazione& num = cached_numerazione(codnum); - - TToken_string kdoc; - kdoc = rdoc.get(RDOC_PROVV); - kdoc.add(anno); - kdoc.add(codnum); - kdoc.add(ndoc); - const TRectype& doc = cache().get(LF_DOC, kdoc); - - TString16 numdoc; num.complete_num(ndoc, numdoc); - _numdoc.format("%d/%s/%s", anno, (const char*)codnum, (const char*)numdoc); - _datadoc = doc.get_date(DOC_DATADOC); -} - - -///////////////////////////////////////////////////////////////////////////////////// -// TPaf_record -///////////////////////////////////////////////////////////////////////////////////// - -// Contenitore di campi di un record di database SQLite -class TPaf_record : public TObject -{ - TString8 _table; - TToken_string _key; - TAssoc_array _fields; - -protected: - void copy(const TPaf_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 TPaf_record(*this); } - virtual bool ok() const { return _table.not_empty(); } - - TPaf_record& operator=(const TPaf_record& rec) { copy(rec); return *this; } - TPaf_record(const TPaf_record& rec) { copy(rec); } - TPaf_record(const char* table); -}; - -// Imposta il valore di un campo variant -void TPaf_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 TPaf_record::set(const char* fld, long val) -{ - const TVariant var(val); - set(fld, var); -} - -// Imposta il valore di un campo stringa -void TPaf_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 TPaf_record::set(const char* fld, const TString& val) -{ - const TVariant var(val); - set(fld, var); -} - -// Imposta il valore di un campo numerico -void TPaf_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 TPaf_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 TPaf_record::set(const char* fld, bool var) -{ - set(fld, var ? "SI" : "NO"); -} - -// Legge il valore di un campo variant -const TVariant& TPaf_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& TPaf_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 TPaf_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 db().sq_set_exec(query); -} - -// Callback per la sottostante funzione search() -static int paf_search_record(void* jolly, int cols, char** values, char** names) -{ - TPaf_record& rec = *(TPaf_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 TPaf_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 << ';'; - // TODO: Da controllare - // return xvt_sql_execute(_db, query, paf_search_record, this) == 1; - return db().sq_set_exec(query); -} - -// Carica un record in base ad un massimo di 3 campi chiave -bool TPaf_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 TPaf_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; - return db().sq_set_exec(query); -} - -// Crea un record della tabella data ed imposta i nomi dei campi chiave -TPaf_record::TPaf_record(const char* table) : _table(table), _key(15, ',') -{ - _key = ini_get_string("./paf.ini", table, "INDEX_1"); - if (_key.empty()) - { - // Cerco di costruire i nomi della chiave cercando la K, come in P1_KEYHEADERFATT - TConfig cfg("paf.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); -} - -///////////////////////////////////////////////////////////////////////////////////// -// TPa_mask -///////////////////////////////////////////////////////////////////////////////////// - -class TPA_mask : public TAutomask -{ -protected: - virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); - - void fill(); - void init(); - bool is_fattura(const TRectype& doc) const; - -public: - TPA_mask() : TAutomask("fp0200a") { } -}; - -bool TPA_mask::is_fattura(const TRectype& doc) const -{ - const TTipo_documento& td = cached_tipodoc(doc.get(DOC_TIPODOC)); - if (!td.is_fattura()) // Tengo per buone solo le fatture e le note di credito - return false; - - const TCodice_numerazione& cn = cached_numerazione(doc.get(DOC_CODNUM)); - return cn.tipo() == 2 && !cn.get_bool("B10"); // Controlla se fattura provvisioria esclusa da P.A. -} - - -void TPA_mask::fill() -{ - TSheet_field& docs = sfield(F_DOCS); - TString_array& sht = docs.rows_array(); - docs.hide(); - - sht.destroy(); - - // Seleziona tutti i clienti che sono pubbliche amministrazioni (PADESTIN!='') - TString query; - query << "USE 17 SELECT PADESTIN!=''" - << "\nJOIN 20 INTO TIPOCF=TIPOCF CODCF==CODCF" - << "\nFROM TIPOCF=C\nTO TIPOCF=C"; - - TISAM_recordset clifo_pa(query); - const TRecnotype n = clifo_pa.items(); - if (n > 0) - { - const TDate dal = get(F_DATAINI); - const bool hide_processed = !get_bool(F_SHOWALL); - - // Record di controllo per eventuali elaborazioni precedenti - TString hfatt(8), bfatt(20); - TPaf_record paf0100f("PAF0100F"); - - TProgress_monitor pi(n, NULL); - for (bool okc = clifo_pa.move_first(); okc; okc = clifo_pa.move_next()) - { - if (!pi.add_status()) - break; - - query.cut(0); - query << "USE 33 KEY 2\nSELECT (BETWEEN(STATO,2,8))"; - query << "\nFROM TIPOCF=C CODCF=#CLIENTE PROVV=D ANNO=" << dal.year() << " DATADOC=" << dal.date2ansi() - << "\nTO TIPOCF=C CODCF=#CLIENTE PROVV=D"; - TISAM_recordset doc_pa(query); - doc_pa.set_var("#CLIENTE", clifo_pa.get(CLI_CODCF)); - const TRectype& doc = doc_pa.cursor()->curr(); - for (bool okd = doc_pa.move_first(); okd; okd = doc_pa.move_next()) - { - const TTipo_documento& td = cached_tipodoc(doc.get(DOC_TIPODOC)); - if (!td.is_fattura()) // Tengo per buone solo le fatture e le note di credito - continue; - - bool sent = false; - if (chiave_paf(doc, hfatt, bfatt)) - { - if (paf0100f.search(hfatt, bfatt)) - { - sent = paf0100f.get("P1_GESTIONE").as_string() == "X"; - if (sent && hide_processed) - continue; - } - } - TToken_string* row = new TToken_string; - *row = sent ? " " : "X"; - row->add(doc_pa.get(DOC_ANNO).as_int(), 1); - row->add(doc_pa.get(DOC_CODNUM).as_string()); - row->add(doc_pa.get(DOC_NDOC).as_int()); - row->add(doc_pa.get(DOC_DATADOC).as_date()); - row->add(clifo_pa.get(CFV_CODCF).as_int()); - row->add(clifo_pa.get("20." CLI_RAGSOC).as_string()); - row->add(clifo_pa.get(CFV_PADESTIN).as_string()); - row->add(clifo_pa.get(CFV_PARIFAMM).as_string()); - row->add(clifo_pa.get("20." CLI_COFI).as_string()); - - bool split = clifo_pa.get("20." CLI_SPLITPAY).as_bool(); - if (split) - { - const long numreg = doc_pa.get(DOC_NUMREG).as_int(); - if (numreg > 0) - { - const TRectype& mov = cache().get(LF_MOV, numreg); - split = is_split_payment(mov); - } - } - row->add(split ? "X" : " "); - - const bool attach = !doc_pa.get("COLL_GOLEM").is_empty(); - row->add(attach ? "X" : " "); - - sht.add(row); - } - } - } - docs.force_update(); - docs.show(); -} - -bool TPA_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, "pa", "LastXML", "31-03-2015")); else - if (e == fe_modify) - fill(); else - if (e == fe_close) - ini_set_string(CONFIG_DITTA, "pa", "LastXML", o.get()); - break; - case F_SHOWALL: - if (e == fe_modify) - fill(); - break; - case F_DOCS: - if (e == fe_init) - fill(); - if (e == se_query_add || e == se_query_del) - return false; - break; - case DLG_USER: - if (e == fe_button && jolly > 0) - { - TSheet_field& docs = sfield(F_DOCS); - TToken_string& row = docs.row(docs.selected()); - TRectype doc(LF_DOC); - doc.put(DOC_PROVV, 'D'); - doc.put(DOC_ANNO, row.get(1)); - doc.put(DOC_CODNUM, row.get()); - doc.put(DOC_NDOC, row.get()); - if (doc.edit()) - fill(); - } - break; - case DLG_ALL: - { - if (e == fe_button) - { - TSheet_field& docs = sfield(F_DOCS); - 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; - } - return true; -} - -///////////////////////////////////////////////////////////////////////////////////// -// TDoc2Paf -///////////////////////////////////////////////////////////////////////////////////// - -class TDoc2Paf : public TSkeleton_application -{ - TAnagrafica _ditta; - TString16 _cofi; - TFilename _dbname; - TLog_report* _log; - TString _logpaf; - -private: - int parse_line(const TString& line, TString& var, TString& val) const; - bool create_table(TScanner& paf, const TString& table); - - const TRectype* find_parent_row(const TRectype& rdoc) const; - int find_ancestors(const TRiga_documento& rdoc, TArray& ancestors) const; - -protected: - bool parse_sconto(const TString& formula, TToken_string& sconti) const; - bool get_bnp_iban(const TString& abi, const TString& cab, int prg, TString& iban) const; - bool get_bank(const TDocumento& doc, TString& iban, TString& abi, TString& cab, TString& istituto) const; - 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(); - const char * natura(const TString& codiva) const; - void set_IVA(const TString& codiva, TPaf_record& paf) const; - void set_IVA(const TRiga_documento& rdoc, TPaf_record& paf) const; - - bool elabora(TDocumentoEsteso& doc); - bool elabora(const TRectype& rec); - bool elabora(const TDoc_key& key); - bool elabora(const TFilename& ini); - bool genera_xml(); - -public: - virtual bool create(); - virtual bool destroy(); - virtual void main_loop(); - - TDoc2Paf() : _log(NULL) {} -}; - -bool TDoc2Paf::parse_sconto(const TString& formula, TToken_string& sconti) const -{ - sconti.cut(0); - int start = 0; - for (int i = 0; ; i++) - { - const char c = formula[i]; - if (c == '+' || c == '-' || c < ' ') - { - if (i > 0) - { - TString8 tok = formula.sub(start, i); - tok.replace(',', '.'); - const real perc = tok; - if (!perc.is_zero()) - sconti.add(tok); - } - if (c < ' ') - break; - start = i; - } - } - return sconti.full(); -} - -bool TDoc2Paf::get_bnp_iban(const TString& abi, const TString& cab, int nprog, TString& iban) const -{ - TTable bnp("BNP"); - TString16 key; - key << abi << cab; - if (nprog > 0) - { - TString4 sprog; sprog.format("%02d", nprog); - key << sprog; - } - bnp.put("CODTAB", key); - int err = bnp.read(_isgteq); - if (err == NOERR && !bnp.get("CODTAB").starts_with(abi)) - err = _iskeynotfound; - if (err == NOERR) - iban = bnp.get("S3"); - - return err == NOERR; -} - -bool TDoc2Paf::get_bank(const TDocumento& doc, TString& iban, TString& abi, TString& cab, TString& istituto) const -{ - bool found = false; - abi = doc.get(DOC_CODABIP); - cab = doc.get(DOC_CODCABP); - int prg = doc.get_int(DOC_PROGBNP); - - found = abi.full() && cab.full(); - if (found) - get_bnp_iban(abi, cab, prg, iban); - - if (!found) // Se non trovo banca sul DOC la cerco su CFBAN - { - TToken_string key; - key.add("C"); key.add(doc.codcf()); key.add("N"); key.add(1); - const TRectype& cfban = cache().get(LF_CFBAN, key); - if (!cfban.empty()) - { - abi = cfban.get(CFBAN_ABI); - cab = cfban.get(CFBAN_CAB); - prg = cfban.get_int(CFBAN_PROGPR); - found = abi.full() && cab.full(); - iban = cfban.get(CFBAN_IBAN); - if (found && iban.blank()) - get_bnp_iban(abi, cab, prg, iban); - } - } - - if (!found) // Se non trovo banca su CFBAN la cerco su CFVEN - { - const TRectype& cfven = doc.clifor().vendite(); - abi = cfven.get(CFV_CODABIPR); - cab = cfven.get(CFV_CODCABPR); - found = abi.full() && cab.full(); - if (found) - get_bnp_iban(abi, cab, 0, iban); - } - - if (found) - istituto = cache().get("%BAN", abi, "S0"); - - return found; -} - -const char* TDoc2Paf::descrizione(const TRiga_documento& rdoc) const -{ - if (rdoc.get_bool(RDOC_DESCLUNGA)) - { - TString tmp; - tmp << rdoc.get(RDOC_DESCR) << rdoc.get(RDOC_DESCEST); - tmp.replace('\n', ' '); tmp.strip_double_spaces(); tmp.trim(); - TParagraph_string para(tmp, 100); - return para.get(0); - } - return rdoc.get(RDOC_DESCR); -} - -const TRectype* TDoc2Paf::find_parent_row(const TRectype& rdoc) const -{ - const long id = rdoc.get_long(RDOC_DAIDRIGA); - if (id > 0L) - { - TToken_string key; - key.add(rdoc.get(RDOC_DACODNUM)); - if (key.full()) - { - key.add(rdoc.get(RDOC_DAANNO)); - key.add(rdoc.get(RDOC_DAPROVV)); - key.add(rdoc.get(RDOC_DANDOC)); - for (int r = 0; ; r++) - { - if (r == 0) - key.add(id, 4); - else - key.add(r, 4); - const TRectype& rec = cache().get(LF_RIGHEDOC, key); - if (r > 0 && rec.empty()) - break; - if (rec.get_long(RDOC_IDRIGA) == id) - return &rec; - } - } - } - return NULL; -} - -int TDoc2Paf::find_ancestors(const TRiga_documento& rdoc, TArray& ancestors) const -{ - if (rdoc.is_articolo()) - { - for (const TRectype* prdoc = find_parent_row(rdoc); prdoc != NULL; prdoc = find_parent_row(*prdoc)) - { - const TCodice_numerazione& cn = cached_numerazione(prdoc->get(RDOC_CODNUM)); - const int td = cn.tipo(); - if (td > 0 && ancestors.objptr(td) == NULL) - ancestors.add(new TAncestor(*prdoc), td); - } - } - return ancestors.items(); -} - -const TRectype& TDoc2Paf::cco(const TRectype& doc) const -{ - TString80 conkey; - const TString& con = doc.get(DOC_CONTRATTO); - if (con.full()) - { - char tcon = doc.get_char(DOC_MODPAG); - if (tcon < 'C') tcon = 'C'; - conkey.format("%c%6ld%s", tcon, doc.get_long(DOC_CODCF), (const char*)con); - } - return cache().get("&CON", conkey); -} - -void TDoc2Paf::log(int severity, const char* msg) -{ - if (severity < 0) - { - _logpaf = msg; - } - else - if (_log == NULL) - { - _log = new TLog_report; - if (_logpaf.full()) - { - TString txt; - txt << _logpaf << ": " << msg; - _log->log(severity, txt); - } - else - _log->log(severity, msg); - } -} - -bool TDoc2Paf::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; -} - - -const char * TDoc2Paf::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; -} - -void TDoc2Paf::set_IVA(const TString& codiva, TPaf_record& paf) const -{ - const TRectype& ai = cache().get("%IVA", codiva); - const real aliquota = ai.get("R0"); - paf.set("PI_ALIQUOTAIVA", aliquota); - if (codiva.full()) - { - if (aliquota.is_zero()) - paf.set("PI_NATURA", natura(codiva)); - else - paf.set("PI_NATURA", ""); - } -} - -void TDoc2Paf::set_IVA(const TRiga_documento& rdoc, TPaf_record& paf) const -{ - const TString8 codiva(rdoc.get(RDOC_CODIVA)); - const TRectype& ai = cache().get("%IVA", codiva); - const real aliquota = ai.get("R0"); - paf.set("PI_ALIQUOTAIVA", aliquota); - if (codiva.full()) - { - if (aliquota.is_zero()) - paf.set("PI_NATURA", natura(codiva)); - else - paf.set("PI_NATURA", ""); - } -} - - -bool TDoc2Paf::elabora(TDocumentoEsteso& doc) -{ - TString8 hfatt; // Codice univoco di 6 caratteri dell'ufficio P.A. - TString20 bfatt; // Codice univoco di 20 caratteri del documento - if (!chiave_paf(doc, hfatt, bfatt)) - return false; - log(-1, bfatt); - - const TFirm& firm = prefix().firm(); - const char* const paese = "IT"; - TCausale caus = TCausale(doc.tipo().causale(), doc.anno()); - - // - TPaf_record paf0100f("PAF0100F"); - paf0100f.set("P1_KEYHEADERFATT", hfatt); - paf0100f.set("P1_KEYBODYFATT", bfatt); - paf0100f.remove(); - - paf0100f.set("P1_TRASMITTPAESE", paese); - paf0100f.set("P1_TRASMITTCOD", _cofi); - paf0100f.set("P1_PRGINVIO", ""); // Ci pensa SiAggPA - paf0100f.set("P1_FMTTRASMISS", "SDI11"); // SDI11 si usa dal 2015 per lo split payment (prima era SDI10) - - paf0100f.set("P1_CODDEST", hfatt); - TString80 tel; tel << firm.get(NDT_PTEL) << firm.get(NDT_TEL); - paf0100f.set("P1_TELEFONO", tel); - paf0100f.set("P1_MAIL", firm.get(NDT_MAIL)); - paf0100f.set("P1_GESTIONE", "D"); - paf0100f.insert(); - // - - // - TPaf_record paf0200f("PAF0200F"); - paf0200f.set("P2_KEYHEADERFATT", hfatt); - paf0200f.set("P2_KEYBODYFATT", bfatt); - paf0200f.remove(); - - if (_ditta.partita_IVA().full()) - { - paf0200f.set("P2_FISCIVAPAESE", paese); // Sempre IT - paf0200f.set("P2_FISCIVACOD", _ditta.partita_IVA()); - } - paf0200f.set("P2_CODFISCALE", _ditta.codice_fiscale()); - if (_ditta.fisica()) - { - paf0200f.set("P2_ANANOME", _ditta.nome()); - paf0200f.set("P2_ANACOGNOME", _ditta.cognome()); - } - else - { - paf0200f.set("P2_ANADENOMIN", _ditta.ragione_sociale()); - } - - const char* regime_fiscale = "RF01"; - if (doc.get_bool(DOC_IVAXCASSA)) - { - // Supponiamo volume d'affari > 200000, altrimenti sarebbe RF17 - regime_fiscale = "RF16"; - } - paf0200f.set("P2_REGFISCALE", regime_fiscale); - - // DatiSede - paf0200f.set("P2_SEDEIND", _ditta.via_residenza()); - paf0200f.set("P2_SEDENRCIVICO", _ditta.civico_residenza()); - paf0200f.set("P2_SEDECAP", _ditta.CAP_residenza()); - paf0200f.set("P2_SEDECOMUNE", _ditta.comune_residenza()); - paf0200f.set("P2_SEDEPROV", _ditta.provincia_residenza()); - paf0200f.set("P2_SEDENAZ", paese); - paf0200f.set("P2_GESTIONE", "D"); - - TAnagrafica cliente(doc.clifor()); - - TString rifamm = cco(doc).get("S4"); - if (rifamm.blank()) - rifamm = doc.clifor().vendite().get(CFV_PARIFAMM); - paf0200f.set("P2_RIFAMMINISTR", rifamm); - - TISAM_recordset unloc("USE UNLOC\nJOIN COMUNI INTO COM==COMCCIAA\nFROM CODDITTA=#DITTA\nTO CODDITTA=#DITTA"); - unloc.set_var("#DITTA", firm.get(NDT_CODDITTA)); - if (unloc.move_first()) - { - const TString& numrea = unloc.get(ULC_NUMCCIAA).as_string(); - if (numrea.full()) - { - paf0200f.set("P2_ISCRREANUM", numrea); - paf0200f.set("P2_ISCRREAUFF", unloc.get("13->" COM_PROVCOM)); - } - } - - if (_ditta.giuridica()) - { - TISAM_recordset anagiu("USE ANAGIU\nFROM CODANAGR=#CODICE\nTO CODANAGR=#CODICE"); - anagiu.set_var("#CODICE", firm.get(NDT_CODANAGR)); - if (anagiu.move_first()) - { - paf0200f.set("P2_ISCRREACAP", anagiu.get(ANG_CAPSOC)); - const int ss = anagiu.get(ANG_STATOSOC).as_int(); - paf0200f.set("P2_ISCRREASLIQUID", (ss == 2 || ss == 3) ? "LS" : "LN"); - } - } - else - paf0200f.set("P2_ISCRREASLIQUID", "LN"); - - paf0200f.insert(); - - // - - // - - TPaf_record paf0400f("PAF0400F"); - paf0400f.set("P4_KEYHEADERFATT", hfatt); - paf0400f.set("P4_KEYBODYFATT", bfatt); - paf0400f.remove(); - - if (cliente.partita_IVA().full()) - { - paf0400f.set("P4_FISCIVAPAESE", paese); - paf0400f.set("P4_FISCIVACOD", cliente.partita_IVA()); - } - paf0400f.set("P4_CODFISC", cliente.codice_fiscale()); - - if (cliente.fisica()) - { - paf0400f.set("P4_ANANOME", cliente.nome()); - paf0400f.set("P4_ANACOGNOME", cliente.cognome()); - } - else - { - paf0400f.set("P4_ANADENOM", cliente.ragione_sociale()); - } - - // DatiSede - paf0400f.set("P4_SEDEIND", cliente.via_residenza()); - paf0400f.set("P4_SEDENRCIVICO", cliente.civico_residenza()); - paf0400f.set("P4_SEDECAP", cliente.CAP_residenza()); - paf0400f.set("P4_SEDECOMUNE", cliente.comune_residenza()); - paf0400f.set("P4_SEDEPROV", cliente.provincia_residenza()); - paf0400f.set("P4_SEDENAZ", "IT"); - paf0400f.set("P4_GESTIONE", "D"); - paf0400f.insert(); - // - - // - TPaf_record paf0700f("PAF0700F"); - paf0700f.set("P7_KEYHEADERFATT", hfatt); - paf0700f.set("P7_KEYBODYFATT", bfatt); - paf0700f.remove(); - paf0700f.set("P7_TIPODOC", doc.is_nota_credito() ? "TD04" : "TD01"); - paf0700f.set("P7_DIVISA", "EUR"); // Aggiungere codice ISO 4217 a tabella divise (%VAL) - paf0700f.set("P7_DATA", doc.data()); - - const TCodice_numerazione& codnum = doc.codice_numerazione(); - TString20 numdoc; codnum.complete_num(doc.numero(), numdoc); - paf0700f.set("P7_NUMERO", numdoc); - paf0700f.set("P7_GESTIONE", "D"); - paf0700f.insert(); - - // - TPaf_record paf0900f("PAF0900F"); - paf0900f.set("P9_KEYHEADERFATT", hfatt); - paf0900f.set("P9_KEYBODYFATT", bfatt); - paf0900f.remove(); - - TString80 sconto_expr = doc.get(DOC_SCONTOPERC); - TToken_string sconti; - if (parse_sconto(sconto_expr, sconti)) - { - long nlin_sconto = 0; - FOR_EACH_TOKEN(sconti, str) - { - const real sconto = str; - if (!sconto.is_zero()) // Precauzione inutile - { - paf0900f.set("P9_RIFNUMLINEA", ++nlin_sconto); - if (sconto > ZERO) - { - paf0900f.set("P9_TIPOSCONTO", "SC"); - paf0900f.set("P9_PERCSCONTO", sconto); - } - else - { - paf0900f.set("P9_TIPOSCONTO", "MG"); - paf0900f.set("P9_PERCSCONTO", -sconto); - } - paf0900f.set("P9_GESTIONE", "D"); - paf0900f.insert(); - } - } - } - // - - // - TPaf_record paf2700f("PAF2700F"); - paf2700f.set("PQ_KEYHEADERFATT", hfatt); - paf2700f.set("PQ_KEYBODYFATT", bfatt); - paf2700f.remove(); - paf2700f.set("PQ_IMPTOTDOC", doc.totale_doc()); - - const TRectype& cont_conv_off = cco(doc); - TString causale = cont_conv_off.get("S1"); - if (causale.full()) - { - causale << ' ' << cont_conv_off.get("S2"); - causale << ' ' << cont_conv_off.get("S3"); - causale.strip_double_spaces(); - causale.cut(200); - } - else - causale = doc.tipo().descrizione(); - paf2700f.set("PQ_CAUSALE", causale); - // paf2700f.set("PQ_ART73", true); - paf2700f.set("PQ_GESTIONE", "D"); - paf2700f.insert(); - // - - // Azzera contratti - TPaf_record paf1000f("PAF1000F"); - paf1000f.set("P0_KEYHEADERFATT", hfatt); - paf1000f.set("P0_KEYBODYFATT", bfatt); - paf1000f.remove(); - - // Azzera convenzioni - TPaf_record paf1100f("PAF1100F"); - paf1100f.set("PA_KEYHEADERFATT", hfatt); - paf1100f.set("PA_KEYBODYFATT", bfatt); - paf1100f.remove(); - - // Azzera ordini - TPaf_record paf1200f("PAF1200F"); - paf1200f.set("PB_KEYHEADERFATT", hfatt); - paf1200f.set("PB_KEYBODYFATT", bfatt); - paf1200f.remove(); - - // Azzera DDT - TPaf_record paf1600f("PAF1600F"); - paf1600f.set("PF_KEYHEADERFATT", hfatt); - paf1600f.set("PF_KEYBODYFATT", bfatt); - paf1600f.remove(); - - const TString16 cup = doc.get(DOC_CUP); - const TString16 cig = doc.get(DOC_CIG); - const TString80 com = doc.get(DOC_CODCMS); - - TString80 con = doc.get(DOC_CONTRATTO); - if (con.full() || cup.full() || cig.full()) - { - char tcon = doc.get_char(DOC_MODPAG); - if (tcon < 'C') tcon = 'C'; - - TDate datadoc; // Data contratto non obbligatoria - if (con.full()) - { - datadoc = cco(doc).get_date("D0"); - } - else - { - // IdDocumento obbligatorio - con = cig; - if (con.blank()) - con = cup; - } - - if (tcon == 'O') - { - paf1000f.set("P0_RIFNUMLINEA", 0L); - paf1000f.set("P0_IDDOC", con); - paf1000f.set("P0_DATADOC", datadoc); - paf1000f.set("P0_COMMCONVENZ", com); - paf1000f.set("P0_CODCUP", cup); - paf1000f.set("P0_CODCIG", cig); - paf1000f.set("P0_GESTIONE", "D"); - paf1000f.insert(); - } - else - if (tcon == 'C') - { - paf1100f.set("PA_RIFNUMLINEA", 0L); - paf1100f.set("PA_IDDOC", con); - paf1100f.set("PA_DATADOCU", datadoc); - paf1100f.set("PA_COMMCONVENZ", com); - paf1100f.set("PA_CODCUP", cup); - paf1100f.set("PA_CODCIG", cig); - paf1000f.set("PA_GESTIONE", "D"); - paf1100f.insert(); - } - else - { - paf1200f.set("PB_RIFNUMLINEA", 0L); - paf1200f.set("PB_IDDOC", con); - paf1200f.set("PB_DATADOCO", datadoc); - paf1200f.set("PB_COMMCONVENZ", com); - paf1200f.set("PB_CODCUP", cup); - paf1200f.set("PB_CODCIG", cig); - paf1200f.set("PB_GESTIONE", "D"); - paf1200f.insert(); - } - } - - if (cup.blank() && cig.blank()) - log(1, "CIG e CUP assenti"); - - // - - TPaf_record paf1800f("PAF1800F"); - paf1800f.set("PI_KEYHEADERFATT", hfatt); - paf1800f.set("PI_KEYBODYFATT", bfatt); - paf1800f.remove(); // Cancella tutte le righe documento - - TPaf_record paf2000f("PAF2000F"); - paf2000f.set("PJ_KEYHEADERFATT", hfatt); - paf2000f.set("PJ_KEYBODYFATT", bfatt); - paf2000f.remove(); // Cancella tutti gli sconti di riga - - long riga = 0; - TString16 codivadefault; - { - FOR_EACH_PHYSICAL_RDOC(doc, r, rdoc) - { - codivadefault = rdoc->get(RDOC_CODIVA); - if (codivadefault.full()) - break; - } - } - FOR_EACH_PHYSICAL_RDOC(doc, r, rdoc) - { - paf1800f.reset(); - paf1800f.set("PI_KEYHEADERFATT", hfatt); - paf1800f.set("PI_KEYBODYFATT", bfatt); - paf1800f.set("PI_NUMEROLINEA", ++riga); - paf1800f.set("PI_DESCRIZIONE", descrizione(*rdoc)); - // paf1800f.set("PI_ALIQUOTAIVA", "22.00"); // Altrimenti scarta le righe di descrizione - - - set_IVA(codivadefault, paf1800f); - - if (rdoc->is_merce()) - { - paf1800f.set("PI_UNITAMISURA", rdoc->get(RDOC_UMQTA)); - const real qta = rdoc->get(RDOC_QTA); - if (qta.is_zero()) - { - TString msg; msg.format("La riga merce %d ha quantità nulla", riga); - log(1, msg); - } - if (qta >= ZERO) - { - paf1800f.set("PI_QUANTITA", qta); - paf1800f.set("PI_PREZZOUNIT", rdoc->prezzo(false, false)); - } - else - { - paf1800f.set("PI_QUANTITA", -qta); - paf1800f.set("PI_PREZZOUNIT", -rdoc->prezzo(true, false)); - } - paf1800f.set("PI_PRZTOTALE", rdoc->importo(true, false)); - set_IVA(*rdoc, paf1800f); - - /* - const TDate data = doc.get(DOC_DATADOC); - paf1800f.set("PI_DTINIZIOPER", data); - paf1800f.set("PI_DTFINEPER", data); - */ - - // - - sconto_expr = rdoc->get(RDOC_SCONTO); - if (parse_sconto(sconto_expr, sconti)) - { - long nlin_sconto = 0; - FOR_EACH_TOKEN(sconti, str) - { - const real perc = str; - if (!perc.is_zero()) - { - paf2000f.set("PJ_KEYNLINEA", (long)r); - paf2000f.set("PJ_KEYNPROGR", ++nlin_sconto); - if (perc > ZERO) - { - paf2000f.set("PJ_TIPOSCONTO", "SC"); - paf2000f.set("PJ_PERCSCONTO", perc); - } - else - { - paf2000f.set("PJ_TIPOSCONTO", "MG"); - paf2000f.set("PJ_PERCSCONTO", -perc); - } - paf2000f.set("PJ_GESTIONE", "D"); - paf2000f.insert(); - } - } - } - // - - TArray ancestors; find_ancestors(*rdoc, ancestors); - for (int i = ancestors.last(); i > 0; i = ancestors.pred(i)) - { - const TAncestor& a = (const TAncestor&)ancestors[i]; - if (i == 1) - { - TPaf_record paf1600f("PAF1600F"); - paf1600f.reset(); - paf1600f.set("PF_KEYHEADERFATT", hfatt); - paf1600f.set("PF_KEYBODYFATT", bfatt); - paf1600f.set("PF_RIFNUMLINEA", (long)r); - paf1600f.set("PF_NUMDDDT", a._numdoc); - paf1600f.set("PF_DATADDT", a._datadoc); - paf1600f.set("PF_GESTIONE", "D"); - paf1600f.insert(); - } - else - if (i == 3) - { - TPaf_record paf1000f("PAF1000F"); - paf1000f.set("P0_KEYHEADERFATT", hfatt); - paf1000f.set("P0_KEYBODYFATT", bfatt); - paf1000f.set("P0_RIFNUMLINEA", (long)r); - paf1000f.set("P0_IDDOC", a._numdoc); - paf1000f.set("P0_DATADOC", a._datadoc); - paf1000f.set("P0_COMMCONVENZ", com); - paf1000f.set("P0_CODCUP", cup); - paf1000f.set("P0_CODCIG", cig); - paf1000f.set("P0_GESTIONE", "D"); - paf1000f.insert(); - } - } - } - else - if (rdoc->is_spese()) - { - const TSpesa_prest& sp = rdoc->spesa(); - const real imp = rdoc->importo(true, false); - real qta = UNO; - if (sp.is_tipo()) - { - paf1800f.set("PI_UNITAMISURA", rdoc->get(RDOC_UMQTA)); - qta = rdoc->get_real(RDOC_QTA); - if (qta.is_zero()) - { - TString msg; msg.format("La riga spese a quantità %d ha quantità nulla (campo %s)", riga, (const char*)rdoc->field_qta()); - log(1, msg); - qta = UNO; - } - paf1800f.set("PI_QUANTITA", qta); - } - real prz = imp; - if (qta != UNO) - { - prz = rdoc->prezzo(true, false); - if (prz.is_zero() && !imp.is_zero()) - { - const TPrice price(imp / qta); - prz = price.get_value(); - } - } - paf1800f.set("PI_PREZZOUNIT", prz); - paf1800f.set("PI_PRZTOTALE", imp); - set_IVA(*rdoc, paf1800f); - } - else - if (rdoc->is_prestazione()) - { - paf1800f.set("PI_UNITAMISURA", rdoc->get(RDOC_UMQTA)); - real qta = rdoc->get(RDOC_QTA); if (qta.is_zero()) qta = UNO; - paf1800f.set("PI_QUANTITA", qta); - paf1800f.set("PI_PREZZOUNIT", rdoc->prezzo(false, false)); - paf1800f.set("PI_PRZTOTALE", rdoc->importo(true, false)); - set_IVA(*rdoc, paf1800f); - } - - paf1800f.set("PI_GESTIONE", "D"); - paf1800f.insert(); - } - // - - // - TPaf_record paf2200f("PAF2200F"); - paf2200f.set("PL_KEYHEADERFATT", hfatt); - paf2200f.set("PL_KEYBODYFATT", bfatt); - paf2200f.remove(); // Cancella tutte le righe di riepilogo IVA - - const char* eiva = "I"; // Esigibilità IVA: Immediata, Differita, Split payment - if (doc.is_split_payment()) - eiva = "S"; else - if (doc.get_bool(DOC_LIQDIFF) || doc.get_bool(DOC_IVAXCASSA)) - eiva = "D"; - - long num_riep = 0; - TAssoc_array& tiva = doc.tabella_iva(false); - FOR_EACH_ASSOC_OBJECT(tiva, obj, key, itm) - { - const TRiepilogo_iva& riva = *(const TRiepilogo_iva*)itm; - const real aliquota = riva.cod_iva().percentuale(); - paf2200f.set("PL_KEYNPROGR", ++num_riep); - paf2200f.set("PL_ALIQUOTAIVA", aliquota); - if (aliquota.is_zero()) - paf2200f.set("PL_NATURA", natura(riva.cod_iva().codice())); - - paf2200f.set("PL_IMPONIBILE", riva.imponibile()); - paf2200f.set("PL_IMPOSTA", riva.imposta()); - paf2200f.set("PL_ESIGIVA", eiva); - if (*eiva == 'S') - paf2200f.set("PL_RIFNORMATIVO", "Scissione pagamenti art.17-ter DPR 633/72"); - else - paf2200f.set("PL_RIFNORMATIVO", riva.cod_iva().descrizione()); - paf2200f.set("PL_GESTIONE", "D"); - paf2200f.insert(); - } - // - - // - TPaf_record paf2400f("PAF2400F"); - paf2400f.set("PN_KEYHEADERFATT", hfatt); - paf2400f.set("PN_KEYBODYFATT", bfatt); - paf2400f.remove(); // Cancella i dati pagamento - - TPagamento& pag = doc.pagamento(); - doc.scadenze_recalc(); // Ricalcola array delle rate - TString_array& scad = doc.scadenze(); - const int nrate = scad.items(); // Conta rate generate - const char* rateazione = nrate > 1 ? "TP01" : "TP02"; // A rate (TP01) o una soluzione(TP02)? - paf2400f.set("PN_CONDPAGAMENTO", rateazione); - paf2400f.set("PN_GESTIONE", "D"); - paf2400f.insert(); - - TPaf_record paf2500f("PAF2500F"); - paf2500f.set("PO_KEYHEADERFATT", hfatt); - paf2500f.set("PO_KEYBODYFATT", bfatt); - paf2500f.remove(); // Cancella tutte le rate - - // Imposto i campi uguali per tutte le rate - paf2500f.set("PO_CONDPAGAMENTO", rateazione); // Condizione di pagamento PA - paf2500f.set("PO_CODICEPAGAM", pag.code()); // Condizione di pagamento CAMPO - - TString80 iban, istituto; - TString8 abi, cab; - if (get_bank(doc, iban, abi, cab, istituto)) - { - paf2500f.set("PO_ISTFINANZ", istituto); - paf2500f.set("PO_IBAN", iban); - paf2500f.set("PO_ABI", abi); - paf2500f.set("PO_CAB", cab); - } - - if (cab.blank()) - log(2, TR("Non sono presenti ABI, CAB, IBAN per il pagamento")); else - if (iban.blank()) - log(1, TR("Non è presente il codice IBAN per il pagamento")); - - for (int nr = 0; nr < nrate; nr++) - { - paf2500f.set("PO_KEYNPROGR", long(nr + 1)); // Numero rata - - const char* mod_pag = "MP01"; // Modalità di pagamento - const int n = nr < pag.n_rate() ? nr : 0; // Si assicura che il numero riga sia accettabile - switch (pag.tipo_rata(n)) - { - case _bonfico: mod_pag = "MP05"; break; // bonifico - case _rid: mod_pag = "MP09"; break; // RID - case _ric_ban: mod_pag = "MP12"; break; // RIBA - default: mod_pag = "MP01"; break; // contanti - } - paf2500f.set("PO_MODALITAPAGAM", mod_pag); - - TToken_string& riga = scad.row(nr); // Data|Importo - paf2500f.set("PO_DATASCADENZA", TDate(riga.get(0))); // Data scadenza - paf2500f.set("PO_IMPORTO", real(riga.get())); // Importo rata - - paf2500f.set("PO_GESTIONE", "D"); - paf2500f.insert(); - } - - TPaf_record paf2600f("PAF2600F"); - paf2600f.set("PP_KEYHEADERFATT", hfatt); - paf2600f.set("PP_KEYBODYFATT", bfatt); - paf2600f.remove(); // Cancella eventuali allegati - TToken_string allegati(doc.get("COLL_GOLEM"), '\n'); - if (allegati.full()) - { - long nprogr = 0; // Numero di file allegati - TFilename fname; - FOR_EACH_TOKEN(allegati, row) - { - const TToken_string entry(row); - if (entry.get(0, fname) && fname.exist()) - { - paf2600f.set("PP_KEYNPROGR", ++nprogr); - paf2600f.set("PP_NOMEATTACHMENT", fname.name()); - paf2600f.set("PP_ATTACHMENT", fname); - fname.upper(); // serve estensione maiuscola - paf2600f.set("PP_FMTATTACHMENT", fname.ext()); - paf2600f.insert(); - } - } - } - - // - - return true; -} - -bool TDoc2Paf::elabora(const TRectype& rec) -{ - bool done = false; - TDocumentoEsteso doc; - if (doc.read(rec) == NOERR) - { - // TODO: Da controllare - // xvt_sql_begin(_db); - done = elabora(doc); - if (done) - done = db().sq_commit(); - else - db().sq_rollback(); - } - return done; -} - -bool TDoc2Paf::elabora(const TDoc_key& key) -{ - TRectype rec(LF_DOC); - rec.put(DOC_PROVV, key.provv()); - rec.put(DOC_ANNO, key.anno()); - rec.put(DOC_CODNUM, key.codnum()); - rec.put(DOC_NDOC, key.ndoc()); - return elabora(rec); -} - -bool TDoc2Paf::elabora(const TFilename& ini) -{ - TConfig cfg(ini, "33"); - const int anno = cfg.get_int(DOC_ANNO); - const long ndoc = cfg.get_long(DOC_NDOC); - const TFixed_string codnum(cfg.get(DOC_CODNUM)); // lascio sapientemente per ultima la get di una stringa - const TDoc_key key(anno, codnum, ndoc); - return elabora(key); -} - - -bool TDoc2Paf::genera_xml() -{ -#define PABASE "SiaggPA" - - TFilename tmp; - - // Copia eventuali protezioni software - TString_array files; - if (list_files(PABASE"/*.ssa", files) == 0) - { - list_files("*.ssa", files); - FOR_EACH_ARRAY_ROW(files, i, row) - { - tmp = PABASE; tmp.add(*row); - xvt_fsys_fupdate(*row, tmp); - } - } - files.destroy(); - if (list_files(PABASE"/*.ssa", files) != 1) - warning_box(FR("Nella cartella %s deve essere presente esattamente un file .ssa"), PABASE); - - TFilename home; - xvt_sys_get_env("USERPROFILE", home.get_buffer(), home.size()); - home.add("SoftwareSirio"); home.add(PABASE); - if (!dexist(home)) - make_dir(home); - - tmp = home; tmp.add("config.properties"); - xvt_fsys_fupdate(PABASE"/config.properties", tmp); - - tmp = home; tmp.add("configGUI.properties"); - xvt_fsys_fupdate(PABASE"/configGUI.properties", tmp); - - if (tmp.exist()) - { - TJava_profile prop(tmp); - if (prop.get("percorso").blank()) - prop.set("percorso", _dbname.path()); - prop.set("nomePAF", _dbname); - } - else - cantread_box(tmp); - - tmp = PABASE"\\SiaggPACAMPO.jar"; - tmp.make_absolute_path(); - - DIRECTORY old_dir; xvt_fsys_get_dir(&old_dir); - DIRECTORY new_dir; xvt_fsys_convert_str_to_dir(tmp.path(), &new_dir); - xvt_fsys_set_dir(&new_dir); - const bool good = goto_url(tmp); - if (good) - xvt_sys_sleep(3000); - else - error_box(FR("Impossibile eseguire Java -jar %s"), (const char*)tmp); - xvt_fsys_set_dir(&old_dir); - - return good; -} - -void TDoc2Paf::main_loop() -{ - int ndocs = 0; - for (int a = 1; a < argc(); a++) - { - TFilename ini = argv(a); - if (ini.starts_with("-i", true) || ini.starts_with("/i", true)) - ini.ltrim(2); - if (ini.exist() && elabora(ini)) - ndocs++; - else - { - if (ini.find('*') >= 0 || ini.find('?') >= 0) - { - TString_array f; list_files(ini, f); - FOR_EACH_ARRAY_ROW(f, r, row) - { - ini = *row; - if (ini.exist() && elabora(ini)) - ndocs++; - } - } - } - } - if (ndocs > 0) - { - if (show_log()) - genera_xml(); - return; - } - - TPA_mask mask; - mask.set(F_COFI, _cofi); - while (mask.run() == K_ENTER) - { - _cofi = mask.get(F_COFI); - - TString_array& sht = mask.sfield(F_DOCS).rows_array(); - if (!sht.empty()) - { - TProgress_monitor pi(sht.items(), NULL); - ndocs = 0; - FOR_EACH_ARRAY_ROW(sht, r, riga) - { - if (riga->starts_with("X")) - { - const int anno = riga->get_int(1); - const long ndoc = riga->get_long(3); - const TFixed_string codnum(riga->get(2)); // lascio sapientemente per ultima la get di una stringa - const TDoc_key key(anno, codnum, ndoc); - if (elabora(key)) - ndocs++; - } - if (!pi.add_status(1)) - break; - } - message_box(FR("Sono stati elaborati %d documenti"), ndocs); - } - - if (ndocs > 0 && show_log()) - genera_xml(); - } -} - -int TDoc2Paf::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 TDoc2Paf::create_table(TScanner& paf, const TString& table) -{ - TString query, var, val; - if (xvt_sql_table_exists(_db, table)) - { - SLIST fields = xvt_sql_list_fields(_db, table); - while (!paf.eof()) - { - const TString& line = paf.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 (!paf.eof()) - { - const TString& line = paf.line(); - const int n = parse_line(line, var, val); - if (n <= 0) - break; - if (n == 1) - { - paf.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 TDoc2Paf::create() -{ - open_files(LF_TAB, LF_TABCOM, LF_TABMOD, LF_ANAG, - LF_CLIFO, LF_CFVEN, LF_CFBAN, LF_NDITTE, - LF_DOC, LF_RIGHEDOC, 0); - - TRectype cfven(LF_CFVEN); - if (cfven.type(CFV_PARIFAMM) != _alfafld) - return error_box(TR("Database non convertito per fatturazione P.A.")); - - _ditta.init(LF_NDITTE, prefix().get_codditta()); - TString ad = ini_get_string(CONFIG_DITTA, "fp", "ip"); ad << "@" << ini_get_string(CONFIG_DITTA, "fp", "db"); - db().sq_connect( - ad, - ini_get_string(CONFIG_DITTA, "fp", "usr"), - decode(ini_get_string(CONFIG_DITTA, "fp", "psw")), - TSDB_MSSQL - ); - db().sq_set_autocommit(false); - if (db().sq_is_connect()) - return false; - - const TFilename ini = "paf.ini"; - bool ok = ini.exist(); - if (ok) - { - // TODO: Controllare begin - // xvt_sql_begin(_db); - TScanner paf(ini); - while (ok && !paf.eof()) - { - const TString& p = paf.line(); - if (p.starts_with("[PA") && p.ends_with("F]")) - { - TString16 table = p; table.strip("[]"); - ok = create_table(paf, table); - } - } - - if (ok) - { - TPaf_record panum("PANUM00F"); - panum.set("PJNKEY", "00001"); - if (!panum.search()) - { - panum.set("PJNINV", "0000000000"); - panum.insert(); - } - - db().sq_commit(); - } - else - db().sq_rollback(); - } - else - return cantread_box(ini); - - _cofi = ini_get_string(CONFIG_DITTA, "pa", "TRASMITTCOD"); - if (_cofi.blank()) - _cofi = _ditta.codice_fiscale(); - - return ok && TSkeleton_application::create(); -} - -bool TDoc2Paf::destroy() -{ - if (_cofi.full()) - ini_set_string(CONFIG_DITTA, "pa", "TRASMITTCOD", _cofi); - - return TSkeleton_application::destroy(); -} int fp0200(int argc, char* argv[]) { - //TFp_app t2t; - //t2t.run(argc, argv, TR("Trasferimento Fatture Elettroniche")); return 0; } \ No newline at end of file diff --git a/src/fp/fp0300.cpp b/src/fp/fp0300.cpp index 6204f9523..79307645c 100644 --- a/src/fp/fp0300.cpp +++ b/src/fp/fp0300.cpp @@ -1,31 +1,17 @@ #include #include #include -#include -#include +#include "fplib01.h" #include -#include -#include -#include -#include +#include #include "../ve/velib05.h" #include "../cg/cglib03.h" +#include "../fe/felib.h" #include "fp0.h" #include "fp0300a.h" -#include "../fe/felib.h" -#include "fplib01.h" - -#include -#include -#include -#include -#include -#include -#include "../cg/cfban.h" - ///////////////////////////////////////////////////////////////////////////////////// // Globals @@ -40,38 +26,6 @@ // Utilities ///////////////////////////////////////////////////////////////////////////////////// -/* - * HFATT: tipocf(1) + codcf(6) - * BFATT: datadoc(8) + tipodoc_SDI(4) + numdoc(7) - */ - -// Crea la coppia di chiavi per il db PAF a partire da un documento vero e proprio -static bool chiave_paf(const TDocumento& doc, TString& hfatt, TString& bfatt) -{ - hfatt.cut(0); - if (doc.clifor().occasionale()) - hfatt << "O" << doc.get("OCFPI"); - else - hfatt << doc.clifor().tipo() << doc.clifor().codice(); - CHECK(hfatt.full(), "Destinatario fattura P.A. non valido"); - - const TCodice_numerazione& codnum = doc.codice_numerazione(); - const long ndoc = doc.numero(); - TString16 fullnumdoc; - codnum.complete_num(ndoc, fullnumdoc); - - bfatt.cut(0) << doc.get_date(DOC_DATADOC).date2ansi() << '/' << doc.tipo().tipo_doc_sdi() << '/' << fullnumdoc; - return hfatt.full() && bfatt.full(); -} - -// Crea la coppia di chiavi per il db PAF a partire da un semplice record di testata documento -static bool chiave_paf(const TRectype& doc, TString& hfatt, TString& bfatt) -{ - TDocumento d(doc); - chiave_paf(d, hfatt, bfatt); - return hfatt.full(); -} - // 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) { @@ -105,305 +59,6 @@ bool xvt_fsys_fupdate(const char* src, const char* dst) return ok; } -///////////////////////////////////////////////////////////////////////////////////// -// TAncestor -///////////////////////////////////////////////////////////////////////////////////// - -struct TAncestor : public TObject -{ - TString20 _numdoc; - TDate _datadoc; - - TAncestor(const TRectype& rdoc); -}; - -TAncestor::TAncestor(const TRectype& rdoc) -{ - const int anno = rdoc.get_int(RDOC_ANNO); - const TString4 codnum = rdoc.get(RDOC_CODNUM); - const long ndoc = rdoc.get_long(RDOC_NDOC); - const TCodice_numerazione& num = cached_numerazione(codnum); - - TToken_string kdoc; - kdoc = rdoc.get(RDOC_PROVV); - kdoc.add(anno); - kdoc.add(codnum); - kdoc.add(ndoc); - const TRectype& doc = cache().get(LF_DOC, kdoc); - - TString16 numdoc; - num.complete_num(ndoc, numdoc); - _numdoc.format("%d/%s/%s", anno, static_cast(codnum), static_cast(numdoc)); - _datadoc = doc.get_date(DOC_DATADOC); -} - - -///////////////////////////////////////////////////////////////////////////////////// -// TPaf_record -///////////////////////////////////////////////////////////////////////////////////// - -// Contenitore di campi di un record di database SQLite -class TPaf_record : public TObject -{ - TString8 _table; - TToken_string _key; - TAssoc_array _fields; - -protected: - void copy(const TPaf_record& rec) - { - _table = rec._table; - _key = rec._key; - _fields = rec._fields; - } - - const TString& var2str(const TString& fld, const TVariant& var) const; - const TVariant& get(const char* fld) 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 TString sq_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 TPaf_record(*this); } - virtual bool ok() const { return _table.not_empty(); } - - TPaf_record& operator=(const TPaf_record& rec) - { - copy(rec); - return *this; - } - - TPaf_record(const TPaf_record& rec) { copy(rec); } - TPaf_record(const char* table); -}; - -// Imposta il valore di un campo variant -void TPaf_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 TPaf_record::set(const char* fld, long val) -{ - const TVariant var(val); - set(fld, var); -} - -// Imposta il valore di un campo stringa -void TPaf_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 TPaf_record::set(const char* fld, const TString& val) -{ - const TVariant var(val); - set(fld, var); -} - -// Imposta il valore di un campo numerico -void TPaf_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 TPaf_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 TPaf_record::set(const char* fld, bool var) -{ - set(fld, var ? "SI" : "NO"); -} - -const TString TPaf_record::sq_get(const char* fld) const -{ - return db().sq_get(fld); -} - -// Legge il valore di un campo variant -const TVariant& TPaf_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& TPaf_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 TPaf_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 db().sq_set_exec(query); -} - -// Carica un record in base ai campi chiave -bool TPaf_record::search() -{ - CHECKS(_fields.items() > 0, "Can't search with empty key on table ", static_cast(_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, paf_search_record, this) == 1; - // TODO: Valutare - return db().sq_set_exec(query); -} - -// Carica un record in base ad un massimo di 3 campi chiave -bool TPaf_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 TPaf_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 db().sq_set_exec(query); -} - -// Crea un record della tabella data ed imposta i nomi dei campi chiave -TPaf_record::TPaf_record(const char* table) : _table(table), _key(15, ',') -{ - TString q; - q << "SELECT col.[name] FROM sys.columns AS col \ - inner JOIN sys.index_columns AS idx on col.[object_id] = idx.[object_id] AND col.[column_id] = idx.[column_id] \ - inner join sys.indexes as K on idx.[index_id] = K.[index_id] \ - where K.[name] = '" << table << "_KEY' \ - AND idx.[object_id] = object_id('" << table << "') \ - ORDER BY index_column_id ASC"; - for (bool ok = db().sq_set_exec(q); ok; ok = db().sq_next()) - { - _key.add(db().sq_get("name")); - } - CHECKS(!_key.empty_items(), "Invalid primary key for table ", table); -} - ///////////////////////////////////////////////////////////////////////////////////// // TPa_mask ///////////////////////////////////////////////////////////////////////////////////// @@ -539,8 +194,6 @@ void TPA_mask::fill() rif = "XXXXXXX"; else { - disable(DLG_OK); - // Segno la riga errata if (first) { @@ -707,1112 +360,26 @@ bool TPA_mask::checkNotEmpty() class TDoc2Paf : public TSkeleton_application { - TAnagrafica _ditta; - TString16 _cofi; - TFilename _dbname; - TLog_report* _log; - TString _logpaf; - TString _def_fld; - TString _def_usr_fld; - -private: - int parse_line(const TString& line, TString& var, TString& val) const; - bool create_table(TScanner& paf, const TString& table); - - const TRectype* find_parent_row(const TRectype& rdoc) const; - int find_ancestors(const TRiga_documento& rdoc, TArray& ancestors) const; - -protected: - bool parse_sconto(const TString& formula, TToken_string& sconti) const; - bool get_bnp_iban(const TString& abi, const TString& cab, int prg, TString& iban) const; - bool get_bank(const TDocumento& doc, TString& iban, TString& abi, TString& cab, - TString& istituto) const; - 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(); - const char* natura(const TString& codiva) const; - static void set_IVA(const TString& codiva, TPaf_record& paf); - static void set_IVA(const TRiga_documento& rdoc, TPaf_record& paf); - static const bool add_row_art(const TString codice_tipo, const TString& codice_valore, TPaf_record& paf); - - - bool elabora(TDocumentoEsteso& doc); - bool elabora(const TRectype& rec); - bool elabora(const TDoc_key& key); - bool elabora(const TFilename& ini); - //bool genera_xml(); public: virtual bool create(); virtual bool destroy(); virtual void main_loop(); - TDoc2Paf() : _log(NULL) - { - } + TDoc2Paf() {} }; -bool TDoc2Paf::parse_sconto(const TString& formula, TToken_string& sconti) const -{ - sconti.cut(0); - int start = 0; - for (int i = 0; ; i++) - { - const char c = formula[i]; - if (c == '+' || c == '-' || c < ' ') - { - if (i > 0) - { - TString8 tok = formula.sub(start, i); - tok.replace(',', '.'); - const real perc = tok; - if (!perc.is_zero()) - sconti.add(tok); - } - if (c < ' ') - break; - start = i; - } - } - return sconti.full(); -} - -bool TDoc2Paf::get_bnp_iban(const TString& abi, const TString& cab, int nprog, TString& iban) const -{ - TTable bnp("BNP"); - TString16 key; - key << abi << cab; - if (nprog > 0) - { - TString4 sprog; - sprog.format("%02d", nprog); - key << sprog; - } - bnp.put("CODTAB", key); - int err = bnp.read(_isgteq); - if (err == NOERR && !bnp.get("CODTAB").starts_with(abi)) - err = _iskeynotfound; - if (err == NOERR) - iban = bnp.get("S3"); - - return err == NOERR; -} - -bool TDoc2Paf::get_bank(const TDocumento& doc, TString& iban, TString& abi, TString& cab, TString& istituto) const -{ - bool found = false; - abi = doc.get(DOC_CODABIP); - cab = doc.get(DOC_CODCABP); - int prg = doc.get_int(DOC_PROGBNP); - - found = abi.full() && cab.full(); - if (found) - get_bnp_iban(abi, cab, prg, iban); - - if (!found) // Se non trovo banca sul DOC la cerco su CFBAN - { - TToken_string key; - key.add("C"); - key.add(doc.codcf()); - key.add("N"); - key.add(1); - const TRectype& cfban = cache().get(LF_CFBAN, key); - if (!cfban.empty()) - { - abi = cfban.get(CFBAN_ABI); - cab = cfban.get(CFBAN_CAB); - prg = cfban.get_int(CFBAN_PROGPR); - found = abi.full() && cab.full(); - iban = cfban.get(CFBAN_IBAN); - if (found && iban.blank()) - get_bnp_iban(abi, cab, prg, iban); - } - } - - if (!found) // Se non trovo banca su CFBAN la cerco su CFVEN - { - const TRectype& cfven = doc.clifor().vendite(); - abi = cfven.get(CFV_CODABIPR); - cab = cfven.get(CFV_CODCABPR); - found = abi.full() && cab.full(); - if (found) - get_bnp_iban(abi, cab, 0, iban); - } - - if (found) - istituto = cache().get("%BAN", abi, "S0"); - - return found; -} - -const char* TDoc2Paf::descrizione(const TRiga_documento& rdoc) const -{ - if (rdoc.get_bool(RDOC_DESCLUNGA)) - { - TString tmp; - tmp << rdoc.get(RDOC_DESCR) << rdoc.get(RDOC_DESCEST); - tmp.replace('\n', ' '); - tmp.strip_double_spaces(); - tmp.trim(); - TParagraph_string para(tmp, 100); - return para.get(0); - } - return rdoc.get(RDOC_DESCR); -} - -const TRectype* TDoc2Paf::find_parent_row(const TRectype& rdoc) const -{ - const long id = rdoc.get_long(RDOC_DAIDRIGA); - if (id > 0L) - { - TToken_string key; - key.add(rdoc.get(RDOC_DACODNUM)); - if (key.full()) - { - key.add(rdoc.get(RDOC_DAANNO)); - key.add(rdoc.get(RDOC_DAPROVV)); - key.add(rdoc.get(RDOC_DANDOC)); - for (int r = 0; ; r++) - { - if (r == 0) - key.add(id, 4); - else - key.add(r, 4); - const TRectype& rec = cache().get(LF_RIGHEDOC, key); - if (r > 0 && rec.empty()) - break; - if (rec.get_long(RDOC_IDRIGA) == id) - return &rec; - } - } - } - return NULL; -} - -int TDoc2Paf::find_ancestors(const TRiga_documento& rdoc, TArray& ancestors) const -{ - if (rdoc.is_articolo()) - { - for (const TRectype* prdoc = find_parent_row(rdoc); prdoc != NULL; prdoc = find_parent_row(*prdoc)) - { - const TCodice_numerazione& cn = cached_numerazione(prdoc->get(RDOC_CODNUM)); - const int td = cn.tipo(); - if (td > 0 && ancestors.objptr(td) == NULL) - ancestors.add(new TAncestor(*prdoc), td); - } - } - return ancestors.items(); -} - -const TRectype& TDoc2Paf::cco(const TRectype& doc) const -{ - TString80 conkey; - const TString& con = doc.get(DOC_CONTRATTO); - if (con.full()) - { - char tcon = doc.get_char(DOC_MODPAG); - if (tcon < 'C') tcon = 'C'; - conkey.format("%c%6ld%s", tcon, doc.get_long(DOC_CODCF), (const char*)con); - } - return cache().get("&CON", conkey); -} - -void TDoc2Paf::log(int severity, const char* msg) -{ - if (severity < 0) - { - _logpaf = msg; - } - else if (_log == NULL) - { - _log = new TLog_report; - if (_logpaf.full()) - { - TString txt; - txt << _logpaf << ": " << msg; - _log->log(severity, txt); - } - else - _log->log(severity, msg); - } -} - -bool TDoc2Paf::show_log() -{ - if (_log) - { - _log->preview(); - delete _log; - _log = NULL; - } - return true; -} - - -const char* TDoc2Paf::natura(const TString& codiva) const -{ - return cache().get("%IVA", codiva, "S12"); -} - -void TDoc2Paf::set_IVA(const TString& codiva, TPaf_record& paf) -{ - // É necessario il cast a real? - paf.set("PI_ALIQUOTAIVA", static_cast(cache().get("%IVA", codiva, "R0"))); - paf.set("PI_NATURA", cache().get("%IVA", codiva, "S12")); -} - -void TDoc2Paf::set_IVA(const TRiga_documento& rdoc, TPaf_record& paf) -{ - set_IVA(rdoc.get(RDOC_CODIVA), paf); -} - -const bool TDoc2Paf::add_row_art(const TString codice_tipo, const TString& codice_valore, TPaf_record& paf) -{ - static long riga_art = 0; - paf.set("PY_KEYNLINAR", ++riga_art); - paf.set("PY_TIPOARTICOLO", codice_tipo); - paf.set("PY_VALOREARTICOLO", codice_valore); - const bool ok = paf.insert(); -#ifdef DBG - if(!ok) - error_box("Allah al bar!"); -#endif - return ok; -} - - -bool TDoc2Paf::elabora(TDocumentoEsteso& doc) -{ - TString8 hfatt; // Codice univoco di 6 caratteri dell'ufficio P.A. o di 7 caratteri per un privato - TString20 bfatt; // Codice univoco di 20 caratteri del documento - - TAnagrafica clifo(doc.clifor().tipo(), doc.clifor().codice()); - - TString8 coddest = doc.clifor().vendite().get("PADESTIN"); - TString pec = doc.clifor().get("PEC"); - bool enapec = false; - if(coddest.empty()) - { - // Controllo se ha la pec - if (pec.full()) - { - coddest = "0000000"; - enapec = true; - } - // Controllo se è straniero - else if(clifo.estero()) - { - coddest = "XXXXXXX"; - } - else - return false; - } - - const bool privato = coddest.len() != 6; - bool ok = true; - - if (!chiave_paf(doc, hfatt, bfatt)) - return false; - log(-1, bfatt); - - const TFirm& firm = prefix().firm(); - const char* const paese = "IT"; - TCausale caus = TCausale(doc.tipo().causale(), doc.anno()); - - // - TPaf_record paf0100f("PAF0100F"); - paf0100f.set("P1_KEYHEADERFATT", hfatt); - paf0100f.set("P1_KEYBODYFATT", bfatt); - paf0100f.remove(); - - paf0100f.set("P1_TRASMITTPAESE", paese); - paf0100f.set("P1_TRASMITTCOD", _cofi); - paf0100f.set("P1_FMTTRASMISS", privato? "FPR12" : "FPA12"); // SDI11 si usa dal 2015 per lo split payment (prima era SDI10) - - paf0100f.set("P1_CODDEST", coddest); - TString80 tel; - tel << firm.get(NDT_PTEL) << firm.get(NDT_TEL); - paf0100f.set("P1_TELEFONO", tel); - paf0100f.set("P1_MAIL", firm.get(NDT_MAIL)); - paf0100f.set("P1_GESTIONE", "D"); - ok &= paf0100f.insert(); - // - - if (enapec) - { - // - TPaf_record paf3200f("PAF3200F"); - paf3200f.set("PU_KEYHEADERFATT", hfatt); - paf3200f.set("PU_KEYBODYFATT", bfatt); - paf3200f.remove(); - paf3200f.set("PU_PEC", pec); - ok &= paf3200f.insert(); - // - } - - // - TPaf_record paf0200f("PAF0200F"); - paf0200f.set("P2_KEYHEADERFATT", hfatt); - paf0200f.set("P2_KEYBODYFATT", bfatt); - paf0200f.remove(); - - if (_ditta.partita_IVA().full()) - { - paf0200f.set("P2_FISCIVAPAESE", _ditta.stato_partita_IVA()); - paf0200f.set("P2_FISCIVACOD", _ditta.partita_IVA()); - } - paf0200f.set("P2_CODFISCALE", _ditta.codice_fiscale()); - if (_ditta.fisica()) - { - paf0200f.set("P2_ANANOME", _ditta.nome()); - paf0200f.set("P2_ANACOGNOME", _ditta.cognome()); - } - else - { - paf0200f.set("P2_ANADENOMIN", _ditta.ragione_sociale()); - } - - paf0200f.set("P2_REGFISCALE", doc.tipo().reg_fisc()); - - // DatiSede - paf0200f.set("P2_SEDEIND", _ditta.via_residenza()); - paf0200f.set("P2_SEDENRCIVICO", _ditta.civico_residenza()); - paf0200f.set("P2_SEDECAP", _ditta.CAP_residenza()); - paf0200f.set("P2_SEDECOMUNE", _ditta.comune_residenza()); - paf0200f.set("P2_SEDEPROV", _ditta.provincia_residenza()); - paf0200f.set("P2_SEDENAZ", paese); - paf0200f.set("P2_GESTIONE", "D"); - - TAnagrafica cliente(doc.clifor()); - - TString rifamm = cco(doc).get("S4"); - if (rifamm.blank()) - rifamm = doc.clifor().vendite().get(CFV_PARIFAMM); - paf0200f.set("P2_RIFAMMINISTR", rifamm); - - paf0200f.set("P2_ISCRREASOCIOU", _ditta.sociounico() == 'S' ? "SU" : "SM"); - - TISAM_recordset unloc("USE UNLOC\nJOIN COMUNI INTO COM==COMCCIAA\nFROM CODDITTA=#DITTA\nTO CODDITTA=#DITTA"); - unloc.set_var("#DITTA", firm.get(NDT_CODDITTA)); - if (unloc.move_first()) - { - const TString& numrea = unloc.get(ULC_NUMCCIAA).as_string(); - if (numrea.full()) - { - paf0200f.set("P2_ISCRREANUM", numrea); - paf0200f.set("P2_ISCRREAUFF", unloc.get("13->" COM_PROVCOM)); - } - } - - if (_ditta.giuridica()) - { - TISAM_recordset anagiu("USE ANAGIU\nFROM CODANAGR=#CODICE\nTO CODANAGR=#CODICE"); - anagiu.set_var("#CODICE", firm.get(NDT_CODANAGR)); - if (anagiu.move_first()) - { - paf0200f.set("P2_ISCRREACAP", anagiu.get(ANG_CAPSOC)); - const int ss = anagiu.get(ANG_STATOSOC).as_int(); - paf0200f.set("P2_ISCRREASLIQUID", (ss == 2 || ss == 3) ? "LS" : "LN"); - } - } - else - paf0200f.set("P2_ISCRREASLIQUID", "LN"); - - ok &= paf0200f.insert(); - - // - - // - - TPaf_record paf0400f("PAF0400F"); - paf0400f.set("P4_KEYHEADERFATT", hfatt); - paf0400f.set("P4_KEYBODYFATT", bfatt); - paf0400f.remove(); - - if (cliente.partita_IVA().full()) - { - paf0400f.set("P4_FISCIVAPAESE", cliente.stato_partita_IVA()); - paf0400f.set("P4_FISCIVACOD", cliente.partita_IVA()); - } - paf0400f.set("P4_CODFISC", cliente.codice_fiscale()); - - if (cliente.fisica()) - { - paf0400f.set("P4_ANANOME", cliente.nome()); - paf0400f.set("P4_ANACOGNOME", cliente.cognome()); - } - else - { - paf0400f.set("P4_ANADENOM", cliente.ragione_sociale()); - } - - // DatiSede - paf0400f.set("P4_SEDEIND", cliente.via_residenza()); - paf0400f.set("P4_SEDENRCIVICO", cliente.civico_residenza()); - paf0400f.set("P4_SEDECAP", cliente.CAP_residenza()); - paf0400f.set("P4_SEDECOMUNE", cliente.comune_residenza()); - paf0400f.set("P4_SEDEPROV", cliente.provincia_residenza()); - paf0400f.set("P4_SEDENAZ", cliente.stato_residenza_ISO()); - paf0400f.set("P4_GESTIONE", "D"); - ok &= paf0400f.insert(); - // - - // - TPaf_record paf0700f("PAF0700F"); - paf0700f.set("P7_KEYHEADERFATT", hfatt); - paf0700f.set("P7_KEYBODYFATT", bfatt); - paf0700f.remove(); - paf0700f.set("P7_TIPODOC", doc.tipo().tipo_doc_sdi()); - paf0700f.set("P7_DIVISA", "EUR"); // Aggiungere codice ISO 4217 a tabella divise (%VAL) - paf0700f.set("P7_DATA", doc.data()); - - const TCodice_numerazione& codnum = doc.codice_numerazione(); - TString20 numdoc; - codnum.complete_num(doc.numero(), numdoc); - paf0700f.set("P7_NUMERO", numdoc); - paf0700f.set("P7_GESTIONE", "D"); - - // - if(doc.get_real("BOLLI") > ZERO) - { - paf0700f.set("P7_IMPORTOBOLLO", doc.get("BOLLI")); - } - // - - // - // Non la mettiamo! - // - - // Non inserisco più adesso il paf0700f ma lo faccio alla fine (per inserire le ritenute) - - // - TPaf_record paf0900f("PAF0900F"); - paf0900f.set("P9_KEYHEADERFATT", hfatt); - paf0900f.set("P9_KEYBODYFATT", bfatt); - paf0900f.remove(); - - TString80 sconto_expr = doc.get(DOC_SCONTOPERC); - TToken_string sconti; - if (parse_sconto(sconto_expr, sconti)) - { - long nlin_sconto = 0; - FOR_EACH_TOKEN(sconti, str) - { - const real sconto = str; - if (!sconto.is_zero()) // Precauzione inutile - { - paf0900f.set("P9_RIFNUMLINEA", ++nlin_sconto); - if (sconto > ZERO) - { - paf0900f.set("P9_TIPOSCONTO", "SC"); - paf0900f.set("P9_PERCSCONTO", sconto); - } - else - { - paf0900f.set("P9_TIPOSCONTO", "MG"); - paf0900f.set("P9_PERCSCONTO", -sconto); - } - paf0900f.set("P9_GESTIONE", "D"); - ok &= paf0900f.insert(); - } - } - } - // - - // - TPaf_record paf2700f("PAF2700F"); - paf2700f.set("PQ_KEYHEADERFATT", hfatt); - paf2700f.set("PQ_KEYBODYFATT", bfatt); - paf2700f.remove(); - paf2700f.set("PQ_IMPTOTDOC", doc.totale_doc()); - - const TRectype& cont_conv_off = cco(doc); - TString causale = cont_conv_off.get("S1"); - if (causale.full()) - { - causale << ' ' << cont_conv_off.get("S2"); - causale << ' ' << cont_conv_off.get("S3"); - causale.strip_double_spaces(); - causale.cut(200); - } - else - causale = doc.tipo().descrizione(); - paf2700f.set("PQ_CAUSALE", causale); - // paf2700f.set("PQ_ART73", true); - paf2700f.set("PQ_GESTIONE", "D"); - ok &= paf2700f.insert(); - // - - // Azzera DDT - TPaf_record paf1600f("PAF1600F"); - paf1600f.set("PF_KEYHEADERFATT", hfatt); - paf1600f.set("PF_KEYBODYFATT", bfatt); - paf1600f.remove(); - - // Fuori dallo scope per dopo - const TString16 cup = doc.get(DOC_CUP); - const TString16 cig = doc.get(DOC_CIG); - const TString80 com = doc.get(DOC_CODCMS); - - if (!privato) - { - // Azzera contratti - TPaf_record paf1000f("PAF1000F"); - paf1000f.set("P0_KEYHEADERFATT", hfatt); - paf1000f.set("P0_KEYBODYFATT", bfatt); - paf1000f.remove(); - - // Azzera convenzioni - TPaf_record paf1100f("PAF1100F"); - paf1100f.set("PA_KEYHEADERFATT", hfatt); - paf1100f.set("PA_KEYBODYFATT", bfatt); - paf1100f.remove(); - - // Azzera ordini - TPaf_record paf1200f("PAF1200F"); - paf1200f.set("PB_KEYHEADERFATT", hfatt); - paf1200f.set("PB_KEYBODYFATT", bfatt); - paf1200f.remove(); - - TString80 con = doc.get(DOC_CONTRATTO); - if (con.full() || cup.full() || cig.full()) - { - char tcon = doc.get_char(DOC_MODPAG); - if (tcon < 'C') tcon = 'C'; - - TDate datadoc; // Data contratto non obbligatoria - if (con.full()) - { - datadoc = cco(doc).get_date("D0"); - } - else - { - // IdDocumento obbligatorio - con = cig; - if (con.blank()) - con = cup; - } - - if (tcon == 'O') - { - paf1000f.set("P0_RIFNUMLINEA", 0L); - paf1000f.set("P0_IDDOC", con); - paf1000f.set("P0_DATADOC", datadoc); - paf1000f.set("P0_COMMCONVENZ", com); - paf1000f.set("P0_CODCUP", cup); - paf1000f.set("P0_CODCIG", cig); - paf1000f.set("P0_GESTIONE", "D"); - ok &= paf1000f.insert(); - } - else if (tcon == 'C') - { - paf1100f.set("PA_RIFNUMLINEA", 0L); - paf1100f.set("PA_IDDOC", con); - paf1100f.set("PA_DATADOCU", datadoc); - paf1100f.set("PA_COMMCONVENZ", com); - paf1100f.set("PA_CODCUP", cup); - paf1100f.set("PA_CODCIG", cig); - paf1000f.set("PA_GESTIONE", "D"); - ok &= paf1100f.insert(); - } - else - { - paf1200f.set("PB_RIFNUMLINEA", 0L); - paf1200f.set("PB_IDDOC", con); - paf1200f.set("PB_DATADOCO", datadoc); - paf1200f.set("PB_COMMCONVENZ", com); - paf1200f.set("PB_CODCUP", cup); - paf1200f.set("PB_CODCIG", cig); - paf1200f.set("PB_GESTIONE", "D"); - ok &= paf1200f.insert(); - } - } - - if (cup.blank() && cig.blank()) - log(1, "CIG e CUP assenti"); - } - // - - TPaf_record paf1800f("PAF1800F"); - paf1800f.set("PI_KEYHEADERFATT", hfatt); - paf1800f.set("PI_KEYBODYFATT", bfatt); - paf1800f.remove(); // Cancella tutte le righe documento - - TPaf_record paf2000f("PAF2000F"); - paf2000f.set("PJ_KEYHEADERFATT", hfatt); - paf2000f.set("PJ_KEYBODYFATT", bfatt); - paf2000f.remove(); // Cancella tutti gli sconti di riga - - TPaf_record paf1900f("PAF1900F"); - paf1900f.set("PY_KEYHEADERFATT", hfatt); - paf1900f.set("PY_KEYBODYFATT", bfatt); - paf1900f.remove(); // Cancella tutte le righe articoli del documento - - - long riga = 0; - TString16 codivadefault; - { - FOR_EACH_PHYSICAL_RDOC(doc, r, rdoc) - { - codivadefault = rdoc->get(RDOC_CODIVA); - if (codivadefault.full()) - break; - } - } - FOR_EACH_PHYSICAL_RDOC(doc, r, rdoc) - { - paf1800f.reset(); - paf1800f.set("PI_KEYHEADERFATT", hfatt); - paf1800f.set("PI_KEYBODYFATT", bfatt); - paf1800f.set("PI_NUMEROLINEA", ++riga); - paf1800f.set("PI_DESCRIZIONE", descrizione(*rdoc)); - // paf1800f.set("PI_ALIQUOTAIVA", "22.00"); // Altrimenti scarta le righe di descrizione - - // - long riga_art = 0; - TArticolo& art = rdoc->articolo(); - if (art.ok()) - { - paf1900f.reset(); - paf1900f.set("PY_KEYHEADERFATT", hfatt); - paf1900f.set("PY_KEYBODYFATT", bfatt); - paf1900f.set("PY_KEYNLINEA", riga); - - TString& tmp = get_tmp_string(); - - if (art.codice().full()) - { - tmp.cut(0) << art.codice(); // Fixed_string di merda - ok &= add_row_art("Codice interno", tmp, paf1900f); - } - if (rdoc->tipo().codice() == "14") - { - ok &= add_row_art("Codice cliente", rdoc->get("CODARTALT"), paf1900f); - } - } - // - - - set_IVA(codivadefault, paf1800f); - - if (rdoc->is_merce()) - { - paf1800f.set("PI_UNITAMISURA", rdoc->get(RDOC_UMQTA)); - const real qta = rdoc->get(RDOC_QTA); - if (qta.is_zero()) - { - TString msg; - msg.format("La riga merce %d ha quantità nulla", riga); - log(1, msg); - } - if (qta >= ZERO) - { - paf1800f.set("PI_QUANTITA", qta); - paf1800f.set("PI_PREZZOUNIT", rdoc->prezzo(false, false)); - } - else - { - paf1800f.set("PI_QUANTITA", -qta); - paf1800f.set("PI_PREZZOUNIT", -rdoc->prezzo(true, false)); - } - paf1800f.set("PI_PRZTOTALE", rdoc->importo(true, false)); - set_IVA(*rdoc, paf1800f); - - /* - const TDate data = doc.get(DOC_DATADOC); - paf1800f.set("PI_DTINIZIOPER", data); - paf1800f.set("PI_DTFINEPER", data); - */ - - // - - sconto_expr = rdoc->get(RDOC_SCONTO); - if (parse_sconto(sconto_expr, sconti)) - { - long nlin_sconto = 0; - FOR_EACH_TOKEN(sconti, str) - { - const real perc = str; - if (!perc.is_zero()) - { - paf2000f.set("PJ_KEYNLINEA", (long)r); - paf2000f.set("PJ_KEYNLINAR", ++nlin_sconto); - if (perc > ZERO) - { - paf2000f.set("PJ_TIPOSCONTO", "SC"); - paf2000f.set("PJ_PERCSCONTO", perc); - } - else - { - paf2000f.set("PJ_TIPOSCONTO", "MG"); - paf2000f.set("PJ_PERCSCONTO", -perc); - } - paf2000f.set("PJ_GESTIONE", "D"); - ok &= paf2000f.insert(); - } - } - } - // - - - /* - * Ogni riga si può rifare a un DDT/Ordine diverso, per questo devo inserire i dati da qua e non in testata - */ - TArray ancestors; - find_ancestors(*rdoc, ancestors); - for (int i = ancestors.last(); i > 0; i = ancestors.pred(i)) - { - const TAncestor& a = (const TAncestor&)ancestors[i]; - if (i == 1) - { - // - TPaf_record paf1600f("PAF1600F"); - paf1600f.reset(); - paf1600f.set("PF_KEYHEADERFATT", hfatt); - paf1600f.set("PF_KEYBODYFATT", bfatt); - paf1600f.set("PF_RIFNUMLINEA", (long)r); - paf1600f.set("PF_NUMDDDT", a._numdoc); - paf1600f.set("PF_DATADDT", a._datadoc); - paf1600f.set("PF_GESTIONE", "D"); - ok &= paf1600f.insert(); - // - } - else if (i == 3) - { - // - TPaf_record paf1000f("PAF1000F"); - paf1000f.set("P0_KEYHEADERFATT", hfatt); - paf1000f.set("P0_KEYBODYFATT", bfatt); - paf1000f.set("P0_RIFNUMLINEA", (long)r); - paf1000f.set("P0_IDDOC", a._numdoc); - paf1000f.set("P0_DATADOC", a._datadoc); - if (!privato) - { - paf1000f.set("P0_COMMCONVENZ", com); - paf1000f.set("P0_CODCUP", cup); - paf1000f.set("P0_CODCIG", cig); - } - paf1000f.set("P0_GESTIONE", "D"); - ok &= paf1000f.insert(); - // - } - } - - } - else if (rdoc->is_spese()) - { - const TSpesa_prest& sp = rdoc->spesa(); - const real imp = rdoc->importo(true, false); - real qta = UNO; - if (sp.is_tipo()) - { - paf1800f.set("PI_UNITAMISURA", rdoc->get(RDOC_UMQTA)); - qta = rdoc->get_real(RDOC_QTA); - if (qta.is_zero()) - { - TString msg; - msg.format("La riga spese a quantità %d ha quantità nulla (campo %s)", riga, (const char*)rdoc->field_qta()); - log(1, msg); - qta = UNO; - } - paf1800f.set("PI_QUANTITA", qta); - } - real prz = imp; - if (qta != UNO) - { - prz = rdoc->prezzo(true, false); - if (prz.is_zero() && !imp.is_zero()) - { - const TPrice price(imp / qta); - prz = price.get_value(); - } - } - paf1800f.set("PI_PREZZOUNIT", prz); - paf1800f.set("PI_PRZTOTALE", imp); - set_IVA(*rdoc, paf1800f); - - // Controllo se è una ritenuta fiscale - // - if(sp.tipo_ritenuta() == 'F') - { - paf0700f.set("P7_TIPORITENUTA", cliente.fisica() ? "RT01" : "RT02"); - paf0700f.set("P7_IMPORTORIT", doc.imponibile() * sp.perc() / CENTO); - paf0700f.set("P7_ALIQUOTARIT", TCodiceIVA(sp.cod_iva()).percentuale()); - paf0700f.set("P7_CAUSPAGAM", cache().get("CA7", to_tstring(sp.caus_770()), "S2")); - } - // - } - else if (rdoc->is_prestazione()) - { - paf1800f.set("PI_UNITAMISURA", rdoc->get(RDOC_UMQTA)); - real qta = rdoc->get(RDOC_QTA); - if (qta.is_zero()) qta = UNO; - paf1800f.set("PI_QUANTITA", qta); - paf1800f.set("PI_PREZZOUNIT", rdoc->prezzo(false, false)); - paf1800f.set("PI_PRZTOTALE", rdoc->importo(true, false)); - set_IVA(*rdoc, paf1800f); - } - - paf1800f.set("PI_GESTIONE", "D"); - ok &= paf1800f.insert(); - } - // - - - // - /* - * Non valorizziamo nulla al momento in quanto su Campo i dati obbligatori non ci sono/non sono obbligatori - TString cod_vettore = doc.get("CODVETT1"); - // É una fattura accompagnatoria! - if(cod_vettore.full()) - { - } - */ - // - - // Salvo la testata - ok &= paf0700f.insert(); - - // - TPaf_record paf2200f("PAF2200F"); - paf2200f.set("PL_KEYHEADERFATT", hfatt); - paf2200f.set("PL_KEYBODYFATT", bfatt); - paf2200f.remove(); // Cancella tutte le righe di riepilogo IVA - - const char* eiva = "I"; // Esigibilità IVA: Immediata, Differita, Split payment - if (doc.is_split_payment()) - eiva = "S"; - else if (doc.get_bool(DOC_LIQDIFF) || doc.get_bool(DOC_IVAXCASSA)) - eiva = "D"; - - long num_riep = 0; - TAssoc_array& tiva = doc.tabella_iva(false); - FOR_EACH_ASSOC_OBJECT(tiva, obj, key, itm) - { - const TRiepilogo_iva& riva = *(const TRiepilogo_iva*)itm; - const real aliquota = riva.cod_iva().percentuale(); - paf2200f.set("PL_ALIQUOTAIVA", aliquota); - if (aliquota.is_zero()) - paf2200f.set("PL_NATURA", natura(riva.cod_iva().codice())); - - paf2200f.set("PL_IMPONIBILE", riva.imponibile()); - paf2200f.set("PL_IMPOSTA", riva.imposta()); - paf2200f.set("PL_ESIGIVA", eiva); - if (*eiva == 'S') - paf2200f.set("PL_RIFNORMATIVO", "Scissione pagamenti art.17-ter DPR 633/72"); - else - paf2200f.set("PL_RIFNORMATIVO", riva.cod_iva().descrizione()); - paf2200f.set("PL_GESTIONE", "D"); - ok &= paf2200f.insert(); - } - // - - // - TPaf_record paf2400f("PAF2400F"); - paf2400f.set("PN_KEYHEADERFATT", hfatt); - paf2400f.set("PN_KEYBODYFATT", bfatt); - paf2400f.remove(); // Cancella i dati pagamento - - TPagamento& pag = doc.pagamento(); - doc.scadenze_recalc(); // Ricalcola array delle rate - TString_array& scad = doc.scadenze(); - const int nrate = scad.items(); // Conta rate generate - const char* rateazione = pag.cond_pag_sdi(); // A rate (TP01) o una soluzione(TP02)? - paf2400f.set("PN_RIGA", ZERO); // Al momento non gestiamo più tipologie di pagamento per documento - paf2400f.set("PN_CONDPAGAMENTO", rateazione); - paf2400f.set("PN_GESTIONE", "D"); - ok &= paf2400f.insert(); - - TPaf_record paf2500f("PAF2500F"); - paf2500f.set("PO_KEYHEADERFATT", hfatt); - paf2500f.set("PO_KEYBODYFATT", bfatt); - paf2500f.remove(); // Cancella tutte le rate - - // Imposto i campi uguali per tutte le rate - paf2500f.set("PO_CONDPAGAMENTO", rateazione); // Condizione di pagamento PA - paf2500f.set("PO_CODICEPAGAM", pag.code()); // Condizione di pagamento CAMPO - - TString80 iban, istituto; - TString8 abi, cab; - if (get_bank(doc, iban, abi, cab, istituto)) - { - paf2500f.set("PO_ISTFINANZ", istituto); - paf2500f.set("PO_IBAN", iban); - paf2500f.set("PO_ABI", abi); - paf2500f.set("PO_CAB", cab); - } - - if (cab.blank()) - log(2, TR("Non sono presenti ABI, CAB, IBAN per il pagamento")); - else if (iban.blank()) - log(1, TR("Non è presente il codice IBAN per il pagamento")); - - for (int nr = 0; nr < nrate; nr++) - { - paf2500f.set("PO_RIGA", long(nr + 1)); // Numero rata - int rp = nr < pag.n_rate() ? nr : 0; - static TString key_class; key_class.cut(0) << pag.tipo_rata(rp) << pag.ulc_rata(rp); -#ifdef DBG - bool tolla = true; - TString pop = cache().get("%CLR", key_class, "S12"); - bool aaaa = true; -#endif - paf2500f.set("PO_MODALITAPAGAM", cache().get("%CLR", key_class, "S12")); // Si assicura che il numero riga sia accettabile - - TToken_string& riga = scad.row(nr); // Data|Importo - paf2500f.set("PO_DATASCADENZA", TDate(riga.get(0))); // Data scadenza - paf2500f.set("PO_IMPORTO", real(riga.get())); // Importo rata - - paf2500f.set("PO_GESTIONE", "D"); - ok &= paf2500f.insert(); - } - - TPaf_record paf2600f("PAF2600F"); - paf2600f.set("PP_KEYHEADERFATT", hfatt); - paf2600f.set("PP_KEYBODYFATT", bfatt); - paf2600f.remove(); // Cancella eventuali allegati - TToken_string allegati(doc.get("COLL_GOLEM"), '\n'); - if (allegati.full()) - { - long nprogr = 0; // Numero di file allegati - TFilename fname; - FOR_EACH_TOKEN(allegati, row) - { - const TToken_string entry(row); - if (entry.get(0, fname) && fname.exist()) - { - static TString dest_path; - static TString dest_usr_path; - - dest_path.cut(0) << _def_fld << fname.name(); - dest_usr_path.cut(0) << _def_usr_fld << fname.name(); - - if(!fcopy(fname, dest_usr_path)) - { - if (yesno_box("Errore critico nel copiare il file %s, si desidera continuare?", fname.name())) - continue; - else - return false; - } - - // Provo a copiare il file - paf2600f.set("PP_NUMEROLINEA", ++nprogr); - paf2600f.set("PP_NOMEATTACHMENT", fname.name()); - paf2600f.set("PP_ATTACHMENT", dest_path); - fname.upper(); // serve estensione maiuscola - paf2600f.set("PP_FMTATTACHMENT", fname.ext()); - ok &= paf2600f.insert(); - } - } - - } - // - - // Tabella di non invio XML - TPaf_record pafw300f("PAFW300F"); - pafw300f.set("PW_KEYPRGINVIO", hfatt); - pafw300f.set("PW_KEYHEADERFATT", bfatt); - pafw300f.remove(); // Cancella eventuali allegati - const TTipo_documento& td = cached_tipodoc(doc.get(DOC_TIPODOC)); - TString codsdi = !td.invio_xml() ? "**********" : (enapec ? pec : coddest); - pafw300f.set("PW_CODSDI", codsdi); - ok &= pafw300f.insert(); - - - return ok; -} - -bool TDoc2Paf::elabora(const TRectype& rec) -{ - TDocumentoEsteso doc; - if (doc.read(rec) == NOERR) - { - return elabora(doc) ? db().sq_commit() : db().sq_rollback(); - } - return false; -} - -bool TDoc2Paf::elabora(const TDoc_key& key) -{ - TRectype rec(LF_DOC); - rec.put(DOC_PROVV, key.provv()); - rec.put(DOC_ANNO, key.anno()); - rec.put(DOC_CODNUM, key.codnum()); - rec.put(DOC_NDOC, key.ndoc()); - return elabora(rec); -} - -bool TDoc2Paf::elabora(const TFilename& ini) -{ - TConfig cfg(ini, "33"); - const int anno = cfg.get_int(DOC_ANNO); - const long ndoc = cfg.get_long(DOC_NDOC); - const TFixed_string codnum(cfg.get(DOC_CODNUM)); // lascio sapientemente per ultima la get di una stringa - const TDoc_key key(anno, codnum, ndoc); - return elabora(key); -} - void TDoc2Paf::main_loop() { int ndocs = 0; - for (int a = 1; a < argc(); a++) - { - TFilename ini = argv(a); - if (ini.starts_with("-i", true) || ini.starts_with("/i", true)) - ini.ltrim(2); - if (ini.exist() && elabora(ini)) - ndocs++; - else - { - if (ini.find('*') >= 0 || ini.find('?') >= 0) - { - TString_array f; - list_files(ini, f); - FOR_EACH_ARRAY_ROW(f, r, row) - { - ini = *row; - if (ini.exist() && elabora(ini)) - ndocs++; - } - } - } - } - if (ndocs > 0) - { - show_log(); - //if (show_log()) - //genera_xml(); - return; - } - TPA_mask mask; - mask.set(F_COFI, _cofi); while (mask.run() == K_ENTER) { - _cofi = mask.get(F_COFI); - - _def_fld = ini_get_string(CONFIG_DITTA, "fp", "flddest"); - if(!_def_fld.ends_with("\\")) - { - _def_fld << "\\"; - } - - _def_usr_fld = ini_get_string(CONFIG_DITTA, "fp", "fldusrdest", ""); - if(_def_usr_fld.empty()) - { - _def_usr_fld = _def_fld; - } - else if (!_def_usr_fld.ends_with("\\")) - { - _def_usr_fld << "\\"; - } - TString_array& sht = mask.sfield(F_DOCS).rows_array(); if (!sht.empty()) { - TProgress_monitor pi(sht.items(), NULL); + TDoc_fp elab; + TProgress_monitor pi(sht.items(), "Esportazione Fatture"); ndocs = 0; FOR_EACH_ARRAY_ROW(sht, r, riga) { @@ -1822,7 +389,7 @@ void TDoc2Paf::main_loop() const long ndoc = riga->get_long(mask.sfield(F_DOCS).cid2index(S_NDOC)); const TFixed_string codnum(riga->get(mask.sfield(F_DOCS).cid2index(S_CODNUM))); // lascio sapientemente per ultima la get di una stringa const TDoc_key key(anno, codnum, ndoc); - if (elabora(key)) + if (elab.doc_to_paf(key)) ndocs++; } if (!pi.add_status(1)) @@ -1830,15 +397,15 @@ void TDoc2Paf::main_loop() } if (ndocs > 0) { - db().sq_set_exec("UPDATE PAF0100F SET P1_GESTIONE = 'P' WHERE P1_GESTIONE = 'D'"); - db().sq_commit(); + if (elab.commit() > 0) + { + message_box(FR("Sono stati elaborati %d documenti"), ndocs); + } + else + error_box("Errore durante il salvataggio"); + elab.show_log(); } - - message_box(FR("Sono stati elaborati %d documenti"), ndocs); } - - if (ndocs > 0) - show_log(); } } @@ -1849,24 +416,15 @@ bool TDoc2Paf::create() LF_DOC, LF_RIGHEDOC, 0); TRectype cfven(LF_CFVEN); - if (cfven.type(CFV_PARIFAMM) != _alfafld) + if (cfven.length(CFV_PADESTIN) != 7) // Nuova lunghezza per privati return error_box(TR("Database non convertito per fatturazione F.P.")); - _ditta.init(LF_NDITTE, prefix().get_codditta()); - - _cofi = ini_get_string(CONFIG_DITTA, "fp", "TRASMITTCOD"); - if (_cofi.blank()) - _cofi = _ditta.codice_fiscale(); - return check_tables() && TSkeleton_application::create(); } bool TDoc2Paf::destroy() { - if (_cofi.full()) - ini_set_string(CONFIG_DITTA, "fp", "TRASMITTCOD", _cofi); - db().sq_disconnect(); return TSkeleton_application::destroy(); } diff --git a/src/fp/fp0300a.h b/src/fp/fp0300a.h index edf4ab1d1..31f85c56f 100644 --- a/src/fp/fp0300a.h +++ b/src/fp/fp0300a.h @@ -2,9 +2,8 @@ #define F_DATAINI 301 #define F_DATAEND 302 #define F_FATTSEL 303 -#define F_COFI 304 -#define F_DATIPODOC 305 -#define F_ATIPODOC 306 +#define F_DATIPODOC 304 +#define F_ATIPODOC 305 #define END_MASK 399 #define F_DOCS 201 diff --git a/src/fp/fp0300a.uml b/src/fp/fp0300a.uml index 9e67ab5c6..7018d4c5c 100644 --- a/src/fp/fp0300a.uml +++ b/src/fp/fp0300a.uml @@ -32,12 +32,6 @@ BEGIN ITEM "N|Accettate" END -STRING F_COFI 16 -BEGIN - PROMPT 30 1 "Codice fiscale trasmittente " - CHECKTYPE REQUIRED -END - STRING F_DATIPODOC 4 BEGIN PROMPT 30 2 "Da tipo doc " diff --git a/src/fp/fplib01.cpp b/src/fp/fplib01.cpp index 748836b87..b90a30d9b 100644 --- a/src/fp/fplib01.cpp +++ b/src/fp/fplib01.cpp @@ -7,6 +7,18 @@ #include #include "text.h" #include +#include + +#include "../fe/felib.h" +#include "../cg/cglib03.h" + +#include +#include +#include +#include +#include +#include +#include "../cg/cfban.h" void set_connection(SSimple_query& s) { @@ -19,6 +31,13 @@ void set_connection(SSimple_query& s) } +string getline(ifstream& f) +{ + string app; + getline(f, app); + return app; +} + SSimple_query& db() { static SSimple_query* db = nullptr; @@ -98,9 +117,1346 @@ bool check_tables() return true; } -string getline(ifstream& f) +/* +* HFATT: tipocf(1) + codcf(6) +* BFATT: datadoc(8) + tipodoc_SDI(4) + numdoc(7) +*/ + +// Crea la coppia di chiavi per il db PAF a partire da un documento vero e proprio +bool chiave_paf(const TDocumento& doc, TString& hfatt, TString& bfatt) { - string app; - getline(f, app); - return app; -} \ No newline at end of file + hfatt.cut(0); + if (doc.clifor().occasionale()) + hfatt << "O" << doc.get("OCFPI"); + else + hfatt << doc.clifor().tipo() << doc.clifor().codice(); + CHECK(hfatt.full(), "Destinatario fattura P.A. non valido"); + + const TCodice_numerazione& codnum = doc.codice_numerazione(); + const long ndoc = doc.numero(); + TString16 fullnumdoc; + codnum.complete_num(ndoc, fullnumdoc); + + bfatt.cut(0) << doc.get_date(DOC_DATADOC).date2ansi() << '/' << doc.tipo().tipo_doc_sdi() << '/' << fullnumdoc; + return hfatt.full() && bfatt.full(); +} + +// Crea la coppia di chiavi per il db PAF a partire da un semplice record di testata documento +bool chiave_paf(const TRectype& doc, TString& hfatt, TString& bfatt) +{ + TDocumento d(doc); + chiave_paf(d, hfatt, bfatt); + return hfatt.full(); +} + +/*************************************************************************** + * TPaf_record + ***************************************************************************/ + +// Imposta il valore di un campo variant +void TPaf_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 TPaf_record::set(const char* fld, long val) +{ + const TVariant var(val); + set(fld, var); +} + +// Imposta il valore di un campo stringa +void TPaf_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 TPaf_record::set(const char* fld, const TString& val) +{ + const TVariant var(val); + set(fld, var); +} + +// Imposta il valore di un campo numerico +void TPaf_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 TPaf_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 TPaf_record::set(const char* fld, bool var) +{ + set(fld, var ? "SI" : "NO"); +} + +const TString TPaf_record::sq_get(const char* fld) const +{ + return db().sq_get(fld); +} + +// Legge il valore di un campo variant +const TVariant& TPaf_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& TPaf_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 TPaf_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 db().sq_set_exec(query); +} + +// Carica un record in base ai campi chiave +bool TPaf_record::search() +{ + CHECKS(_fields.items() > 0, "Can't search with empty key on table ", static_cast(_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, paf_search_record, this) == 1; + // TODO: Valutare + return db().sq_set_exec(query); +} + +// Carica un record in base ad un massimo di 3 campi chiave +bool TPaf_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 TPaf_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 db().sq_set_exec(query); +} + +// Crea un record della tabella data ed imposta i nomi dei campi chiave +TPaf_record::TPaf_record(const char* table) : _table(table), _key(15, ',') +{ + TString q; + q << "SELECT col.[name] FROM sys.columns AS col \ + inner JOIN sys.index_columns AS idx on col.[object_id] = idx.[object_id] AND col.[column_id] = idx.[column_id] \ + inner join sys.indexes as K on idx.[index_id] = K.[index_id] \ + where K.[name] = '" << table << "_KEY' \ + AND idx.[object_id] = object_id('" << table << "') \ + ORDER BY index_column_id ASC"; + for (bool ok = db().sq_set_exec(q); ok; ok = db().sq_next()) + { + _key.add(db().sq_get("name")); + } + CHECKS(!_key.empty_items(), "Invalid primary key for table ", table); +} + +/*************************************************************************** + * TAncestor + ***************************************************************************/ + +struct TAncestor : public TObject +{ + TString20 _numdoc; + TDate _datadoc; + + TAncestor(const TRectype& rdoc); +}; + +TAncestor::TAncestor(const TRectype& rdoc) +{ + const int anno = rdoc.get_int(RDOC_ANNO); + const TString4 codnum = rdoc.get(RDOC_CODNUM); + const long ndoc = rdoc.get_long(RDOC_NDOC); + const TCodice_numerazione& num = cached_numerazione(codnum); + + TToken_string kdoc; + kdoc = rdoc.get(RDOC_PROVV); + kdoc.add(anno); + kdoc.add(codnum); + kdoc.add(ndoc); + const TRectype& doc = cache().get(LF_DOC, kdoc); + + TString16 numdoc; + num.complete_num(ndoc, numdoc); + _numdoc.format("%d/%s/%s", anno, static_cast(codnum), static_cast(numdoc)); + _datadoc = doc.get_date(DOC_DATADOC); +} + +/*************************************************************************** + * TDoc_fp + ***************************************************************************/ + +bool TDoc_fp::parse_sconto(const TString& formula, TToken_string& sconti) const +{ + sconti.cut(0); + int start = 0; + for (int i = 0; ; i++) + { + const char c = formula[i]; + if (c == '+' || c == '-' || c < ' ') + { + if (i > 0) + { + TString8 tok = formula.sub(start, i); + tok.replace(',', '.'); + const real perc = tok; + if (!perc.is_zero()) + sconti.add(tok); + } + if (c < ' ') + break; + start = i; + } + } + return sconti.full(); +} + +bool TDoc_fp::get_bnp_iban(const TString& abi, const TString& cab, int nprog, TString& iban) +{ + TTable bnp("BNP"); + TString16 key; + key << abi << cab; + if (nprog > 0) + { + TString4 sprog; + sprog.format("%02d", nprog); + key << sprog; + } + bnp.put("CODTAB", key); + int err = bnp.read(_isgteq); + if (err == NOERR && !bnp.get("CODTAB").starts_with(abi)) + err = _iskeynotfound; + if (err == NOERR) + iban = bnp.get("S3"); + + return err == NOERR; +} + +bool TDoc_fp::get_bank(const TDocumento& doc, TString& iban, TString& abi, TString& cab, TString& istituto) const +{ + bool found = false; + abi = doc.get(DOC_CODABIP); + cab = doc.get(DOC_CODCABP); + int prg = doc.get_int(DOC_PROGBNP); + + found = abi.full() && cab.full(); + if (found) + get_bnp_iban(abi, cab, prg, iban); + + if (!found) // Se non trovo banca sul DOC la cerco su CFBAN + { + TToken_string key; + key.add("C"); + key.add(doc.codcf()); + key.add("N"); + key.add(1); + const TRectype& cfban = cache().get(LF_CFBAN, key); + if (!cfban.empty()) + { + abi = cfban.get(CFBAN_ABI); + cab = cfban.get(CFBAN_CAB); + prg = cfban.get_int(CFBAN_PROGPR); + found = abi.full() && cab.full(); + iban = cfban.get(CFBAN_IBAN); + if (found && iban.blank()) + get_bnp_iban(abi, cab, prg, iban); + } + } + + if (!found) // Se non trovo banca su CFBAN la cerco su CFVEN + { + const TRectype& cfven = doc.clifor().vendite(); + abi = cfven.get(CFV_CODABIPR); + cab = cfven.get(CFV_CODCABPR); + found = abi.full() && cab.full(); + if (found) + get_bnp_iban(abi, cab, 0, iban); + } + + if (found) + istituto = cache().get("%BAN", abi, "S0"); + + return found; +} + +const char* TDoc_fp::descrizione(const TRiga_documento& rdoc) const +{ + if (rdoc.get_bool(RDOC_DESCLUNGA)) + { + TString tmp; + tmp << rdoc.get(RDOC_DESCR) << rdoc.get(RDOC_DESCEST); + tmp.replace('\n', ' '); + tmp.strip_double_spaces(); + tmp.trim(); + TParagraph_string para(tmp, 100); + return para.get(0); + } + return rdoc.get(RDOC_DESCR); +} + +const TRectype* TDoc_fp::find_parent_row(const TRectype& rdoc) const +{ + const long id = rdoc.get_long(RDOC_DAIDRIGA); + if (id > 0L) + { + TToken_string key; + key.add(rdoc.get(RDOC_DACODNUM)); + if (key.full()) + { + key.add(rdoc.get(RDOC_DAANNO)); + key.add(rdoc.get(RDOC_DAPROVV)); + key.add(rdoc.get(RDOC_DANDOC)); + for (int r = 0; ; r++) + { + if (r == 0) + key.add(id, 4); + else + key.add(r, 4); + const TRectype& rec = cache().get(LF_RIGHEDOC, key); + if (r > 0 && rec.empty()) + break; + if (rec.get_long(RDOC_IDRIGA) == id) + return &rec; + } + } + } + return NULL; +} + +int TDoc_fp::find_ancestors(const TRiga_documento& rdoc, TArray& ancestors) const +{ + if (rdoc.is_articolo()) + { + for (const TRectype* prdoc = find_parent_row(rdoc); prdoc != NULL; prdoc = find_parent_row(*prdoc)) + { + const TCodice_numerazione& cn = cached_numerazione(prdoc->get(RDOC_CODNUM)); + const int td = cn.tipo(); + if (td > 0 && ancestors.objptr(td) == NULL) + ancestors.add(new TAncestor(*prdoc), td); + } + } + return ancestors.items(); +} + +const TRectype& TDoc_fp::cco(const TRectype& doc) const +{ + TString80 conkey; + const TString& con = doc.get(DOC_CONTRATTO); + if (con.full()) + { + char tcon = doc.get_char(DOC_MODPAG); + if (tcon < 'C') tcon = 'C'; + conkey.format("%c%6ld%s", tcon, doc.get_long(DOC_CODCF), (const char*)con); + } + return cache().get("&CON", conkey); +} + +void TDoc_fp::log(int severity, const char* msg) +{ + if (severity < 0) + { + _logpaf = msg; + } + else if (_log == NULL) + { + _log = new TLog_report; + if (_logpaf.full()) + { + TString txt; + txt << _logpaf << ": " << msg; + _log->log(severity, txt); + } + else + _log->log(severity, msg); + } +} + +bool TDoc_fp::show_log() +{ + if (_log) + { + _log->preview(); + delete _log; + _log = NULL; + } + return true; +} + +const int TDoc_fp::commit() +{ + int r = 0; + if (_to_commit) + { + if(db().sq_set_exec("UPDATE PAF0100F SET P1_GESTIONE = 'P' WHERE P1_GESTIONE = 'D'") && db().sq_commit()) + { + r = 1; + } + else + { + r = -1; + log(3, db().sq_get_string_error()); + } + } + _to_commit = false; + return r; +} + + +const char* TDoc_fp::natura(const TString& codiva) const +{ + return cache().get("%IVA", codiva, "S12"); +} + +void TDoc_fp::set_IVA(const TString& codiva, TPaf_record& paf) +{ + // É necessario il cast a real? + paf.set("PI_ALIQUOTAIVA", static_cast(cache().get("%IVA", codiva, "R0"))); + paf.set("PI_NATURA", cache().get("%IVA", codiva, "S12")); +} + +void TDoc_fp::set_IVA(const TRiga_documento& rdoc, TPaf_record& paf) +{ + set_IVA(rdoc.get(RDOC_CODIVA), paf); +} + +bool TDoc_fp::add_row_art(const TString codice_tipo, const TString& codice_valore, TPaf_record& paf) +{ + static long riga_art = 0; + paf.set("PY_KEYNLINAR", ++riga_art); + paf.set("PY_TIPOARTICOLO", codice_tipo); + paf.set("PY_VALOREARTICOLO", codice_valore); + const bool ok = paf.insert(); +#ifdef DBG + if (!ok) + error_box("Allah al bar!"); +#endif + return ok; +} + +bool TDoc_fp::doc_to_paf(TDocumentoEsteso& doc) +{ + TString8 hfatt; // Codice univoco di 6 caratteri dell'ufficio P.A. o di 7 caratteri per un privato + TString20 bfatt; // Codice univoco di 20 caratteri del documento + + TAnagrafica clifo(doc.clifor().tipo(), doc.clifor().codice()); + + TString8 coddest = doc.clifor().vendite().get("PADESTIN"); + TString pec = doc.clifor().get("PEC"); + bool enapec = false; + if (coddest.empty()) + { + // Controllo se ha la pec + if (pec.full()) + { + coddest = "0000000"; + enapec = true; + } + // Controllo se è straniero + else if (clifo.estero()) + { + coddest = "XXXXXXX"; + } + else + return false; + } + + const bool privato = coddest.len() != 6; + bool ok = true; + + if (!chiave_paf(doc, hfatt, bfatt)) + return false; + log(-1, bfatt); + + const TFirm& firm = prefix().firm(); + const char* const paese = "IT"; + TCausale caus = TCausale(doc.tipo().causale(), doc.anno()); + + // + TPaf_record paf0100f("PAF0100F"); + paf0100f.set("P1_KEYHEADERFATT", hfatt); + paf0100f.set("P1_KEYBODYFATT", bfatt); + paf0100f.remove(); + + paf0100f.set("P1_TRASMITTPAESE", paese); + paf0100f.set("P1_TRASMITTCOD", _cofi); + paf0100f.set("P1_FMTTRASMISS", privato ? "FPR12" : "FPA12"); // SDI11 si usa dal 2015 per lo split payment (prima era SDI10) + + paf0100f.set("P1_CODDEST", coddest); + TString80 tel; + tel << firm.get(NDT_PTEL) << firm.get(NDT_TEL); + paf0100f.set("P1_TELEFONO", tel); + paf0100f.set("P1_MAIL", firm.get(NDT_MAIL)); + paf0100f.set("P1_GESTIONE", "D"); + ok &= paf0100f.insert(); + // + + if (enapec) + { + // + TPaf_record paf3200f("PAF3200F"); + paf3200f.set("PU_KEYHEADERFATT", hfatt); + paf3200f.set("PU_KEYBODYFATT", bfatt); + paf3200f.remove(); + paf3200f.set("PU_PEC", pec); + ok &= paf3200f.insert(); + // + } + + // + TPaf_record paf0200f("PAF0200F"); + paf0200f.set("P2_KEYHEADERFATT", hfatt); + paf0200f.set("P2_KEYBODYFATT", bfatt); + paf0200f.remove(); + + if (_ditta.partita_IVA().full()) + { + paf0200f.set("P2_FISCIVAPAESE", _ditta.stato_partita_IVA()); + paf0200f.set("P2_FISCIVACOD", _ditta.partita_IVA()); + } + paf0200f.set("P2_CODFISCALE", _ditta.codice_fiscale()); + if (_ditta.fisica()) + { + paf0200f.set("P2_ANANOME", _ditta.nome()); + paf0200f.set("P2_ANACOGNOME", _ditta.cognome()); + } + else + { + paf0200f.set("P2_ANADENOMIN", _ditta.ragione_sociale()); + } + + paf0200f.set("P2_REGFISCALE", doc.tipo().reg_fisc()); + + // DatiSede + paf0200f.set("P2_SEDEIND", _ditta.via_residenza()); + paf0200f.set("P2_SEDENRCIVICO", _ditta.civico_residenza()); + paf0200f.set("P2_SEDECAP", _ditta.CAP_residenza()); + paf0200f.set("P2_SEDECOMUNE", _ditta.comune_residenza()); + paf0200f.set("P2_SEDEPROV", _ditta.provincia_residenza()); + paf0200f.set("P2_SEDENAZ", paese); + paf0200f.set("P2_GESTIONE", "D"); + + TAnagrafica cliente(doc.clifor()); + + TString rifamm = cco(doc).get("S4"); + if (rifamm.blank()) + rifamm = doc.clifor().vendite().get(CFV_PARIFAMM); + paf0200f.set("P2_RIFAMMINISTR", rifamm); + + paf0200f.set("P2_ISCRREASOCIOU", _ditta.sociounico() == 'S' ? "SU" : "SM"); + + TISAM_recordset unloc("USE UNLOC\nJOIN COMUNI INTO COM==COMCCIAA\nFROM CODDITTA=#DITTA\nTO CODDITTA=#DITTA"); + unloc.set_var("#DITTA", firm.get(NDT_CODDITTA)); + if (unloc.move_first()) + { + const TString& numrea = unloc.get(ULC_NUMCCIAA).as_string(); + if (numrea.full()) + { + paf0200f.set("P2_ISCRREANUM", numrea); + paf0200f.set("P2_ISCRREAUFF", unloc.get("13->" COM_PROVCOM)); + } + } + + if (_ditta.giuridica()) + { + TISAM_recordset anagiu("USE ANAGIU\nFROM CODANAGR=#CODICE\nTO CODANAGR=#CODICE"); + anagiu.set_var("#CODICE", firm.get(NDT_CODANAGR)); + if (anagiu.move_first()) + { + paf0200f.set("P2_ISCRREACAP", anagiu.get(ANG_CAPSOC)); + const int ss = anagiu.get(ANG_STATOSOC).as_int(); + paf0200f.set("P2_ISCRREASLIQUID", (ss == 2 || ss == 3) ? "LS" : "LN"); + } + } + else + paf0200f.set("P2_ISCRREASLIQUID", "LN"); + + ok &= paf0200f.insert(); + + // + + // + + TPaf_record paf0400f("PAF0400F"); + paf0400f.set("P4_KEYHEADERFATT", hfatt); + paf0400f.set("P4_KEYBODYFATT", bfatt); + paf0400f.remove(); + + if (cliente.partita_IVA().full()) + { + paf0400f.set("P4_FISCIVAPAESE", cliente.stato_partita_IVA()); + paf0400f.set("P4_FISCIVACOD", cliente.partita_IVA()); + } + paf0400f.set("P4_CODFISC", cliente.codice_fiscale()); + + if (cliente.fisica()) + { + paf0400f.set("P4_ANANOME", cliente.nome()); + paf0400f.set("P4_ANACOGNOME", cliente.cognome()); + } + else + { + paf0400f.set("P4_ANADENOM", cliente.ragione_sociale()); + } + + // DatiSede + paf0400f.set("P4_SEDEIND", cliente.via_residenza()); + paf0400f.set("P4_SEDENRCIVICO", cliente.civico_residenza()); + paf0400f.set("P4_SEDECAP", cliente.CAP_residenza()); + paf0400f.set("P4_SEDECOMUNE", cliente.comune_residenza()); + paf0400f.set("P4_SEDEPROV", cliente.provincia_residenza()); + paf0400f.set("P4_SEDENAZ", cliente.stato_residenza_ISO()); + paf0400f.set("P4_GESTIONE", "D"); + ok &= paf0400f.insert(); + // + + // + TPaf_record paf0700f("PAF0700F"); + paf0700f.set("P7_KEYHEADERFATT", hfatt); + paf0700f.set("P7_KEYBODYFATT", bfatt); + paf0700f.remove(); + paf0700f.set("P7_TIPODOC", doc.tipo().tipo_doc_sdi()); + paf0700f.set("P7_DIVISA", "EUR"); // Aggiungere codice ISO 4217 a tabella divise (%VAL) + paf0700f.set("P7_DATA", doc.data()); + + const TCodice_numerazione& codnum = doc.codice_numerazione(); + TString20 numdoc; + codnum.complete_num(doc.numero(), numdoc); + paf0700f.set("P7_NUMERO", numdoc); + paf0700f.set("P7_GESTIONE", "D"); + + // + if (doc.get_real("BOLLI") > ZERO) + { + paf0700f.set("P7_IMPORTOBOLLO", doc.get("BOLLI")); + } + // + + // + // Non la mettiamo! + // + + // Non inserisco più adesso il paf0700f ma lo faccio alla fine (per inserire le ritenute) + + // + TPaf_record paf0900f("PAF0900F"); + paf0900f.set("P9_KEYHEADERFATT", hfatt); + paf0900f.set("P9_KEYBODYFATT", bfatt); + paf0900f.remove(); + + TString80 sconto_expr = doc.get(DOC_SCONTOPERC); + TToken_string sconti; + if (parse_sconto(sconto_expr, sconti)) + { + long nlin_sconto = 0; + FOR_EACH_TOKEN(sconti, str) + { + const real sconto = str; + if (!sconto.is_zero()) // Precauzione inutile + { + paf0900f.set("P9_RIFNUMLINEA", ++nlin_sconto); + if (sconto > ZERO) + { + paf0900f.set("P9_TIPOSCONTO", "SC"); + paf0900f.set("P9_PERCSCONTO", sconto); + } + else + { + paf0900f.set("P9_TIPOSCONTO", "MG"); + paf0900f.set("P9_PERCSCONTO", -sconto); + } + paf0900f.set("P9_GESTIONE", "D"); + ok &= paf0900f.insert(); + } + } + } + // + + // + TPaf_record paf2700f("PAF2700F"); + paf2700f.set("PQ_KEYHEADERFATT", hfatt); + paf2700f.set("PQ_KEYBODYFATT", bfatt); + paf2700f.remove(); + paf2700f.set("PQ_IMPTOTDOC", doc.totale_doc()); + + const TRectype& cont_conv_off = cco(doc); + TString causale = cont_conv_off.get("S1"); + if (causale.full()) + { + causale << ' ' << cont_conv_off.get("S2"); + causale << ' ' << cont_conv_off.get("S3"); + causale.strip_double_spaces(); + causale.cut(200); + } + else + causale = doc.tipo().descrizione(); + paf2700f.set("PQ_CAUSALE", causale); + // paf2700f.set("PQ_ART73", true); + paf2700f.set("PQ_GESTIONE", "D"); + ok &= paf2700f.insert(); + // + + // Azzera DDT + TPaf_record paf1600f("PAF1600F"); + paf1600f.set("PF_KEYHEADERFATT", hfatt); + paf1600f.set("PF_KEYBODYFATT", bfatt); + paf1600f.remove(); + + // Fuori dallo scope per dopo + const TString16 cup = doc.get(DOC_CUP); + const TString16 cig = doc.get(DOC_CIG); + const TString80 com = doc.get(DOC_CODCMS); + + if (!privato) + { + // Azzera contratti + TPaf_record paf1000f("PAF1000F"); + paf1000f.set("P0_KEYHEADERFATT", hfatt); + paf1000f.set("P0_KEYBODYFATT", bfatt); + paf1000f.remove(); + + // Azzera convenzioni + TPaf_record paf1100f("PAF1100F"); + paf1100f.set("PA_KEYHEADERFATT", hfatt); + paf1100f.set("PA_KEYBODYFATT", bfatt); + paf1100f.remove(); + + // Azzera ordini + TPaf_record paf1200f("PAF1200F"); + paf1200f.set("PB_KEYHEADERFATT", hfatt); + paf1200f.set("PB_KEYBODYFATT", bfatt); + paf1200f.remove(); + + TString80 con = doc.get(DOC_CONTRATTO); + if (con.full() || cup.full() || cig.full()) + { + char tcon = doc.get_char(DOC_MODPAG); + if (tcon < 'C') tcon = 'C'; + + TDate datadoc; // Data contratto non obbligatoria + if (con.full()) + { + datadoc = cco(doc).get_date("D0"); + } + else + { + // IdDocumento obbligatorio + con = cig; + if (con.blank()) + con = cup; + } + + if (tcon == 'O') + { + paf1000f.set("P0_RIFNUMLINEA", 0L); + paf1000f.set("P0_IDDOC", con); + paf1000f.set("P0_DATADOC", datadoc); + paf1000f.set("P0_COMMCONVENZ", com); + paf1000f.set("P0_CODCUP", cup); + paf1000f.set("P0_CODCIG", cig); + paf1000f.set("P0_GESTIONE", "D"); + ok &= paf1000f.insert(); + } + else if (tcon == 'C') + { + paf1100f.set("PA_RIFNUMLINEA", 0L); + paf1100f.set("PA_IDDOC", con); + paf1100f.set("PA_DATADOCU", datadoc); + paf1100f.set("PA_COMMCONVENZ", com); + paf1100f.set("PA_CODCUP", cup); + paf1100f.set("PA_CODCIG", cig); + paf1000f.set("PA_GESTIONE", "D"); + ok &= paf1100f.insert(); + } + else + { + paf1200f.set("PB_RIFNUMLINEA", 0L); + paf1200f.set("PB_IDDOC", con); + paf1200f.set("PB_DATADOCO", datadoc); + paf1200f.set("PB_COMMCONVENZ", com); + paf1200f.set("PB_CODCUP", cup); + paf1200f.set("PB_CODCIG", cig); + paf1200f.set("PB_GESTIONE", "D"); + ok &= paf1200f.insert(); + } + } + + if (cup.blank() && cig.blank()) + log(1, "CIG e CUP assenti"); + } + // + + TPaf_record paf1800f("PAF1800F"); + paf1800f.set("PI_KEYHEADERFATT", hfatt); + paf1800f.set("PI_KEYBODYFATT", bfatt); + paf1800f.remove(); // Cancella tutte le righe documento + + TPaf_record paf2000f("PAF2000F"); + paf2000f.set("PJ_KEYHEADERFATT", hfatt); + paf2000f.set("PJ_KEYBODYFATT", bfatt); + paf2000f.remove(); // Cancella tutti gli sconti di riga + + TPaf_record paf1900f("PAF1900F"); + paf1900f.set("PY_KEYHEADERFATT", hfatt); + paf1900f.set("PY_KEYBODYFATT", bfatt); + paf1900f.remove(); // Cancella tutte le righe articoli del documento + + + long riga = 0; + TString16 codivadefault; + { + FOR_EACH_PHYSICAL_RDOC(doc, r, rdoc) + { + codivadefault = rdoc->get(RDOC_CODIVA); + if (codivadefault.full()) + break; + } + } + FOR_EACH_PHYSICAL_RDOC(doc, r, rdoc) + { + paf1800f.reset(); + paf1800f.set("PI_KEYHEADERFATT", hfatt); + paf1800f.set("PI_KEYBODYFATT", bfatt); + paf1800f.set("PI_NUMEROLINEA", ++riga); + paf1800f.set("PI_DESCRIZIONE", descrizione(*rdoc)); + // paf1800f.set("PI_ALIQUOTAIVA", "22.00"); // Altrimenti scarta le righe di descrizione + + // + long riga_art = 0; + TArticolo& art = rdoc->articolo(); + if (art.ok()) + { + paf1900f.reset(); + paf1900f.set("PY_KEYHEADERFATT", hfatt); + paf1900f.set("PY_KEYBODYFATT", bfatt); + paf1900f.set("PY_KEYNLINEA", riga); + + TString& tmp = get_tmp_string(); + + if (art.codice().full()) + { + tmp.cut(0) << art.codice(); // Fixed_string di merda + ok &= add_row_art("Codice interno", tmp, paf1900f); + } + if (rdoc->tipo().codice() == "14") + { + ok &= add_row_art("Codice cliente", rdoc->get("CODARTALT"), paf1900f); + } + } + // + + + set_IVA(codivadefault, paf1800f); + + if (rdoc->is_merce()) + { + paf1800f.set("PI_UNITAMISURA", rdoc->get(RDOC_UMQTA)); + const real qta = rdoc->get(RDOC_QTA); + if (qta.is_zero()) + { + TString msg; + msg.format("La riga merce %d ha quantità nulla", riga); + log(1, msg); + } + if (qta >= ZERO) + { + paf1800f.set("PI_QUANTITA", qta); + paf1800f.set("PI_PREZZOUNIT", rdoc->prezzo(false, false)); + } + else + { + paf1800f.set("PI_QUANTITA", -qta); + paf1800f.set("PI_PREZZOUNIT", -rdoc->prezzo(true, false)); + } + paf1800f.set("PI_PRZTOTALE", rdoc->importo(true, false)); + set_IVA(*rdoc, paf1800f); + + /* + const TDate data = doc.get(DOC_DATADOC); + paf1800f.set("PI_DTINIZIOPER", data); + paf1800f.set("PI_DTFINEPER", data); + */ + + // + + sconto_expr = rdoc->get(RDOC_SCONTO); + if (parse_sconto(sconto_expr, sconti)) + { + long nlin_sconto = 0; + FOR_EACH_TOKEN(sconti, str) + { + const real perc = str; + if (!perc.is_zero()) + { + paf2000f.set("PJ_KEYNLINEA", (long)r); + paf2000f.set("PJ_KEYNLINAR", ++nlin_sconto); + if (perc > ZERO) + { + paf2000f.set("PJ_TIPOSCONTO", "SC"); + paf2000f.set("PJ_PERCSCONTO", perc); + } + else + { + paf2000f.set("PJ_TIPOSCONTO", "MG"); + paf2000f.set("PJ_PERCSCONTO", -perc); + } + paf2000f.set("PJ_GESTIONE", "D"); + ok &= paf2000f.insert(); + } + } + } + // + + + /* + * Ogni riga si può rifare a un DDT/Ordine diverso, per questo devo inserire i dati da qua e non in testata + */ + TArray ancestors; + find_ancestors(*rdoc, ancestors); + for (int i = ancestors.last(); i > 0; i = ancestors.pred(i)) + { + const TAncestor& a = (const TAncestor&)ancestors[i]; + if (i == 1) + { + // + TPaf_record paf1600f("PAF1600F"); + paf1600f.reset(); + paf1600f.set("PF_KEYHEADERFATT", hfatt); + paf1600f.set("PF_KEYBODYFATT", bfatt); + paf1600f.set("PF_RIFNUMLINEA", (long)r); + paf1600f.set("PF_NUMDDDT", a._numdoc); + paf1600f.set("PF_DATADDT", a._datadoc); + paf1600f.set("PF_GESTIONE", "D"); + ok &= paf1600f.insert(); + // + } + else if (i == 3) + { + // + TPaf_record paf1000f("PAF1000F"); + paf1000f.set("P0_KEYHEADERFATT", hfatt); + paf1000f.set("P0_KEYBODYFATT", bfatt); + paf1000f.set("P0_RIFNUMLINEA", (long)r); + paf1000f.set("P0_IDDOC", a._numdoc); + paf1000f.set("P0_DATADOC", a._datadoc); + if (!privato) + { + paf1000f.set("P0_COMMCONVENZ", com); + paf1000f.set("P0_CODCUP", cup); + paf1000f.set("P0_CODCIG", cig); + } + paf1000f.set("P0_GESTIONE", "D"); + ok &= paf1000f.insert(); + // + } + } + + } + else if (rdoc->is_spese()) + { + const TSpesa_prest& sp = rdoc->spesa(); + const real imp = rdoc->importo(true, false); + real qta = UNO; + if (sp.is_tipo()) + { + paf1800f.set("PI_UNITAMISURA", rdoc->get(RDOC_UMQTA)); + qta = rdoc->get_real(RDOC_QTA); + if (qta.is_zero()) + { + TString msg; + msg.format("La riga spese a quantità %d ha quantità nulla (campo %s)", riga, (const char*)rdoc->field_qta()); + log(1, msg); + qta = UNO; + } + paf1800f.set("PI_QUANTITA", qta); + } + real prz = imp; + if (qta != UNO) + { + prz = rdoc->prezzo(true, false); + if (prz.is_zero() && !imp.is_zero()) + { + const TPrice price(imp / qta); + prz = price.get_value(); + } + } + paf1800f.set("PI_PREZZOUNIT", prz); + paf1800f.set("PI_PRZTOTALE", imp); + set_IVA(*rdoc, paf1800f); + + // Controllo se è una ritenuta fiscale + // + if (sp.tipo_ritenuta() == 'F') + { + paf0700f.set("P7_TIPORITENUTA", cliente.fisica() ? "RT01" : "RT02"); + paf0700f.set("P7_IMPORTORIT", doc.imponibile() * sp.perc() / CENTO); + paf0700f.set("P7_ALIQUOTARIT", TCodiceIVA(sp.cod_iva()).percentuale()); + paf0700f.set("P7_CAUSPAGAM", cache().get("CA7", to_tstring(sp.caus_770()), "S2")); + } + // + } + else if (rdoc->is_prestazione()) + { + paf1800f.set("PI_UNITAMISURA", rdoc->get(RDOC_UMQTA)); + real qta = rdoc->get(RDOC_QTA); + if (qta.is_zero()) qta = UNO; + paf1800f.set("PI_QUANTITA", qta); + paf1800f.set("PI_PREZZOUNIT", rdoc->prezzo(false, false)); + paf1800f.set("PI_PRZTOTALE", rdoc->importo(true, false)); + set_IVA(*rdoc, paf1800f); + } + + paf1800f.set("PI_GESTIONE", "D"); + ok &= paf1800f.insert(); + } + // + + + // + /* + * Non valorizziamo nulla al momento in quanto su Campo i dati obbligatori non ci sono/non sono obbligatori + TString cod_vettore = doc.get("CODVETT1"); + // É una fattura accompagnatoria! + if(cod_vettore.full()) + { + } + */ + // + + // Salvo la testata + ok &= paf0700f.insert(); + + // + TPaf_record paf2200f("PAF2200F"); + paf2200f.set("PL_KEYHEADERFATT", hfatt); + paf2200f.set("PL_KEYBODYFATT", bfatt); + paf2200f.remove(); // Cancella tutte le righe di riepilogo IVA + + const char* eiva = "I"; // Esigibilità IVA: Immediata, Differita, Split payment + if (doc.is_split_payment()) + eiva = "S"; + else if (doc.get_bool(DOC_LIQDIFF) || doc.get_bool(DOC_IVAXCASSA)) + eiva = "D"; + + long num_riep = 0; + TAssoc_array& tiva = doc.tabella_iva(false); + FOR_EACH_ASSOC_OBJECT(tiva, obj, key, itm) + { + const TRiepilogo_iva& riva = *(const TRiepilogo_iva*)itm; + const real aliquota = riva.cod_iva().percentuale(); + paf2200f.set("PL_ALIQUOTAIVA", aliquota); + if (aliquota.is_zero()) + paf2200f.set("PL_NATURA", natura(riva.cod_iva().codice())); + + paf2200f.set("PL_IMPONIBILE", riva.imponibile()); + paf2200f.set("PL_IMPOSTA", riva.imposta()); + paf2200f.set("PL_ESIGIVA", eiva); + if (*eiva == 'S') + paf2200f.set("PL_RIFNORMATIVO", "Scissione pagamenti art.17-ter DPR 633/72"); + else + paf2200f.set("PL_RIFNORMATIVO", riva.cod_iva().descrizione()); + paf2200f.set("PL_GESTIONE", "D"); + ok &= paf2200f.insert(); + } + // + + // + TPaf_record paf2400f("PAF2400F"); + paf2400f.set("PN_KEYHEADERFATT", hfatt); + paf2400f.set("PN_KEYBODYFATT", bfatt); + paf2400f.remove(); // Cancella i dati pagamento + + TPagamento& pag = doc.pagamento(); + doc.scadenze_recalc(); // Ricalcola array delle rate + TString_array& scad = doc.scadenze(); + const int nrate = scad.items(); // Conta rate generate + const char* rateazione = pag.cond_pag_sdi(); // A rate (TP01) o una soluzione(TP02)? + paf2400f.set("PN_RIGA", ZERO); // Al momento non gestiamo più tipologie di pagamento per documento + paf2400f.set("PN_CONDPAGAMENTO", rateazione); + paf2400f.set("PN_GESTIONE", "D"); + ok &= paf2400f.insert(); + + TPaf_record paf2500f("PAF2500F"); + paf2500f.set("PO_KEYHEADERFATT", hfatt); + paf2500f.set("PO_KEYBODYFATT", bfatt); + paf2500f.remove(); // Cancella tutte le rate + + // Imposto i campi uguali per tutte le rate + paf2500f.set("PO_CONDPAGAMENTO", rateazione); // Condizione di pagamento PA + paf2500f.set("PO_CODICEPAGAM", pag.code()); // Condizione di pagamento CAMPO + + TString80 iban, istituto; + TString8 abi, cab; + if (get_bank(doc, iban, abi, cab, istituto)) + { + paf2500f.set("PO_ISTFINANZ", istituto); + paf2500f.set("PO_IBAN", iban); + paf2500f.set("PO_ABI", abi); + paf2500f.set("PO_CAB", cab); + } + + if (cab.blank()) + log(2, TR("Non sono presenti ABI, CAB, IBAN per il pagamento")); + else if (iban.blank()) + log(1, TR("Non è presente il codice IBAN per il pagamento")); + + for (int nr = 0; nr < nrate; nr++) + { + paf2500f.set("PO_RIGA", long(nr + 1)); // Numero rata + int rp = nr < pag.n_rate() ? nr : 0; + static TString key_class; key_class.cut(0) << pag.tipo_rata(rp) << pag.ulc_rata(rp); +#ifdef DBG + bool tolla = true; + TString pop = cache().get("%CLR", key_class, "S12"); + bool aaaa = true; +#endif + paf2500f.set("PO_MODALITAPAGAM", cache().get("%CLR", key_class, "S12")); // Si assicura che il numero riga sia accettabile + + TToken_string& riga = scad.row(nr); // Data|Importo + paf2500f.set("PO_DATASCADENZA", TDate(riga.get(0))); // Data scadenza + paf2500f.set("PO_IMPORTO", real(riga.get())); // Importo rata + + paf2500f.set("PO_GESTIONE", "D"); + ok &= paf2500f.insert(); + } + + TPaf_record paf2600f("PAF2600F"); + paf2600f.set("PP_KEYHEADERFATT", hfatt); + paf2600f.set("PP_KEYBODYFATT", bfatt); + paf2600f.remove(); // Cancella eventuali allegati + TToken_string allegati(doc.get("COLL_GOLEM"), '\n'); + bool load_allegati = true; + if (allegati.full()) + { + if(_def_fld.empty()) + { + TString msgerr; msgerr << "Errore: il documento " << bfatt << " ha degli allegati ma nella configurazione non è stato impostato come trametterli\nCaricare il documento senza allegati?"; + load_allegati = false; + if (!yesno_box(msgerr)) + return false; + } + else + { + long nprogr = 0; // Numero di file allegati + TFilename fname; + FOR_EACH_TOKEN(allegati, row) + { + const TToken_string entry(row); + if (entry.get(0, fname) && fname.exist()) + { + static TString dest_path; + static TString dest_usr_path; + + dest_path.cut(0) << _def_fld << fname.name(); + dest_usr_path.cut(0) << _def_usr_fld << fname.name(); + + if (!fcopy(fname, dest_usr_path)) + { + if (yesno_box("Errore critico nel copiare il file %s, si desidera continuare?", fname.name())) + continue; + else + return false; + } + + // Provo a copiare il file + paf2600f.set("PP_NUMEROLINEA", ++nprogr); + paf2600f.set("PP_NOMEATTACHMENT", fname.name()); + paf2600f.set("PP_ATTACHMENT", dest_path); + fname.upper(); // serve estensione maiuscola + paf2600f.set("PP_FMTATTACHMENT", fname.ext()); + ok &= paf2600f.insert(); + } + } + } + } + // + + // Tabella di non invio XML + TPaf_record pafw300f("PAFW300F"); + pafw300f.set("PW_KEYPRGINVIO", hfatt); + pafw300f.set("PW_KEYHEADERFATT", bfatt); + pafw300f.remove(); // Cancella eventuali allegati + const TTipo_documento& td = cached_tipodoc(doc.get(DOC_TIPODOC)); + const TString codsdi = !td.invio_xml() ? "**********" : (enapec ? pec : coddest); + pafw300f.set("PW_CODSDI", codsdi); + ok &= pafw300f.insert(); + + return _to_commit = ok; +} + +bool TDoc_fp::doc_to_paf(const TRectype& rec) +{ + TDocumentoEsteso doc; + if (doc.read(rec) == NOERR) + { + return doc_to_paf(doc) ? db().sq_commit() : db().sq_rollback(); + } + return false; +} + +bool TDoc_fp::doc_to_paf(const TDoc_key& key) +{ + TRectype rec(LF_DOC); + rec.put(DOC_PROVV, key.provv()); + rec.put(DOC_ANNO, key.anno()); + rec.put(DOC_CODNUM, key.codnum()); + rec.put(DOC_NDOC, key.ndoc()); + return doc_to_paf(rec); +} + +bool TDoc_fp::doc_to_paf(const TFilename& ini) +{ + TConfig cfg(ini, "33"); + const int anno = cfg.get_int(DOC_ANNO); + const long ndoc = cfg.get_long(DOC_NDOC); + const TFixed_string codnum(cfg.get(DOC_CODNUM)); // lascio sapientemente per ultima la get di una stringa + const TDoc_key key(anno, codnum, ndoc); + return doc_to_paf(key); +} + +TDoc_fp::TDoc_fp() : _log(nullptr) +{ + _ditta.init(LF_NDITTE, prefix().get_codditta()); + _cofi = ini_get_string(CONFIG_DITTA, "fp", "cofitras"); + + if (_cofi.blank()) + _cofi = _ditta.codice_fiscale(); + + _def_fld = ini_get_string(CONFIG_DITTA, "fp", "flddest"); + if (!_def_fld.ends_with("\\")) + { + _def_fld << "\\"; + } + + _def_usr_fld = ini_get_string(CONFIG_DITTA, "fp", "fldusrdest", ""); + if (_def_usr_fld.empty()) + { + _def_usr_fld = _def_fld; + } + else if (!_def_usr_fld.ends_with("\\")) + { + _def_usr_fld << "\\"; + } +} + +TDoc_fp::~TDoc_fp() +{ + commit(); +} diff --git a/src/fp/fplib01.h b/src/fp/fplib01.h index 15dc287c6..9f404db48 100644 --- a/src/fp/fplib01.h +++ b/src/fp/fplib01.h @@ -5,9 +5,114 @@ #include #include +#include "../ve/velib05.h" +#include "../fe/felib.h" +#include + #define SQL_FLD "sql/" +// Ritorna la connessione al DB paf secondo i parametri impostati nel programma di configurazione SSimple_query& db(); +// Controlla il livello di patch installato e aggiorna le tabelle se necessario bool check_tables(); +// Genera la chiave per i paf +bool chiave_paf(const TDocumento& doc, TString& hfatt, TString& bfatt); +bool chiave_paf(const TRectype& doc, TString& hfatt, TString& bfatt); + + +// Contenitore di campi di un record di database MSSQLServer +class TPaf_record : public TObject +{ + TString8 _table; + TToken_string _key; + TAssoc_array _fields; + +protected: + void copy(const TPaf_record& rec) + { + _table = rec._table; + _key = rec._key; + _fields = rec._fields; + } + + const TString& var2str(const TString& fld, const TVariant& var) const; + const TVariant& get(const char* fld) 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 TString sq_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 TPaf_record(*this); } + virtual bool ok() const { return _table.not_empty(); } + + TPaf_record& operator=(const TPaf_record& rec) + { + copy(rec); + return *this; + } + + TPaf_record(const TPaf_record& rec) { copy(rec); } + TPaf_record(const char* table); +}; + +// Gestione PAF +class TDoc_fp +{ +private: + TAnagrafica _ditta; + TString16 _cofi; + TFilename _dbname; + TLog_report* _log; + TString _logpaf; + TString _def_fld; + TString _def_usr_fld; + bool _to_commit; + + int parse_line(const TString& line, TString& var, TString& val) const; + bool create_table(TScanner& paf, const TString& table); + + const TRectype* find_parent_row(const TRectype& rdoc) const; + int find_ancestors(const TRiga_documento& rdoc, TArray& ancestors) const; + +protected: + bool parse_sconto(const TString& formula, TToken_string& sconti) const; +static bool get_bnp_iban(const TString& abi, const TString& cab, int prg, TString& iban); + bool get_bank(const TDocumento& doc, TString& iban, TString& abi, TString& cab, + TString& istituto) const; + 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); + const char* natura(const TString& codiva) const; + static void set_IVA(const TString& codiva, TPaf_record& paf); + static void set_IVA(const TRiga_documento& rdoc, TPaf_record& paf); + static bool add_row_art(const TString codice_tipo, const TString& codice_valore, TPaf_record& paf); + +public: + bool doc_to_paf(TDocumentoEsteso& doc); + bool doc_to_paf(const TRectype& rec); + bool doc_to_paf(const TDoc_key& key); + bool doc_to_paf(const TFilename& ini); + // Mostra il log a fine esecuzione + bool show_log(); + const int commit(); + + TDoc_fp(); + ~TDoc_fp(); +}; + + #endif // __FPLIB01_H