3309 lines
93 KiB
C++
3309 lines
93 KiB
C++
#include "fplib.h"
|
||
#include <prefix.h>
|
||
#include <config.h>
|
||
#include <utility.h>
|
||
#include <xvt.h>
|
||
#include <diction.h>
|
||
#include <isam.h>
|
||
#include <tabutil.h>
|
||
#include <dongle.h>
|
||
#include <execp.h>
|
||
#include "../fe/felib.h"
|
||
#include "../ve/velib04.h"
|
||
#include <anagiu.h>
|
||
#include <comuni.h>
|
||
#include <cfven.h>
|
||
#include <nditte.h>
|
||
#include <unloc.h>
|
||
#include <indsp.h>
|
||
#include "../cg/cfban.h"
|
||
#include <modaut.h>
|
||
#include <netutils.h>
|
||
#include <urldefid.h>
|
||
#include "../li/letint.h"
|
||
#include <mov.h>
|
||
#include "../cg/cgsaldac.h"
|
||
#include <scadenze.h>
|
||
|
||
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") // 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;
|
||
}
|
||
|
||
/*
|
||
* 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();
|
||
}
|
||
|
||
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<const char*>(_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<const char*>(_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<const char*>(_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()
|
||
{
|
||
if (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;
|
||
q << "SELECT col.[name] FROM sys.columns AS col \
|
||
inner JOIN sys.index_columns AS idx on col.[object_id] = idx.[object_id] AND col.[column_id] = idx.[column_id] \
|
||
inner join sys.indexes as K on idx.[index_id] = K.[index_id] \
|
||
where K.[name] = '" << table << "_KEY' \
|
||
AND idx.[object_id] = object_id('" << table << "') \
|
||
ORDER BY index_column_id ASC";
|
||
for (bool ok = fp_db().sq_set_exec(q); ok; ok = fp_db().sq_next())
|
||
{
|
||
_key.add(fp_db().sq_get("name"));
|
||
}
|
||
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 == "PAF1000F")
|
||
return "P0";
|
||
if (paf_name == "PAF1100F")
|
||
return "PA";
|
||
if (paf_name == "PAF1200F")
|
||
return "PB";
|
||
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<const char *, TPaf_record>("PAF0100F", TPaf_record("PAF0100F")));
|
||
// Cedente/Prestatore
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF0200F", TPaf_record("PAF0200F")));
|
||
// Cessionario/Committente
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF0400F", TPaf_record("PAF0400F")));
|
||
// Testata documento
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF0700F", TPaf_record("PAF0700F")));
|
||
// Cassa previdenziale
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF0800F", TPaf_record("PAF0800F")));
|
||
// Contratti
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF1000F", TPaf_record("PAF1000F")));
|
||
// Convenzioni
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF1100F", TPaf_record("PAF1100F")));
|
||
// Ordini
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF1200F", TPaf_record("PAF1200F")));
|
||
// DatiFattureCollegate
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF1400F", TPaf_record("PAF1400F")));
|
||
// DDT Testata
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF1600F", TPaf_record("PAF1600F")));
|
||
// DDT Righe
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF1700F", TPaf_record("PAF1700F")));
|
||
// Righe documento
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF1800F", TPaf_record("PAF1800F")));
|
||
// Righe articoli del documento
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF1900F", TPaf_record("PAF1900F")));
|
||
// Sconti di riga
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF2000F", TPaf_record("PAF2000F")));
|
||
// Altri dati gestionali per le righe documento
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF2100F", TPaf_record("PAF2100F")));
|
||
// Dati Riepilogo
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF2200F", TPaf_record("PAF2200F")));
|
||
// Dati pagamento
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF2400F", TPaf_record("PAF2400F")));
|
||
// Rate
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF2500F", TPaf_record("PAF2500F")));
|
||
// Allegati
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF2600F", TPaf_record("PAF2600F")));
|
||
// Testata documento (aggiunte)
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF2700F", TPaf_record("PAF2700F")));
|
||
// Descrizione
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF3000F", TPaf_record("PAF3000F")));
|
||
// PEC
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF3200F", TPaf_record("PAF3200F")));
|
||
// Causale documento
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAF3400F", TPaf_record("PAF3400F")));
|
||
// Non invio XML
|
||
_pafs.insert(std::pair<const char *, TPaf_record>("PAFW300F", TPaf_record("PAFW300F")));
|
||
}
|
||
/***************************************************************************
|
||
* TAncestor
|
||
***************************************************************************/
|
||
struct TAncestor : public TObject
|
||
{
|
||
TString20 _numdoc;
|
||
TDate _datadoc;
|
||
TAncestor(const TRectype& rdoc);
|
||
};
|
||
TAncestor::TAncestor(const TRectype& rdoc)
|
||
{
|
||
const int anno = rdoc.get_int(RDOC_ANNO);
|
||
const TString4 codnum = rdoc.get(RDOC_CODNUM);
|
||
const long ndoc = rdoc.get_long(RDOC_NDOC);
|
||
const TCodice_numerazione& num = cached_numerazione(codnum);
|
||
TToken_string kdoc;
|
||
kdoc = rdoc.get(RDOC_PROVV);
|
||
kdoc.add(anno);
|
||
kdoc.add(codnum);
|
||
kdoc.add(ndoc);
|
||
const TRectype& doc = cache().get(LF_DOC, kdoc);
|
||
TString16 numdoc;
|
||
num.complete_num(ndoc, numdoc);
|
||
_numdoc.format("%d/%s/%s", anno, static_cast<const char*>(codnum), static_cast<const char*>(numdoc));
|
||
_datadoc = doc.get_date(DOC_DATADOC);
|
||
}
|
||
/***************************************************************************
|
||
* TFPBuono_di_consegna
|
||
***************************************************************************/
|
||
bool TFPBuono_di_consegna::already_exist(map<TString20, TDate>& 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 ok;
|
||
if (_cache_insert)
|
||
{
|
||
_query.push_back(p.insert_string());
|
||
ok = true;
|
||
}
|
||
else
|
||
{
|
||
ok = p.insert();
|
||
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;
|
||
if (_cache_insert)
|
||
{
|
||
_query.push_back(p.remove_string());
|
||
ok = true;
|
||
}
|
||
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)
|
||
{
|
||
string query;
|
||
for (auto i = _query.begin(); i != _query.end(); ++i)
|
||
query += *i;
|
||
ok = fp_db().sq_set_exec(query);
|
||
if (!ok)
|
||
{
|
||
_log.log(2, fp_db().sq_get_token_text_error(1));
|
||
_log.log(2, query.c_str());
|
||
}
|
||
}
|
||
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<const char*>(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();
|
||
}
|
||
|
||
bool TDoc_fp::show_log()
|
||
{
|
||
TReport_book b;
|
||
TFilename name = "fp_err.log";
|
||
|
||
b.add(_log);
|
||
b.export_text(name);
|
||
return _log.preview();
|
||
}
|
||
|
||
int TDoc_fp::commit()
|
||
{
|
||
int r = 0;
|
||
if (_to_commit)
|
||
{
|
||
// Controllo stato diagnosticato
|
||
if (!get_no_export_pronto())
|
||
{
|
||
if (fp_db().sq_set_exec("UPDATE PAF0100F SET P1_GESTIONE = 'P' WHERE P1_GESTIONE = 'D'"))
|
||
{
|
||
r += 1;
|
||
_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));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
_log.log(2, "Le fatture sono state esportate in stato diagnosticato");
|
||
}
|
||
if (r >= 0 && fp_db().sq_commit())
|
||
{
|
||
r += 2;
|
||
}
|
||
else
|
||
{
|
||
r = -1;
|
||
_log.log(2, fp_db().sq_get_token_text_error(1));
|
||
_log.log(2, "UPDATE PAF0100F SET P1_GESTIONE = 'P' WHERE P1_GESTIONE = 'D'");
|
||
}
|
||
}
|
||
_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<real>(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_cambio._is_valuta_estera)
|
||
{
|
||
TCurrency app(prezzo, _doc_cambio._cod_val, _doc_cambio._cambio, 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
|
||
{
|
||
// <DatiRitenuta>
|
||
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);
|
||
// </DatiRitenuta>
|
||
}
|
||
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);
|
||
}
|
||
|
||
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)));
|
||
|
||
if (scat.full() && cache().get("&VESCC", scat).not_empty() && !_has_cust)
|
||
{
|
||
reset(paf2100f);
|
||
paf2100f.set("PK_KEYNLINEA", static_cast<long>(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", rdoc->get_real(conai_peso_name(i)).string());
|
||
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<long>(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()
|
||
{
|
||
// <DatiTrassmissione>
|
||
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;
|
||
|
||
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));
|
||
paf0100f.set("P1_GESTIONE", stato_paf());
|
||
paf0100f.set("P1_ERRINT", "");
|
||
// </DatiTrassmissione>
|
||
return insert(paf0100f);
|
||
}
|
||
bool TDoc_fp::export_paf3200f()
|
||
{
|
||
if (_enapec)
|
||
{
|
||
// <Datipec>
|
||
TPaf_record& paf3200f = _paf_container.get_paf("PAF3200F");
|
||
paf3200f.set("PU_PEC", _pec);
|
||
// </Datipec>
|
||
return insert(paf3200f);
|
||
}
|
||
return true;
|
||
}
|
||
|
||
void TDoc_fp::fill_buoni(map<TString20, TFPBuono_di_consegna>& 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)
|
||
{
|
||
if (!initialize(doc))
|
||
return false;
|
||
bool ok = true;
|
||
|
||
ok &= export_paf0100f();
|
||
|
||
ok &= export_paf3200f();
|
||
|
||
|
||
// <CedentePrestatore>
|
||
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);
|
||
// </CedentePrestatore>
|
||
// <CessionarioCommittente>
|
||
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);
|
||
// </CessionarioCommittente>
|
||
// <DatiGenerali>
|
||
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
|
||
paf0700f.set("P7_DATA", doc.data());
|
||
paf0700f.set("P7_NUMERO", complete_num_fp(doc.codice_numerazione(), doc.numero()));
|
||
paf0700f.set("P7_GESTIONE", stato_paf());
|
||
// <DatiBollo>
|
||
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));
|
||
}
|
||
// </DatiBollo>
|
||
// <DatiCassaPrevidenziale>
|
||
// Non la mettiamo!
|
||
// </DatiCassaPrevidenziale>
|
||
// 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
|
||
*/
|
||
// <DatiGenerali>
|
||
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);
|
||
// <DatiOrdineAcquisto>
|
||
if ((doc.is_nota_credito() || get_send_all_rifs()) && doc.get(DOC_NUMDOCRIF).full())
|
||
{
|
||
TPaf_record& paf1400f = _paf_container.get_paf("PAF1400F");
|
||
reset(paf1400f);
|
||
paf1400f.set("PD_IDDOC", doc.get(DOC_NUMDOCRIF));
|
||
paf1400f.set("PD_DATADOC", doc.get_date(DOC_DATADOCRIF));
|
||
ok &= insert(paf1400f);
|
||
}
|
||
// </DatiOrdineAcquisto>
|
||
// </DatiGenerali>
|
||
// 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("#");
|
||
}
|
||
|
||
// SEMPRE
|
||
// Azzera contratti
|
||
TPaf_record& paf1000f = _paf_container.get_paf("PAF1000F");
|
||
paf1000f.set("P0_RIFNUMLINEA", 0L);
|
||
// Azzera convenzioni
|
||
TPaf_record& paf1100f = _paf_container.get_paf("PAF1100F");
|
||
paf1100f.set("PA_RIFNUMLINEA", 0L);
|
||
// Azzera ordini
|
||
TPaf_record& paf1200f = _paf_container.get_paf("PAF1200F");
|
||
paf1200f.set("PB_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);
|
||
paf1000f.set("P0_GESTIONE", stato_paf());
|
||
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);
|
||
paf1100f.set("PA_GESTIONE", stato_paf());
|
||
ok &= insert(paf1100f);
|
||
}
|
||
else
|
||
{
|
||
paf1200f.set("PB_RIFNUMLINEA", 0L);
|
||
paf1200f.set("PB_IDDOC", con);
|
||
paf1200f.set("PB_DATADOCO", datadoc);
|
||
paf1200f.set("PB_COMMCONVENZ", com);
|
||
paf1200f.set("PB_CODCUP", cup);
|
||
paf1200f.set("PB_CODCIG", cig);
|
||
paf1200f.set("PB_GESTIONE", stato_paf());
|
||
ok &= insert(paf1200f);
|
||
}
|
||
}
|
||
if (_is_pa && cup.blank() && cig.blank())
|
||
_log.log(1, "CIG e CUP assenti");
|
||
// <DatiBeniServizi>
|
||
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<TString20, TDate> 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);
|
||
if (rifs.len() > 25 && rifs[25] == ' ')
|
||
{
|
||
temp = rifs;
|
||
rifs = temp.left(25);
|
||
temp.ltrim(26);
|
||
rifs << temp;
|
||
}
|
||
rifs.trim();
|
||
if (rifs == "0")
|
||
rifs.cut(0);
|
||
|
||
int len = rifs.len();
|
||
|
||
if (len > 0)
|
||
{
|
||
rifs.replace(" - ", "|");
|
||
|
||
long numlinea = 0;
|
||
TToken_string elab_rifs(rifs);
|
||
|
||
FOR_EACH_STR_TOKEN(elab_rifs, str)
|
||
{
|
||
TToken_string rif(str, ' ');
|
||
|
||
// <DatiDDT> //
|
||
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());
|
||
paf1600f.set("PF_RIFNUMLINEA", numlinea++);
|
||
ok &= insert(paf1600f); // </DatiDDT>
|
||
}
|
||
}
|
||
}
|
||
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);
|
||
// <CodiceArticolo>
|
||
if (rdoc->is_articolo())
|
||
{
|
||
ok &= export_info_articolo(rdoc, paf1900f, paf2100f, riga, r);
|
||
}
|
||
// </CodiceArticolo>
|
||
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);
|
||
/*
|
||
const TDate data = doc.get(DOC_DATADOC);
|
||
paf1800f.set("PI_DTINIZIOPER", data);
|
||
paf1800f.set("PI_DTFINEPER", data);
|
||
*/
|
||
|
||
/*
|
||
* 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<const TAncestor&>(ancestors[i]);
|
||
|
||
ancestors_s.insert({ a._numdoc, a._datadoc }); // Per i buoni di consegna lavanderie
|
||
if (i == 1)
|
||
{
|
||
// <DatiDDT>
|
||
reset(paf1600f);
|
||
paf1600f.set("PF_RIFNUMLINEA", static_cast<long>(r));
|
||
paf1600f.set("PF_NUMDDDT", a._numdoc);
|
||
paf1600f.set("PF_DATADDT", a._datadoc);
|
||
paf1600f.set("PF_GESTIONE", stato_paf());
|
||
ok &= insert(paf1600f);
|
||
// </DatiDDT>
|
||
}
|
||
else if (i == 3)
|
||
{
|
||
// <DatiOrdineAcquisto>
|
||
paf1000f.set("P0_KEYHEADERFATT", _hfatt);
|
||
paf1000f.set("P0_KEYBODYFATT", _bfatt);
|
||
paf1000f.set("P0_RIFNUMLINEA", static_cast<long>(r));
|
||
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);
|
||
// </DatiOrdineAcquisto>
|
||
}
|
||
}
|
||
}
|
||
}
|
||
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 = UNO;
|
||
bool qta_inverse = false;
|
||
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<const char*>(rdoc->field_qta()));
|
||
_log.log(1, msg);
|
||
qta = UNO;
|
||
}
|
||
if (qta < ZERO)
|
||
{
|
||
qta = -qta;
|
||
qta_inverse = true;
|
||
}
|
||
paf1800f.set("PI_QUANTITA", qta);
|
||
}
|
||
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();
|
||
}
|
||
}
|
||
paf1800f.set("PI_PREZZOUNIT", converti_prezzo(qta_inverse ? -abs(prz) : abs(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", static_cast<long>(r));
|
||
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);
|
||
// Non metto l'imposta, gi presente nei totali
|
||
//riepilogo_agg.imposta += rdoc->iva_omaggio(8, 2);
|
||
}
|
||
else
|
||
{
|
||
paf2100f.set("PK_RIFDATO", "Omaggio senza rivalsa");
|
||
// Aggiungo uno sconto
|
||
paf2000f.set("PJ_KEYNLINEA", static_cast<long>(r));
|
||
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;
|
||
// <ScontoMaggiorazione>
|
||
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", static_cast<long>(r));
|
||
paf2000f.set("PJ_KEYNLINAR", ++nlin_sconto);
|
||
if (perc > ZERO)
|
||
{
|
||
paf2000f.set("PJ_TIPOSCONTO", "SC");
|
||
paf2000f.set("PJ_PERCSCONTO", perc);
|
||
}
|
||
else
|
||
{
|
||
paf2000f.set("PJ_TIPOSCONTO", "MG");
|
||
paf2000f.set("PJ_PERCSCONTO", -perc);
|
||
}
|
||
paf2000f.set("PJ_GESTIONE", stato_paf());
|
||
ok &= insert(paf2000f);
|
||
}
|
||
}
|
||
}
|
||
// </ScontoMaggiorazione>
|
||
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<TString20, TFPBuono_di_consegna> 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);
|
||
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.is_nota_credito())
|
||
{
|
||
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(descr);
|
||
|
||
dichiar << " : " << protinf;
|
||
if (protins.full())
|
||
dichiar << "-" << protins;
|
||
reset(paf2100f);
|
||
paf2100f.set("PK_KEYNLINEA", static_cast<long>(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++;
|
||
}
|
||
}
|
||
// 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<const TRiepilogo_iva*>(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++;
|
||
}
|
||
|
||
// </DatiBeniServizi>
|
||
// <DatiDDT>
|
||
// 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);
|
||
}
|
||
// </DatiDDT>
|
||
// Salvo la testata
|
||
ok &= insert(paf0700f);
|
||
// <DatiRiepilogo>
|
||
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<const TRiepilogo_iva*>(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);
|
||
}
|
||
}
|
||
// </DatiRiepilogo>
|
||
// <DatiPagamento>
|
||
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);
|
||
}
|
||
// </DatiPagamento>
|
||
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()));
|
||
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)
|
||
{
|
||
if (_doc_rec != nullptr)
|
||
delete _doc_rec;
|
||
_doc_rec = new TRectype(LF_DOC);
|
||
_doc_rec->put(DOC_PROVV, key.provv());
|
||
_doc_rec->put(DOC_ANNO, key.anno());
|
||
_doc_rec->put(DOC_CODNUM, key.codnum());
|
||
_doc_rec->put(DOC_NDOC, key.ndoc());
|
||
return *_doc_rec;
|
||
}
|
||
TDoc_fp::TDoc_fp(bool provvisorio) : _doc_rec(nullptr), _log(nullptr), _cache_insert(false) , _provvisorio(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 ok;
|
||
|
||
if (_cache_insert)
|
||
{
|
||
_query.push_back(p.insert_string());
|
||
ok = true;
|
||
}
|
||
else
|
||
{
|
||
ok = p.insert();
|
||
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;
|
||
|
||
if (_cache_insert)
|
||
{
|
||
_query.push_back(p.remove_string());
|
||
ok = true;
|
||
}
|
||
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)
|
||
{
|
||
string query;
|
||
for (auto i = _query.begin(); i != _query.end(); ++i)
|
||
query += *i;
|
||
ok = fp_db().sq_set_exec(query);
|
||
if (!ok)
|
||
{
|
||
_log.log(2, fp_db().sq_get_token_text_error(1));
|
||
_log.log(2, query.c_str());
|
||
}
|
||
}
|
||
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));
|
||
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;
|
||
if (!get_coddest(mov.get_char(MOV_TIPO), mov.get_long(MOV_CODCF), _coddest, _pec))
|
||
{
|
||
_log.log(1, "Impossibile trovare il codice destinatario per la fattura");
|
||
return false;
|
||
}
|
||
_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())
|
||
{
|
||
if (fp_db().sq_set_exec("UPDATE PAF0100F SET P1_GESTIONE = 'P' WHERE P1_GESTIONE = 'D'"))
|
||
{
|
||
r += 1;
|
||
_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));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
_log.log(2, "Le fatture sono state esportate in stato diagnosticato");
|
||
}
|
||
if (r >= 0 && fp_db().sq_commit())
|
||
{
|
||
r += 2;
|
||
}
|
||
else
|
||
{
|
||
r = -1;
|
||
_log.log(2, fp_db().sq_get_token_text_error(1));
|
||
_log.log(2, "UPDATE PAF0100F SET P1_GESTIONE = 'P' WHERE P1_GESTIONE = 'D'");
|
||
}
|
||
}
|
||
_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<real>(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");
|
||
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();
|
||
|
||
reset(paf2200f);
|
||
// Aliquota
|
||
paf2200f.set("PL_ALIQUOTAIVA", aliquota);
|
||
// Natura
|
||
if (aliquota.is_zero())
|
||
paf2200f.set("PL_NATURA", natura(cod_aliquota));
|
||
// Imponibile
|
||
paf2200f.set("PL_IMPONIBILE", rec_iva.get(RMI_IMPONIBILE));
|
||
// Imposta
|
||
paf2200f.set("PL_IMPOSTA", rec_iva.get(RMI_IMPOSTA));
|
||
// Esigibilit IVA
|
||
paf2200f.set("PL_ESIGIVA", ""); // TODO va compilato ???
|
||
|
||
paf2200f.set("PL_RIFNORMATIVO", cod_iva.descrizione());
|
||
paf2200f.set("PL_GESTIONE", stato_paf());
|
||
|
||
// Inserisco
|
||
return insert(paf2200f);
|
||
}
|
||
|
||
bool TReg_fp::export_paf0100f()
|
||
{
|
||
// <DatiTrassmissione>
|
||
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;
|
||
|
||
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));
|
||
paf0100f.set("P1_GESTIONE", stato_paf());
|
||
paf0100f.set("P1_ERRINT", "");
|
||
// </DatiTrassmissione>
|
||
return insert(paf0100f);
|
||
}
|
||
|
||
bool TReg_fp::export_paf3200f()
|
||
{
|
||
if (_enapec)
|
||
{
|
||
// <Datipec>
|
||
TPaf_record& paf3200f = _paf_container.get_paf("PAF3200F");
|
||
paf3200f.set("PU_PEC", _pec);
|
||
// </Datipec>
|
||
return insert(paf3200f);
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool TReg_fp::reg_to_paf(const TMovimento_contabile& mov)
|
||
{
|
||
if (!initialize(mov))
|
||
return false;
|
||
bool ok = true;
|
||
|
||
ok &= export_paf0100f();
|
||
ok &= export_paf3200f();
|
||
// <CedentePrestatore>
|
||
|
||
TPaf_record& paf0200f = _paf_container.get_paf("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());
|
||
}
|
||
paf0200f.set("P2_CODFISCALE", fornitore.codice_fiscale()); //
|
||
if (_ditta.fisica())
|
||
{
|
||
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", ""); //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()); //
|
||
paf0200f.set("P2_GESTIONE", stato_paf());
|
||
|
||
// I clienti esteri possono avere CAP alfanumerici, li tolgo
|
||
if (fornitore.stato_residenza_ISO() != "IT")
|
||
{
|
||
paf0200f.set("P2_SEDECAP", "00000");//
|
||
}
|
||
else
|
||
{
|
||
paf0200f.set("P2_SEDECAP", fornitore.CAP_residenza()); //
|
||
paf0200f.set("P2_SEDEPROV", fornitore.provincia_residenza()); //
|
||
}
|
||
}
|
||
|
||
ok &= insert(paf0200f);
|
||
|
||
|
||
// </CedentePrestatore>
|
||
// </CedentePrestatore>
|
||
// <CessionarioCommittente>
|
||
TPaf_record& paf0400f = _paf_container.get_paf("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);
|
||
// </CessionarioCommittente>
|
||
TPaf_record& paf0700f = _paf_container.get_paf("PAF0700F");
|
||
paf0700f.set("P7_TIPODOC", _tipo_doc_sdi);
|
||
paf0700f.set("P7_DIVISA", "EUR"); // Fisso su euro in quanto effettuiamo il cambio
|
||
paf0700f.set("P7_DATA", mov.get_date(MOV_DATAREG)); // sembra sempre la data di registrazione visto che <20> na data di ricezione
|
||
TString numdoc = mov.get(MOV_NUMDOCEXT);
|
||
|
||
if (numdoc.blank())
|
||
numdoc = mov.get(MOV_NUMDOC);
|
||
else
|
||
{
|
||
if (numdoc.len() > 20)
|
||
numdoc = numdoc.mid(30);
|
||
}
|
||
|
||
paf0700f.set("P7_NUMERO", numdoc);
|
||
paf0700f.set("P7_GESTIONE", stato_paf());
|
||
|
||
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", mov.get(MOV_TOTDOC));
|
||
paf2700f.set("PQ_GESTIONE", stato_paf());
|
||
ok &= insert(paf2700f);
|
||
// </DatiOrdineAcquisto>
|
||
// 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);
|
||
}
|
||
}
|
||
paf1400f.set("PD_IDDOC", idsdi);
|
||
paf1400f.set("PD_DATADOC", datasdi);
|
||
ok &= insert(paf1400f);
|
||
// </DatiGenerali>
|
||
// Azzera DDT
|
||
TPaf_record& paf1600f = _paf_container.get_paf("PAF1600F");
|
||
// SEMPRE
|
||
// <DatiBeniServizi>
|
||
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");
|
||
int n_righe_iva = mov.iva().rows();
|
||
|
||
for (int i = 1; i <= n_righe_iva; i++)
|
||
{
|
||
reset(paf1800f);
|
||
paf1800f.set("PI_NUMEROLINEA", (long)i);
|
||
add_riepilogo_iva(mov, i);
|
||
ok &= insert(paf1800f);
|
||
|
||
reset(paf3000f);
|
||
paf3000f.set("PT_RIFNUMLINEA", (long)i);
|
||
paf3000f.set("PT_COMMENTO", "");//TODO COSA DOBBIAMO METTERE NELLA DESCRIZIONE IVA CHE NON C'<27>
|
||
// <CodiceArticolo>
|
||
|
||
if (ok) ok &= insert(paf3000f);
|
||
|
||
if (ok) ok &= insert(paf0700f);
|
||
|
||
// Tabella di non invio XML
|
||
TPaf_record& pafw300f = _paf_container.get_paf("PAFW300F");
|
||
pafw300f.set("PW_TIPODOC", ""); //TODO PASSARE IL TIPO DOCUMENTO DELLA MASK NEL COSTRUTTORE
|
||
pafw300f.set("PW_TIPONUM", ""); //TODO COSA CI METTIAMO NEL TIPO NUM
|
||
pafw300f.set("PW_NUMERO", mov.get(MOV_NUMDOC));
|
||
pafw300f.set("PW_DATA", mov.get_date(MOV_DATADOC));
|
||
/*
|
||
if (!cached_tipodoc(doc.get(DOC_TIPODOC)).invio_xml() || doc.noinvioxml()) //TODO COSA CI VA MESSO?? COSA VUOL DIRE INVIO XML
|
||
pafw300f.set("PW_CODSDI", "**********");
|
||
*/
|
||
pafw300f.set("PW_CDEST", _coddest);
|
||
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 ?????
|
||
ok &= insert(pafw300f);
|
||
return _to_commit = (ok && save_paf());
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TReg_fp::reg_to_paf(long n_mov)
|
||
{
|
||
const TMovimento_contabile mov(n_mov);
|
||
|
||
return reg_to_paf(mov);
|
||
}
|
||
|
||
//NON LE CAPISCO
|
||
|
||
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();
|
||
}
|
||
|
||
bool TReg_fp::show_log()
|
||
{
|
||
TReport_book b;
|
||
TFilename name = "fp_err.log";
|
||
|
||
b.add(_log);
|
||
b.export_text(name);
|
||
return _log.preview();
|
||
}
|