#include "fplib.h" #include #include #include #include #include #include #include #include #include #include "../fe/felib.h" #include "../ve/velib04.h" #include #include #include #include #include #include #include "../cg/cfban.h" #include #include #include #include "../li/letint.h" #include #include "../cg/cgsaldac.h" #include #include bool set_connection(SSimple_query& s) { bool ok = true; if (s.sq_connect( get_db_str_con(), get_db_user(), get_db_password(), TSDB_MSSQL) != NOERR) { warning_box("Impossibile connettersi al DB esterno"); ok = false; } return ok; } SSimple_query& fp_db() { static SSimple_query* db = nullptr; if (db == nullptr) { db = new SSimple_query(); const bool ok = set_connection(*db); // Non utilizzo l'autocommit, viene gestito manualmente if (ok) db->sq_set_autocommit(false); } return *db; } bool run_fp_psw_mask() { TMask m("Password", 1, 30, 5); m.add_button_tool(DLG_OK, "~Conferma", TOOL_OK); m.add_button_tool(DLG_CANCEL, "Annulla", TOOL_CANCEL); m.add_string(101, 0, "Password ", 1, 1, 15, "*"); m.field(101).check_type(CHECK_REQUIRED); while (m.run() == K_ENTER) { if (m.get(101) == "sirioFATT99"||(is_power_station())) // Hardcoded password are the best! return true; else return error_box("Password errata"); } return false; } string getline(ifstream& f) { string app; getline(f, app); return app; } bool check_tables() { /* * Da questo programma in poi verr utilizzato un sistema diverso per la creazione e aggiornamento delle tabelle * Verranno utilizzati dei file.sql aggiornati con il numero di patch, leggermente scomodo durante la creazione ma facile per i controlli successivamente */ SLIST files = xvt_fsys_list_files(".sql", "sql/fp0/", false); TLocalisamfile tabmod(LF_TABMOD); tabmod.put("MOD", "FP"); tabmod.put("COD", "SQL"); tabmod.put("CODTAB", "VERSION"); int version; if (tabmod.read() == NOERR) version = tabmod.get_int("S0"); for (SLIST_ELT file = xvt_slist_get_first(files); file; file = xvt_slist_get_next(files, file)) { TFilename fn(file->str); fn = fn.name_only(); int file_version = atoi(fn.mid(2, 4)); if (file_version <= version) continue; ifstream f(file->str); if (f.is_open()) { string s; while (!f.eof()) { static string r; r = getline(f); if (r[0] == '-' && r[1] == '-') continue; s += r + '\n'; // Cerco un ; const int limiter = s.find(';') + 1; if (limiter > 0) { string query = s.substr(0, limiter); s.erase(0, limiter); if (!fp_db().sq_set_exec(query, false) || !fp_db().sq_commit()) { error_box("Impossibile eseguire/salvare la query:\n%s\n%s", query.c_str(), fp_db().sq_get_text_error(false)); } } } } else { cantread_box(file->str); return false; } // Salvo su tabmod tabmod.zero(); tabmod.put("MOD", "FP"); tabmod.put("COD", "SQL"); tabmod.put("CODTAB", "VERSION"); tabmod.put("S0", file_version); if (tabmod.rewrite_write() != NOERR && !yesno_box("Attenzione! Errore di aggiornamento versione di Database in Campo, continuare? %s", file_version)) { return false; } } return true; } TString& complete_num_fp(const TCodice_numerazione& codnum, const int numdoc) { static const int len_num_doc = TRectype(LF_DOC).length(DOC_NDOC); TString& ret = get_tmp_string(); const TString& prefisso = codnum.prefisso(); const TString& postfisso = codnum.postfisso(); static TString ndoc; ndoc.cut(0) << numdoc; if (prefisso.full() || postfisso.full()) { for (; ndoc.len() < len_num_doc;) ndoc.add_front("0"); } ret << prefisso << ndoc << postfisso; return ret; } // 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 // P1 P2 P3 P4 P5 P6 P7 P8 P9 P0 PA PB PC PD PE PF PG PI PY PJ PK PL PM PN PO PP PQ PR PS PT PH PU PZ P7 r // Ritorna i nomi delle tabelle paa const char * get_pa_field_name(const TString & table, const char * name) { const char prefix[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'I', 'Y', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'H', 'U', '\0', 'Z', '7' }; const char suffix[] = { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 'F', 'G', 'I', 'Y', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', '\0', '\0', '\0', '\0', '\0', 'r' }; TString & fname = get_tmp_string(); int pos = atoi(table.mid(3, 2)); fname << 'P' << prefix[pos] << name << suffix[pos]; return fname; } // Ritorna i nomi delle tabelle paa TString_array & get_paa_names() { static TString_array __paa_names; if (__paa_names.items() == 0) { const char * names[] = { "PAF0100F", "PAA0200F", "PAA0400F", "PAA0700F", "PAA0800F", "PAA0900F", "PAA1000F", "PAA1100F", "PAA1200F", "PAA1300F", "PAA1400F", "PAA1500F", "PAA1600F", "PAA1700F", "PAA1800F", "PAA1900F", "PAA2000F", "PAA2100F", "PAA2200F", "PAA2400F", "PAA2500F", "PAA2600F", "PAA2700F", "PAA2800F", "PAA2900F", "PAA3000F", "PAA3100F", "PAA3200F", "PAA3400F", "PAAW300F", nullptr }; int i = 0; while (names[i] != nullptr) __paa_names.add(names[i++]); } return __paa_names; } // Ritorna i nomi delle tabelle paf TString_array & get_paf_names() { static TString_array __paf_names; if (__paf_names.items() == 0) { const char * names[] = { "PAF0100F", "PAF0200F", "PAF0400F", "PAF0700F", "PAF0800F", "PAF0900F", "PAF1000F", "PAF1100F", "PAF1200F", "PAF1300F", "PAF1400F", "PAF1600F", "PAF1700F", "PAF1800F", "PAF1900F", "PAF2000F", "PAF2100F", "PAF2200F", "PAF2400F", "PAF2500F", "PAF2600F", "PAF2700F", "PAF3000F", "PAF3200F", "PAF3400F", "PAF3400F", "PAFW300F", nullptr }; int i = 0; while (names[i] != nullptr) __paf_names.add(names[i++]); } return __paf_names; } /* * 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 movimento bool chiave_paf_mov(const TRectype& mov, const char* tipo_doc_sdi, TString& hfatt, TString& bfatt) { TCli_for cli(mov.get_char(MOV_TIPO), mov.get_long(MOV_CODCF)); hfatt.cut(0); if (cli.is_occasionale()) hfatt << "O" << mov.get(MOV_OCFPI); else hfatt << cli.tipo() << cli.codice(); CHECK(hfatt.full(), "Destinatario fattura P.A. non valido"); //20180101_TD01_123456712345671234567 TString numdoc = mov.get(MOV_NUMDOC); numdoc.lpad(mov.length(DOC_NDOC), '0'); bfatt.cut(0); bfatt << mov.get_date(MOV_DATAREG).date2ansi() << '_' << tipo_doc_sdi << '_' << numdoc; return hfatt.full() && bfatt.full(); } bool chiave_paf_doc(const TDocumento& doc, TString& hfatt, TString& bfatt) { hfatt.cut(0); if (doc.clifor().is_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(); //20180101_TD01_123456712345671234567 bfatt.cut(0) << doc.get_date(DOC_DATADOC).date2ansi() << '_' << tipo_doc_sdi(doc) << '_' << complete_num_fp(codnum, doc.numero()); return hfatt.full() && bfatt.full(); } // Crea la coppia di chiavi per il db PAF a partire da un semplice record di testata documento bool chiave_paf_doc(const TRectype& doc, TString& hfatt, TString& bfatt) { const TDocumento d(doc); chiave_paf_doc(d, hfatt, bfatt); return hfatt.full(); } TString get_dest_sdi(const char tipocf, const long codcf, const TString& cod_ind_sped) { TString codsdi, pec; get_coddest(tipocf, codcf, codsdi, pec, cod_ind_sped); return pec.full() ? pec : codsdi; } bool get_coddest(const char tipocf, const long codcf, TString& coddest, TString& pec, const TString& cod_ind_sped) { coddest.cut(0); pec.cut(0); const TCli_for clifo(tipocf, codcf); pec = clifo.get("PEC"); if (!cod_ind_sped.empty()) { TLocalisamfile indsp(LF_INDSP); indsp.put(IND_TIPOCF, tipocf); indsp.put(IND_CODCF, codcf); indsp.put(IND_CODIND, cod_ind_sped); indsp.read(); coddest = indsp.get(IND_PADESTIN); } if (coddest.empty()) coddest = clifo.vendite().get("PADESTIN"); const TAnagrafica anag(LF_CLIFO, tipocf, codcf); if (coddest.empty()) { if (pec.full() || get_esp_pri_empty()) coddest = "0000000"; // Controllo se straniero else if (anag.estero() && anag.stato_partita_IVA() != "IT") { coddest = get_esp_est() ? get_esp_est_cod() : ""; } } else pec = ""; return coddest.full(); } inline const TString& no_special(char a) { TString& r = get_tmp_string().cut(0); if (a != '\'') { r << a; } return r; } const TString& tipo_doc_sdi(const TDocumento& doc) { TString & tipo_doc_sdi = get_tmp_string(); tipo_doc_sdi = doc.get(DOC_TIPODOCSDI); // Controlli da fare per clienti a cui si corrompe la conversione e mi trovo dati sporchi nella colonna if (tipo_doc_sdi.len() == 4 && tipo_doc_sdi.starts_with("TD")) { return tipo_doc_sdi; } return doc.tipo().tipo_doc_sdi(); } // rimuove i record da un paf void remove_from_table(const TString & table, const char * hfatt, const char * bfatt) { TString query("DELETE FROM "); query << table << " WHERE (" << get_pa_field_name(table, "KEYHEADERFATT") << "=" << hfatt << ") AND (" << get_pa_field_name(table, "KEYBODYFATT") << "=" << bfatt; const bool ok = fp_db().sq_set_exec(query); if (!ok) { ofstream fout; fout.open("fperror_remove.txt"); fout << query << "\n" << fp_db().sq_get_text_error(false) << "\n" << fp_db().sq_get_string_error(false); } } // rimuove un movimento contabile dai paf void remove_paf_mov(const TRectype& mov, const char* tipo_doc_sdi) { TString hfatt; TString bfatt; TString_array & tables = get_paf_names(); chiave_paf_mov(mov, tipo_doc_sdi, hfatt, bfatt); FOR_EACH_ARRAY_ROW(tables, r, table) remove_from_table(*table, hfatt, bfatt); } // rimuove un documento dai paf void remove_paf_doc(const TDocumento & doc, const char* tipo_doc_sdi) { TString hfatt; TString bfatt; TString_array & tables = get_paf_names(); chiave_paf_doc(doc, hfatt, bfatt); FOR_EACH_ARRAY_ROW(tables, r, table) remove_from_table(*table, hfatt, bfatt); } bool is_fattura(const TRectype& doc) { 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. } TString& add_filter(const TString& field, const TString& from, const TString& to) { TString& query = get_tmp_string(); const TString qf = field.find('.') < 0 ? field : field.sub(field.find('.') + 1); if (from.full() && to.full()) { query << "&&(BETWEEN(" << field << ", #DA" << qf << ", #A" << qf << "))"; } else if (from.full()) { query << "&&(" << field << ">=#DA" << qf << ")"; } else if (to.full()) { query << "&&(" << field << "<=#A" << qf << ")"; } return query; } /*************************************************************************** * TPaf_record ***************************************************************************/ // Imposta il valore di un campo variant void TPaf_record::set(const char* fld, const TVariant& var) { CHECK(fld && *fld, "Null field name"); if (var.is_null()) { _fields.remove(fld); } else { TVariant* obj = (TVariant*)_fields.objptr(fld); if (obj != NULL) *obj = var; else _fields.add(fld, new TVariant(var)); } } // Imposta il valore di un campo intero void TPaf_record::set(const char* fld, long val) { const TVariant var(val); set(fld, var); } // Imposta il valore di un campo stringa void TPaf_record::set(const char* fld, const char* val) { if (val == NULL) set(fld, NULL_VARIANT); else { const TVariant var(val); set(fld, var); } } // Imposta il valore di un campo stringa void TPaf_record::set(const char* fld, const TString& val) { const TVariant var(val); if (!var.is_string() || (val.full())) set(fld, var); } // Imposta il valore di un campo numerico void TPaf_record::set(const char* fld, const real& val) { const TVariant var(val); set(fld, var); } // Imposta il valore di un campo data in formato ISO void TPaf_record::set(const char* fld, const TDate& val) { if (val.ok()) { const TVariant var(val); set(fld, var); } else set(fld, ""); } // Imposta il valore di un campo booleano void TPaf_record::set(const char* fld, bool var) { set(fld, var ? "SI" : "NO"); } const TString TPaf_record::sq_get(const char* fld) const { return fp_db().sq_get(fld); } // Legge il valore di un campo variant const TVariant& TPaf_record::get(const char* fld) const { const TVariant* var = (const TVariant*)_fields.objptr(fld); return var ? *var : NULL_VARIANT; } // Converte un variant in una stringa valida per SQLite const TString& TPaf_record::var2str(const TString& fldname, const TVariant& var) const { const TFieldtypes vt = var.type(); TString& tmp = get_tmp_string(); if (vt == _realfld) { const TCurrency v(var.as_real(), "", ZERO, fldname.find("PRZ") > 0 || fldname.find("PREZZO") > 0); tmp << '\'' << v.string() << '\''; tmp.replace(',', '.'); return tmp; } if (vt == _datefld) { 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; // Parso i caratteri speciali for (int i = 0; i < str.len(); i++) { tmp << no_special(str[i]); } if (apici) { // Aggiungo apici a inizio e fine riga tmp.insert("'", 0); tmp << '\''; } return tmp; } TString& TPaf_record::remove_string(const bool id_riga) { TString& query = get_tmp_string().cut(0); query << "DELETE FROM " << _table << " WHERE "; int nkf = 0; FOR_EACH_TOKEN(_key, fld) { const TVariant& var = get(fld); if (!var.is_null()) { if (!id_riga && TString(fld).find("RIFNUMLINEA") > 0) continue; if (nkf++ > 0) query << " AND "; query << fld << '=' << var2str(fld, var); } } // 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 << ';'; if (nkf == 0) query.cut(0); // Crea una query sbagliata "WHERE AND": "DELETE FROM [table] WHERE AND [prefix]_KEYPRGINVIO != '';" return query; } // Elimina il record in base ai campi chiave bool TPaf_record::remove() { TString& str = remove_string(); if (str.empty()) // Se la query e' vuota (sbagliata) salto, non c'e' nulla da eliminare return true; const bool ok = fp_db().sq_set_exec(str); if (!ok) { ofstream fout; fout.open("fperror_remove.txt"); fout << str << "\n" << fp_db().sq_get_text_error(false) << "\n" << fp_db().sq_get_string_error(false); } return ok; } // 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; bool first = true; query << "SELECT TOP 1 * FROM " << _table << " WHERE " << filter_string() << " ORDER BY "; //first = true; FOR_EACH_TOKEN(_key, fld) { const TVariant& var = get(fld); if (!var.is_null()) { if (!first) query << ", "; first = false; query << fld; } } query << ";"; // return xvt_sql_execute(_db, query, paf_search_record, this) == 1; // TODO: Valutare return fp_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(); } TString & TPaf_record::insert_string() { CHECKS(_fields.items() >= _key.items(), "Can't insert empty record on table ", _table); TString & query = get_tmp_string(); TString & values = get_tmp_string(); bool first = true; query << "INSERT INTO " << _table << "\n("; FOR_EACH_ASSOC_OBJECT(_fields, obj, fld, itm) { const TVariant& var = get(fld); if (!var.is_null()) { if (!first) { query << ", "; values << ", "; } first = false; query << fld; values << var2str(fld, var); } } query << ")\nVALUES (" << values << ");"; return query; } TString & TPaf_record::update_string() { CHECKS(_fields.items() >= _key.items(), "Can't insert empty record on table ", _table); TString & query = get_tmp_string(); bool first = true; query << "UPDATE " << _table << "\nSET "; FOR_EACH_ASSOC_OBJECT(_fields, obj, fld, itm) { const TVariant& var = get(fld); if (!first) query << ", "; first = false; query << fld << " = " << var2str(fld, var); } query << "\nWHERE " << filter_string(); return query; } TString & TPaf_record::filter_string() { CHECKS(_fields.items() > 0, "Can't search with empty key on table ", static_cast(_table)); TString & filter = get_tmp_string(); bool first = true; FOR_EACH_TOKEN(_key, fld) { const TVariant& var = get(fld); if (!var.is_null()) { if (!first) filter << " AND "; first = false; filter << fld << '=' << var2str(fld, var); } } return filter; } // Aggiunge un record al db bool TPaf_record::insert(bool force) { if (!force && search()) return update(); else return fp_db().sq_set_exec(insert_string(), false); } // Aggiunge un record al db bool TPaf_record::update() { return fp_db().sq_set_exec(update_string(), false); } // 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; TString constraint(table); constraint.rtrim(1); constraint << 'Q'; q << "SELECT col.[name] FROM sys.columns AS col \ inner JOIN sys.index_columns AS idx on col.[object_id] = idx.[object_id] AND col.[column_id] = idx.[column_id] \ inner join sys.indexes as K on idx.[index_id] = K.[index_id] \ where K.[name] = '" << constraint << "' \ AND idx.[object_id] = object_id('" << table << "') \ ORDER BY index_column_id ASC"; for (bool ok = fp_db().sq_set_exec(q); ok; ok = fp_db().sq_next()) { _key.add(fp_db().sq_get("name")); } if (_key.empty_items()) { q = "SELECT col.[name] FROM sys.columns AS col "; q << "inner JOIN sys.index_columns AS idx on col.[object_id] = idx.[object_id] AND col.[column_id] = idx.[column_id] \ inner join sys.indexes as K on idx.[index_id] = K.[index_id] \ where K.[name] = '" << table << "_KEY' \ AND idx.[object_id] = object_id('" << table << "') \ ORDER BY index_column_id ASC"; for (bool ok = fp_db().sq_set_exec(q); ok; ok = fp_db().sq_next()) { _key.add(fp_db().sq_get("name")); } if (constraint.starts_with("PAF1600")) { _key.add("PF_NUMDDDT"); _key.add("PF_RIFNUMLINEA"); } else if (constraint.starts_with("PAF2000")) { _key.add("PJ_KEYNLINEA"); _key.add("PJ_KEYNLINAR"); } else if (constraint.starts_with("PAF2100")) { _key.add("PK_KEYNLINEA"); _key.add("PK_KEYNLINAR"); } else if (constraint.starts_with("PAF2200")) { _key.add("PL_ALIQUOTAIVA"); _key.add("PL_NATURA"); } else if (constraint.starts_with("PAF2500")) { _key.add("PO_RIGA"); } } CHECKS(!_key.empty_items(), "Invalid primary key for table ", table); } //////////////////////////////////////////////////////// // TPaf_container //////////////////////////////////////////////////////// bool TPaf_container::clean_and_erase_paf(const TString& hfatt, const TString& bfatt) { bool ok = true; for (auto i = _pafs.begin(); i != _pafs.end() && ok; ++i) { set_keys_paf(i->second, hfatt, bfatt, strcmp(i->first, "PAF0200F") != 0); ok = i->second.remove(); } return ok; } void TPaf_container::set_keys_paf(TPaf_record& paf, const TString& hfatt, const TString& bfatt, const bool reset) { if (reset) paf.reset(); const char * prefix = paf_to_prefix(paf.get_table()); paf.set(TString(prefix) << "_KEYHEADERFATT", hfatt); paf.set(TString(prefix) << "_KEYBODYFATT", bfatt); } const char* TPaf_container::paf_to_prefix(const char * paf) { static TString paf_name; paf_name.cut(0) << paf; if (paf_name == "PAF0100F") return "P1"; if (paf_name == "PAF0200F") return "P2"; if (paf_name == "PAF0400F") return "P4"; if (paf_name == "PAF0700F") return "P7"; if (paf_name == "PAF0800F") return "P8"; if (paf_name == "PAF0900F") return "P9"; if (paf_name == "PAF1000F") return "P0"; if (paf_name == "PAF1100F") return "PA"; if (paf_name == "PAF1200F") return "PB"; if (paf_name == "PAF1300F") return "PC"; if (paf_name == "PAF1400F") return "PD"; if (paf_name == "PAF1600F") return "PF"; if (paf_name == "PAF1700F") return "PG"; if (paf_name == "PAF1800F") return "PI"; if (paf_name == "PAF1900F") return "PY"; if (paf_name == "PAF2000F") return "PJ"; if (paf_name == "PAF2100F") return "PK"; if (paf_name == "PAF2200F") return "PL"; if (paf_name == "PAF2400F") return "PN"; if (paf_name == "PAF2500F") return "PO"; if (paf_name == "PAF2600F") return "PP"; if (paf_name == "PAF2700F") return "PQ"; if (paf_name == "PAF3000F") return "PT"; if (paf_name == "PAF3200F") return "PU"; if (paf_name == "PAF3400F") return "PZ"; if (paf_name == "PAFW300F") return "PW"; return "ERROR"; } TPaf_record& TPaf_container::get_paf(const char * paf) { return _pafs[paf]; } TPaf_container::TPaf_container() { _pafs.insert(std::pair("PAF0100F", TPaf_record("PAF0100F"))); // Cedente/Prestatore _pafs.insert(std::pair("PAF0200F", TPaf_record("PAF0200F"))); // Cessionario/Committente _pafs.insert(std::pair("PAF0400F", TPaf_record("PAF0400F"))); // Testata documento _pafs.insert(std::pair("PAF0700F", TPaf_record("PAF0700F"))); // Cassa previdenziale _pafs.insert(std::pair("PAF0800F", TPaf_record("PAF0800F"))); // Sconto in fattura _pafs.insert(std::pair("PAF0900F", TPaf_record("PAF0900F"))); // Ordini _pafs.insert(std::pair("PAF1000F", TPaf_record("PAF1000F"))); // Contratti _pafs.insert(std::pair("PAF1100F", TPaf_record("PAF1100F"))); // Convenzioni _pafs.insert(std::pair("PAF1200F", TPaf_record("PAF1200F"))); // Ricezioni _pafs.insert(std::pair("PAF1300F", TPaf_record("PAF1300F"))); // DatiFattureCollegate _pafs.insert(std::pair("PAF1400F", TPaf_record("PAF1400F"))); // DDT Testata _pafs.insert(std::pair("PAF1600F", TPaf_record("PAF1600F"))); // DDT Righe _pafs.insert(std::pair("PAF1700F", TPaf_record("PAF1700F"))); // Righe documento _pafs.insert(std::pair("PAF1800F", TPaf_record("PAF1800F"))); // Righe articoli del documento _pafs.insert(std::pair("PAF1900F", TPaf_record("PAF1900F"))); // Sconti di riga _pafs.insert(std::pair("PAF2000F", TPaf_record("PAF2000F"))); // Altri dati gestionali per le righe documento _pafs.insert(std::pair("PAF2100F", TPaf_record("PAF2100F"))); // Dati Riepilogo _pafs.insert(std::pair("PAF2200F", TPaf_record("PAF2200F"))); // Dati pagamento _pafs.insert(std::pair("PAF2400F", TPaf_record("PAF2400F"))); // Rate _pafs.insert(std::pair("PAF2500F", TPaf_record("PAF2500F"))); // Allegati _pafs.insert(std::pair("PAF2600F", TPaf_record("PAF2600F"))); // Testata documento (aggiunte) _pafs.insert(std::pair("PAF2700F", TPaf_record("PAF2700F"))); // Descrizione _pafs.insert(std::pair("PAF3000F", TPaf_record("PAF3000F"))); // PEC _pafs.insert(std::pair("PAF3200F", TPaf_record("PAF3200F"))); // Causale documento _pafs.insert(std::pair("PAF3400F", TPaf_record("PAF3400F"))); // Non invio XML _pafs.insert(std::pair("PAFW300F", TPaf_record("PAFW300F"))); } /*************************************************************************** * TAncestor ***************************************************************************/ class TAncestor : public TObject { TString20 _numdoc; TDate _datadoc; public: const TString & numdoc() const { return _numdoc; } const TDate & datadoc() const { return _datadoc; } TAncestor(const TRectype& rdoc); }; TAncestor::TAncestor(const TRectype& rdoc) { const int anno = rdoc.get_int(RDOC_ANNO); const TString4 codnum = rdoc.get(RDOC_CODNUM); const long ndoc = rdoc.get_long(RDOC_NDOC); const TCodice_numerazione& num = cached_numerazione(codnum); TToken_string kdoc; kdoc = rdoc.get(RDOC_PROVV); kdoc.add(anno); kdoc.add(codnum); kdoc.add(ndoc); const TRectype& doc = cache().get(LF_DOC, kdoc); TString16 numdoc; num.complete_num(ndoc, numdoc); _numdoc.format("%d/%s/%s", anno, static_cast(codnum), static_cast(numdoc)); _datadoc = doc.get_date(DOC_DATADOC); } /*************************************************************************** * TFPBuono_di_consegna ***************************************************************************/ bool TFPBuono_di_consegna::already_exist(map& ancestors_s) const { for (auto it = ancestors_s.begin(); it != ancestors_s.end(); ++it) { TFPBuono_di_consegna b(it->first, it->second); if (b == *this) return true; } return false; } /* /$$$$$$$$ /$$$$$$$ |__ $$__/| $$__ $$ | $$ | $$ \ $$ /$$$$$$ /$$$$$$$ | $$ | $$ | $$ /$$__ $$ /$$_____/ | $$ | $$ | $$| $$ \ $$| $$ | $$ | $$ | $$| $$ | $$| $$ | $$ | $$$$$$$/| $$$$$$/| $$$$$$$ |__/ |_______/ \______/ \_______/ */ bool TDoc_fp::parse_sconto(const TString& formula, TToken_string& sconti) const { sconti.cut(0); int start = 0; for (int i = 0; ; i++) { const char c = formula[i]; if (c == '+' || c == '-' || c < ' ') { if (i > 0) { TString8 tok = formula.sub(start, i); tok.replace(',', '.'); const real perc = tok; if (!perc.is_zero()) sconti.add(tok); } if (c < ' ') break; start = i; } } return sconti.full(); } bool TDoc_fp::get_bnp_iban(const TString& abi, const TString& cab, int nprog, TString& iban) { TTable bnp("BNP"); TString16 key; key << abi << cab; if (nprog > 0) { TString4 sprog; sprog.format("%02d", nprog); key << sprog; } bnp.put("CODTAB", key); int err = bnp.read(_isgteq); if (err == NOERR && !bnp.get("CODTAB").starts_with(abi)) err = _iskeynotfound; if (err == NOERR) iban = bnp.get("S3"); return err == NOERR; } bool TDoc_fp::get_bank(TDocumento& doc, TString& iban, TString& abi, TString& cab, TString& istituto) const { bool found = false; if (doc.pagamento().tipo_rata(0) == TTipo_pag::_bonfico) { found = get_bank_presentazione(doc, iban, abi, cab, istituto); } else if (doc.pagamento().tipo_rata(0) == TTipo_pag::_ric_ban || doc.pagamento().tipo_rata(0) == TTipo_pag::_rid) { found = get_bank_appoggio(doc, iban, abi, cab, istituto); } return found; } bool TDoc_fp::get_bank_presentazione(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); else // 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); found = abi.full() && cab.full(); iban = cfban.get(CFBAN_IBAN); if (found && iban.blank()) get_bnp_iban(abi, cab, -1, 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; } bool TDoc_fp::get_bank_appoggio(const TDocumento& doc, TString& iban, TString& abi, TString& cab, TString& istituto) const { abi = doc.get(DOC_CODABIA); cab = doc.get(DOC_CODCABA); iban = doc.get(DOC_IBAN); bool found = abi.full() && cab.full(); if (found) istituto = cache().get("%BAN", abi, "S0"); if (iban.empty()) { TToken_string key; key.add("C"); key.add(doc.codcf()); key.add("V"); key.add(1); const TRectype& cfban = cache().get(LF_CFBAN, key); if (!cfban.empty()) { const TString& abi_cf = cfban.get(CFBAN_ABI); const TString& cab_cf = cfban.get(CFBAN_CAB); const bool found_cf = abi_cf.full() && cab_cf.full(); iban = cfban.get(CFBAN_IBAN); if (found_cf && iban.blank()) get_bnp_iban(abi_cf, cab_cf, -1, iban); } } return found; } const TString& TDoc_fp::descrizione(const TRiga_documento& rdoc) { if (rdoc.get_bool(RDOC_DESCLUNGA)) { TString& tmp = get_tmp_string(); tmp << rdoc.get(RDOC_DESCR) << rdoc.get(RDOC_DESCEST); tmp.replace('\n', ' '); tmp.strip_double_spaces(); tmp.trim(); if (tmp.len() > 900) { TString err; err << "Il documento " << rdoc.doc().anno() << " " << rdoc.doc().codice_numerazione().codice() << " " << rdoc.doc().numero() << " ha la riga numero " << rdoc.numero() << " pi lunga di quanto supportato dal formato dell'agenzia delle entrate, verr troncata a 900 caratteri"; _log.log(1, err); } return tmp.left(900); } return rdoc.get(RDOC_DESCR); } const TRectype* TDoc_fp::find_parent_row(const TRectype& rdoc) const { const long id = rdoc.get_long(RDOC_DAIDRIGA); if (id > 0L) { TToken_string key; key.add(rdoc.get(RDOC_DACODNUM)); if (key.full()) { key.add(rdoc.get(RDOC_DAANNO)); key.add(rdoc.get(RDOC_DAPROVV)); key.add(rdoc.get(RDOC_DANDOC)); for (int r = 0; ; r++) { if (r == 0) key.add(id, 4); else key.add(r, 4); const TRectype& rec = cache().get(LF_RIGHEDOC, key); if (r > 0 && rec.empty()) break; if (rec.get_long(RDOC_IDRIGA) == id) return &rec; } } } return NULL; } int TDoc_fp::find_ancestors(const TRiga_documento& rdoc, TArray& ancestors) const { if (rdoc.is_articolo()) { for (const TRectype* prdoc = find_parent_row(rdoc); prdoc != NULL; prdoc = find_parent_row(*prdoc)) { const TCodice_numerazione& cn = cached_numerazione(prdoc->get(RDOC_CODNUM)); const int td = cn.tipo(); if (td > 0 && ancestors.objptr(td) == NULL) ancestors.add(new TAncestor(*prdoc), td); } } return ancestors.items(); } bool TDoc_fp::insert(TPaf_record& p, bool force) { bool ok = true; if (_cache_insert) _query.add(p.insert_string()); else { ok = p.insert(force); if (!ok) { _log.log(2, fp_db().sq_get_token_text_error(1)); _log.log(2, p.insert_string()); } } return ok; } bool TDoc_fp::remove(TPaf_record& p) { bool ok = true; if (_cache_insert) _query.add(p.remove_string()); else { ok = p.remove(); if (!ok) { _log.log(2, fp_db().sq_get_token_text_error(1)); _log.log(2, p.remove_string()); } } return ok; } bool TDoc_fp::save_paf() { bool ok = true; if (_cache_insert) { TString query; FOR_EACH_ARRAY_ROW(_query, r, row) query << *row; ok = fp_db().sq_set_exec(query); if (!ok) { _log.log(2, fp_db().sq_get_token_text_error(1)); _log.log(2, query); } } return ok; } bool TDoc_fp::check_initial(TDocumentoEsteso& doc) { bool ok = true; static TString msg; if (_coddest.len() != 6 && _coddest.len() != 7) { _log.log(1, "Il codice destinatario ha una lunghezza non conforme."); ok = false; } const int alleg = _rec_clifo.get_int(CLI_ALLEG); bool privato = (alleg == 5 || alleg == 9) && _rec_clifo.get(CLI_STATOCF).full(); if (_rec_clifo.get(CLI_PAIV).empty() && _rec_clifo.get(CLI_COFI).empty() && !privato) { _log.log(1, "Sia la partita IVA che il codice fiscale del cessionario committente sono vuoti, almeno uno dei due deve essere valorizzato."); ok = false; } TPagamento& pag = doc.pagamento(); if (pag.cond_pag_sdi().empty()) { msg.cut(0) << "Non e' valorizzata la condizione di pagamento SDI (TP01, TP02, TP03) per la condizione di pagamento " << pag.code(); _log.log(1, msg); ok = false; } doc.scadenze_recalc(); for (int nr = 0; nr < doc.scadenze_items(); nr++) { const int rp = nr < pag.n_rate() ? nr : 0; static TString key_class; key_class.cut(0) << pag.tipo_rata(rp) << pag.ulc_rata(rp); if (cache().get("%CLR", key_class, "S12").empty()) { msg.cut(0) << "Non e' valorizzata la tipologia di pagamento SDI (MPXX) per la condizione di pagamento " << pag.code(); _log.log(1, msg); ok = false; } } return ok; } bool TDoc_fp::check_row(const TRiga_documento& rdoc) { bool ok = false; static TString msg; if (rdoc.is_spese()) { const TSpesa_prest& spesa = rdoc.spesa(); if (spesa.is_percentuale() && spesa.perc().is_zero()) { msg.cut(0) << "E' corretto che per la spesa " << spesa.codice() << " la percentuale sia zero?"; _log.log(1, msg); } } const TCodiceIVA& codice_iva = rdoc.iva(); if (codice_iva.codice().full() && codice_iva.percentuale() == ZERO && natura(codice_iva.codice()).empty()) { msg.cut(0) << "Impossibile avere la natura non valorizzata a fronte di una aliquota con percentuale zero. Codice IVA: "; msg << codice_iva.codice(); _log.log(1, msg); ok = false; } return ok; } bool TDoc_fp::check_riepilogo(const TDocumentoEsteso& doc, const TRiepilogo_iva& riva) { bool ok = true; static TString msg; if (*get_esigibilita_iva(doc) == 'S' && natura(riva.cod_iva().codice()) == "N6") { msg.cut(0) << "Impossibile avere un documento con scissione dei pagamenti e natura iva N6, codice: " << riva.cod_iva().codice(); _log.log(1, msg); ok = false; } return ok; } bool TDoc_fp::initialize(TDocumentoEsteso& doc) { // Azzero _hfatt.cut(0); _bfatt.cut(0); // Preparo il record del cliente _rec_clifo = doc.clifor(); // Valorizzo la gestione del cambio //_doc_cambio._cod_val = doc.valuta(); //_doc_cambio._is_valuta_estera = doc.valuta().full() && !is_euro_value(doc.valuta()); //_doc_cambio._cambio = doc.cambio(); // Paese del documento _paese = "IT"; _has_bolla = false; if (!chiave_paf_doc(doc, _hfatt, _bfatt)) return false; // Preparo il log _log.log(-1, _bfatt); // Controllo se il documento almeno in stato di stampa if (doc.stato() < doc.tipo().stato_finale_stampa()) { _log.log(3, "Il documento non e' stato ancora stampato, verra' saltato"); return false; } _is_pa = doc.clifor().get_int("ALLEG") == 7; if (!doc.get_coddest(_coddest, _pec)) { _log.log(1, "Impossibile trovare il codice destinatario per la fattura"); return false; } _enapec = _coddest == "0000000" && _pec.full(); _privato = _coddest.len() != 6; _caus = TCausale(doc.tipo().causale(), doc.anno()); // Preparo il codice iva di default { FOR_EACH_PHYSICAL_RDOC(doc, r, rdoc) { _codivadefault = rdoc->get(RDOC_CODIVA); if (_codivadefault.full()) break; } } // Azzero indici _idx_cassa_previdenziale = 1; // Controllo custom _has_cust = cached_custom_fp().has_custom(doc); if (check_initial(doc) || get_check_not_block()) { return _paf_container.clean_and_erase_paf(_hfatt, _bfatt); } return false; } const TRectype& TDoc_fp::cco(const TRectype& doc) const { TString80 conkey; const TString& con = doc.get(DOC_CONTRATTO); if (con.full()) { char tcon = doc.get_char(DOC_MODPAG); if (tcon < 'C') tcon = 'C'; conkey.format("%c%6ld%s", tcon, doc.get_long(DOC_CODCF), static_cast(con)); } static TLocalisamfile tabmod(LF_TABMOD); // Controllo se non sono gi sul record, cos evito read inutili // Lo sto facendo a mano perch usare cache() metterebbe FP nella colonna "MOD" if (tabmod.get("MOD") != "PA" || tabmod.get("COD") != "CON" || tabmod.get("CODTAB") != conkey) { tabmod.zero(); tabmod.put("MOD", "PA"); tabmod.put("COD", "CON"); tabmod.put("CODTAB", conkey); if (tabmod.read() != NOERR) tabmod.zero(); } return tabmod.curr(); } const char* TDoc_fp::stato_paf() { if (get_no_export_pronto()) { _diagn = true; return "D"; } else { _diagn = false; return "P"; } } bool TDoc_fp::show_log() { TReport_book b; TFilename name = "fp_err.log"; b.add(_log); b.export_text(name); return _log.preview(); } //DA CORREGGERE PER EVITARE DI CONVERTIRE TUTTE DA STATO D A P int TDoc_fp::commit() { int r = 0; if (_to_commit) { if (r >= 0 && fp_db().sq_commit()) { r += 2; // Controllo stato diagnosticato if (get_no_export_pronto()) { _log.log(2, "Le fatture sono state esportate in stato diagnosticato"); } else { _log.log(2, "Le fatture sono state esportate correttamente in stato pronto"); } } else { r = -1; _log.log(2, fp_db().sq_get_token_text_error(1)); } } _to_commit = false; return r; } int TDoc_fp::force_commit() { _to_commit = true; return commit(); } const TString & TDoc_fp::natura(const char* codiva) const { const TCodiceIVA iva(codiva); TString & natura = get_tmp_string(4); natura = iva.natura(); if (!tracciati_2021() && natura.len() > 2) natura = natura.sleft(2); return natura; } const char* TDoc_fp::get_esigibilita_iva(const TDocumentoEsteso& doc) { // Esigibilit IVA: Immediata, Differita, Split payment const char* eiva = "I"; if (doc.is_split_payment()) eiva = "S"; else if (doc.get_bool(DOC_LIQDIFF) || doc.get_bool(DOC_IVAXCASSA)) eiva = "D"; return eiva; } void TDoc_fp::set_IVA(TString codiva, TPaf_record& paf) const { if (codiva.empty()) codiva = _codivadefault; // necessario il cast a real? paf.set("PI_ALIQUOTAIVA", static_cast(cache().get("%IVA", codiva, "R0"))); paf.set("PI_NATURA", natura(codiva)); } void TDoc_fp::set_IVA(const TRiga_documento& rdoc, TPaf_record& paf) const { set_IVA(rdoc.get(RDOC_CODIVA), paf); } bool TDoc_fp::add_row_art(long& riga_art, const TString& codice_tipo, const TString& codice_valore, TPaf_record& paf) { paf.set("PY_KEYNLINAR", ++riga_art); paf.set("PY_TIPOARTICOLO", codice_tipo); paf.set("PY_VALOREARTICOLO", codice_valore); return insert(paf); } bool TDoc_fp::add_row_alleg(TFilename& file, long& nprogr, TPaf_record& paf) { static TString dest_path; static TString dest_usr_path; bool ok = false; dest_path.cut(0) << _def_fld << file.name(); dest_usr_path.cut(0) << _def_usr_fld << file.name(); if (!fcopy(file, dest_usr_path)) { return yesno_box("Errore critico nel copiare il file %s, si desidera continuare?", file.name()); } // Provo a copiare il file paf.set("PP_NUMEROLINEA", ++nprogr); paf.set("PP_NOMEATTACHMENT", file.name()); paf.set("PP_ATTACHMENT", dest_path); file.upper(); // serve estensione maiuscola paf.set("PP_FMTATTACHMENT", file.ext()); ok = insert(paf); return ok; } const TString& TDoc_fp::converti_prezzo(const real& prezzo) const { TString& ret = get_tmp_string(); ret.cut(0); if (_doc->in_valuta()) { TCurrency_documento app(prezzo, *_doc, true); app.change_to_euro_val(); ret << app.get_num().string(0); } else ret << prezzo; return ret; } void TDoc_fp::set_qta_prezzo(TPaf_record& paf1800f, TFPRiga_documento* rdoc) const { // Setto l'unit di misura paf1800f.set("PI_UNITAMISURA", rdoc->get(RDOC_UMQTA)); const real qta = rdoc->quantita(); // Prendendo la stringa non ho problemi in scrittura della query, a volte accadono cose stupide TString& qta_string = rdoc->quantita_string(); real prezzo_unit = rdoc->prezzo(_nascondi_sconti_righe_fatt, false); real prezzo_tot = rdoc->imponibile(false); if (qta < ZERO) { // Metto la qualit senza il segno qta_string = qta_string.mid(1); // E i prezzi in negativo prezzo_unit = -abs(prezzo_unit); prezzo_tot = -abs(prezzo_tot); } // Salvo tutto paf1800f.set("PI_QUANTITA", qta_string); paf1800f.set("PI_PREZZOUNIT", converti_prezzo(prezzo_unit)); paf1800f.set("PI_PRZTOTALE", converti_prezzo(prezzo_tot)); } const real calc_ritenuta(const TDocumento& doc) { real imponibile_prestazioni = ZERO; { FOR_EACH_PHYSICAL_RDOC(doc, r, rdoc) { if (rdoc->is_prestazione()) imponibile_prestazioni += rdoc->imponibile(); } } real imponibile = imponibile_prestazioni; { // Riciclo per sommare la % delle spese da sommare FOR_EACH_PHYSICAL_RDOC(doc, r, rdoc) { if (rdoc->is_spese() && rdoc->spesa().spe_cal_rit()) imponibile += imponibile * rdoc->spesa().perc() / CENTO; } } return imponibile; } void TDoc_fp::add_ritenuta(const TRiga_documento & rdoc, TPaf_record& paf0700f) const { // const TSpesa_prest & sp = rdoc.spesa(); const real importo_ritenuta = rdoc.ritenuta(); TString tipo_rit = sp.codice_tipo_ritenuta_fp(); if (tipo_rit.empty()) tipo_rit = _rec_clifo.get_char(CLI_TIPOPERS) == 'F' ? "RT01" : "RT02"; paf0700f.set("P7_TIPORITENUTA", tipo_rit); paf0700f.set("P7_IMPORTORIT", converti_prezzo(importo_ritenuta)); paf0700f.set("P7_ALIQUOTARIT", sp.perc()); static TString caus_la; caus_la.cut(0); caus_la << sp.get("S14")[0]; if (caus_la.empty()) { caus_la << sp.rec_caus_770().get("S2"); } paf0700f.set("P7_CAUSPAGAM", caus_la); // } bool TDoc_fp::add_riepilogo_iva(TPaf_record& paf2200f, const TCodiceIVA& cod_iva, const char* eiva, const real& imponibile, const real& imposta) { reset(paf2200f); const real aliquota = cod_iva.percentuale(); const TString& cod_aliquota = cod_iva.codice(); TRiepilogo_agg& riepilogo_agg = _riepilogo_agg[cod_aliquota]; // Aliquota paf2200f.set("PL_ALIQUOTAIVA", aliquota); // Natura if (aliquota.is_zero()) paf2200f.set("PL_NATURA", natura(cod_aliquota)); // Imponibile paf2200f.set("PL_IMPONIBILE", converti_prezzo(imponibile + riepilogo_agg.imponibile)); // Imposta paf2200f.set("PL_IMPOSTA", converti_prezzo(imposta + riepilogo_agg.imposta)); // Esigibilit IVA 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", cod_iva.descrizione()); paf2200f.set("PL_GESTIONE", stato_paf()); // Elimino l'oggetto _riepilogo_agg.erase(cod_aliquota); // Inserisco return insert(paf2200f, true); } bool TDoc_fp::add_cassa_previdenziale(TRiga_documento& rdoc) { TPaf_record& paf0800f = _paf_container.get_paf("PAF0800F"); reset(paf0800f); paf0800f.set("P8_RIFNUMLINEA", _idx_cassa_previdenziale++); // Resto const TSpesa_prest& sp = rdoc.spesa(); const real imponibile_doc = rdoc.doc().prestazioni(); const real importo_cassa = imponibile_doc * sp.perc() / CENTO; paf0800f.set("P8_TIPOCASSA", sp.cassa_previdenziale()); // Aliquota della cassa paf0800f.set("P8_ALIQCASSA", sp.perc()); // Importo contributo cassa paf0800f.set("P8_IMCONTRCASSA", converti_prezzo(importo_cassa)); // Imponibile cassa paf0800f.set("P8_IMPONCASSA", converti_prezzo(imponibile_doc)); // Aliquota applicata alla riga spesa paf0800f.set("P8_ALIQIVA", rdoc.iva().percentuale()); if (sp.sogg_a_rit()) paf0800f.set("P8_RITENUTA", "SI"); paf0800f.set("P8_NATURA", natura(rdoc.iva().codice())); // Inserisco il tutto nei dati riepilogo /*TRiepilogo_agg& pop = _riepilogo_agg[rdoc.iva().codice()]; pop.imponibile += importo_cassa; pop.imposta += importo_cassa * rdoc.iva().percentuale() / CENTO;*/ return insert(paf0800f); } bool TDoc_fp::export_info_articolo(TFPRiga_documento* rdoc, TPaf_record& paf1900f, TPaf_record& paf2100f, const long riga_xml, const int riga_doc) { bool ok = true; const TString& codartmag = rdoc->get(RDOC_CODARTMAG); const TString& codart = rdoc->get(RDOC_CODART); long riga_art = 0; if (_has_cust) { cached_custom_fp().get_custom(rdoc->doc()).load_articolo_paf(paf1900f, *rdoc, riga_xml, *this); } else { if (codart.full()) { if (codartmag.full()) { reset(paf1900f); paf1900f.set("PY_KEYNLINEA", riga_xml); ok &= add_row_art(riga_art, "Codice articolo interno", codartmag, paf1900f); } // Se il codice articolo del magazzino diverso quello del cliente if (codart.full() && codart != codartmag) { reset(paf1900f); paf1900f.set("PY_KEYNLINEA", riga_xml); ok &= add_row_art(riga_art, "Codice articolo cliente", codart, paf1900f); } } } // Controllo se ha il CONAI in tal caso aggiungo i dati const TTipo_documento & tipodoc = rdoc->doc().tipo(); if (tipodoc.add_conai()) for (int i = 0; i < FR_CMAX; i++) { const TString scat(rdoc->get(conai_sottocat_name(i))); const real peso_conai = rdoc->get_real(conai_peso_name(i)).string(); if (scat.full() && peso_conai != ZERO && cache().get("&VESCC", scat).not_empty() && !_has_cust) { reset(paf2100f); paf2100f.set("PK_KEYNLINEA", static_cast(riga_doc)); paf2100f.set("PK_KEYNLINAR", _idx_adg_doc_row++); TString msg_conai; msg_conai << "Contributo CONAI " << conai_material(conai_str2class(scat)) << " (Kg)"; paf2100f.set("PK_TIPODATO", "CONAI"); paf2100f.set("PK_RIFDATO", msg_conai); paf2100f.set("PK_RIFNUMERO", peso_conai); ok &= insert(paf2100f); TLocalisamfile cfven(LF_CFVEN); cfven.put("TIPOCF", "C"); cfven.put("CODCF", rdoc->doc().codcf()); cfven.read(); TString esen_field = conai_esenzione_name(conai_str2class(scat)); real perc_esenz = cfven.get_real(esen_field); if (perc_esenz > ZERO) { reset(paf2100f); paf2100f.set("PK_KEYNLINEA", static_cast(riga_doc)); paf2100f.set("PK_KEYNLINAR", _idx_adg_doc_row++); real qta = rdoc->calc_conai_qta(i); qta = qta * perc_esenz / CENTO; qta.round(2); TString msg_esen; msg_esen << "Esenzione CONAI sul totale riga (Kg)"; paf2100f.set("PK_TIPODATO", "ESEN CONAI"); paf2100f.set("PK_RIFDATO", msg_esen); paf2100f.set("PK_RIFNUMERO", qta); ok &= insert(paf2100f); } } } return ok; } const TFirm& TDoc_fp::get_firm() { return prefix().firm(); } bool TDoc_fp::export_paf0100f() { // TPaf_record& paf0100f = _paf_container.get_paf("PAF0100F"); paf0100f.set("P1_TRASMITTPAESE", _paese); paf0100f.set("P1_TRASMITTCOD", _cofi); paf0100f.set("P1_FMTTRASMISS", _privato ? "FPR12" : "FPA12"); paf0100f.set("P1_CODDEST", _coddest); TString80 tel; TString80 pec; tel << get_firm().get(NDT_PTEL) << get_firm().get(NDT_TEL); paf0100f.set("P1_TELEFONO", tel); pec << get_firm().get(NDT_MAIL); paf0100f.set("P1_MAIL", pec); paf0100f.set("P1_GESTIONE", stato_paf()); paf0100f.set("P1_ERRINT", ""); // return insert(paf0100f); } bool TDoc_fp::export_paf3200f() { if (_enapec) { // TPaf_record& paf3200f = _paf_container.get_paf("PAF3200F"); paf3200f.set("PU_PEC", _pec); // return insert(paf3200f); } return true; } void TDoc_fp::fill_buoni(map& buoni, const TString& memo, bool last) { if (memo.full()) { if (!last) // Prima riga { TToken_string b(memo, 'n'); for (int i = 4; i < b.items(); i++) { TToken_string str(b.get(i), ' '); TString20 ndoc = str.get(1); TDate data(str.get(3)); if (data == TDate(NULLDATE)) data = str.get(2); TFPBuono_di_consegna buono(ndoc, data); buoni.insert({ buono._numdoc, buono }); } } else // Ultima riga { TToken_string b(memo, '\n'); for (int i = 0; i < b.items(); ++i) { TToken_string str(b.get(i), ' '); str.replace(" ", " "); TString20 ndoc = str.get(4); TDate data(str.get(6)); TFPBuono_di_consegna buono(ndoc, data); buoni.insert({ buono._numdoc, buono }); } } } } bool TDoc_fp::doc_to_paf(TDocumentoEsteso& doc) { int linea_sconto = 0; if (!initialize(doc)) return false; bool ok = true; ok &= export_paf0100f(); ok &= export_paf3200f(); TBit_array ddt_linee; // TPaf_record& paf0200f = _paf_container.get_paf("PAF0200F"); TAnagrafica cliente(doc.clifor()); if (!paf0200f.is_full()) { if (_ditta.partita_IVA().full()) { paf0200f.set("P2_FISCIVAPAESE", _ditta.stato_partita_IVA()); paf0200f.set("P2_FISCIVACOD", _ditta.partita_IVA()); } paf0200f.set("P2_CODFISCALE", _ditta.codice_fiscale()); if (_ditta.fisica()) { paf0200f.set("P2_ANANOME", _ditta.nome()); paf0200f.set("P2_ANACOGNOME", _ditta.cognome()); } else { paf0200f.set("P2_ANADENOMIN", _ditta.ragione_sociale()); } paf0200f.set("P2_REGFISCALE", doc.tipo().reg_fisc()); // DatiSede paf0200f.set("P2_SEDEIND", _ditta.via_residenza()); paf0200f.set("P2_SEDENRCIVICO", _ditta.civico_residenza().left(8)); 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", stato_paf()); TString rifamm = cco(doc).get("S4"); if (rifamm.blank()) { TLocalisamfile indsp(LF_INDSP); indsp.put(IND_TIPOCF, doc.get(DOC_TIPOCF)); indsp.put(IND_CODCF, doc.get(DOC_CODCF)); indsp.put(IND_CODIND, doc.get(DOC_CODINDSP)); indsp.read(); rifamm = indsp.get(IND_PARIFAMM); if (rifamm.blank()) rifamm = doc.clifor().vendite().get(CFV_PARIFAMM); } paf0200f.set("P2_RIFAMMINISTR", rifamm); paf0200f.set("P2_ISCRREASOCIOU", _ditta.sociounico() == 'S' ? "SU" : "SM"); TISAM_recordset unloc("USE UNLOC\nJOIN COMUNI INTO COM==COMCCIAA\nFROM CODDITTA=#DITTA\nTO CODDITTA=#DITTA"); unloc.set_var("#DITTA", get_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", get_firm().get(NDT_CODANAGR)); if (anagiu.move_first()) { paf0200f.set("P2_ISCRREACAP", anagiu.get(ANG_CAPSOC)); const int ss = anagiu.get(ANG_STATOSOC).as_int(); paf0200f.set("P2_ISCRREASLIQUID", (ss == 2 || ss == 3) ? "LS" : "LN"); } } else paf0200f.set("P2_ISCRREASLIQUID", "LN"); } ok &= insert(paf0200f); // // TPaf_record& paf0400f = _paf_container.get_paf("PAF0400F"); TString stato = cliente.stato_partita_IVA(); TTable tab_codiso("%SCE"); tab_codiso.tab(); tab_codiso.put("CODTAB", stato); tab_codiso.read(); TString piva = cliente.partita_IVA(), fisc = cliente.codice_fiscale(); if (!stato.full()) stato = "IT"; if (tab_codiso.get_bool("B0") || stato == "IT") // Cliente EU { if (stato == "IT") { if (piva.full()) { if (piva.len() == 11 && (piva[0] == '8' || piva[0] == '9')) { fisc = piva; piva.cut(0); } } else if (fisc.full() && fisc.len() == 11 && (fisc[0] == '8' || fisc[0] == '9')) piva.cut(0); } if (piva.full()) { paf0400f.set("P4_FISCIVAPAESE", stato); paf0400f.set("P4_FISCIVACOD", piva); } if (fisc.full()) paf0400f.set("P4_CODFISC", fisc); } else // Cliente EXTRA-EU sempre nel campo della partita iva sui paf { paf0400f.set("P4_FISCIVAPAESE", stato); if (fisc.full()) // Guardo prima l'id fiscale, perche' e' qui che dovrebbero stare in Campo paf0400f.set("P4_FISCIVACOD", fisc); else if (piva.full()) // Altrimenti dovrebbe essere nella partita iva paf0400f.set("P4_FISCIVACOD", piva); } if (cliente.fisica() && cliente.nome().full()) { 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().left(8)); paf0400f.set("P4_SEDECOMUNE", cliente.comune_residenza()); paf0400f.set("P4_SEDENAZ", cliente.stato_residenza_ISO()); // I clienti esteri possono avere CAP alfanumerici, li tolgo if (cliente.stato_residenza_ISO() != "IT") { paf0400f.set("P4_SEDECAP", "00000"); } else { paf0400f.set("P4_SEDECAP", cliente.CAP_residenza()); paf0400f.set("P4_SEDEPROV", cliente.provincia_residenza()); } // Titolo onorifico! if (_rec_clifo.vendite().get(CFV_TITOLO).full()) { paf0400f.set("P4_ANATITOLO", cache().get("TIT", _rec_clifo.vendite().get(CFV_TITOLO), "S0")); } paf0400f.set("P4_GESTIONE", stato_paf()); ok &= insert(paf0400f); // // TPaf_record& paf0700f = _paf_container.get_paf("PAF0700F"); paf0700f.set("P7_TIPODOC", tipo_doc_sdi(doc)); paf0700f.set("P7_DIVISA", "EUR"); // Fisso su euro in quanto effettuiamo il cambio TDate data = doc.data(); paf0700f.set("P7_DATA", doc.data()); paf0700f.set("P7_NUMERO", complete_num_fp(doc.codice_numerazione(), doc.numero())); paf0700f.set("P7_GESTIONE", stato_paf()); // if (doc.bolli_esenti_dovuti()) { const real bolli_es = ini_get_real(CONFIG_STUDIO, "ve", "BOLLIES"); paf0700f.set("P7_NUMEROBOLLO", "SI"); paf0700f.set("P7_IMPORTOBOLLO", converti_prezzo(bolli_es)); } // // // Non la mettiamo! // // Non inserisco pi adesso il paf0700f ma lo faccio alla fine (per inserire le ritenute) /* * Lo sconto in testata stato disabilitato in quanto su Campo influenza solo le righe merci mentre dovrebbe modificare tutte le righe */ // TPaf_record& paf2700f = _paf_container.get_paf("PAF2700F"); // Disabilitata la scrittura del totale del documento, questo causa problemi se presente uno sconto in testata e l'addebito del bollo. // Campo calcola prima il totale, poi lo sconta e ci applica il bollo mentre lo SDI sconta a bollo gi applicato. paf2700f.set("PQ_IMPTOTDOC", doc.totale_doc()); const TRectype& cont_conv_off = cco(doc); if (_has_cust) { TPaf_record& paf3400f = _paf_container.get_paf("PAF3400F"); reset(paf3400f); cached_custom_fp().get_custom(doc).load_caus_paf(paf3400f, doc, *this); } else { 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", stato_paf()); ok &= insert(paf2700f); // if ((doc.is_nota_credito() || get_send_all_rifs()) && doc.get(DOC_NUMDOCRIF).full()) { TPaf_record& paf1000f = _paf_container.get_paf("PAF1000F"); reset(paf1000f); paf1000f.set("P0_IDDOC", doc.get(DOC_NUMDOCRIF)); paf1000f.set("P0_DATADOC", doc.get_date(DOC_DATADOCRIF)); ok &= insert(paf1000f); } // // // Azzera DDT TPaf_record& paf1600f = _paf_container.get_paf("PAF1600F"); // Fuori dallo scope per dopo const TString16 cup = doc.get(DOC_CUP); const TString16 cig = doc.get(DOC_CIG); // Codice commessa, spostato nel campo S5 di TABCOM TString80 com = cco(doc).get("S5"); // Se una commessa della sanit bisogna aggiungere un cancelletto davanti e dietro if (cco(doc).get_bool("B0")) { com.add_front_and_back("#"); } //SCONTO IN FATTURA const real sconto_in_fat = doc.get_real(DOC_SCONTOFATT); if (sconto_in_fat > ZERO) { TPaf_record& paf0900f = _paf_container.get_paf("PAF0900F"); reset(paf0900f); paf0900f.set("P9_RIFNUMLINEA", (real)linea_sconto++); paf0900f.set("P9_TIPOSCONTO", "SC"); paf0900f.set("P9_IMPSCONTO", sconto_in_fat); paf0900f.set("P9_GESTIONE", stato_paf()); ok &= insert(paf0900f); } // SEMPRE // Azzera ordini TPaf_record& paf1000f = _paf_container.get_paf("PAF1000F"); paf1000f.set("P0_RIFNUMLINEA", 0L); // Azzera contratti TPaf_record& paf1100f = _paf_container.get_paf("PAF1100F"); paf1100f.set("PA_RIFNUMLINEA", 0L); // Azzera convenzioni TPaf_record& paf1200f = _paf_container.get_paf("PAF1200F"); paf1200f.set("PB_RIFNUMLINEA", 0L); // Azzera Ricezione TPaf_record& paf1300f = _paf_container.get_paf("PAF1300F"); paf1300f.set("PC_RIFNUMLINEA", 0L); // Azzera Fatture Collegate TPaf_record& paf1400f = _paf_container.get_paf("PAF1400F"); paf1400f.set("PD_RIFNUMLINEA", 0L); 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_COMMESSACONV", com); paf1000f.set("P0_CODCUP", cup); paf1000f.set("P0_CODCIG", cig); ok &= insert(paf1000f); } 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); ok &= insert(paf1100f); } else if(tcon == 'V') { paf1200f.set("PB_RIFNUMLINEA", 0L); paf1200f.set("PB_IDDOC", con); paf1200f.set("PB_DATADOC", datadoc); paf1200f.set("PB_COMMCONVENZ", com); paf1200f.set("PB_CODCUP", cup); paf1200f.set("PB_CODCIG", cig); ok &= insert(paf1200f); } else if (tcon == 'R') { paf1300f.set("PC_RIFNUMLINEA", 0L); paf1300f.set("PC_IDDOC", con); paf1300f.set("PC_DATADOC", datadoc); paf1300f.set("PC_COMMCONVENZ", com); paf1300f.set("PC_CODCUP", cup); paf1300f.set("PC_CODCIG", cig); ok &= insert(paf1300f); } else if (tcon == 'F') { paf1400f.set("PD_RIFNUMLINEA", 0L); paf1400f.set("PD_IDDOC", con); paf1400f.set("PD_DATADOC", datadoc); paf1400f.set("PD_COMMCONVENZ", com); paf1400f.set("PD_CODCUP", cup); paf1400f.set("PD_CODCIG", cig); ok &= insert(paf1400f); } } if (_is_pa && cup.blank() && cig.blank()) _log.log(1, "CIG e CUP assenti"); // TPaf_record& paf1800f = _paf_container.get_paf("PAF1800F"); TPaf_record& paf2000f = _paf_container.get_paf("PAF2000F"); TPaf_record& paf2100f = _paf_container.get_paf("PAF2100F"); TPaf_record& paf1900f = _paf_container.get_paf("PAF1900F"); TPaf_record& paf3000f = _paf_container.get_paf("PAF3000F"); long riga = 1; bool f_buonocons = false; bool first_row = false; const bool riftesta = main_app().has_module(LVAUT, CHK_DONGLE) && ini_get_bool(CONFIG_DITTA, "lv", "RifTest"); map ancestors_s; TString riga_buoni_cons; TString temp; if (riftesta) { TString rifs = doc.get(DOC_NOTE); const int posret = rifs.find('\n'); if (posret > 0) rifs.cut(posret); rifs.replace(" - ", "|"); TToken_string patched_rifs; TToken_string rifs_token = rifs; FOR_EACH_STR_TOKEN(rifs_token, rif) { TToken_string boll_rif(rif, ' '); if(boll_rif.items()>2) { TToken_string work(boll_rif.get(0), ' '); TString data = boll_rif.get(1); data << boll_rif.get(2); work.add(data); boll_rif = work; } patched_rifs.add(boll_rif); } rifs = patched_rifs; rifs.trim(); if (rifs == "0") rifs.cut(0); int len = rifs.len(); if (len > 0) { long numlinea = 0; TToken_string elab_rifs(rifs); FOR_EACH_STR_TOKEN(elab_rifs, str) { TToken_string rif(str, ' '); // // reset(paf1600f); temp = rif.get(); paf1600f.set("PF_NUMDDDT", temp); temp = rif.get(); TDate dataddt(atoi(temp.left(2)), atoi(temp.mid(3, 2)), atoi(temp.right(2))); paf1600f.set("PF_DATADDT", dataddt); paf1600f.set("PF_GESTIONE", stato_paf()); ddt_linee.set(numlinea); paf1600f.set("PF_RIFNUMLINEA", numlinea++); ok &= insert(paf1600f); // } } } FOR_EACH_PHYSICAL_FPRDOC(doc, r, rdoc) { // Controllo la riga if (check_row(*rdoc) && !get_check_not_block()) return false; _idx_adg_doc_row = 1L; bool skip_riga = false; reset(paf1800f); paf1800f.set("PI_NUMEROLINEA", riga); const TString& descrizione_riga = descrizione(*rdoc); if (descrizione_riga.empty()) continue; if (!f_buonocons && descrizione_riga.starts_with("Buono di consegna")) { TString memo; memo << rdoc->get(RDOC_DESCR); if (rdoc->get_bool(RDOC_DESCLUNGA)) memo << rdoc->get(RDOC_DESCEST); riga_buoni_cons = memo; f_buonocons = true; first_row = r == 0; continue; } reset(paf3000f); paf3000f.set("PT_RIFNUMLINEA", riga); paf3000f.set("PT_COMMENTO", descrizione_riga); // if (rdoc->is_articolo()) ok &= export_info_articolo(rdoc, paf1900f, paf2100f, riga, r); // if (rdoc->is_descrizione()) { paf1800f.set("PI_QUANTITA", UNO); paf1800f.set("PI_PREZZOUNIT", ZERO); paf1800f.set("PI_PRZTOTALE", ZERO); set_IVA(_codivadefault, paf1800f); } else if (rdoc->is_merce()) { if (rdoc->get(RDOC_QTA).is_zero()) { TString msg; msg.format("La riga merce %d ha quantit nulla", riga); _log.log(1, msg); } set_qta_prezzo(paf1800f, rdoc); if (rdoc->iva().codice().empty()) { set_IVA(_codivadefault, paf1800f); } else set_IVA(*rdoc, paf1800f); /* * Ogni riga si pu rifare a un DDT/Ordine diverso, per questo devo inserire i dati da qua e non in testata */ if (!riftesta) { TArray ancestors; find_ancestors(*rdoc, ancestors); for (int i = ancestors.last(); i > 0; i = ancestors.pred(i)) { _has_bolla |= true; const TAncestor& a = dynamic_cast(ancestors[i]); ancestors_s.insert({ a.numdoc(), a.datadoc() }); // Per i buoni di consegna lavanderie if (i == 1) { // reset(paf1600f); ddt_linee.set(r); paf1600f.set("PF_RIFNUMLINEA", riga); paf1600f.set("PF_NUMDDDT", a.numdoc()); paf1600f.set("PF_DATADDT", a.datadoc()); paf1600f.set("PF_GESTIONE", stato_paf()); ok &= insert(paf1600f); // } else if (i == 3) { // paf1000f.set("P0_KEYHEADERFATT", _hfatt); paf1000f.set("P0_KEYBODYFATT", _bfatt); paf1000f.set("P0_RIFNUMLINEA", riga); paf1000f.set("P0_IDDOC", a.numdoc()); paf1000f.set("P0_DATADOC", a.datadoc()); paf1000f.set("P0_COMMESSACONV", com); paf1000f.set("P0_CODCUP", cup); paf1000f.set("P0_CODCIG", cig); paf1000f.set("P0_GESTIONE", stato_paf()); ok &= insert(paf1000f); // } } } } else if (rdoc->is_spese()) { const TSpesa_prest& sp = rdoc->spesa(); // Controllo se ha la cassa professionale lo metto in testata if (sp.cassa_previdenziale().full()) { ok &= add_cassa_previdenziale(*rdoc); skip_riga = true; } // Altrimenti lo metto in riga else { const real imp = rdoc->imponibile(false); real qta = rdoc->quantita(); // bool qta_inverse = false; real prz = imp; if (qta != UNO) { prz = rdoc->prezzo(_nascondi_sconti_righe_fatt, false); if (prz.is_zero() && !imp.is_zero()) { const TPrice price(imp / qta); prz = price.get_value(); } } 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, static_cast(rdoc->field_qta())); _log.log(1, msg); qta = UNO; } if (qta < ZERO) { qta = -qta; prz = -prz; } paf1800f.set("PI_QUANTITA", qta); } paf1800f.set("PI_PREZZOUNIT", converti_prezzo(prz)); paf1800f.set("PI_PRZTOTALE", converti_prezzo(imp)); set_IVA(*rdoc, paf1800f); // Controllo se una ritenuta fiscale if (sp.tipo_ritenuta() == 'F') { paf1800f.set("PI_RITENUTA", "SI"); // Todo: modifica nuovo tracciato xml: si possono aggiungere piu' casse prev. la prima sempre sul paf07, le altre sulla nuova tab paf35. add_ritenuta(*rdoc, paf0700f); } } } else if (rdoc->is_prestazione()) { real qta = rdoc->get_real(RDOC_QTA); if (qta.is_zero()) qta = UNO; set_qta_prezzo(paf1800f, rdoc); set_IVA(*rdoc, paf1800f); } else if (rdoc->is_sconto() || rdoc->is_sconto_perc()) { TString msg; msg << "Il documento " << doc.codice_numerazione().codice() << " " << doc.tipo().codice() << " " << doc.numero() << " presenta una o pi righe di tipo sconto o sconto percentuale.\n" \ "Esportazione impossibile"; _log.log(2, msg); return false; } else if (rdoc->is_omaggio()) { if (rdoc->get(RDOC_QTA).is_zero()) { TString msg; msg.format("La riga omaggi %d ha quantità nulla", riga); _log.log(1, msg); } paf1800f.set("PI_TIPOCESSPREST", "AB"); set_qta_prezzo(paf1800f, rdoc); set_IVA(*rdoc, paf1800f); reset(paf2100f); paf2100f.set("PK_KEYNLINEA", riga); paf2100f.set("PK_KEYNLINAR", _idx_adg_doc_row++); paf2100f.set("PK_TIPODATO", "AswTRiga"); if (rdoc->get_bool(RDOC_ADDIVA)) { paf2100f.set("PK_RIFDATO", "Omaggio con rivalsa"); // Metto i dati come si trattasse di una riga normalissima paf1800f.set("PI_UNITAMISURA", rdoc->get(RDOC_UMQTA)); paf1800f.set("PI_QUANTITA", rdoc->get_real(RDOC_QTA).string(0)); paf1800f.set("PI_PREZZOUNIT", converti_prezzo(rdoc->prezzo(false, false))); paf1800f.set("PI_PRZTOTALE", converti_prezzo(rdoc->prezzo(false, false) * rdoc->get_real(RDOC_QTA))); TRiepilogo_agg& riepilogo_agg = _riepilogo_agg[rdoc->iva().codice()]; riepilogo_agg.imponibile += rdoc->imponibile_omaggio(2); paf1800f.set("PI_GESTIONE", stato_paf()); ok &= insert(paf1800f) && insert(paf3000f); reset(paf1800f); paf1800f.set("PI_NUMEROLINEA", ++riga); reset(paf3000f); paf3000f.set("PT_RIFNUMLINEA", riga); paf3000f.set("PT_COMMENTO", descrizione_riga); set_qta_prezzo(paf1800f, rdoc); paf1800f.set("PI_UNITAMISURA", rdoc->get(RDOC_UMQTA)); paf1800f.set("PI_QUANTITA", rdoc->get_real(RDOC_QTA).string(0)); paf1800f.set("PI_PREZZOUNIT", converti_prezzo(-rdoc->prezzo(false, false))); const real imponibile = converti_prezzo(-rdoc->prezzo(false, false) * rdoc->get_real(RDOC_QTA)); paf1800f.set("PI_PRZTOTALE", imponibile); const TCodiceIVA & iva_storno = cached_codIVA(ini_get_string(CONFIG_DITTA, "VE", "IVASTO")); paf1800f.set("PI_ALIQUOTAIVA", "0.00"); paf1800f.set("PI_NATURA", iva_storno.natura()); ok &= insert(paf2100f); if (rdoc->is_articolo()) { ok &= insert(paf1900f); ok &= insert(paf2100f); reset(paf1900f); ok &= export_info_articolo(rdoc, paf1900f, paf2100f, riga, r); } TPaf_record& paf2200f = _paf_container.get_paf("PAF2200F"); add_riepilogo_iva(paf2200f, iva_storno, get_esigibilita_iva(doc), imponibile, ZERO); reset(paf2100f); paf2100f.set("PK_KEYNLINEA", riga); paf2100f.set("PK_KEYNLINAR", _idx_adg_doc_row++); paf2100f.set("PK_TIPODATO", "AswCodIva"); paf2100f.set("PK_RIFDATO", "Fuori campo IVA"); ok &= insert(paf2100f); reset(paf2100f); paf2100f.set("PK_KEYNLINEA", riga); paf2100f.set("PK_KEYNLINAR", _idx_adg_doc_row++); paf2100f.set("PK_TIPODATO", "AswTRiga"); paf2100f.set("PK_RIFDATO", "Storno omaggio"); ok &= insert(paf2100f); reset(paf2100f); paf2100f.set("PK_KEYNLINEA", riga); paf2100f.set("PK_KEYNLINAR", _idx_adg_doc_row++); paf2100f.set("PK_TIPODATO", "AswRifRiga"); TString descstorno("Storno omaggio "); descstorno << riga - 1; paf2100f.set("PK_RIFDATO", descstorno); } else { paf2100f.set("PK_RIFDATO", "Omaggio senza rivalsa"); // Aggiungo uno sconto paf2000f.set("PJ_KEYNLINEA", riga); paf2000f.set("PJ_KEYNLINAR", 1L); paf2000f.set("PJ_TIPOSCONTO", "SC"); // Applico uno sconto del 100% portando l'importo a zero paf2000f.set("PJ_PERCSCONTO", CENTO); paf1800f.set("PI_PRZTOTALE", ZERO); paf2000f.set("PJ_GESTIONE", stato_paf()); ok &= insert(paf2000f); } ok &= insert(paf2100f); } else // Salto tutte le altre righe continue; // TString80 sconto_expr = rdoc->get(RDOC_SCONTO); TToken_string sconti; if (!_nascondi_sconti_righe_fatt && 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", riga); paf2000f.set("PJ_KEYNLINAR", ++nlin_sconto); if (perc > ZERO) { paf2000f.set("PJ_TIPOSCONTO", "SC"); paf2000f.set("PJ_PERCSCONTO", perc); } else { paf2000f.set("PJ_TIPOSCONTO", "MG"); paf2000f.set("PJ_PERCSCONTO", -perc); } paf2000f.set("PJ_GESTIONE", stato_paf()); ok &= insert(paf2000f); } } } // if (!skip_riga) { if (_has_cust) { cached_custom_fp().get_custom(doc).load_adg_paf(paf2100f, *rdoc, *this, riga); } paf1800f.set("PI_GESTIONE", stato_paf()); ok &= insert(paf1800f) && insert(paf3000f); riga++; } } /* Se ho una fattura che deriva dalla fatturazione differita delle lavanderie prendo * dalla relativa riga descrizione tutti i riferimenti alle bolle che mancano */ if (!riftesta && f_buonocons) { TString& memo = riga_buoni_cons; if (memo.full()) { map buoni; fill_buoni(buoni, memo, !first_row); long rifnumlinea = 0; FOR_EACH_BUONI(buoni, n, buono) { if (!buono->already_exist(ancestors_s)) { reset(paf1600f); paf1600f.set("PF_NUMDDDT", buono->_numdoc); paf1600f.set("PF_DATADDT", buono->_datadoc); while (ddt_linee[rifnumlinea]) rifnumlinea++; ddt_linee.set(rifnumlinea); paf1600f.set("PF_RIFNUMLINEA", rifnumlinea++); paf1600f.set("PF_GESTIONE", stato_paf()); ok &= insert(paf1600f); } } f_buonocons = true; } } // Controllo plafond // Riga esenzione? if (doc.is_fattura()) { doc.set_riga_esenzione(); if (doc.ha_riga_esenzione()) { const TRiga_documento& riga_es = doc.get_riga_esenzione(); reset(paf1800f); paf1800f.set("PI_NUMEROLINEA", riga); reset(paf3000f); paf3000f.set("PT_RIFNUMLINEA", riga); paf3000f.set("PT_COMMENTO", "Informazioni documento"); paf1800f.set("PI_QUANTITA", UNO); paf1800f.set("PI_PREZZOUNIT", ZERO); paf1800f.set("PI_PRZTOTALE", ZERO); set_IVA(_codivadefault, paf1800f); ok &= insert(paf1800f) && insert(paf3000f); TToken_string le_plafs(doc.get("PLAFOND"), ','); const TLi_manager & plaf = doc.plafond(); TString protinf; TString protins; TDate dataprot; TString rif; TString descr; bool to_print; bool add_date; real utilizzo; for (int i = plaf.get_plafond_row(doc, protinf, protins, dataprot, utilizzo, rif, descr, to_print, add_date); i >= 0; i = plaf.get_plafond_row(doc, protinf, protins, dataprot, utilizzo, rif, descr, to_print, add_date, i)) { TString dichiar(protinf); dichiar << "-" << protins; reset(paf2100f); paf2100f.set("PK_KEYNLINEA", static_cast(riga)); paf2100f.set("PK_KEYNLINAR", _idx_adg_doc_row++); paf2100f.set("PK_TIPODATO", "INTENTO"); paf2100f.set("PK_RIFDATO", dichiar); paf2100f.set("PK_RIFDATA", dataprot); ok &= insert(paf2100f); } riga++; } } if (sconto_in_fat > ZERO) { reset(paf2100f); paf2100f.set("PK_KEYNLINAR", _idx_adg_doc_row++); paf2100f.set("PK_TIPODATO", "Sconto"); //DA CAPIRE COSA METTERCI paf2100f.set("PK_RIFDATO", "Sconto in base all articolo 121 del dl 34 del 2020"); ok &= insert(paf2100f); } // Se il bollo va fatto pagare bisogna aggiungere una riga! const real importo_bolli = doc.get_real(DOC_BOLLI); if (doc.get_bool(DOC_ADDBOLLI) && importo_bolli > ZERO) { reset(paf1800f); paf1800f.set("PI_NUMEROLINEA", riga); reset(paf3000f); paf3000f.set("PT_RIFNUMLINEA", riga); paf3000f.set("PT_COMMENTO", "Imposta di bollo assolta virtualmente ai sensi dell'art. 6 D.M. 17.6.2014"); paf1800f.set("PI_QUANTITA", UNO); paf1800f.set("PI_PREZZOUNIT", converti_prezzo(importo_bolli)); paf1800f.set("PI_PRZTOTALE", converti_prezzo(importo_bolli)); set_IVA(doc.codiva_bolli(), paf1800f); ok &= insert(paf1800f) && insert(paf3000f); riga++; } // OMAGGI???? // Aggiungo le spese incasso if (doc.get_real("SPESINC") > ZERO) { reset(paf1800f); paf1800f.set("PI_NUMEROLINEA", riga); reset(paf3000f); paf3000f.set("PT_RIFNUMLINEA", riga); paf3000f.set("PT_COMMENTO", "Spese incasso"); paf1800f.set("PI_QUANTITA", UNO); real imponibile = doc.imponibile(); paf1800f.set("PI_PREZZOUNIT", converti_prezzo(doc.spese_incasso(imponibile, AUTO_DECIMALS, _netto))); paf1800f.set("PI_PRZTOTALE", converti_prezzo(doc.spese_incasso(imponibile, AUTO_DECIMALS, _netto))); set_IVA(ini_get_string(CONFIG_DITTA, "ve", "SPINCODIVA"), paf1800f); ok &= insert(paf1800f) && insert(paf3000f); riga++; } // Conai assolto if (doc.clifor().vendite().get_bool("CONAIASS")) { reset(paf1800f); paf1800f.set("PI_NUMEROLINEA", riga); reset(paf3000f); paf3000f.set("PT_RIFNUMLINEA", riga); paf3000f.set("PT_COMMENTO", _conai_str); paf1800f.set("PI_QUANTITA", UNO); paf1800f.set("PI_PREZZOUNIT", ZERO); paf1800f.set("PI_PRZTOTALE", ZERO); set_IVA(_codivadefault, paf1800f); ok &= insert(paf1800f) && insert(paf3000f); riga++; } // Riga sconto di testata // Se presente uno sconto in testata devo sottrarlo come riga sconto o lo SDI urla if (doc.get(DOC_SCONTOPERC).full() && doc.get(DOC_SCONTOPERC) != "0") { TAssoc_array& tiva = doc.tabella_iva(false); FOR_EACH_ASSOC_OBJECT(tiva, obj, key, itm) { const TRiepilogo_iva& riva = *dynamic_cast(itm); reset(paf1800f); paf1800f.set("PI_NUMEROLINEA", riga); reset(paf3000f); paf3000f.set("PT_RIFNUMLINEA", riga); paf1800f.set("PI_TIPOCESSPREST", "AB"); TString msg = "Riga sconto merci in testata "; if (riva.cod_iva().percentuale() > ZERO) msg << riva.cod_iva().percentuale() << "%"; else msg << riva.cod_iva().codice(); paf3000f.set("PT_COMMENTO", msg); paf1800f.set("PI_QUANTITA", UNO); paf1800f.set("PI_PREZZOUNIT", -abs(riva.sconto_perc())); paf1800f.set("PI_PRZTOTALE", -abs(riva.sconto_perc())); set_IVA(riva.cod_iva().codice(), paf1800f); ok &= insert(paf1800f) && insert(paf3000f); riga++; } } const TString& nota_piede_fatt = _riga_npf.get_nota_piede(doc.tipo().codice()); if (nota_piede_fatt.full()) { reset(paf1800f); paf1800f.set("PI_NUMEROLINEA", riga); reset(paf3000f); paf3000f.set("PT_RIFNUMLINEA", riga); paf3000f.set("PT_COMMENTO", nota_piede_fatt.left(900)); paf1800f.set("PI_QUANTITA", UNO); paf1800f.set("PI_PREZZOUNIT", ZERO); paf1800f.set("PI_PRZTOTALE", ZERO); set_IVA(_codivadefault, paf1800f); ok &= insert(paf1800f) && insert(paf3000f); riga++; } // Se dopo tutto ha ancora delle righe di altri dati gestionali che vanno messi a parte if (_has_cust && cached_custom_fp().get_custom(doc).has_adg_split()) { reset(paf1800f); paf1800f.set("PI_NUMEROLINEA", riga); reset(paf3000f); paf3000f.set("PT_RIFNUMLINEA", riga); paf3000f.set("PT_COMMENTO", "Riga altri dati gestionali"); paf1800f.set("PI_QUANTITA", UNO); paf1800f.set("PI_PREZZOUNIT", ZERO); paf1800f.set("PI_PRZTOTALE", ZERO); set_IVA(_codivadefault, paf1800f); // Resetto il contatore _idx_adg_doc_row = 1L; ok &= cached_custom_fp().get_custom(doc).load_adg_paf(paf2100f, doc[1], *this, riga, true); if (_idx_adg_doc_row > 1L) ok &= insert(paf1800f) && insert(paf3000f); riga++; } // // // Metto qua i dati DDT per capire se la fattura accompagnatoria o deriva da bolla TPaf_record& paf1700f = _paf_container.get_paf("PAF1700F"); if (doc.get("CODVETT1").full() && !_has_bolla) { TRectype vet = cache().get("%VET", doc.get("CODVETT1")); const TString4 statopiva = vet.get("S3").mid(49, 2); const TString piva = vet.get("S3").mid(20, 28); const TString codfisc = vet.get("S13").mid(28, 16); if (piva.empty() && codfisc.empty()) { TString msg = "Il vettore "; msg << vet.get("S0").mid(0, 50) << " non ha n codice fiscale n partita IVA, la fattura " << doc.anno() << " " << doc.codice_numerazione().codice() << " " << doc.numero() << " non pu essere trasmessa"; _log.log(3, msg); } if (piva.full()) { paf1700f.set("PG_FISCIVAPAESE", statopiva.full() ? statopiva : "IT"); paf1700f.set("PG_FISCIVACODICE", piva); } paf1700f.set("PG_CODICEFISCALE", codfisc); if (vet.get_bool("B0")) { paf1700f.set("PG_ANANOME", vet.get("S0").mid(0, 30)); paf1700f.set("PG_ANACOGNOME", vet.get("S0").mid(30, 20)); } else paf1700f.set("PG_ANADENOMINAZ", vet.get("S0").mid(0, 50)); paf1700f.set("PG_ANACODEORI", vet.get("S2").mid(0, 17)); ok &= insert(paf1700f); } // // Salvo la testata ok &= insert(paf0700f); // TPaf_record& paf2200f = _paf_container.get_paf("PAF2200F"); const char * eiva = get_esigibilita_iva(doc); long num_riep = 0; TAssoc_array& tiva = doc.tabella_iva(false); for (TObject* itm = tiva.first_item(); itm != nullptr; itm = tiva.succ_item()) { const TRiepilogo_iva& riva = *dynamic_cast(itm); if (!check_riepilogo(doc, riva) && !get_check_not_block()) return false; add_riepilogo_iva(paf2200f, riva.cod_iva(), eiva, riva.imponibile(), riva.imposta()); } if (!_riepilogo_agg.empty()) { for (auto i = _riepilogo_agg.begin(); i != _riepilogo_agg.end(); ++i) { const TCodiceIVA cod_iva(i->first); add_riepilogo_iva(paf2200f, cod_iva, eiva); } } // // TPaf_record& paf2400f = _paf_container.get_paf("PAF2400F"); TPagamento& pag = doc.pagamento(); doc.scadenze_recalc(); // Ricalcola array delle rate TString_array& scad = doc.scadenze(); const char* rateazione = pag.cond_pag_sdi(); // A rate (TP01) o una soluzione(TP02)? paf2400f.set("PN_RIGA", ZERO); // Al momento non gestiamo pi tipologie di pagamento per documento paf2400f.set("PN_CONDPAGAMENTO", rateazione); paf2400f.set("PN_GESTIONE", stato_paf()); ok &= insert(paf2400f); TPaf_record& paf2500f = _paf_container.get_paf("PAF2500F"); // 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 TRectype cod_pag = cache().get("CPG", doc.pagamento().code()); const int tipo_pag = cod_pag.get_int("S4"); 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 (tipo_pag == 3 && cab.blank()) // Ricevuta bancaria _log.log(2, TR("Non sono presenti ABI, CAB, IBAN per il pagamento")); if ((tipo_pag == 8 || tipo_pag == 9) && iban.blank()) // R.I.D. o Bonifico { _log.log(1, TR("Non presente il codice IBAN per il pagamento")); } for (int nr = 0; nr < scad.items(); nr++) { paf2500f.set("PO_RIGA", long(nr + 1)); // Numero rata const int rp = nr < pag.n_rate() ? nr : 0; static TString key_class; key_class.cut(0) << pag.tipo_rata(rp) << pag.ulc_rata(rp); paf2500f.set("PO_MODALITAPAGAM", cache().get("%CLR", key_class, "S12")); // Si assicura che il numero riga sia accettabile TToken_string& riga_scadenze = scad.row(nr); // Data|Importo paf2500f.set("PO_DATASCADENZA", TDate(riga_scadenze.get(0))); // Data scadenza paf2500f.set("PO_IMPORTO", converti_prezzo(real(riga_scadenze.get()))); // Importo rata paf2500f.set("PO_GESTIONE", stato_paf()); ok &= insert(paf2500f); } // if (_gestioneallegati) { TPaf_record& paf2600f = _paf_container.get_paf("PAF2600F"); long nprogr = 0; // Numero di file allegati // Se abilitato stampo il documento e lo allego TFilename rep; if (_allegafattura) { if (!dongle().active(RSAUT)) { _log.log(1, "Impossibile generare la fattura, il modulo RS non abilitato!"); } else if (!doc.tipo().main_print_profile(rep, 2)) { _log.log(1, "Impossibile generare la fattura, non disponibile un profilo di stampa per questo tipo documento!"); } else { //ve1 -2 {CODNUM} {ANNO} {PROVV} {NDOC}(-{ANDOC}) {TIPO_ELABORAZIONE} {TIPO_STAMPA} {NUM_COPIE} {ARCHIVIAZIONE} // Costruisco la chiamata static TString commandline; commandline.cut(0) << "ve1 -2 " << doc.get(DOC_CODNUM) << ' ' << doc.get(DOC_ANNO) << ' ' << doc.get(DOC_PROVV) << ' ' << doc.get(DOC_NDOC) << " X P 1 D"; // X: stampa su disco, P: provvisorio, 1: 1 copia, D: disabilita archiviazione TExternal_app interattivo(commandline); if (interattivo.run() != NOERR) { TString msgerr = "Fallita generazione PDF documento "; msgerr << doc.get(DOC_CODNUM) << ' ' << doc.get(DOC_ANNO) << ' ' << doc.get(DOC_PROVV) << ' ' << doc.get(DOC_NDOC); error_box(msgerr); } else { TFilename pdf; pdf.tempdir(); pdf << SLASH << doc.get(DOC_ANNO) << '_' << doc.get(DOC_CODNUM) << '_' << doc.get(DOC_NDOC) << ".pdf"; if (!pdf.exist() && !yesno_box("Attenzione! Non stato possibile creare il pdf, continuare?")) { return false; } if (!add_row_alleg(pdf, nprogr, paf2600f)) return false; } } TToken_string allegati(doc.get("COLL_GOLEM"), '\n'); bool load_allegati = true; if (allegati.full()) { if (_def_fld.empty()) { TString msgerr; msgerr << "Errore: il documento " << _bfatt << " ha degli allegati ma nella configurazione non stato impostato come trametterli\nCaricare il documento senza allegati?"; load_allegati = false; if (!yesno_box(msgerr)) return false; } else { TFilename fname; FOR_EACH_TOKEN(allegati, row) { const TToken_string entry(row); if (entry.get(0, fname) && fname.exist()) { if (!add_row_alleg(fname, nprogr, paf2600f)) return false; } } } } } } // Tabella di non invio XML TPaf_record& pafw300f = _paf_container.get_paf("PAFW300F"); pafw300f.set("PW_TIPODOC", tipo_doc_sdi(doc)); pafw300f.set("PW_TIPONUM", doc.codice_numerazione().codice()); pafw300f.set("PW_NUMERO", doc.numero()); pafw300f.set("PW_DATA", doc.data()); if (!cached_tipodoc(doc.get(DOC_TIPODOC)).invio_xml() || doc.noinvioxml()) { pafw300f.set("PW_CODSDI", "**********"); } pafw300f.set("PW_CDEST", _coddest); pafw300f.set("PW_RAGSOC", cliente.ragione_sociale().left(35)); pafw300f.set("PW_PAESE", cliente.stato_residenza_ISO()); pafw300f.set("PW_CODICE", cliente.codice_fiscale_estero()); pafw300f.set("PW_CFISCA", cliente.codice_fiscale()); pafw300f.set("PW_DENOM", cliente.ragione_sociale()); if (cliente.fisica() && cliente.nome().full()) { pafw300f.set("PW_NOME", cliente.nome()); pafw300f.set("PW_COGN", cliente.cognome()); } else pafw300f.set("PW_RAGSOC", cliente.ragione_sociale().left(35)); pafw300f.set("PW_IMPO", converti_prezzo(doc.totale_doc())); pafw300f.set("PW_UPAG", ""); ok &= insert(pafw300f); return _to_commit = (ok && save_paf()); } bool TDoc_fp::doc_to_paf(const TRectype& rec) { TDocumentoEsteso doc; if (doc.read(rec) == NOERR) { if (doc_to_paf(doc)) return fp_db().sq_commit(); fp_db().sq_rollback(); } return false; } bool TDoc_fp::doc_to_paf(const TDoc_key& key) { return doc_to_paf(key_to_doc(key)); } bool TDoc_fp::doc_to_paf(const TFilename& ini) { TConfig cfg(ini, "33"); const int anno = cfg.get_int(DOC_ANNO); const long ndoc = cfg.get_long(DOC_NDOC); const TFixed_string codnum(cfg.get(DOC_CODNUM)); // lascio sapientemente per ultima la get di una stringa const TDoc_key key(anno, codnum, ndoc); return doc_to_paf(key); } bool TDoc_fp::doc_to_paf() { return _doc_rec != nullptr ? doc_to_paf(*_doc_rec) : false; } TRectype& TDoc_fp::key_to_doc(const TDoc_key& key) { SAFE_DELETE(_doc_rec); SAFE_DELETE(_doc); _doc = new TDocumentoEsteso(key); _doc_rec = new TRectype(*_doc); return *_doc_rec; } TDoc_fp::TDoc_fp(bool provvisorio) : _doc(nullptr), _doc_rec(nullptr), _log(nullptr), _cache_insert(false) , _diagn(provvisorio) { _ditta.init(LF_NDITTE, prefix().get_codditta()); _cofi = get_cofi_tras(); const TDate data_inizio = get_date_start_new_fatt(); _tracciati_2021 = (data_inizio <= today); if (_cofi.blank()) _cofi = _ditta.codice_fiscale(); _gestioneallegati = get_gest_alleg(); _allegafattura = get_allega_fat(); _def_fld = get_fld_dest(); if (!_def_fld.ends_with("\\")) { _def_fld << "\\"; } _def_usr_fld = get_fld_dest_usr(); if (_def_usr_fld.empty()) { _def_usr_fld = _def_fld; } else if (!_def_usr_fld.ends_with("\\")) { _def_usr_fld << "\\"; } // Mi preparo la stringa del CONAI _conai_str = ini_get_string(CONFIG_DITTA, "ve", "DESCCONAIASS"); if (_conai_str.empty()) _conai_str = "Contributo CONAI assolto ove dovuto"; _nascondi_sconti_righe_fatt = get_no_sconti_fatt(); } TDoc_fp::~TDoc_fp() { commit(); if (_doc_rec != nullptr) delete _doc_rec; } /* /$$$$$$$$ /$$$$$$$ |__ $$__/| $$__ $$ | $$ | $$ \ $$ /$$$$$$ /$$$$$$ | $$ | $$$$$$$/ /$$__ $$ /$$__ $$ | $$ | $$__ $$| $$$$$$$$| $$ \ $$ | $$ | $$ \ $$| $$_____/| $$ | $$ | $$ | $$ | $$| $$$$$$$| $$$$$$$ |__/ |__/ |__/ \_______/ \____ $$ /$$ \ $$ | $$$$$$/ \______/ */ bool TReg_fp::insert(TPaf_record& p, bool force) { bool ok = true; if (_cache_insert) _query.add(p.insert_string()); else { ok = p.insert(force); if (!ok) { _log.log(2, fp_db().sq_get_token_text_error(1)); _log.log(2, p.insert_string()); } } return ok; } bool TReg_fp::remove(TPaf_record& p) { bool ok = true; if (_cache_insert) _query.add(p.remove_string()); else { ok = p.remove(); if (!ok) { _log.log(2, fp_db().sq_get_token_text_error(1)); _log.log(2, p.remove_string()); } } return ok; } bool TReg_fp::save_paf() { bool ok = true; if (_cache_insert) { TString query; FOR_EACH_ARRAY_ROW(_query, r, row) query << *row; ok = fp_db().sq_set_exec(query); if (!ok) { _log.log(2, fp_db().sq_get_token_text_error(1)); _log.log(2, query); } } return ok; } bool TReg_fp::check_initial(const TMovimento_contabile& mov) { const TCli_for & clifo = mov.clifo(); if (_coddest.len() != 6 && _coddest.len() != 7) { _log.log(1, "Il codice destinatario ha una lunghezza non conforme."); return false; } const int alleg = clifo.get_int(CLI_ALLEG); bool privato = (alleg == 5 || alleg == 9) && clifo.get(CLI_STATOCF).full(); if (clifo.get(CLI_PAIV).empty() && clifo.get(CLI_COFI).empty() && !privato) { _log.log(1, "Sia la partita IVA che il codice fiscale del cessionario committente sono vuoti, almeno uno dei due deve essere valorizzato."); return false; } TPartite_array par; par.add_numreg(mov.get_long(MOV_NUMREG)); //PROVVISORIO if (_tipo_doc_sdi != "TD28") { for (TPartita* p = par.first(); p != nullptr; p = par.next()) { int riga_p = p->prima_fattura(); if (riga_p >= 0) { const TRiga_partite& rp = p->riga(riga_p); for (int r = 0; r < rp.rate(); r++) { const TRiga_scadenze & rata = rp.rata(r); TString key_class; key_class << rata.get(SCAD_TIPOPAG) << rata.get(SCAD_ULTCLASS); if (cache().get("%CLR", key_class, "S12").empty()) { TString msg; msg.cut(0) << "Non e' valorizzata la tipologia di pagamento SDI (MPXX) per la condizione di pagamento " << mov.get(MOV_CODPAG); _log.log(1, msg); return false; } } } } } return true; } bool TReg_fp::check_row(const TMovimento_contabile& mov, int n_riga) { TRectype & riga_iva = ((TMovimento_contabile &)mov).iva(n_riga); const TCodiceIVA& codice_iva = cached_codIVA(riga_iva.get(RMI_CODIVA)); if (codice_iva.codice().full() && codice_iva.percentuale() == ZERO && natura(codice_iva.codice()).empty()) { TString msg; msg << "Impossibile avere la natura non valorizzata a fronte di una aliquota con percentuale zero. Codice IVA: "; msg << codice_iva.codice(); _log.log(1, msg); return false; } return true; } bool TReg_fp::initialize(const TMovimento_contabile& mov) { // Azzero _hfatt.cut(0); _bfatt.cut(0); // Paese del documento _paese = "IT"; if (!chiave_paf_mov(mov, _tipo_doc_sdi, _hfatt, _bfatt)) return false; // Preparo il log _log.log(-1, _bfatt); // Controllo se il documento almeno in stato di stampa _is_pa = mov.clifo().get_int("ALLEG") == 7; _pec = _ditta.pec(); if (_ditta.coddest().empty() && _pec.empty()) _coddest = "0000000"; else _coddest = _ditta.coddest(); _enapec = _coddest == "0000000" && _pec.full(); _privato = _coddest.len() != 6; // Azzero indici _idx_cassa_previdenziale = 1; // Controllo custom // _has_cust = cached_custom_fp().has_custom(doc); //DA VERIFICARE if (check_initial(mov) || get_check_not_block()) return _paf_container.clean_and_erase_paf(_hfatt, _bfatt); return false; } int TReg_fp::commit() { int r = 0; if (_to_commit) { // Controllo stato diagnosticato if (get_no_export_pronto() || !_definitivo) _log.log(2, "Le fatture sono state esportate in stato diagnosticato"); else _log.log(2, "Le fatture sono state esportate correttamente in stato pronto"); if (r >= 0 && fp_db().sq_commit()) r += 2; else { r = -1; _log.log(2, fp_db().sq_get_token_text_error(1)); } } _to_commit = false; return r; } int TReg_fp::force_commit() { _to_commit = true; return commit(); } const TString & TReg_fp::natura(const char* codiva) const { const TCodiceIVA iva(codiva); return get_tmp_string(4) = iva.natura(); } const char* TReg_fp::get_esigibilita_iva(const TMovimento_contabile& mov) { // Esigibilit IVA: Immediata, Differita, Split payment const char* eiva = "I"; if (mov.is_split_payment()) eiva = "S"; else if (mov.get_bool(MOV_LIQDIFF) || mov.get_bool(MOV_IVAXCASSA)) eiva = "D"; return eiva; } void TReg_fp::set_IVA(TString codiva, TPaf_record& paf) const { if (codiva.empty()) codiva = _codivadefault; // necessario il cast a real? paf.set("PI_ALIQUOTAIVA", static_cast(cache().get("%IVA", codiva, "R0"))); paf.set("PI_NATURA", natura(codiva)); } //???SERVE?????? bool TReg_fp::add_row_art(long& riga_art, const TString& codice_tipo, const TString& codice_valore, TPaf_record& paf) { paf.set("PY_KEYNLINAR", ++riga_art); paf.set("PY_TIPOARTICOLO", codice_tipo); paf.set("PY_VALOREARTICOLO", codice_valore); return insert(paf); } bool TReg_fp::add_row_alleg(TFilename& file, long& nprogr, TPaf_record& paf) { static TString dest_path; static TString dest_usr_path; bool ok = false; dest_path.cut(0) << _def_fld << file.name(); dest_usr_path.cut(0) << _def_usr_fld << file.name(); if (!fcopy(file, dest_usr_path)) { return yesno_box("Errore critico nel copiare il file %s, si desidera continuare?", file.name()); } // Provo a copiare il file paf.set("PP_NUMEROLINEA", ++nprogr); paf.set("PP_NOMEATTACHMENT", file.name()); paf.set("PP_ATTACHMENT", dest_path); file.upper(); // serve estensione maiuscola paf.set("PP_FMTATTACHMENT", file.ext()); ok = insert(paf); return ok; } bool TReg_fp::add_riepilogo_iva(const TMovimento_contabile & mov, int n_riga) { TPaf_record& paf2200f = _paf_container.get_paf("PAF2200F"); reset(paf2200f); const TRectype& rec_iva = mov.iva()[n_riga]; const TString16 cod_aliquota = rec_iva.get(RMI_CODIVA); const TCodiceIVA& cod_iva= cached_codIVA(cod_aliquota); const real aliquota = cod_iva.percentuale(); const real imponibile = rec_iva.get(RMI_IMPONIBILE); const real imposta = rec_iva.get(RMI_IMPOSTA); const char * eiva = get_esigibilita_iva(mov); TRiepilogo_agg& riepilogo_agg = _riepilogo_agg[cod_aliquota]; // Aliquota paf2200f.set("PL_ALIQUOTAIVA", aliquota); // Natura if (aliquota.is_zero()) paf2200f.set("PL_NATURA", natura(cod_aliquota)); // Imponibile paf2200f.set("PL_IMPONIBILE", (imponibile + riepilogo_agg.imponibile)); // Imposta paf2200f.set("PL_IMPOSTA", (imposta + riepilogo_agg.imposta)); // Esigibilit IVA paf2200f.set("PL_ESIGIVA", eiva); paf2200f.set("PL_RIFNORMATIVO", cod_iva.descrizione()); // Aggiorno il riepilogo IVA riepilogo_agg.imponibile += imponibile; riepilogo_agg.imposta += imposta; // Elimino l'oggetto _riepilogo_agg.erase(cod_aliquota); // Inserisco return insert(paf2200f); } bool TReg_fp::export_paf0100f() { // TPaf_record& paf0100f = _paf_container.get_paf("PAF0100F"); reset(paf0100f); paf0100f.set("P1_TRASMITTPAESE", _paese); paf0100f.set("P1_TRASMITTCOD", _cofi); paf0100f.set("P1_FMTTRASMISS", _privato ? "FPR12" : "FPA12"); //if(_tipo_doc_sdi != "TD28") paf0100f.set("P1_CODDEST", _coddest); TString80 tel; tel << get_firm().get(NDT_PTEL) << get_firm().get(NDT_TEL); paf0100f.set("P1_TELEFONO", tel); paf0100f.set("P1_MAIL", get_firm().get(NDT_MAIL)); const char* c = stato_paf(); paf0100f.set("P1_GESTIONE", stato_paf()); paf0100f.set("P1_ERRINT", ""); // return insert(paf0100f); } bool TReg_fp::export_paf3200f() { if (_enapec) { // TPaf_record& paf3200f = _paf_container.get_paf("PAF3200F"); reset(paf3200f); paf3200f.set("PU_PEC", _pec); // return insert(paf3200f); } return true; } TString TReg_fp::get_line_descr(TAnagrafica cli) { TString descr; TString16 tdsdi = _tipo_doc_sdi; bool estero_cee = cli.estero_CEE(); bool ita = cli.italiano(); if (tdsdi == "TD16") descr = "Integrazione fattura reverse charge interno"; else if (tdsdi == "TD17") { if (ita || estero_cee) descr = "Integrazione per acquisto servizi da estero"; else descr = "Autofattura per acquisto servizi da estero"; } else if (tdsdi == "TD18") descr = "Integrazione per acquisto beni intracomunitari"; else if (tdsdi == "TD19") { if (ita || estero_cee) descr = "Integrazione per acquisto beni ex art.17 c.2 DPR 633/72"; else descr = "Autofattura per acquisto beni ex art.17 c.2 DPR 633/72"; } else if (tdsdi == "TD20") descr = "Autofattura"; else if (tdsdi == "TD28") descr = "Fattura cartacea San Marino"; else error_box("Tipo documento non conforme"); return descr; } bool TReg_fp::reg_to_paf(const TMovimento_contabile& mov) { if (!initialize(mov)) return false; bool ok = true; ok &= export_paf0100f(); ok &= export_paf3200f(); // TPaf_record& paf0200f = _paf_container.get_paf("PAF0200F"); reset(paf0200f); const TAnagrafica& fornitore = mov.clifo().anagrafica(); if (!paf0200f.is_full()) { if (fornitore.partita_IVA().full()) { paf0200f.set("P2_FISCIVAPAESE", fornitore.stato_partita_IVA()); paf0200f.set("P2_FISCIVACOD", fornitore.partita_IVA()); } if (fornitore.estero_non_CEE() && fornitore.stato_residenza_ISO() != "SM") { paf0200f.set("P2_FISCIVAPAESE", fornitore.stato_partita_IVA()); paf0200f.set("P2_FISCIVACOD", fornitore.codice_fiscale()); paf0200f.set("P2_CODFISCALE", ""); } else { paf0200f.set("P2_CODFISCALE", fornitore.codice_fiscale()); } const bool df = _ditta.fisica(); if (_ditta.fisica()) { TString forn_n = fornitore.nome(); TString forn_c = fornitore.cognome(); paf0200f.set("P2_ANANOME", fornitore.nome()); paf0200f.set("P2_ANACOGNOME", fornitore.cognome()); } else { paf0200f.set("P2_ANADENOMIN", fornitore.ragione_sociale()); } paf0200f.set("P2_ANACODEORI", fornitore.cod_EORI()); paf0200f.set("P2_REGFISCALE", _regfisc); //TODO DA RF01 A RF09 // DatiSede paf0200f.set("P2_SEDEIND", fornitore.via_residenza()); paf0200f.set("P2_SEDENRCIVICO", fornitore.civico_residenza().left(8)); paf0200f.set("P2_SEDECOMUNE", fornitore.comune_residenza()); paf0200f.set("P2_SEDENAZ", fornitore.stato_residenza_ISO()); // I clienti esteri possono avere CAP alfanumerici, li tolgo if (fornitore.stato_residenza_ISO() != "IT") { int i = 0; //paf0200f.set("P2_SEDECAP", "0000"); } else { paf0200f.set("P2_SEDECAP", fornitore.CAP_residenza()); paf0200f.set("P2_SEDEPROV", fornitore.provincia_residenza()); } } ok &= insert(paf0200f); // TPaf_record& paf0400f = _paf_container.get_paf("PAF0400F"); reset(paf0400f); TString stato = _ditta.stato_partita_IVA(); TTable tab_codiso("%SCE"); tab_codiso.tab(); tab_codiso.put("CODTAB", stato); tab_codiso.read(); TString piva = _ditta.partita_IVA(); TString fisc = _ditta.codice_fiscale(); if (!stato.full()) stato = "IT"; if (tab_codiso.get_bool("B0") || stato == "IT") // Cliente EU { if (piva.full()) { if (piva.len() == 11 && (piva[0] == '8' || piva[0] == '9')) { fisc = piva; piva.cut(0); } } else if (fisc.full() && fisc.len() == 11 && (fisc[0] == '8' || fisc[0] == '9')) piva.cut(0); if (piva.full()) { paf0400f.set("P4_FISCIVAPAESE", stato); paf0400f.set("P4_FISCIVACOD", piva); } if (fisc.full()) paf0400f.set("P4_CODFISC", fisc); } else // Cliente EXTRA-EU sempre nel campo della partita iva sui paf { paf0400f.set("P4_FISCIVAPAESE", stato); if (fisc.full()) // Guardo prima l'id fiscale, perche' e' qui che dovrebbero stare in Campo paf0400f.set("P4_FISCIVACOD", fisc); else if (piva.full()) // Altrimenti dovrebbe essere nella partita iva paf0400f.set("P4_FISCIVACOD", piva); } if (_ditta.fisica() && _ditta.nome().full()) { paf0400f.set("P4_ANANOME", _ditta.nome()); paf0400f.set("P4_ANACOGNOME", _ditta.cognome()); } else { paf0400f.set("P4_ANADENOM", _ditta.ragione_sociale()); } // DatiSede paf0400f.set("P4_SEDEIND", _ditta.via_residenza()); paf0400f.set("P4_SEDENRCIVICO", _ditta.civico_residenza().left(8)); paf0400f.set("P4_SEDECAP", _ditta.CAP_residenza()); paf0400f.set("P4_SEDECOMUNE", _ditta.comune_residenza()); paf0400f.set("P4_SEDEPROV", _ditta.provincia_residenza()); paf0400f.set("P4_SEDENAZ", _ditta.stato_residenza_ISO()); // Titolo onorifico! const TString& titolo = (mov.clifo().vendite().get(CFV_TITOLO)); if (titolo.full()) paf0400f.set("P4_ANATITOLO", cache().get("TIT", titolo, "S0")); paf0400f.set("P4_GESTIONE", stato_paf()); ok &= insert(paf0400f); // TPaf_record& paf0700f = _paf_container.get_paf("PAF0700F"); reset(paf0700f); paf0700f.set("P7_TIPODOC", _tipo_doc_sdi); paf0700f.set("P7_DIVISA", "EUR"); // Fisso su euro in quanto effettuiamo il cambio if (_tipo_doc_sdi == "TD28") paf0700f.set("P7_DATA", mov.get_date(MOV_DATADOC)); //Se è un TD28 ci metto la data della fattura cartacea originale else paf0700f.set("P7_DATA", mov.get_date(MOV_DATAREG)); // sembra sempre la data di registrazione visto che è na data di ricezione TString numdoc = mov.get(MOV_NUMDOC); if (numdoc.blank()) numdoc = mov.get(MOV_PROTIVA); else { if (numdoc.len() > 20) numdoc = numdoc.mid(30); } const TCausale & caus = cached_causale(mov); const TString & prefisso = caus.reg().prefisso(); if (prefisso.full()) { numdoc.insert("/"); numdoc.insert(prefisso); } paf0700f.set("P7_NUMERO", numdoc); paf0700f.set("P7_GESTIONE", stato_paf()); TPaf_record& paf2700f = _paf_container.get_paf("PAF2700F"); reset(paf2700f); // Disabilitata la scrittura del totale del documento, questo causa problemi se presente uno sconto in testata e l'addebito del bollo. // Campo calcola prima il totale, poi lo sconta e ci applica il bollo mentre lo SDI sconta a bollo gi applicato. paf2700f.set("PQ_IMPTOTDOC", mov.get(MOV_TOTDOC)); paf2700f.set("PQ_GESTIONE", stato_paf()); ok &= insert(paf2700f); // // paf1400 Dati fatture collegate TPaf_record& paf1400f = _paf_container.get_paf("PAF1400F"); reset(paf1400f); TString idsdi = mov.get(MOV_IDDOCSDI); TDate datasdi = mov.get_date(MOV_DATADOCSDI); if (idsdi.blank()) { const long nregcoll = mov.get_long(MOV_MOVCOLL); if (nregcoll > 0L) { const TRectype& movcoll = cache().get(LF_MOV, nregcoll); idsdi = movcoll.get(MOV_IDDOCSDI); datasdi = movcoll.get_date(MOV_DATADOCSDI); } } if (idsdi.blank()) { idsdi = mov.get(MOV_NUMDOC); datasdi = mov.get_date(MOV_DATADOC); } paf1400f.set("PD_IDDOC", idsdi); paf1400f.set("PD_DATADOC", datasdi); ok &= insert(paf1400f); // // Azzera DDT TPaf_record& paf1600f = _paf_container.get_paf("PAF1600F"); reset(paf1600f); // SEMPRE // TPaf_record& paf1800f = _paf_container.get_paf("PAF1800F"); TPaf_record& paf2000f = _paf_container.get_paf("PAF2000F"); TPaf_record& paf2100f = _paf_container.get_paf("PAF2100F"); TPaf_record& paf3000f = _paf_container.get_paf("PAF3000F"); reset(paf1800f); reset(paf2000f); reset(paf2100f); reset(paf3000f); int n_righe_iva = mov.iva().rows(); TString descr = get_line_descr(fornitore); for (int i = 1; i <= n_righe_iva; i++) { const TRectype& rec_iva = mov.iva()[i]; const TString16 cod_aliquota = rec_iva.get(RMI_CODIVA); const TCodiceIVA& cod_iva = cached_codIVA(cod_aliquota); const real aliquota = cod_iva.percentuale(); paf1800f.set("PI_NUMEROLINEA", (long)i); paf1800f.set("PI_DESCRIZIONE", descr); paf1800f.set("PI_QUANTITA", 1l); paf1800f.set("PI_PREZZOUNIT", rec_iva.get(RMI_IMPONIBILE)); paf1800f.set("PI_PRZTOTALE", rec_iva.get(RMI_IMPONIBILE)); paf1800f.set("PI_ALIQUOTAIVA", aliquota); if (aliquota.is_zero()) paf1800f.set("PI_NATURA", natura(cod_aliquota)); paf1800f.set("PI_GESTIONE", stato_paf()); paf1800f.set("PI_ERRINT", ""); paf1800f.set("PI_ERREST", ""); ok &= insert(paf1800f); add_riepilogo_iva(mov, i); paf3000f.set("PT_RIFNUMLINEA", (long)i); paf3000f.set("PT_COMMENTO", "");//TODO COSA DOBBIAMO METTERE NELLA DESCRIZIONE IVA CHE NON C'è // if (ok) ok &= insert(paf3000f); if (ok) ok &= insert(paf0700f); } // Tabella di non invio XML TPaf_record& pafw300f = _paf_container.get_paf("PAFW300F"); reset(pafw300f); pafw300f.set("PW_TIPODOC", _tipo_doc_sdi); pafw300f.set("PW_TIPONUM", caus.reg().name()); //TODO COSA CI METTIAMO NEL TIPO NUM ava pafw300f.set("PW_NUMERO", mov.get(MOV_NUMDOC)); pafw300f.set("PW_DATA", mov.get_date(MOV_DATADOC)); pafw300f.set("PW_CDEST", _coddest); //CHECKARE pafw300f.set("PW_RAGSOC", fornitore.ragione_sociale().left(35)); pafw300f.set("PW_PAESE", fornitore.stato_residenza_ISO()); pafw300f.set("PW_CODICE", fornitore.codice_fiscale_estero()); pafw300f.set("PW_CFISCA", fornitore.codice_fiscale()); pafw300f.set("PW_DENOM", fornitore.ragione_sociale()); if (fornitore.fisica() && fornitore.nome().full()) { pafw300f.set("PW_NOME", fornitore.nome()); pafw300f.set("PW_COGN", fornitore.cognome()); } else pafw300f.set("PW_RAGSOC", fornitore.ragione_sociale().left(35)); pafw300f.set("PW_IMPO", mov.get_real(MOV_TOTDOC)); //TODO controllare ????? pafw300f.set("PW_CXML", ""); pafw300f.set("PW_CXMLP", ""); pafw300f.set("PW_UPAG", ""); ok &= insert(pafw300f); return _to_commit = (ok && save_paf()); } bool TReg_fp::reg_to_paf(long n_mov) { const TMovimento_contabile mov(n_mov); return reg_to_paf(mov); } bool TReg_fp::show_log() { TReport_book b; TFilename name = "fp_err.log"; b.add(_log); b.export_text(name); return _log.preview(); } //COSTRUTTORI E DISTRUTTORI TReg_fp::TReg_fp(const char* tipo_doc_sdi, bool definitivo) : _cache_insert(false) , _tipo_doc_sdi(tipo_doc_sdi), _definitivo(definitivo) { _ditta.init(LF_NDITTE, prefix().get_codditta()); _cofi = get_cofi_tras(); const TDate data_inizio = get_date_start_new_fatt(); if (_cofi.blank()) _cofi = _ditta.codice_fiscale(); _gestioneallegati = get_gest_alleg(); _allegafattura = get_allega_fat(); _def_fld = get_fld_dest(); if (!_def_fld.ends_with("\\")) { _def_fld << "\\"; } _def_usr_fld = get_fld_dest_usr(); if (_def_usr_fld.empty()) { _def_usr_fld = _def_fld; } else if (!_def_usr_fld.ends_with("\\")) { _def_usr_fld << "\\"; } } TReg_fp::~TReg_fp() { commit(); }