From e894bf5e120af0a228d0fd3eafdcf107b03d8015 Mon Sep 17 00:00:00 2001 From: Mattia Tollari Date: Mon, 8 Oct 2018 17:40:11 +0200 Subject: [PATCH] Patch level : 12.0 no-patch Files correlati : fp Commento : - Aggiunto supporto all'eliminazione dell'FP --- src/fp/fp0200.cpp~RF1e8fd00e.TMP | 1757 ------------------------------ src/fp/fp0300.cpp | 2 +- src/fp/fp0300.cpp~RF5235131.TMP | 1652 ---------------------------- src/fp/fplib01.cpp | 19 +- 4 files changed, 17 insertions(+), 3413 deletions(-) delete mode 100644 src/fp/fp0200.cpp~RF1e8fd00e.TMP delete mode 100644 src/fp/fp0300.cpp~RF5235131.TMP diff --git a/src/fp/fp0200.cpp~RF1e8fd00e.TMP b/src/fp/fp0200.cpp~RF1e8fd00e.TMP deleted file mode 100644 index 179283ca7..000000000 --- a/src/fp/fp0200.cpp~RF1e8fd00e.TMP +++ /dev/null @@ -1,1757 +0,0 @@ -#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("pa0100a") { } -}; - -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_USER, "fp", "ip"); ad << "@" << ini_get_string(CONFIG_USER, "fp", "db"); - db().sq_connect( - ad, - ini_get_string(CONFIG_USER, "fp", "usr"), - decode(ini_get_string(CONFIG_USER, "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 1e1085ca6..53c18f8ff 100644 --- a/src/fp/fp0300.cpp +++ b/src/fp/fp0300.cpp @@ -177,7 +177,7 @@ void TPA_mask::fill() bool sent = false; if (chiave_paf(doc, hfatt, bfatt)) { - if (paf0100f.search(nullptr, hfatt, bfatt)) + if (paf0100f.search(nullptr, hfatt, bfatt) && paf0100f.sq_get("P1_GESTIONE") != " " && paf0100f.sq_get("P1_ERRINT") != "*") { if (paf0100f.sq_get("P1_GESTIONE") != filter_selected) continue; diff --git a/src/fp/fp0300.cpp~RF5235131.TMP b/src/fp/fp0300.cpp~RF5235131.TMP deleted file mode 100644 index ee864dc15..000000000 --- a/src/fp/fp0300.cpp~RF5235131.TMP +++ /dev/null @@ -1,1652 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../ve/velib05.h" -#include "../cg/cglib03.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 -///////////////////////////////////////////////////////////////////////////////////// - - - -///////////////////////////////////////////////////////////////////////////////////// -// 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) -{ - SLIST_ELT e = NULL; - for (e = xvt_slist_get_first(list); e; e = xvt_slist_get_next(list, e)) - { - const char* val = xvt_slist_get(list, e, NULL); - if (xvt_str_compare_ignoring_case(str, val) == 0) - break; - } - return e; -} - -// Aggiorna il file dst se più vecchio di src (Potrebbe diventare una funzione di XVT.h) -bool xvt_fsys_fupdate(const char* src, const char* dst) -{ - bool ok = false; - if (xvt_fsys_file_exists(src)) - { - const long tsrc = xvt_fsys_file_attr(src, XVT_FILE_ATTR_MTIME); - if (tsrc > 0) - { - long tdst = 0; - if (xvt_fsys_file_exists(dst)) - tdst = xvt_fsys_file_attr(dst, XVT_FILE_ATTR_MTIME); - if (tsrc > tdst) - ok = xvt_fsys_fcopy(src, dst) != 0; - } - } - - 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, (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() > 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 * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME = '" << table << "' ORDER BY ORDINAL_POSITION"; - for (bool ok = db().sq_set_exec(q); ok; ok = db().sq_next()) - { - _key.add(db().sq_get("COLUMN_NAME")); - } - 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("fp0300a") { } -}; - -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 char filter_selected = get(F_FATTSEL)[0]; - - // 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() || td.tipo_doc_sdi().empty()) // Tengo per buone solo le fatture e le note di credito e che hanno il tipo doc SDI per l'invio - continue; - - bool sent = false; - if (chiave_paf(doc, hfatt, bfatt)) - { - if (paf0100f.search(NULL, hfatt, bfatt)) - { - sent = paf0100f.get("P1_GESTIONE").as_string() == "X"; - if (sent && !filter_selected) - 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(td.tipo_doc_sdi()); - 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()); - row->add(!td.invio_xml() ? "X" : ""); - - 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", "01-01-2018")); 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. o di 7 caratteri per un privato - 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) -{ - 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); -} - -/* -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) - { - 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); - - 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(); - return; - } -} - -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()); - - _cofi = ini_get_string(CONFIG_DITTA, "pa", "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, "pa", "TRASMITTCOD", _cofi); - - db().sq_disconnect(); - return TSkeleton_application::destroy(); -} - -int fp0300(int argc, char* argv[]) -{ - TDoc2Paf d2p; - d2p.run(argc, argv, TR("Fatturazione P.A.")); - return 0; -} diff --git a/src/fp/fplib01.cpp b/src/fp/fplib01.cpp index 9ac5512f3..a170e42b1 100644 --- a/src/fp/fplib01.cpp +++ b/src/fp/fplib01.cpp @@ -375,7 +375,12 @@ TString& TPaf_record::remove_string() query << fld << '=' << var2str(fld, var); } } - CHECKS(nkf >= 2, "Can't remove partial key on table ", static_cast(_table)); + // Faccio un triccheballacche per mettere il progressivo non vuoto + TString prefix = _key.get(0); + prefix = prefix.sub(0, prefix.find('_') + 1); + query << " AND " << prefix << "KEYPRGINVIO != ''"; + + CHECKS(++nkf >= 2, "Can't remove partial key on table ", static_cast(_table)); query << ';'; return query; } @@ -392,7 +397,7 @@ 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 "; + query << "SELECT TOP 1 * FROM " << _table << " WHERE "; FOR_EACH_TOKEN(_key, fld) { const TVariant& var = get(fld); @@ -400,7 +405,15 @@ bool TPaf_record::search() query << fld << '=' << var2str(fld, var) << " AND "; } query.rtrim(5); - query << ';'; + query << " ORDER BY "; + + FOR_EACH_TOKEN(_key, fld) + { + const TVariant& var = get(fld); + if (!var.is_null()) + query << fld << ", "; + } + query.rtrim(1) << "DESC;"; // return xvt_sql_execute(_db, query, paf_search_record, this) == 1; // TODO: Valutare