campo-sirio/src/fp/fplib01.cpp

2241 lines
63 KiB
C++

#include "fplib.h"
#include <prefix.h>
#include <config.h>
#include <utility.h>
#include <scanner.h>
#include <xvt.h>
#include <diction.h>
#include "text.h"
#include <isam.h>
#include <tabutil.h>
#include <dongle.h>
#include <execp.h>
#include "../fe/felib.h"
#include "../cg/cglib03.h"
#include "../ve/velib04.h"
#include <anagiu.h>
#include <comuni.h>
#include <cfven.h>
#include <nditte.h>
#include <unloc.h>
#include <causali.h>
#include "../cg/cfban.h"
#include "modaut.h"
void set_connection(SSimple_query& s)
{
#ifdef DBG
TString ip = fp_settings().get_db_indirizzo();
if (ip.upper() != "TESTCAMPO2012")
{
if (s.sq_connect("TESTCAMPO2012@campo_fp",
"fp",
"fp",
TSDB_MSSQL) != NOERR)
fatal_box("Impossibile connettersi al DB esterno");
}
else
{
#endif
if (s.sq_connect(
fp_settings().get_db_str_con(),
fp_settings().get_db_user(),
fp_settings().get_db_password(),
TSDB_MSSQL) != NOERR)
fatal_box("Impossibile connettersi al DB esterno");
#ifdef DBG
}
#endif
}
SSimple_query& fp_db()
{
static SSimple_query* db = nullptr;
if (db == nullptr)
{
db = new SSimple_query();
set_connection(*db);
// Non utilizzo l'autocommit, viene gestito manualmente
db->sq_set_autocommit(false);
}
return *db;
}
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");
TString version;
if (tabmod.read() == NOERR)
version = tabmod.get("S0");
for(SLIST_ELT file = xvt_slist_get_first(files); file; file = xvt_slist_get_next(files, file))
{
TString file_version = TFilename(file->str).name_only();
file_version = file_version.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;
// 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) || !fp_db().sq_commit())
{
fatal_box("Impossibile eseguire/salvare la query:\n%s\n%s", query.c_str(), fp_db().sq_get_string_error());
}
}
}
}
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 documento vero e proprio
bool chiave_paf(const TDocumento& doc, TString& hfatt, TString& bfatt)
{
hfatt.cut(0);
if (doc.clifor().occasionale())
hfatt << "O" << doc.get("OCFPI");
else
hfatt << doc.clifor().tipo() << doc.clifor().codice();
CHECK(hfatt.full(), "Destinatario fattura P.A. non valido");
const TCodice_numerazione& codnum = doc.codice_numerazione();
//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(const TRectype& doc, TString& hfatt, TString& bfatt)
{
TDocumento d(doc);
chiave_paf(d, hfatt, bfatt);
return hfatt.full();
}
TString get_dest_sdi(const char tipocf, const long codcf)
{
TString codsdi, pec;
get_coddest(tipocf, codcf, codsdi, pec);
return pec.full() ? pec : codsdi;
}
bool get_coddest(const char tipocf, const long codcf, TString& coddest, TString& pec)
{
TCli_for clifo(tipocf, codcf);
coddest = clifo.vendite().get("PADESTIN");
pec = clifo.get("PEC");
TAnagrafica anag(LF_CLIFO, tipocf, codcf);
if (coddest.empty())
{
if (pec.full() || fp_settings().get_esp_pri_empty())
coddest = "0000000";
// Controllo se è straniero
else if (anag.estero() && anag.stato_partita_IVA() != "IT")
{
coddest = fp_settings().get_esp_est() ? fp_settings().get_esp_est_cod() : "";
}
}
else
pec = "";
return coddest.full();
}
inline const TString& no_special(char a)
{
TString& r = get_tmp_string().cut(0);
switch(a)
{
case '\'':
break;
default:
r << a;
}
return r;
}
const TString& tipo_doc_sdi(const TDocumento& doc)
{
static TString tipo_doc_sdi;
tipo_doc_sdi.cut(0) << doc.get(DOC_TIPODOCSDI);
// Controlli da fare per clienti a cui si fotte 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(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 << ';';
return query;
}
// Elimina il record in base ai campi chiave
bool TPaf_record::remove()
{
return fp_db().sq_set_exec(remove_string());
}
// 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;
query << "SELECT TOP 1 * FROM " << _table << " WHERE ";
FOR_EACH_TOKEN(_key, fld)
{
const TVariant& var = get(fld);
if (!var.is_null())
query << fld << '=' << var2str(fld, var) << " AND ";
}
query.rtrim(5);
query << " ORDER BY ";
FOR_EACH_TOKEN(_key, fld)
{
const TVariant& var = get(fld);
if (!var.is_null())
query << fld << ", ";
}
query.rtrim(2) << " DESC;";
// 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);
static TString query, values;
query.cut(0); values.cut(0);
query << "INSERT INTO " << _table << "\n(";
FOR_EACH_ASSOC_OBJECT(_fields, obj, fld, itm)
{
const TVariant& var = get(fld);
if (!var.is_null())
{
query << fld << ',';
values << var2str(fld, var) << ',';
}
}
query.rtrim(1);
values.rtrim(1);
query << ")\nVALUES (" << values << ");";
return query;
}
// Aggiunge un record al db
bool TPaf_record::insert()
{
return fp_db().sq_set_exec(insert_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);
}
/***************************************************************************
* 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);
}
/***************************************************************************
* TDoc_fp
***************************************************************************/
bool TDoc_fp::parse_sconto(const TString& formula, TToken_string& sconti) const
{
sconti.cut(0);
int start = 0;
for (int i = 0; ; i++)
{
const char c = formula[i];
if (c == '+' || c == '-' || c < ' ')
{
if (i > 0)
{
TString8 tok = formula.sub(start, i);
tok.replace(',', '.');
const real perc = tok;
if (!perc.is_zero())
sconti.add(tok);
}
if (c < ' ')
break;
start = i;
}
}
return sconti.full();
}
bool TDoc_fp::get_bnp_iban(const TString& abi, const TString& cab, int nprog, TString& iban)
{
TTable bnp("BNP");
TString16 key;
key << abi << cab;
if (nprog > 0)
{
TString4 sprog;
sprog.format("%02d", nprog);
key << sprog;
}
bnp.put("CODTAB", key);
int err = bnp.read(_isgteq);
if (err == NOERR && !bnp.get("CODTAB").starts_with(abi))
err = _iskeynotfound;
if (err == NOERR)
iban = bnp.get("S3");
return err == NOERR;
}
bool TDoc_fp::get_bank(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);
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
{
bool found = false;
abi = doc.get(DOC_CODABIA);
cab = doc.get(DOC_CODCABA);
iban = doc.get(DOC_IBAN);
found = iban.full();
if (!found) // Se non trovo banca sul DOC la cerco su CFBAN
{
TToken_string key;
key.add("C");
key.add(doc.codcf());
key.add("N");
key.add(1);
const TRectype& cfban = cache().get(LF_CFBAN, key);
if (!cfban.empty())
{
abi = cfban.get(CFBAN_ABI);
cab = cfban.get(CFBAN_CAB);
found = abi.full() && cab.full();
iban = cfban.get(CFBAN_IBAN);
if (found && iban.blank())
get_bnp_iban(abi, cab, -1, iban);
}
}
if (found)
istituto = cache().get("%BAN", abi, "S0");
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(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(2, fp_db().sq_get_string_error());
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(2, fp_db().sq_get_string_error());
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(2, fp_db().sq_get_string_error());
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(1, "Il codice destinatario ha una lunghezza non conforme.");
ok = false;
}
if (_rec_clifo.get(CLI_PAIV).empty() && _rec_clifo.get(CLI_COFI).empty())
{
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 è valorizzata la condizione di pagamento SDI (TP01, TP02, TP03) per la condizione di pagamento " << pag.code();
log(1, msg);
ok = false;
}
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 è valorizzata la tipologia di pagamento SDI (MPXX) per la condizione di pagamento " << pag.code();
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.perc().is_zero())
{
msg.cut(0) << "É corretto che per la spesa " << spesa.codice() << " la percentuale sia zero?";
log(1, msg);
}
}
const TCodiceIVA& codice_iva = rdoc.iva();
if (codice_iva.codice().full() && codice_iva.percentuale() == ZERO && codice_iva.natura().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(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' && riva.cod_iva().natura() == "N6")
{
msg.cut(0) << "Impossibile avere un documento con scissione dei pagamenti e natura iva N6, codice: " << riva.cod_iva().codice();
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 = cache().get(LF_CLIFO, TString() << doc.tipocf() << "|" << doc.codcf());
// 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, _hfatt, _bfatt))
return false;
// Preparo il log
log(-1, _bfatt);
#ifndef DBG
// Controllo se il documento è almeno in stato di stampa
if (doc.stato() < doc.tipo().stato_finale_stampa())
{
log(3, "Il documento non è stato ancora stampato, verrà saltato");
return false;
}
#endif
#ifndef DBG
_is_pa = doc.clifor().get_int("ALLEG") == 7;
if (!get_coddest(doc.clifor().tipo(), doc.clifor().codice(), _coddest, _pec))
{
log(1, "Impossibile trovare il codice destinatario per la fattura");
return false;
}
#else
_is_pa = true;
_coddest = "WSUHKZ";
#endif
_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
_index_cassa_previdenziale = 1;
return check_initial(doc) || fp_settings().get_check_not_block();
}
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));
}
return cache().get("&CON", conkey);
}
void TDoc_fp::log(int severity, const char* msg)
{
if (_log == nullptr)
{
_log = new TLog_report;
// Tento l'eliminazione del file
std::remove("fp_err.log");
}
if (severity < 0)
{
_logpaf = msg;
}
else
{
static TString txt;
txt.cut(0);
if (_logpaf.full())
{
txt << _logpaf << ": " << msg;
}
else
txt << msg;
_log->log(severity, txt);
// Scrivo anche su file
std::filebuf fb;
fb.open("fp_err.log", std::ios::out|std::ios::app);
std::ostream os(&fb);
os << txt << std::endl;
fb.close();
}
}
bool TDoc_fp::show_log()
{
if (_log)
{
_log->preview();
delete _log;
_log = NULL;
}
return true;
}
const int TDoc_fp::commit()
{
int r = 0;
if (_to_commit)
{
if(fp_db().sq_set_exec("UPDATE PAF0100F SET P1_GESTIONE = 'P' WHERE P1_GESTIONE = 'D'") && fp_db().sq_commit())
{
r = 1;
}
else
{
r = -1;
log(2, fp_db().sq_get_string_error());
log(2, "UPDATE PAF0100F SET P1_GESTIONE = 'P' WHERE P1_GESTIONE = 'D'");
}
}
_to_commit = false;
return r;
}
const int TDoc_fp::force_commit()
{
_to_commit = true;
return commit();
}
const char* TDoc_fp::natura(const TString& codiva) const
{
return cache().get("%IVA", codiva, "S12");
}
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);
const bool ok = insert(paf);
return ok;
}
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,8);
}
else
ret << prezzo;
return ret;
}
void TDoc_fp::set_qta_prezzo(TPaf_record& paf1800f, TRiga_documento* rdoc) const
{
// Setto l'unità di misura
paf1800f.set("PI_UNITAMISURA", rdoc->get(RDOC_UMQTA));
static TFP_righe_custom righe_custom;
const TString field_qta = righe_custom.get_qta(rdoc->tipo().codice(), rdoc->doc().tipo().codice());
const TString field_prezzo = righe_custom.get_prezzo(rdoc->tipo().codice(), rdoc->doc().tipo().codice());
const TString field_imponibile = righe_custom.get_imponibile(rdoc->tipo().codice(), rdoc->doc().tipo().codice());
const bool custom_prezzo = field_prezzo != RDOC_PREZZO;
real qta = rdoc->get_real(field_qta);
// Prendendo la stringa non ho problemi in scrittura della query, a volte accadono cose stupide
const TString& qta_string = rdoc->get(field_qta);
real prezzo_unit;
real prezzo_tot;
if (qta >= ZERO)
{
if (qta == ZERO)
qta = UNO;
paf1800f.set("PI_QUANTITA", qta_string);
if(custom_prezzo)
{
prezzo_unit = rdoc->get_real(field_prezzo);
prezzo_tot = rdoc->get_real(field_imponibile);
}
else
{
prezzo_unit = rdoc->prezzo(false, false, 8);
prezzo_tot = rdoc->importo(true, false);
}
}
else if(qta < ZERO)
{
// Metto la qualità senza il segno
paf1800f.set("PI_QUANTITA", qta_string.mid(1));
// E i prezzi in negativo, perchè l'importo non ha lo stesso segno del prezzo?
if (custom_prezzo)
{
prezzo_unit = -abs(rdoc->get_real(field_prezzo));
prezzo_tot = -abs(rdoc->get_real(field_imponibile));
}
else
{
prezzo_unit = -abs(rdoc->prezzo(false, false, 8));
prezzo_tot = -abs(rdoc->importo(true, false));
}
}
// Salvo tutto
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 TDocumentoEsteso& doc, const TSpesa_prest& sp, TPaf_record& paf0700f) const
{
// <DatiRitenuta>
paf0700f.set("P7_TIPORITENUTA", _rec_clifo.get_char(CLI_TIPOPERS) == 'F' ? "RT01" : "RT02");
TString doc_imponibile = doc.imponibile().string();
const real imponibile = calc_ritenuta(doc);
paf0700f.set("P7_IMPORTORIT", converti_prezzo(imponibile * sp.perc() / CENTO));
paf0700f.set("P7_ALIQUOTARIT", sp.perc());
static TString caus_la; caus_la.cut(0);
caus_la << sp.get("S14");
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)
{
paf2200f.reset();
paf2200f.set("PL_KEYHEADERFATT", _hfatt);
paf2200f.set("PL_KEYBODYFATT", _bfatt);
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", "D");
// Elimino l'oggetto
_riepilogo_agg.erase(cod_aliquota);
// Inserisco
return insert(paf2200f);
}
bool TDoc_fp::add_cassa_previdenziale(TRiga_documento& rdoc)
{
static TPaf_record paf0800f("PAF0800F");
paf0800f.reset();
if (_index_cassa_previdenziale == 1)
{
paf0800f.set("P8_KEYHEADERFATT", _hfatt);
paf0800f.set("P8_KEYBODYFATT", _bfatt);
remove(paf0800f);
}
// Chiavi
paf0800f.set("P8_KEYHEADERFATT", _hfatt);
paf0800f.set("P8_KEYBODYFATT", _bfatt);
paf0800f.set("P8_RIFNUMLINEA", _index_cassa_previdenziale++);
// Resto
const TSpesa_prest& sp = rdoc.spesa();
const real imponibile_ritenuta = calc_ritenuta(rdoc.doc());
const real importo_cassa = imponibile_ritenuta * 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_ritenuta));
// 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", rdoc.iva().natura());
// 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);
}
const TFirm& TDoc_fp::get_firm()
{
return prefix().firm();
}
bool TDoc_fp::export_paf0100f()
{
// <DatiTrassmissione>
TPaf_record paf0100f("PAF0100F");
paf0100f.set("P1_KEYHEADERFATT", _hfatt);
paf0100f.set("P1_KEYBODYFATT", _bfatt);
remove(paf0100f);
paf0100f.set("P1_TRASMITTPAESE", _paese);
paf0100f.set("P1_TRASMITTCOD", _cofi);
paf0100f.set("P1_FMTTRASMISS", _privato ? "FPR12" : "FPA12"); // SDI11 si usa dal 2015 per lo split payment (prima era SDI10)
paf0100f.set("P1_CODDEST", _coddest);
TString80 tel;
tel << 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", "D");
paf0100f.set("P1_ERRINT", "");
// </DatiTrassmissione>
return insert(paf0100f);
}
bool TDoc_fp::export_paf3200f()
{
if (_enapec)
{
// <Datipec>
TPaf_record paf3200f("PAF3200F");
paf3200f.set("PU_KEYHEADERFATT", _hfatt);
paf3200f.set("PU_KEYBODYFATT", _bfatt);
remove(paf3200f);
paf3200f.set("PU_PEC", _pec);
// </Datipec>
return insert(paf3200f);
}
return true;
}
bool TDoc_fp::doc_to_paf(TDocumentoEsteso& doc)
{
if (!initialize(doc))
return false;
bool ok = true;
ok &= export_paf0100f();
#ifndef DBG
ok &= export_paf3200f();
#endif
// <CedentePrestatore>
TPaf_record paf0200f("PAF0200F");
paf0200f.set("P2_KEYHEADERFATT", _hfatt);
paf0200f.set("P2_KEYBODYFATT", _bfatt);
remove(paf0200f);
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", "D");
TAnagrafica cliente(doc.clifor());
TString rifamm = cco(doc).get("S4");
if (rifamm.blank())
rifamm = doc.clifor().vendite().get(CFV_PARIFAMM);
paf0200f.set("P2_RIFAMMINISTR", rifamm);
paf0200f.set("P2_ISCRREASOCIOU", _ditta.sociounico() == 'S' ? "SU" : "SM");
TISAM_recordset unloc("USE UNLOC\nJOIN COMUNI INTO COM==COMCCIAA\nFROM CODDITTA=#DITTA\nTO CODDITTA=#DITTA");
unloc.set_var("#DITTA", 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("PAF0400F");
paf0400f.set("P4_KEYHEADERFATT", _hfatt);
paf0400f.set("P4_KEYBODYFATT", _bfatt);
remove(paf0400f);
#ifndef DBG
if (cliente.partita_IVA().full())
{
paf0400f.set("P4_FISCIVAPAESE", cliente.stato_partita_IVA());
paf0400f.set("P4_FISCIVACOD", cliente.partita_IVA());
}
paf0400f.set("P4_CODFISC", cliente.codice_fiscale());
#else
paf0400f.set("P4_FISCIVAPAESE", "IT");
paf0400f.set("P4_FISCIVACOD", "00261170039");
#endif
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());
}
paf0400f.set("P4_GESTIONE", "D");
ok &= insert(paf0400f);
// </CessionarioCommittente>
// <DatiGenerali>
TPaf_record paf0700f("PAF0700F");
paf0700f.set("P7_KEYHEADERFATT", _hfatt);
paf0700f.set("P7_KEYBODYFATT", _bfatt);
remove(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", "D");
// <DatiBollo>
const bool set_bollo = doc.get_bool("ADDBOLLI");
if(!set_bollo)
{
doc.put("ADDBOLLI", true);
}
{
real imponibile = doc.imponibile(true);
paf0700f.set("P7_IMPORTOBOLLO", converti_prezzo(doc.bolli(imponibile, 8)));
}
// Nel dubbio risetto
doc.put("ADDBOLLI", set_bollo);
// </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("PAF2700F");
paf2700f.set("PQ_KEYHEADERFATT", _hfatt);
paf2700f.set("PQ_KEYBODYFATT", _bfatt);
remove(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);
TString causale = cont_conv_off.get("S1");
if (causale.full())
{
causale << ' ' << cont_conv_off.get("S2");
causale << ' ' << cont_conv_off.get("S3");
causale.strip_double_spaces();
causale.cut(200);
}
else
causale = doc.tipo().descrizione();
paf2700f.set("PQ_CAUSALE", causale);
// paf2700f.set("PQ_ART73", true);
paf2700f.set("PQ_GESTIONE", "D");
ok &= insert(paf2700f);
// </DatiGenerali>
// Azzera DDT
TPaf_record paf1600f("PAF1600F");
paf1600f.set("PF_KEYHEADERFATT", _hfatt);
paf1600f.set("PF_KEYBODYFATT", _bfatt);
remove(paf1600f);
// Fuori dallo scope per dopo
const TString16 cup = doc.get(DOC_CUP);
const TString16 cig = doc.get(DOC_CIG);
const TString80 com = doc.get(DOC_CODCMS);
// SEMPRE
// Azzera contratti
TPaf_record paf1000f("PAF1000F");
paf1000f.set("P0_KEYHEADERFATT", _hfatt);
paf1000f.set("P0_KEYBODYFATT", _bfatt);
paf1000f.set("P0_RIFNUMLINEA", 0L);
remove(paf1000f);
// Azzera convenzioni
TPaf_record paf1100f("PAF1100F");
paf1100f.set("PA_KEYHEADERFATT", _hfatt);
paf1100f.set("PA_KEYBODYFATT", _bfatt);
paf1100f.set("PA_RIFNUMLINEA", 0L);
remove(paf1100f);
// Azzera ordini
TPaf_record paf1200f("PAF1200F");
paf1200f.set("PB_KEYHEADERFATT", _hfatt);
paf1200f.set("PB_KEYBODYFATT", _bfatt);
paf1200f.set("PB_RIFNUMLINEA", 0L);
remove(paf1200f);
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", "D");
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", "D");
ok &= insert(paf1100f);
}
else
{
paf1200f.set("PB_RIFNUMLINEA", 0L);
paf1200f.set("PB_IDDOC", con);
paf1200f.set("PB_DATADOCO", datadoc);
paf1200f.set("PB_COMMESSACONV", com);
paf1200f.set("PB_CODCUP", cup);
paf1200f.set("PB_CODCIG", cig);
paf1200f.set("PB_GESTIONE", "D");
ok &= insert(paf1200f);
}
}
if (_is_pa && cup.blank() && cig.blank())
log(1, "CIG e CUP assenti");
// <DatiBeniServizi>
TPaf_record paf1800f("PAF1800F");
paf1800f.set("PI_KEYHEADERFATT", _hfatt);
paf1800f.set("PI_KEYBODYFATT", _bfatt);
remove(paf1800f); // Cancella tutte le righe documento
TPaf_record paf2000f("PAF2000F");
paf2000f.set("PJ_KEYHEADERFATT", _hfatt);
paf2000f.set("PJ_KEYBODYFATT", _bfatt);
remove(paf2000f); // Cancella tutti gli sconti di riga
TPaf_record paf2100f("PAF2100F");
paf2100f.set("PK_KEYHEADERFATT", _hfatt);
paf2100f.set("PK_KEYBODYFATT", _bfatt);
remove(paf2000f); // Cancella tutti i "altri dati gestionali"
TPaf_record paf1900f("PAF1900F");
paf1900f.set("PY_KEYHEADERFATT", _hfatt);
paf1900f.set("PY_KEYBODYFATT", _bfatt);
remove(paf1900f); // Cancella tutte le righe articoli del documento
TPaf_record paf3000f("PAF3000F");
paf3000f.set("PT_KEYHEADERFATT", _hfatt);
paf3000f.set("PT_KEYBODYFATT", _bfatt);
remove(paf3000f);
long riga = 1;
FOR_EACH_PHYSICAL_RDOC(doc, r, rdoc)
{
// Controllo la riga
if (check_row(*rdoc) && !fp_settings().get_check_not_block())
return false;
bool skip_riga = false;
paf1800f.reset();
paf1800f.set("PI_KEYHEADERFATT", _hfatt);
paf1800f.set("PI_KEYBODYFATT", _bfatt);
paf1800f.set("PI_NUMEROLINEA", riga);
const TString& descrizione_riga = descrizione(*rdoc);
if (descrizione_riga.empty())
continue;
paf3000f.reset();
paf3000f.set("PT_KEYHEADERFATT", _hfatt);
paf3000f.set("PT_KEYBODYFATT", _bfatt);
paf3000f.set("PT_RIFNUMLINEA", riga);
paf3000f.set("PT_COMMENTO", descrizione_riga);
// <CodiceArticolo>
if (rdoc->is_articolo())
{
TString codartmag = rdoc->get(RDOC_CODARTMAG);
TString codart = rdoc->get(RDOC_CODART);
long riga_art = 0;
if (codart.full())
{
if (codartmag.full())
{
paf1900f.reset();
paf1900f.set("PY_KEYHEADERFATT", _hfatt);
paf1900f.set("PY_KEYBODYFATT", _bfatt);
paf1900f.set("PY_KEYNLINEA", riga);
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)
{
paf1900f.reset();
paf1900f.set("PY_KEYHEADERFATT", _hfatt);
paf1900f.set("PY_KEYBODYFATT", _bfatt);
paf1900f.set("PY_KEYNLINEA", riga);
ok &= add_row_art(riga_art, "Codice articolo cliente", codart, paf1900f);
}
}
}
// </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(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
*/
TArray ancestors;
find_ancestors(*rdoc, ancestors);
for (int i = ancestors.last(); i > 0; i = ancestors.pred(i))
{
_has_bolla |= true;
const TAncestor& a = (const TAncestor&)ancestors[i];
if (i == 1)
{
// <DatiDDT>
paf1600f.reset();
paf1600f.set("PF_KEYHEADERFATT", _hfatt);
paf1600f.set("PF_KEYBODYFATT", _bfatt);
paf1600f.set("PF_RIFNUMLINEA", (long)r);
paf1600f.set("PF_NUMDDDT", a._numdoc);
paf1600f.set("PF_DATADDT", a._datadoc);
paf1600f.set("PF_GESTIONE", "D");
ok &= insert(paf1600f);
// </DatiDDT>
}
else if (i == 3)
{
// <DatiOrdineAcquisto>
paf1000f.set("P0_KEYHEADERFATT", _hfatt);
paf1000f.set("P0_KEYBODYFATT", _bfatt);
paf1000f.set("P0_RIFNUMLINEA", (long)r);
paf1000f.set("P0_IDDOC", a._numdoc);
paf1000f.set("P0_DATADOC", a._datadoc);
paf1000f.set("P0_COMMESSACONV", com);
paf1000f.set("P0_CODCUP", cup);
paf1000f.set("P0_CODCIG", cig);
paf1000f.set("P0_GESTIONE", "D");
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->importo(true, 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(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(true, false, 8);
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");
add_ritenuta(doc, rdoc->spesa(), paf0700f);
}
}
}
else if (rdoc->is_prestazione())
{
real qta = rdoc->get(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(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(1, msg);
}
paf1800f.set("PI_TIPOCESSPREST", "AB");
set_qta_prezzo(paf1800f, rdoc);
set_IVA(*rdoc, paf1800f);
paf2100f.set("PK_KEYNLINEA", static_cast<long>(r));
paf2100f.set("PK_KEYNLINAR", 1L);
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, 8));
paf1800f.set("PI_PREZZOUNIT", converti_prezzo(rdoc->prezzo(false, false, 8)));
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", "D");
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 (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", "D");
ok &= insert(paf2000f);
}
}
}
// </ScontoMaggiorazione>
if (!skip_riga)
{
paf1800f.set("PI_GESTIONE", "D");
ok &= insert(paf1800f) && insert(paf3000f);
riga++;
}
}
// Controllo plafond
// Riga esenzione?
if (doc.is_fattura())
{
doc.set_riga_esenzione();
if(doc.ha_riga_esenzione())
{
const TRiga_documento& riga_es = doc.get_riga_esenzione();
paf1800f.reset();
paf1800f.set("PI_KEYHEADERFATT", _hfatt);
paf1800f.set("PI_KEYBODYFATT", _bfatt);
paf1800f.set("PI_NUMEROLINEA", ++riga);
paf3000f.reset();
paf3000f.set("PT_KEYHEADERFATT", _hfatt);
paf3000f.set("PT_KEYBODYFATT", _bfatt);
paf3000f.set("PT_RIFNUMLINEA", riga);
paf3000f.set("PT_COMMENTO", descrizione(riga_es));
paf1800f.set("PI_QUANTITA", UNO);
paf1800f.set("PI_PREZZOUNIT", ZERO);
paf1800f.set("PI_PRZTOTALE", ZERO);
set_IVA(_codivadefault, paf1800f);
ok &= insert(paf1800f) && insert(paf3000f);
}
}
// Se il bollo va fatto pagare bisogna aggiungere una riga!
if(doc.get_bool("ADDBOLLI") && doc.get_real("BOLLI") > ZERO)
{
paf1800f.reset();
paf1800f.set("PI_KEYHEADERFATT", _hfatt);
paf1800f.set("PI_KEYBODYFATT", _bfatt);
paf1800f.set("PI_NUMEROLINEA", ++riga);
paf3000f.reset();
paf3000f.set("PT_KEYHEADERFATT", _hfatt);
paf3000f.set("PT_KEYBODYFATT", _bfatt);
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(doc.get_real("BOLLI")));
paf1800f.set("PI_PRZTOTALE", converti_prezzo(doc.get_real("BOLLI")));
set_IVA(doc.codiva_bolli(), paf1800f);
ok &= insert(paf1800f) && insert(paf3000f);
}
// OMAGGI????
// Aggiungo le spese incasso
if(doc.get_real("SPESINC") > ZERO)
{
paf1800f.reset();
paf1800f.set("PI_KEYHEADERFATT", _hfatt);
paf1800f.set("PI_KEYBODYFATT", _bfatt);
paf1800f.set("PI_NUMEROLINEA", ++riga);
paf3000f.reset();
paf3000f.set("PT_KEYHEADERFATT", _hfatt);
paf3000f.set("PT_KEYBODYFATT", _bfatt);
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, 6, _netto)));
paf1800f.set("PI_PRZTOTALE", converti_prezzo(doc.spese_incasso(imponibile, 6, _netto)));
set_IVA(doc.clifor().vendite().get("ASSFIS"), paf1800f);
ok &= insert(paf1800f) && insert(paf3000f);
}
// Conai assolto
if(doc.clifor().vendite().get_bool("CONAIASS"))
{
paf1800f.reset();
paf1800f.set("PI_KEYHEADERFATT", _hfatt);
paf1800f.set("PI_KEYBODYFATT", _bfatt);
paf1800f.set("PI_NUMEROLINEA", ++riga);
paf3000f.reset();
paf3000f.set("PT_KEYHEADERFATT", _hfatt);
paf3000f.set("PT_KEYBODYFATT", _bfatt);
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 sconto di testata
// Se è presente uno sconto in testata devo sottrarlo come riga sconto o lo SDI urla
if(doc.get(DOC_SCONTOPERC).full())
{
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);
paf1800f.reset();
paf1800f.set("PI_KEYHEADERFATT", _hfatt);
paf1800f.set("PI_KEYBODYFATT", _bfatt);
paf1800f.set("PI_NUMEROLINEA", ++riga);
paf3000f.reset();
paf3000f.set("PT_KEYHEADERFATT", _hfatt);
paf3000f.set("PT_KEYBODYFATT", _bfatt);
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);
}
}
// </DatiBeniServizi>
// <DatiDDT>
// Metto qua i dati DDT per capire se la fattura è accompagnatoria o deriva da bolla
TPaf_record paf1700f("PAF1700F");
paf1700f.set("PG_KEYHEADERFATT", _hfatt);
paf1700f.set("PG_KEYBODYFATT", _bfatt);
remove(paf1700f); // Cancella la riga del vettore
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(3, msg);
return false;
}
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("PAF2200F");
paf2200f.set("PL_KEYHEADERFATT", _hfatt);
paf2200f.set("PL_KEYBODYFATT", _bfatt);
remove(paf2200f); // Cancella tutte le righe di riepilogo IVA
const char* eiva = get_esigibilita_iva(doc);
long num_riep = 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);
if (!check_riepilogo(doc, riva) && !fp_settings().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("PAF2400F");
paf2400f.set("PN_KEYHEADERFATT", _hfatt);
paf2400f.set("PN_KEYBODYFATT", _bfatt);
remove(paf2400f); // Cancella i dati pagamento
TPagamento& pag = doc.pagamento();
doc.scadenze_recalc(); // Ricalcola array delle rate
TString_array& scad = doc.scadenze();
const int nrate = scad.items(); // Conta rate generate
const char* rateazione = pag.cond_pag_sdi(); // A rate (TP01) o una soluzione(TP02)?
paf2400f.set("PN_RIGA", ZERO); // Al momento non gestiamo più tipologie di pagamento per documento
paf2400f.set("PN_CONDPAGAMENTO", rateazione);
paf2400f.set("PN_GESTIONE", "D");
ok &= insert(paf2400f);
TPaf_record paf2500f("PAF2500F");
paf2500f.set("PO_KEYHEADERFATT", _hfatt);
paf2500f.set("PO_KEYBODYFATT", _bfatt);
remove(paf2500f); // Cancella tutte le rate
// Imposto i campi uguali per tutte le rate
paf2500f.set("PO_CONDPAGAMENTO", rateazione); // Condizione di pagamento PA
paf2500f.set("PO_CODICEPAGAM", pag.code()); // Condizione di pagamento CAMPO
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(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(1, TR("Non è presente il codice IBAN per il pagamento"));
}
for (int nr = 0; nr < nrate; nr++)
{
paf2500f.set("PO_RIGA", long(nr + 1)); // Numero rata
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", "D");
ok &= insert(paf2500f);
}
// </DatiPagamento>
if (_gestioneallegati)
{
TPaf_record paf2600f("PAF2600F");
paf2600f.set("PP_KEYHEADERFATT", _hfatt);
paf2600f.set("PP_KEYBODYFATT", _bfatt);
remove(paf2600f); // Cancella eventuali allegati
long nprogr = 0; // Numero di file allegati
// Se abilitato stampo il documento e lo allego
TFilename rep;
if (_allegafattura)
{
if (!dongle().active(RSAUT))
{
log(1, "Impossibile generare la fattura, il modulo RS non è abilitato!");
}
else if (!doc.tipo().main_print_profile(rep, 2))
{
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}
// 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"; // X: stampa su disco, P: provvisorio
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("PAFW300F");
pafw300f.set("PW_KEYHEADERFATT", _hfatt);
pafw300f.set("PW_KEYBODYFATT", _bfatt);
remove(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())
{
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() : _doc_rec(nullptr), _log(nullptr), _cache_insert(false), _rec_clifo(LF_CLIFO)
{
_ditta.init(LF_NDITTE, prefix().get_codditta());
_cofi = fp_settings().get_cofi_tras();
if (_cofi.blank())
_cofi = _ditta.codice_fiscale();
#ifdef DBG
_gestioneallegati = _allegafattura = false;
#else
_gestioneallegati = fp_settings().get_gest_alleg();
_allegafattura = fp_settings().get_allega_fat();
#endif
_def_fld = fp_settings().get_fld_dest();
if (!_def_fld.ends_with("\\"))
{
_def_fld << "\\";
}
_def_usr_fld = fp_settings().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";
}
TDoc_fp::~TDoc_fp()
{
commit();
if (_doc_rec != nullptr)
delete _doc_rec;
}