#include #include #include #include #include #include #include #include #include #include #include "../ve/velib05.h" #include "../cg/cglib03.h" #include "pa0.h" #include "pa0100a.h" #include "../fe/felib.h" #include #include #include #include #include #include #include "../cg/cfban.h" ///////////////////////////////////////////////////////////////////////////////////// // Globals ///////////////////////////////////////////////////////////////////////////////////// static XVT_SQLDB _db = NULL; // PAF sqlite db ///////////////////////////////////////////////////////////////////////////////////// // Utilities ///////////////////////////////////////////////////////////////////////////////////// // 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(); } // 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; } ///////////////////////////////////////////////////////////////////////////////////// // TJava_profile ///////////////////////////////////////////////////////////////////////////////////// class TJava_profile : public TObject { TFilename _path; TString_array _row; bool _dirty; protected: const TString& path2prop(const char* path) const; public: void set(const char* key, const char* value); const TString& get(const char* key) const; void save(); TJava_profile(const char* path); ~TJava_profile() { if (_dirty) save(); } }; // Converte una stringa in un percorso per un file profile di Java const TString& TJava_profile::path2prop(const char* path) const { TString percorso; for (const char* c = path; *c; c++) { if (*c == ':' || is_slash(*c)) percorso << '\\'; percorso << *c; } return get_tmp_string() = percorso; } const TString& TJava_profile::get(const char* key) const { FOR_EACH_ARRAY_ROW(_row, r, line) { if (line->starts_with(key, true)) { const int equal = line->find('='); if (equal > 0) { TString& value = get_tmp_string(); value = line->mid(equal+1); value.trim(); return value; } } } return EMPTY_STRING; } void TJava_profile::set(const char* key, const char* value) { _dirty = true; FOR_EACH_ARRAY_ROW(_row, r, line) { if (line->starts_with(key, true)) { const int equal = line->find('='); if (equal > 0) { line->cut(equal + 1); *line << path2prop(value); return; } } } TToken_string* prop = new TToken_string(50, '='); prop->add(key); prop->add(path2prop(value)); _row.add(prop); } void TJava_profile::save() { ofstream out(_path); if (out.good()) { FOR_EACH_ARRAY_ROW(_row, r, line) if (line->full()) out << *line << endl; _dirty = false; } else cantwrite_box(_path); } TJava_profile::TJava_profile(const char* path) : _path(path), _dirty(false) { TScanner s(_path); while (!s.eof()) { const TString& line = s.line(); if (line.full()) _row.add(new TToken_string(line, '=')); else break; } } ///////////////////////////////////////////////////////////////////////////////////// // 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 xvt_sql_execute(_db, query, NULL, 0L) > 0; } // 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 << ';'; return xvt_sql_execute(_db, query, paf_search_record, this) == 1; } // 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; } // 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 (_log == nullptr) { _log = new TLog_report; } if (severity < 0) { _logpaf = msg; } else { 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)) { if (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(); } else { TString msg, filename; entry.get(1, filename); msg << "L'allegato \"" << filename << "\" non esiste e non sarà importato nel XML"; log(1, msg); } } } } // return true; } bool TDoc2Paf::elabora(const TRectype& rec) { bool done = false; TDocumentoEsteso doc; if (doc.read(rec) == NOERR) { xvt_sql_begin(_db); done = elabora(doc); if (done) xvt_sql_commit(_db); else xvt_sql_rollback(_db); } 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()); _dbname = prefix().get_studio(); // base direcotry _dbname.add("sql"); make_dir(_dbname); TString16 d; d.format("PAF%05ld.db", prefix().get_codditta()); _dbname.add(d); _db = xvt_sql_open(_dbname, user(), "", _dbname.path()); if (_db == NULL) return false; const TFilename ini = "paf.ini"; bool ok = ini.exist(); if (ok) { 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(); } xvt_sql_commit(_db); } else xvt_sql_rollback(_db); } 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); xvt_sql_close(_db); _db = NULL; return TSkeleton_application::destroy(); } int pa0100(int argc, char* argv[]) { TDoc2Paf d2p; d2p.run(argc, argv, TR("Fatturazione P.A.")); return 0; }