Files correlati : tf Commento : Aggiunto caso documento FF git-svn-id: svn://10.65.10.50/branches/R_10_00@24032 c028cbd2-c16b-5b4b-a496-9718f37d4682
1458 lines
41 KiB
C++
1458 lines
41 KiB
C++
#include "tf0.h"
|
||
#include "tf0100b.h"
|
||
|
||
#include "cglib03.h" // is_split_payment()
|
||
|
||
/* Utilities & Main App */
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////////
|
||
// Utilities
|
||
/////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
// Le funzioni quelle belle
|
||
TString getTipoDoc(int id)
|
||
{
|
||
TString ret;
|
||
switch(id)
|
||
{
|
||
case B_TIPO_AUTOFATT:
|
||
ret = "AF";
|
||
break;
|
||
case B_TIPO_FATTACQ:
|
||
ret = "FA";
|
||
break;
|
||
case B_TIPO_FATTFISC:
|
||
ret = "FF";
|
||
break;
|
||
case B_TIPO_FATTVEN:
|
||
ret = "FV";
|
||
break;
|
||
case B_TIPO_NOTC:
|
||
ret = "NC";
|
||
break;
|
||
case B_TIPO_NOTD:
|
||
ret = "ND";
|
||
break;
|
||
case B_TIPO_STORDOC:
|
||
ret = "ST";
|
||
break;
|
||
case B_TIPO_BOLLADOG:
|
||
ret = "BD";
|
||
break;
|
||
/*
|
||
case B_TIPO_CORRNINC:
|
||
ret = "CN";
|
||
break;
|
||
case B_TIPO_CORR:
|
||
ret = "CR";
|
||
break;
|
||
case B_TIPO_FATTSC:
|
||
ret = "FS";
|
||
break;
|
||
case B_TIPO_RICFIS:
|
||
ret = "RF";
|
||
break;
|
||
|
||
case B_TIPO_RICFISNI:
|
||
ret = "RN";
|
||
break;
|
||
case B_TIPO_SCONT:
|
||
ret = "SC";
|
||
break;
|
||
case B_TIPO_SCONTNI:
|
||
ret = "SN";
|
||
break;
|
||
*/
|
||
default:
|
||
ret = "ERR";
|
||
break;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
int getTipoDoc(TString id)
|
||
{
|
||
int ret = -1;
|
||
if(id == "AF") ret = B_TIPO_AUTOFATT;
|
||
else if(id == "BD") ret = B_TIPO_BOLLADOG;
|
||
// else if(id == "CN") ret = B_TIPO_CORRNINC;
|
||
// else if(id == "CR") ret = B_TIPO_CORR;
|
||
else if(id == "FA") ret = B_TIPO_FATTACQ;
|
||
else if(id == "FF") ret = B_TIPO_FATTFISC;
|
||
// else if(id == "FS") ret = B_TIPO_FATTSC;
|
||
else if(id == "FV") ret = B_TIPO_FATTVEN;
|
||
else if(id == "NC") ret = B_TIPO_NOTC;
|
||
else if(id == "ND") ret = B_TIPO_NOTD;
|
||
// else if(id == "RF") ret = B_TIPO_RICFIS;
|
||
// else if(id == "RN") ret = B_TIPO_RICFISNI;
|
||
// else if(id == "SC") ret = B_TIPO_SCONT;
|
||
// else if(id == "SN") ret = B_TIPO_SCONTNI;
|
||
else if(id == "ST") ret = B_TIPO_STORDOC;
|
||
return ret;
|
||
}
|
||
|
||
// Cerca una stringa all'interno di una SLIST (Potrebbe diventare una funzione di XVT.h)
|
||
static SLIST_ELT xvt_slist_find_str(SLIST list, const char* str)
|
||
{
|
||
SLIST_ELT e = NULL;
|
||
for (e = xvt_slist_get_first(list); e; e = xvt_slist_get_next(list, e))
|
||
{
|
||
const char* val = xvt_slist_get(list, e, NULL);
|
||
if (xvt_str_compare_ignoring_case(str, val) == 0)
|
||
break;
|
||
}
|
||
return e;
|
||
}
|
||
|
||
// Aggiorna il file dst se pi<70> vecchio di src (Potrebbe diventare una funzione di XVT.h)
|
||
bool xvt_fsys_fupdate(const char* src, const char* dst)
|
||
{
|
||
bool ok = false;
|
||
if (xvt_fsys_file_exists(src))
|
||
{
|
||
const long tsrc = xvt_fsys_file_attr(src, XVT_FILE_ATTR_MTIME);
|
||
if (tsrc > 0)
|
||
{
|
||
long tdst = 0;
|
||
if (xvt_fsys_file_exists(dst))
|
||
tdst = xvt_fsys_file_attr(dst, XVT_FILE_ATTR_MTIME);
|
||
if (tsrc > tdst)
|
||
ok = xvt_fsys_fcopy(src, dst) != 0;
|
||
}
|
||
}
|
||
|
||
return ok;
|
||
}
|
||
|
||
/* Ritorno il tipo di documento
|
||
* TD01: Fattura
|
||
* TD04: Nota di credito
|
||
* TD05: Nota di debito
|
||
* NO-> TD07: Fattura semplificata
|
||
* NO-> TD08: NC semplificata
|
||
* TD10: Fatt di acquisto intra beni
|
||
* TD11: Fatt di acquisto intra servizi
|
||
*/
|
||
const char* decodTipo(TToken_string* strarr)
|
||
{
|
||
TRectype mov = cache().get(LF_MOV, strarr->get(_numero));
|
||
TCausale caus(mov.get("CODCAUS"), mov.get_int("ANNOIVA"));
|
||
TString tipodoc; tipodoc << strarr->get(_codnum);
|
||
// Le autofatture possono essere solo di tipo TDO1 e le bolle doganali nel dubbio pure
|
||
if(tipodoc == "AF" || tipodoc == "BD" || tipodoc == "FF")
|
||
return "TD01";
|
||
else if(tipodoc == "FA" || tipodoc == "FV")
|
||
{
|
||
// Potrebbe essere normale o intra
|
||
if(!caus.intra())
|
||
return "TD01";
|
||
else
|
||
{
|
||
// Controlliamo se <20> di beni o servizi
|
||
// Per capire se sono beni o servizi devo prendere il movimento, e trovare quale dei due ha un importo pi<70> alto
|
||
TAssoc_array intraval;
|
||
TRelation r_moviva(LF_RMOVIVA);
|
||
TRectype filter(r_moviva.curr()); filter.put("NUMREG", strarr->get(_numero));
|
||
TCursor c_moviva(&r_moviva, "", 1, &filter, &filter);
|
||
for(c_moviva = 0; c_moviva.pos() < c_moviva.items(); ++c_moviva)
|
||
{
|
||
TRectype row = c_moviva.curr();
|
||
real importo = row.get_real("IMPONIBILE");
|
||
// La chiave deve essere formata da CODIVA, GRUPPO + CONTO + SOTTOCONTO
|
||
TString keyAssoc; keyAssoc << row.get("CODIVA") << "|" << row.get("GRUPPO") << "|" << row.get("CONTO") << "|" << row.get("SOTTOCONTO");
|
||
if(intraval.is_key(keyAssoc))
|
||
{
|
||
importo += *(real*)intraval.objptr(keyAssoc);
|
||
intraval.add(keyAssoc, importo, true);
|
||
}
|
||
else
|
||
{
|
||
intraval.add(keyAssoc, importo);
|
||
}
|
||
}
|
||
|
||
// Adesso che ho tutti i totali divisi per CODIVA e GCS vado a pescare il valore maggiore
|
||
TString keyMax = "";
|
||
real max = ZERO;
|
||
TString_array keys;
|
||
intraval.get_keys(keys);
|
||
for(int i = 0; i < keys.items(); i++)
|
||
{
|
||
TString key = *(TString*)keys.objptr(i);
|
||
real valItem = *(real*)intraval.objptr(key);
|
||
if(valItem > max)
|
||
{
|
||
keyMax = key;
|
||
max = valItem;
|
||
}
|
||
}
|
||
|
||
// Una volta che ho trovato il nostro vincitore vado a prendere il tipo di fattura dal GCS
|
||
TString keyPCon = keyMax.ssub(keyMax.find('|') + 1);
|
||
if(cache().get(LF_PCON, keyPCon, "RICSER") == "1")
|
||
return "TD11";
|
||
else
|
||
return "TD10";
|
||
}
|
||
}
|
||
else if(tipodoc == "NC")
|
||
return "TD04";
|
||
else if(tipodoc == "ND")
|
||
return "TD05";
|
||
else if(tipodoc == "ST")
|
||
{
|
||
// Devo capire a che documento <20> associato
|
||
TRelation r(LF_RMOV);
|
||
TRectype filter(r.curr());
|
||
filter.put("NUMREG", strarr->get(_numero));
|
||
TCursor c(&r, "", 1, &filter, &filter);
|
||
for(c = 0; c.pos() < c.items(); ++c)
|
||
{
|
||
TRectype r = c.curr();
|
||
if(r.get("TIPOC") == "C")
|
||
{
|
||
if(r.get("SEZIONE") == "D")
|
||
return "TD01";
|
||
else
|
||
return "TD04";
|
||
} else
|
||
if(r.get("TIPOC") == "F")
|
||
{
|
||
if(r.get("SEZIONE") == "A")
|
||
return "TD01";
|
||
else
|
||
return "TD04";
|
||
}
|
||
}
|
||
}
|
||
// Nel caso ritorno un valore che da errore
|
||
return "ERR0";
|
||
}
|
||
|
||
/* Salvo il record modificato in TFCustom */
|
||
bool saveRec(TToken_string row, bool esportato)
|
||
{
|
||
static TLocalisamfile trasfatt(LF_TRASFATT);
|
||
TString key = row.get(_numero); key << "|"<< row.get(_aliquota);
|
||
|
||
TRectype rCust = cache().get(LF_TRASFATT, key);
|
||
// Se la riga non esiste metto la chiave
|
||
if(rCust.empty())
|
||
{
|
||
rCust.put("NUMREG", row.get(_numero));
|
||
}
|
||
rCust.put("TIPO", row.get(_tipocf));
|
||
rCust.put("CODCF", row.get(_codcf));
|
||
rCust.put("OCCAS", row.get(_occas));
|
||
rCust.put("TIPODOC", row.get(_codnum));
|
||
rCust.put("NUMDOC", row.get(_numdoc));
|
||
rCust.put("DATAREG", row.get(_datareg));
|
||
rCust.put("DATADOC", row.get(_datadoc));
|
||
rCust.put("IMPONIBILE", row.get(_imponibile));
|
||
rCust.put("IMPOSTA", row.get(_importoIVA));
|
||
rCust.put("CODIVA", row.get(_aliquota));
|
||
rCust.put("AUTOFATT", row.get(_autofatt));
|
||
if(esportato)
|
||
{
|
||
TString invio = esportato? "I" : row.get(_invio);
|
||
rCust.put("TFINVIO", invio);
|
||
rCust.put("TFDATA", TDate(TODAY));
|
||
}
|
||
|
||
return rCust.write_rewrite(trasfatt) == NOERR;
|
||
}
|
||
|
||
inline const char * noSpecial(char a)
|
||
{
|
||
if(a == '<EFBFBD>')
|
||
return "a''";
|
||
else if(a == '<EFBFBD>' || a == '<EFBFBD>')
|
||
return "e''";
|
||
else if(a == '<EFBFBD>')
|
||
return "i''";
|
||
else if(a == '<EFBFBD>')
|
||
return "o''";
|
||
else if(a == '<EFBFBD>')
|
||
return "u''";
|
||
// Se non trovo nulla lo tolgo
|
||
return "";
|
||
}
|
||
|
||
bool bd2017()
|
||
{
|
||
static TDate today = TDate(TODAY), lastDay = TDate(31,12,2017);
|
||
return today <= lastDay;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////////
|
||
// TTrFa_record
|
||
/////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
// Imposta il valore di un campo variant
|
||
void TTrFa_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 TTrFa_record::set(const char* fld, long val)
|
||
{
|
||
const TVariant var(val);
|
||
set(fld, var);
|
||
}
|
||
|
||
// Imposta il valore di un campo stringa
|
||
void TTrFa_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 TTrFa_record::set(const char* fld, const TString& val)
|
||
{
|
||
const TVariant var(val);
|
||
set(fld, var);
|
||
}
|
||
|
||
// Imposta il valore di un campo numerico
|
||
void TTrFa_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 TTrFa_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 TTrFa_record::set(const char* fld, bool var)
|
||
{
|
||
set(fld, var ? "SI" : "NO");
|
||
}
|
||
|
||
// Legge il valore di un campo variant
|
||
const TVariant& TTrFa_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& TTrFa_record::var2str(const TString& fldname, const TVariant& var) const
|
||
{
|
||
const TFieldtypes vt = var.type();
|
||
if (vt == _realfld)
|
||
{
|
||
const real r = var.as_string();
|
||
TString& tmp = get_tmp_string();
|
||
tmp << '\'' << r.string() << '\'';
|
||
return tmp;
|
||
}
|
||
if (vt == _datefld)
|
||
{
|
||
TString& tmp = get_tmp_string();
|
||
tmp << '\'' << var.as_date().string(full, '-', full, full, amg_date) << '\'';
|
||
return tmp;
|
||
}
|
||
|
||
const TString& str = var.as_string();
|
||
|
||
bool apici = vt == _alfafld;
|
||
if (apici && str[0] != '0' && real::is_natural(str))
|
||
apici = false;
|
||
|
||
if (!apici)
|
||
return str;
|
||
|
||
TString& tmp = get_tmp_string();
|
||
TString& tmp2 = get_tmp_string();
|
||
tmp = str;
|
||
TString speciali = CARATTERI_SPECIALI;
|
||
for(int i = 0; i < speciali.len(); i++)
|
||
{
|
||
for (int a = str.rfind(speciali[i]); a >= 0; a--)
|
||
{
|
||
if (tmp[a] == speciali[i])
|
||
{
|
||
tmp2.cut(0) << tmp.left(a) << noSpecial(speciali[i]) << tmp.mid(a+1);
|
||
tmp = tmp2;
|
||
}
|
||
}
|
||
}
|
||
|
||
for (int a = str.rfind('\''); a >= 0; a--)
|
||
{
|
||
if (tmp[a] == '\'')
|
||
tmp.insert("'", a);
|
||
}
|
||
tmp.insert("'", 0);
|
||
tmp << '\'';
|
||
return tmp;
|
||
}
|
||
|
||
// Elimina il record in base ai campi chiave
|
||
bool TTrFa_record::remove()
|
||
{
|
||
TString256 query;
|
||
query << "DELETE FROM " << _table << " WHERE ";
|
||
int nkf = 0;
|
||
FOR_EACH_TOKEN(_key, fld)
|
||
{
|
||
const TVariant& var = get(fld);
|
||
if (!var.is_null())
|
||
{
|
||
if (nkf++ > 0)
|
||
query << " AND ";
|
||
query << fld << '=' << var2str(fld, var) ;
|
||
}
|
||
}
|
||
CHECKS(nkf >= 2, "Can't remove partial key on table ", (const char*)_table);
|
||
query << ';';
|
||
return xvt_sql_execute(_db, query, NULL, 0L) > 0;
|
||
}
|
||
|
||
// Callback per la sottostante funzione search()
|
||
static int tff_search_record(void* jolly, int cols, char** values, char** names)
|
||
{
|
||
TTrFa_record& rec = *(TTrFa_record*)jolly;
|
||
for (int i = 0; i < cols; i++)
|
||
rec.set(names[i], values[i]);
|
||
return 0;
|
||
}
|
||
|
||
// Carica un record in base ai campi chiave
|
||
bool TTrFa_record::search()
|
||
{
|
||
CHECKS(_fields.items() >= _key.items(), "Can't search partial key on table ", _table);
|
||
TString256 query;
|
||
query << "SELECT * FROM " << _table << " WHERE ";
|
||
FOR_EACH_TOKEN(_key, fld)
|
||
{
|
||
const TVariant& var = get(fld);
|
||
if (!var.is_null())
|
||
query << fld << '=' << var2str(fld, var) << " AND ";
|
||
}
|
||
query.rtrim(5);
|
||
query << ';';
|
||
return xvt_sql_execute(_db, query, tff_search_record, this) == 1;
|
||
}
|
||
|
||
// Carica un record in base ad un massimo di 3 campi chiave
|
||
bool TTrFa_record::search(const char* k1, const char* k2, const char* k3)
|
||
{
|
||
_fields.destroy();
|
||
|
||
set(_key.get(0), k1);
|
||
if (k2 && *k2)
|
||
set(_key.get(1), k2);
|
||
if (k3 && *k3)
|
||
set(_key.get(2), k3);
|
||
|
||
return search();
|
||
}
|
||
|
||
// Aggiunge un record al db
|
||
bool TTrFa_record::insert()
|
||
{
|
||
CHECKS(_fields.items() > _key.items(), "Can't insert empty record on table ", _table);
|
||
|
||
TString query, values;
|
||
query << "INSERT INTO " << _table << "\n(";
|
||
FOR_EACH_ASSOC_OBJECT(_fields, obj, fld, itm)
|
||
{
|
||
const TVariant& var = get(fld);
|
||
if (!var.is_null())
|
||
{
|
||
query << fld << ',';
|
||
values << var2str(fld, var) << ',';
|
||
}
|
||
}
|
||
query.rtrim(1); values.rtrim(1);
|
||
query << ")\nVALUES (" << values << ");";
|
||
return xvt_sql_execute(_db, query, NULL, 0L) == 1;
|
||
}
|
||
|
||
// Crea un record della tabella data ed imposta i nomi dei campi chiave
|
||
TTrFa_record::TTrFa_record(const char* table) : _table(table), _key(15, ',')
|
||
{
|
||
_key = ini_get_string("./tff.ini", table, "INDEX_1");
|
||
if (_key.empty())
|
||
{
|
||
// Cerco di costruire i nomi della chiave cercando la K, come in P1_KEYHEADERFATT
|
||
TConfig cfg("tff.ini", table);
|
||
TAssoc_array& fields = cfg.list_variables();
|
||
FOR_EACH_ASSOC_STRING(fields, obj, key, str)
|
||
{
|
||
if (key[3] == 'K')
|
||
_key.add(key);
|
||
}
|
||
}
|
||
CHECKS(!_key.empty_items(), "Invalid primary key for table ", table);
|
||
}
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////////
|
||
// TTrFa_app
|
||
/////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
void TTrFa_app::log(int severity, const char* msg)
|
||
{
|
||
if (severity < 0)
|
||
{
|
||
_logTFF = msg;
|
||
} else
|
||
if (_log == NULL)
|
||
{
|
||
_log = new TLog_report;
|
||
if (_logTFF.full())
|
||
{
|
||
TString txt;
|
||
txt << _logTFF << ": " << msg;
|
||
_log->log(severity, txt);
|
||
}
|
||
else
|
||
_log->log(severity, msg);
|
||
}
|
||
}
|
||
|
||
bool TTrFa_app::show_log()
|
||
{
|
||
bool ok = true;
|
||
if (_log)
|
||
{
|
||
_log->preview();
|
||
delete _log;
|
||
_log = NULL;
|
||
ok = noyes_box(TR("Si desidera procedere con la generazione file xml?"));
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
int TTrFa_app::parse_line(const TString& line, TString& var, TString& val) const
|
||
{
|
||
if (line.blank())
|
||
return 0;
|
||
|
||
if (line[0] == '[')
|
||
{
|
||
var = line.mid(1);
|
||
var.rtrim(1);
|
||
val.cut(0);
|
||
return 1;
|
||
}
|
||
|
||
const int equal = line.find('=');
|
||
if (equal < 6)
|
||
return 0;
|
||
var = line.left(equal); var.trim();
|
||
val = line.mid(equal+1); val.trim();
|
||
return 2;
|
||
}
|
||
|
||
bool TTrFa_app::create_table(TScanner& tff, const TString& table)
|
||
{
|
||
TString query, var, val;
|
||
if (xvt_sql_table_exists(_db, table))
|
||
{
|
||
SLIST fields = xvt_sql_list_fields(_db, table);
|
||
while (!tff.eof())
|
||
{
|
||
const TString& line = tff.line();
|
||
const int n = parse_line(line, var, val);
|
||
if (n <= 0)
|
||
break;
|
||
if (var.starts_with("INDEX_"))
|
||
break;
|
||
if (xvt_slist_find_str(fields, var) == NULL)
|
||
{
|
||
query.cut(0) << "ALTER TABLE " << table << " ADD COLUMN " << var << ' ' << val << " NOT NULL";
|
||
if (val.find("INT") >= 0 || val.find("NUM") >= 0)
|
||
query << " DEFAULT 0";
|
||
else
|
||
query << " DEFAULT ''";
|
||
query << ";";
|
||
xvt_sql_execute(_db, query, NULL, NULL); // Create table
|
||
}
|
||
}
|
||
xvt_slist_destroy(fields);
|
||
}
|
||
else
|
||
{
|
||
query << "CREATE TABLE " << table << " (";
|
||
while (!tff.eof())
|
||
{
|
||
const TString& line = tff.line();
|
||
const int n = parse_line(line, var, val);
|
||
if (n <= 0)
|
||
break;
|
||
if (n == 1)
|
||
{
|
||
tff.push(line);
|
||
break;
|
||
}
|
||
if (var.starts_with("INDEX_"))
|
||
{
|
||
query.rtrim(1); // toglie ultima ,
|
||
query << ");";
|
||
xvt_sql_execute(_db, query, NULL, NULL); // Create table
|
||
query.cut(0);
|
||
query << "CREATE UNIQUE INDEX "
|
||
<< table << "_1 ON " << table
|
||
<< " (" << val << ");";
|
||
xvt_sql_execute(_db, query, NULL, NULL); // Create index
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
query << "\n " << var << ' ' << val << " NOT NULL";
|
||
if (val.find("INT") >= 0 || val.find("NUM") >= 0)
|
||
query << " DEFAULT 0";
|
||
else
|
||
query << " DEFAULT ''";
|
||
query << ",";
|
||
}
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
bool TTrFa_app::create()
|
||
{
|
||
open_files(LF_MOV, LF_RMOV, LF_RMOVIVA, LF_TABCOM, LF_ANAG,
|
||
LF_CLIFO, LF_OCCAS, LF_CFVEN, LF_NDITTE, 0);
|
||
|
||
// Controllo preventivo dell'avvenuta conversione del tracciato record
|
||
TRectype rmoviva(LF_RMOVIVA);
|
||
|
||
//if (rmoviva.type("TFINVIO") != _boolfld)
|
||
//return error_box(TR("Database non convertito per il Trasferimento Elettronico"));
|
||
|
||
_ditta.init(LF_NDITTE, prefix().get_codditta());
|
||
|
||
_dbname = prefix().get_studio(); // base direcotry
|
||
_dbname.add("sql"); make_dir(_dbname);
|
||
TString16 d; d.format("TF%05ld.db", prefix().get_codditta());
|
||
_dbname.add(d);
|
||
|
||
bool create = !_dbname.exist();
|
||
_db = xvt_sql_open(_dbname, user(), "", _dbname.path());
|
||
if (_db == NULL)
|
||
return false;
|
||
|
||
if(create)
|
||
{
|
||
createDB();
|
||
}
|
||
|
||
return TSkeleton_application::create();
|
||
}
|
||
|
||
// Sincronizzo il DB SQL con quello di campo
|
||
bool TTrFa_app::syncronizeDB()
|
||
{
|
||
//xvt_sql_begin(_db);
|
||
|
||
return true;
|
||
}
|
||
|
||
bool TTrFa_app::createDB()
|
||
{
|
||
const TFilename ini = "tff.ini";
|
||
bool ok = ini.exist();
|
||
if (ok)
|
||
{
|
||
xvt_sql_begin(_db);
|
||
TScanner TFF(ini);
|
||
while (ok && !TFF.eof())
|
||
{
|
||
const TString& p = TFF.line();
|
||
if (p.starts_with("[TF") && p.ends_with("F]"))
|
||
{
|
||
TString16 table = p; table.strip("[]");
|
||
ok = create_table(TFF, table);
|
||
}
|
||
}
|
||
if(ok)
|
||
{
|
||
// Aggiungo il valore di default in TFNUM
|
||
TTrFa_record tfnum("TFNUM00F");
|
||
tfnum.set("PJNKEY", "00001");
|
||
tfnum.set("PJNINV", "0000000000");
|
||
ok = tfnum.insert();
|
||
}
|
||
if (ok)
|
||
xvt_sql_commit(_db);
|
||
else
|
||
xvt_sql_rollback(_db);
|
||
}
|
||
else
|
||
return cantread_box(ini);
|
||
|
||
return true;
|
||
}
|
||
|
||
bool TTrFa_app::copySSA()
|
||
{
|
||
TFilename tmp;
|
||
|
||
// Copia eventuali protezioni software
|
||
TString_array files;
|
||
if (list_files(SPESOMETROBASE "/*.ssa", files) == 0)
|
||
{
|
||
list_files("*.ssa", files);
|
||
FOR_EACH_ARRAY_ROW(files, i, row)
|
||
{
|
||
tmp = SPESOMETROBASE; tmp.add(*row);
|
||
xvt_fsys_fupdate(*row, tmp);
|
||
}
|
||
}
|
||
files.destroy();
|
||
if (list_files(SPESOMETROBASE "/*.ssa", files) != 1)
|
||
{
|
||
warning_box(FR("Nella cartella %s deve essere presente esattamente un file .ssa"), SPESOMETROBASE);
|
||
return false;
|
||
}
|
||
|
||
TFilename home;
|
||
xvt_sys_get_env("USERPROFILE", home.get_buffer(), home.size());
|
||
home.add("SoftwareSirio"); home.add(SPESOMETROBASE);
|
||
if (!dexist(home))
|
||
make_dir(home);
|
||
return true;
|
||
}
|
||
|
||
bool TTrFa_app::send(TTrFa_mask* msk)
|
||
{
|
||
// Controllo se <20> la prima esecuzione, in caso positivo chiedo se vuole controllare p.iva e cf
|
||
bool first = ini_get_bool(CONFIG_DITTA, "tf", "FirstExec", true);
|
||
if(first)
|
||
{
|
||
ini_set_bool(CONFIG_DITTA, "tf", "FirstExec", false);
|
||
if(yesno_box("Stai eseguendo il programma per la prima volta,\nvuoi controllare di avere tutti i Codici Fiscali e Partite IVA corrette?"))
|
||
{
|
||
TExternal_app checkApp("cg1 -2 L");
|
||
checkApp.run();
|
||
if(!yesno_box("Desideri proseguire con l'esportazione?"))
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Mi carico i miei dati
|
||
TSheet_field& sheet = msk->sfield(F_RIGHE);
|
||
// Booleano per appendere i record nel db
|
||
|
||
/***********************************************************************************************
|
||
* Esporto
|
||
***********************************************************************************************/
|
||
xvt_sql_begin(_db);
|
||
|
||
// Eseguo l'esportazione
|
||
bool ok = tff0100(sheet) && tff0400(sheet) && tff0700(sheet);
|
||
|
||
if(!ok)
|
||
{
|
||
log(-1, "WTF!?");
|
||
xvt_sql_rollback(_db);
|
||
message_box("Esportazione fallita");
|
||
return false;
|
||
}
|
||
if(xvt_sql_commit(_db))
|
||
{
|
||
message_box("Ho esportato correttamente!");
|
||
// Imposto l'esportazione
|
||
if(yesno_box("Vuoi segnare i record esportati?"))
|
||
{
|
||
if(setEsportato(sheet))
|
||
message_box("Record segnati correttamente!");
|
||
else
|
||
message_box("Ci sono stati degli errori durante la riscrittura dei records");
|
||
msk->setFilterChanged();
|
||
}
|
||
|
||
}
|
||
else
|
||
message_box("Errore durante il salvataggio delle modifiche");
|
||
return true;
|
||
}
|
||
|
||
TString TTrFa_app::getKey(TToken_string* strarr)
|
||
{
|
||
return strarr->get_char(_tipocf) == 'C' ? DTE_PROVV : DTR_PROVV;
|
||
}
|
||
|
||
TString TTrFa_app::getHeader(TToken_string* strarr)
|
||
{
|
||
/*
|
||
// Chiave header (20): TIPOCF(1) + NANANANANA(10) + CODCF(6)
|
||
TString header; header.format("%c3753N4108E%06ld", strarr->get_char(_tipocf), strarr->get_int(_codcf));
|
||
return header;
|
||
*/
|
||
|
||
/* Devo crearmi una struttura dove immagazzino delle strutture di clienti e all'interno ci metto i numeratori che mi chiedono
|
||
* Cos<6F> facendo mando a puttane persino l'append che potevo tranquillamente implementare prima e creare fastidiose query per capire dove cazzo sto
|
||
*/
|
||
// Chiave header (20): TIPOCF(1) + CODCF(6)
|
||
static long int idHeader = 0L;
|
||
|
||
// Cerco/Aggiungo il Clifo all'std::map
|
||
TString keyMap; keyMap << strarr->get_char(_tipocf) << "|" << strarr->get_int(_codcf);
|
||
clifoDoc app;
|
||
// Non <20> presente e lo inserisco per la chiave body
|
||
if(mCliDoc.find(keyMap) == mCliDoc.end())
|
||
{
|
||
idHeader++;
|
||
app.contCliFo = idHeader;
|
||
app.countDoc = 0L;
|
||
mCliDoc.insert(std::pair<TString,clifoDoc>(keyMap, app));
|
||
}
|
||
TString header; header.format("%c%06ld", strarr->get_char(_tipocf), strarr->get_int(_codcf));
|
||
// Ritorno l'header
|
||
return header;
|
||
}
|
||
|
||
TString TTrFa_app::getBody(TToken_string* strarr, bool add)
|
||
{
|
||
/*
|
||
// Chiave body (20): TIPODOC(2) + DATADOC[YEAR](4) + NUMDOC(7) + AAA(3) + CODALIQUOTA(4)
|
||
TDate datadoc(strarr->get(_datadoc));
|
||
TString body; body.format("%02s%04d%07s%04s", strarr->get(_codnum), datadoc.year(), strarr->get(_numdoc), strarr->get(_aliquota));
|
||
return body;
|
||
*/
|
||
|
||
/* Sembra che utilizzare identificatori chiari e sensati in questo mondo non <20> concesso, quindi adesso vi sbatto un bell'ID numerico
|
||
* Ok per OGNI cliente devo assegnarli un identificativo del numero della fattura
|
||
*/
|
||
TString keyMap; keyMap << strarr->get_char(_tipocf) << "|" << strarr->get_int(_codcf);
|
||
|
||
clifoDoc app = mCliDoc[keyMap];
|
||
if(add)
|
||
app.countDoc += 1;
|
||
mCliDoc[keyMap] = app;
|
||
|
||
TString body; body.format("%010d%010d", app.contCliFo, app.countDoc);
|
||
return body;
|
||
}
|
||
|
||
bool TTrFa_app::tff0100(TSheet_field& sheet)
|
||
{
|
||
const char* const paese = "IT";
|
||
static const TFirm& firm = prefix().firm();
|
||
|
||
// Controllo la presenza di clienti e fornitori
|
||
// Scandisco in maniera ignorante sperando di beccare subito un cliente e un fornitore
|
||
bool cli = false, fo = false;
|
||
FOR_EACH_SHEET_ROW(sheet, r, strarr)
|
||
{
|
||
IF_IS_ENABLED(strarr);
|
||
if(strarr->get_char(_tipocf) == 'C')
|
||
cli = true;
|
||
else
|
||
fo = true;
|
||
if(cli || fo) break;
|
||
}
|
||
bool ok = false;
|
||
if(cli)
|
||
{
|
||
ok = true;
|
||
TTrFa_record dte("TFF0100F");
|
||
|
||
// Controllo la presenza di un caricamento in attesa
|
||
if(dte.search(DTE_PROVV))
|
||
{
|
||
bool sent = dte.get("P1_KEYPRGINVIO").as_string() == DTE_PROVV;
|
||
if(sent)
|
||
{
|
||
TString msg = "<EFBFBD> presente un'altra esportazione non ancora elaborata vuoi eliminarla?";
|
||
if(yesno_box(msg))
|
||
{
|
||
if(!emptyTables(DTE_PROVV))
|
||
{
|
||
error_box("Fallita eliminazione record!!!");
|
||
return false;
|
||
}
|
||
}
|
||
else
|
||
return false;
|
||
}
|
||
}
|
||
|
||
dte.set("P1_KEYPRGINVIO", DTE_PROVV);
|
||
dte.set("P1_TRASMITTPAESE", paese);
|
||
dte.set("P1_TRASMITTCOD", "");
|
||
dte.set("P1_TIPOINVIO", "DTE");
|
||
dte.set("P1_GESTIONE", "");
|
||
ok = dte.insert();
|
||
if(!ok) return false;
|
||
ok = tff0200(DTE_PROVV);
|
||
if(!ok) return false;
|
||
}
|
||
if(fo)
|
||
{
|
||
ok = true;
|
||
TTrFa_record dtr("TFF0100F");
|
||
|
||
// Controllo la presenza di un caricamento in attesa
|
||
if(dtr.search(DTR_PROVV))
|
||
{
|
||
bool sent = dtr.get("P1_KEYPRGINVIO").as_string() == DTR_PROVV;
|
||
TString msg = "<EFBFBD> presente un'altra esportazione non ancora elaborata vuoi eliminarla?";
|
||
if(sent)
|
||
{
|
||
if(yesno_box(msg))
|
||
{
|
||
if(!emptyTables(DTR_PROVV))
|
||
{
|
||
error_box("Fallita eliminazione record!!!");
|
||
return false;
|
||
}
|
||
}
|
||
else
|
||
return false;
|
||
}
|
||
}
|
||
|
||
dtr.set("P1_KEYPRGINVIO", DTR_PROVV);
|
||
dtr.set("P1_TRASMITTPAESE", paese);
|
||
dtr.set("P1_TRASMITTCOD", "");
|
||
dtr.set("P1_TIPOINVIO", "DTR");
|
||
dtr.set("P1_GESTIONE", "");
|
||
ok = dtr.insert();
|
||
if(!ok) return false;
|
||
ok = tff0200(DTR_PROVV);
|
||
if(!ok) return false;
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TTrFa_app::tff0200(TString key)
|
||
{
|
||
/********************************************************************************************************************
|
||
* Cedeprest *
|
||
********************************************************************************************************************/
|
||
// <CedentePrestatore>
|
||
TTrFa_record tff0200f("TFF0200F");
|
||
tff0200f.set("P2_KEYPRGINVIO", key);
|
||
|
||
if (_ditta.partita_IVA().full())
|
||
{
|
||
tff0200f.set("P2_FISCIVAPAESE", _ditta.stato_partita_IVA()); // Sempre IT
|
||
tff0200f.set("P2_FISCIVACOD", _ditta.partita_IVA());
|
||
}
|
||
tff0200f.set("P2_CODFISCALE", _ditta.codice_fiscale());
|
||
if (_ditta.fisica())
|
||
{
|
||
tff0200f.set("P2_ANANOME", _ditta.nome());
|
||
tff0200f.set("P2_ANACOGNOME", _ditta.cognome());
|
||
}
|
||
else
|
||
{
|
||
tff0200f.set("P2_ANADENOMIN", _ditta.ragione_sociale());
|
||
}
|
||
|
||
// DatiSede
|
||
TString via = _ditta.via_residenza(), cap = _ditta.CAP_residenza(), nazione = _ditta.stato_residenza_ISO();
|
||
// Valori necessari, se non ci sono salto
|
||
if(via.full() && cap.full() && nazione.full())
|
||
{
|
||
tff0200f.set("P2_SEDEIND", via);
|
||
tff0200f.set("P2_SEDENRCIVICO", _ditta.civico_residenza().left(7));
|
||
tff0200f.set("P2_SEDECAP", cap);
|
||
tff0200f.set("P2_SEDECOMUNE", _ditta.comune_residenza());
|
||
if(_ditta.italiano()) // Campo ritornerebbe "EE" se estero
|
||
tff0200f.set("P2_SEDEPROV", _ditta.provincia_residenza());
|
||
tff0200f.set("P2_SEDENAZ", nazione);
|
||
}
|
||
|
||
myrfso = "";
|
||
if(haveRFSO(myrfso))
|
||
{
|
||
TRectype r_ana = cache().get(LF_ANAG, TString(myrfso.left(1)) << "|" << myrfso.sub(1));
|
||
if(r_ana.get_char("TIPORFSO") == 'S') // Stabile Organizzazione
|
||
{
|
||
TAnagrafica rfso(r_ana);
|
||
TString via = rfso.via_residenza(), cap = rfso.CAP_residenza(), nazione = rfso.stato_residenza_ISO();
|
||
|
||
tff0200f.set("P2_STABORGIND", via);
|
||
tff0200f.set("P2_STABORGNRCIVICO", rfso.civico_residenza().left(7));
|
||
tff0200f.set("P2_STABORGCAP", cap);
|
||
tff0200f.set("P2_STABORGCOMUNE", rfso.comune_residenza());
|
||
if(rfso.italiano())
|
||
tff0200f.set("P2_STABORGPROV", rfso.provincia_residenza());
|
||
tff0200f.set("P2_STABORGNAZ", nazione);
|
||
}
|
||
else // Rappresentante Fiscale
|
||
{
|
||
bool ok = tff0300(key, r_ana);
|
||
if(!ok) return false;
|
||
}
|
||
}
|
||
tff0200f.set("P2_GESTIONE", "");
|
||
return tff0200f.insert();
|
||
}
|
||
|
||
bool TTrFa_app::tff0300(TString key, TRectype r_ana)
|
||
{
|
||
// Il copy constructor non <20> accessibile (e non sar<61> io a modificarlo)
|
||
TAnagrafica rfso(r_ana);
|
||
|
||
// Per il nome e cognome non mi faccio gli stessi problemi con i cli/fo in quanto stiamo parlando di cose "nuove"
|
||
// Se il cliente ha messo nome e cognome insieme pu<70> bruciare nelle fiamme dei controlli dell'agenzia delle entrate
|
||
TString paiv = rfso.partita_IVA(), ragsoc = rfso.ragione_sociale(), nom = rfso.nome(), cog = rfso.cognome();
|
||
|
||
TTrFa_record tff0300f("TFF0300F");
|
||
tff0300f.set("P3_KEYPRGINVIO", key);
|
||
tff0300f.set("P3_FISCIVAPAESE", rfso.stato_residenza_ISO());
|
||
tff0300f.set("P3_FISCIVACODICE", paiv);
|
||
|
||
if(r_ana.get_char("TIPOA") == 'G')
|
||
{
|
||
tff0300f.set("P3_ANADENOMI", ragsoc);
|
||
}
|
||
else
|
||
{
|
||
TString nomCom = r_ana.get("RAGSOC");
|
||
tff0300f.set("P3_ANANOME", nom);
|
||
tff0300f.set("P3_ANACOGNOME", cog);
|
||
}
|
||
tff0300f.set("P3_GESTIONE", "D");
|
||
return tff0300f.insert();
|
||
}
|
||
|
||
bool TTrFa_app::tff0400(TSheet_field& sheet)
|
||
{
|
||
// Siccome non siamo in grado di fare delle join devo in qualche modo evitare di caricare clienti gi<67> caricati quindi mi salvo tutto in un bel TToken_string e controllo
|
||
// Era troppo complicato fare una join codice cliente con i documenti per prendere solo quelli valorizzati.
|
||
TToken_string clifoSent = "";
|
||
bool ok = true;
|
||
TProgress_monitor p(sheet.items(),"Caricamento Clienti/Fornitori");
|
||
FOR_EACH_SHEET_ROW(sheet, r, strarr)
|
||
{
|
||
if(!p.add_status())
|
||
return false;
|
||
|
||
IF_IS_ENABLED(strarr);
|
||
|
||
// Controllo il clifo, se non c'<27> lo aggiungo altrimenti salto sto giro
|
||
TString checkClifo; checkClifo << strarr->get_char(_tipocf) << strarr->get_long(_codcf);
|
||
if(clifoSent.get_pos(checkClifo) < 0)
|
||
clifoSent.add(checkClifo);
|
||
else
|
||
continue;
|
||
|
||
TVariant vtipocf = strarr->get(_tipocf), vcodcf = strarr->get(_codcf), voccas = strarr->get(_occas);
|
||
|
||
#ifdef DBG
|
||
if(vtipocf.as_string() == "C" && vcodcf.as_string() == "316")
|
||
bool tolla = true;
|
||
#endif
|
||
|
||
TRectype r_cedeprest = getCli(vtipocf.as_string(), vcodcf.as_string(), voccas.as_string());
|
||
TAnagrafica cedeprest;
|
||
|
||
// Con l'uscita di questo programma <20> stato messo un collegamento in prima nota
|
||
// per il fornitore a cui <20> riferita la bolla doganale
|
||
if(strcmp(strarr->get(_codnum),"BD") == 0)
|
||
{
|
||
TString codcf;
|
||
// Attenzione! Se <20> una riga inserita a mano dall'utente prendo lo stesso il fornitore della riga!
|
||
int movimento = strarr->get_int(_numero);
|
||
if(movimento >= MOV_CUSTOM)
|
||
codcf << strarr->get(_codcf);
|
||
else
|
||
codcf = cache().get(LF_MOV, strarr->get(_numero), "CFBOLLADOG");
|
||
r_cedeprest = getCli("F", codcf, "");
|
||
cedeprest.init('F', atol(codcf));
|
||
}
|
||
else
|
||
{
|
||
cedeprest.init(vtipocf.as_string()[0], vcodcf.as_int(), voccas.as_string());
|
||
}
|
||
|
||
TTrFa_record tff0400f("TFF0400F");
|
||
tff0400f.set("P4_KEYPRGINVIO", getKey(strarr));
|
||
tff0400f.set("P4_KEYHEADERFATT", getHeader(strarr));
|
||
|
||
// Autofattura
|
||
if(strcmp(strarr->get(_autofatt),"X") == 0)
|
||
{
|
||
tff0400f.set("P4_FISCIVAPAESE", _ditta.stato_partita_IVA());
|
||
tff0400f.set("P4_FISCIVACOD", _ditta.partita_IVA());
|
||
tff0400f.set("P4_CODFISC", _ditta.codice_fiscale());
|
||
}
|
||
else // Fattura normale
|
||
{
|
||
if (cedeprest.stato_partita_IVA().full() && cedeprest.partita_IVA().full())
|
||
{
|
||
tff0400f.set("P4_FISCIVAPAESE", cedeprest.stato_partita_IVA());
|
||
tff0400f.set("P4_FISCIVACOD", cedeprest.partita_IVA());
|
||
}
|
||
else
|
||
{
|
||
// Ovviamente tutte le bolle doganali fatte prima del rilascio
|
||
// non avranno questo campo compilato e quindi dovr<76> passare la partita IVA "OO99999999999"
|
||
// Controllo anche di essere in una data entro il 31/12/2017, dopo tale data sto ragionamento non <20> valido
|
||
if(strcmp(strarr->get(_codnum),"BD") == 0 && bd2017())
|
||
{
|
||
tff0400f.set("P4_FISCIVAPAESE", "OO");
|
||
tff0400f.set("P4_FISCIVACOD", "99999999999");
|
||
}
|
||
else
|
||
{
|
||
// Se <20> un estero non CEE prendo nella partita IVA metto l'identificativo fiscale
|
||
if(cedeprest.estero_non_CEE())
|
||
{
|
||
tff0400f.set("P4_FISCIVAPAESE", cedeprest.stato_partita_IVA());
|
||
tff0400f.set("P4_FISCIVACOD", cedeprest.codice_fiscale());
|
||
}
|
||
else
|
||
{
|
||
tff0400f.set("P4_CODFISC", cedeprest.codice_fiscale());
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if(cedeprest.ok()) // Con bolle doganali non a posto impazzisce
|
||
{
|
||
// Sono sicuro che se <20> di tipo 3,7 o 8 ha la ragione sociale
|
||
char tipo = r_cedeprest.get_char(CLI_ALLEG);
|
||
bool rsoc = cedeprest.giuridica() || (tipo == '3' || tipo == '7' || tipo == '8' || tipo == '\0');
|
||
bool privato = tipo == '6';
|
||
|
||
if (!rsoc)
|
||
{
|
||
// Bisogna fare un ragionamento pi<70> complesso, esistono ancora record salvati con Nome e Cognome nella prima parte
|
||
// e non divisi come si fa adesso quindi far<61> cos<6F>:
|
||
|
||
// Controllo se il nome <20> pieno
|
||
if(cedeprest.nome().full())
|
||
{
|
||
// La vita <20> bella faccio che scrivere
|
||
tff0400f.set("P4_ANANOME", cedeprest.nome());
|
||
tff0400f.set("P4_ANACOGNOME", cedeprest.cognome());
|
||
}
|
||
else
|
||
{
|
||
// Devo indovinare quale <20> il nome e il cognome
|
||
TToken_string nomeCog(cedeprest.cognome(), ' '); // Notare il separatore spazio
|
||
// Se ho solo un nominativo <20> una ditta per Diana
|
||
if(nomeCog.items() == 1)
|
||
{
|
||
rsoc = true;
|
||
}
|
||
// Controllo se ho solo un nome e un cognome
|
||
else if(nomeCog.items() == 2)
|
||
{
|
||
tff0400f.set("P4_ANANOME", nomeCog.get(1));
|
||
tff0400f.set("P4_ANACOGNOME", nomeCog.get(0));
|
||
}
|
||
else
|
||
{
|
||
TString cognome; cognome << nomeCog.get(0);
|
||
|
||
// Potrebbe essere un cognome tipo "De Fischello"
|
||
// Dai quante persone hanno pi<70> di 4 parole per nome e cognome?
|
||
if(privato || (cognome.len() >= 2 && cognome.len() <= 4))
|
||
{
|
||
// Controllo che non sia una Ragione sociale! Tipo "ZG di Gianluigi Zibello"
|
||
// Se <20> segnato privato me ne sbatto anche di sto controllo
|
||
if(privato || TString(nomeCog.get(1)).len() > 2)
|
||
{
|
||
cognome << " " << nomeCog.get(1);
|
||
TString nome;
|
||
for(int i = 2; i < nomeCog.items(); i++)
|
||
nome << nomeCog.get(i) << " ";
|
||
tff0400f.set("P4_ANANOME", nome);
|
||
tff0400f.set("P4_ANACOGNOME", cognome);
|
||
}
|
||
else
|
||
rsoc = true;
|
||
}
|
||
else
|
||
rsoc = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Ricontrollo!!!! rsoc potrebbe essere cambiato sopra
|
||
if(rsoc)
|
||
{
|
||
tff0400f.set("P4_ANADENOM", cedeprest.ragione_sociale());
|
||
}
|
||
|
||
tff0400f.set("P4_SEDEIND", cedeprest.via_residenza());
|
||
tff0400f.set("P4_SEDENRCIVICO", cedeprest.civico_residenza().left(7));
|
||
tff0400f.set("P4_SEDECAP", cedeprest.CAP_residenza());
|
||
tff0400f.set("P4_SEDECOMUNE", cedeprest.comune_residenza());
|
||
if(cedeprest.italiano()) // Campo ritornerebbe "EE" se estero
|
||
tff0400f.set("P4_SEDEPROV", cedeprest.provincia_residenza());
|
||
tff0400f.set("P4_SEDENAZ", cedeprest.stato_residenza_ISO());
|
||
}
|
||
tff0400f.set("P4_GESTIONE", "D");
|
||
|
||
ok = tff0400f.insert();
|
||
|
||
// Controllo dopo l'inserimento del tff0400
|
||
if(!ok) return false;
|
||
|
||
TString rfso = strarr->get(_rfso);
|
||
if(rfso.full())
|
||
{
|
||
TRectype r_ana = cache().get(LF_ANAG, TString(rfso.left(1)) << "|" << rfso.sub(1));
|
||
ok = r_ana.full() && tff3100(strarr, r_ana);
|
||
}
|
||
|
||
// E dopo l'inserimento del tff3100
|
||
if(!ok) return false;
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TTrFa_app::tff0700(TSheet_field& sheet)
|
||
{
|
||
|
||
/********************************************************************************************************************
|
||
* Fattura *
|
||
********************************************************************************************************************/
|
||
// Mentre per i clienti <20> una porcata per le fatture non posso fare altrimenti, potrebbe essere che i clienti mettono righe in fondo customizzate spezzando fatture
|
||
TToken_string fattSent = "";
|
||
bool ok = true;
|
||
TProgress_monitor p(sheet.items(), "Caricamento Fatture");
|
||
|
||
TString oldKey = "";
|
||
int numRiga;
|
||
|
||
FOR_EACH_SHEET_ROW(sheet, r, strarr)
|
||
{
|
||
if(!p.add_status())
|
||
return false;
|
||
|
||
IF_IS_ENABLED(strarr);
|
||
|
||
TString checkFatt; checkFatt << strarr->get_char(_tipocf) << "|" << strarr->get_long(_codcf) << "|" << strarr->get(_numdoc);
|
||
if(fattSent.get_pos(checkFatt) < 0)
|
||
{
|
||
fattSent.add(checkFatt);
|
||
|
||
// <DatiFatturaBody>
|
||
TTrFa_record tff0700f("TFF0700F");
|
||
tff0700f.set("P7_KEYPRGINVIO", getKey(strarr));
|
||
tff0700f.set("P7_KEYHEADERFATT", getHeader(strarr));
|
||
tff0700f.set("P7_KEYBODYFATT", getBody(strarr));
|
||
|
||
TString natura = strarr->get(_natura);
|
||
|
||
tff0700f.set("P7_TIPODOC", decodTipo(strarr));
|
||
|
||
// Controllo il tipo di esigilit<69>
|
||
tff0700f.set("P7_DATA", toDate(strarr->get(_datadoc)));
|
||
tff0700f.set("P7_NUMERO", strarr->get(_numdoc));
|
||
tff0700f.set("P7_DATAREG", toDate(strarr->get(_datareg))); // Obbligatoria nei DTR
|
||
tff0700f.set("P7_GESTIONE", "");
|
||
ok = tff0700f.insert();
|
||
|
||
// Controllo dopo l'inserimento del tff0700f
|
||
if(!ok) return false;
|
||
}
|
||
// In qualsiasi caso va messa la riga ma prima elaboro il numero della riga!
|
||
TString newKey = getBody(strarr, false);
|
||
if(oldKey != newKey)
|
||
{
|
||
numRiga = 1;
|
||
oldKey = newKey;
|
||
}
|
||
else
|
||
numRiga++;
|
||
ok = tff2200(strarr, numRiga);
|
||
|
||
// E dopo l'inserimento del tff2200
|
||
if(!ok) return false;
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TTrFa_app::tff2200(TToken_string* strarr, int nriga)
|
||
{
|
||
TTrFa_record tff2200f("TFF2200F");
|
||
tff2200f.set("PL_KEYPRGINVIO", getKey(strarr));
|
||
tff2200f.set("PL_KEYHEADERFATT", getHeader(strarr));
|
||
tff2200f.set("PL_KEYBODYFATT", getBody(strarr, false));
|
||
|
||
TString numriga; numriga.format("%020d", nriga);
|
||
|
||
tff2200f.set("PL_KEYBODYDETT", numriga);
|
||
|
||
tff2200f.set("PL_IMPONIBILE", real(strarr->get(_imponibile))); // Se li converto in real una volta passati vengono parsati da var2str nel formato che vuole l'agenzia delle entrate
|
||
tff2200f.set("PL_IMPOSTA", real(strarr->get(_importoIVA)));
|
||
real aliquota = cache().get("%IVA", strarr->get(_aliquota), "R0");
|
||
tff2200f.set("PL_ALIQUOTAIVA", aliquota);
|
||
TRectype thisMov = cache().get(LF_MOV, strarr->get(_numero));
|
||
tff2200f.set("PL_ESIGIVA", is_split_payment(thisMov) ? "S" : is_IVA_diff(thisMov) || is_IVAxCassa(thisMov) ? "D" : "I");
|
||
tff2200f.set("PL_NATURA", strarr->get(_natura));
|
||
real det(strarr->get(_detraibile));
|
||
// Nella conversione la vigola viene persa e 100,00 diventa 10.000 quindi divido
|
||
det /= CENTO;
|
||
if(det > ZERO)
|
||
{
|
||
tff2200f.set("PL_DETRAIBILE", det);
|
||
}
|
||
else if(false) // Sempre disabilitato!
|
||
{
|
||
tff2200f.set("PL_DEDUCIBILE", "SI");
|
||
}
|
||
|
||
tff2200f.set("PL_GESTIONE", "D");
|
||
return tff2200f.insert();
|
||
}
|
||
|
||
bool TTrFa_app::tff3100(TToken_string* strarr, TRectype r_ana)
|
||
{
|
||
TTrFa_record tff3100f("TFF3100F");
|
||
tff3100f.set("PH_KEYPRGINVIO", getKey(strarr));
|
||
tff3100f.set("PH_KEYHEADERFATT", getHeader(strarr));
|
||
if(_append)
|
||
tff3100f.remove();
|
||
|
||
TAnagrafica rfso(r_ana);
|
||
|
||
if(r_ana.get_char("TIPORFSO") == 'S') // Stabile Organizzazione
|
||
{
|
||
TString via = rfso.via_residenza(), cap = rfso.CAP_residenza(), nazione = rfso.stato_residenza_ISO();
|
||
|
||
tff3100f.set("PH_STABORGIND", via);
|
||
tff3100f.set("PH_STABORGNRCIVICO", rfso.civico_residenza().left(7));
|
||
tff3100f.set("PH_STABORGCAP", cap);
|
||
tff3100f.set("PH_STABORGCOMUNE", rfso.comune_residenza());
|
||
if(rfso.italiano())
|
||
tff3100f.set("PH_STABORGPROV", rfso.provincia_residenza());
|
||
tff3100f.set("PH_STABORGNAZ", nazione);
|
||
}
|
||
else // Rappresentante Fiscale
|
||
{
|
||
// La P.IVA del rappresentante fiscale deve essere in AT quindi non faccio alcun controllo,
|
||
// se il valore nullo perch<63> Extra CEE non <20> un errore di campo (Anche perch<63> che senso ha un RF extra CEE?)
|
||
|
||
TString paiv = rfso.partita_IVA(), ragsoc = rfso.ragione_sociale(), nom = rfso.nome(), cog = rfso.cognome();
|
||
|
||
tff3100f.set("PH_FISCIVAPAESE", rfso.stato_residenza_ISO());
|
||
tff3100f.set("PH_FISCIVACODICE", paiv);
|
||
|
||
if(r_ana.get_char("TIPOA") == 'G')
|
||
{
|
||
tff3100f.set("PH_ANADENOMI", ragsoc);
|
||
}
|
||
else
|
||
{
|
||
TString nomCom = r_ana.get("RAGSOC");
|
||
tff3100f.set("PH_ANANOME", nom);
|
||
tff3100f.set("PH_ANACOGNOME", cog);
|
||
}
|
||
}
|
||
tff3100f.set("PH_GESTIONE", "D");
|
||
return tff3100f.insert();
|
||
}
|
||
|
||
bool TTrFa_app::setEsportato(TSheet_field& sheet)
|
||
{
|
||
bool ok = true;
|
||
TProgress_monitor p(sheet.items(),"Segno l'esportazione sui records");
|
||
FOR_EACH_SHEET_ROW(sheet, r, strarr)
|
||
{
|
||
if(!p.add_status())
|
||
return false;
|
||
TString modificato = strarr->get(_forzata);
|
||
if(modificato == "X")
|
||
{
|
||
ok = saveRec(*strarr, true);
|
||
if(!ok) return false;
|
||
}
|
||
else
|
||
{
|
||
TRectype row = cache().get(LF_MOV, TString(strarr->get(_numero)));
|
||
char invio = strarr->get_char(_invio);
|
||
if(invio == 'F' || invio == 'X')
|
||
invio = 'I';
|
||
|
||
row.put("TFINVIO", invio);
|
||
row.put("TFDATA", TDate(TODAY).string());
|
||
ok = row.rewrite(TLocalisamfile(LF_MOV)) == NOERR;
|
||
if(!ok) return false;
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TTrFa_app::emptyTables(TString key)
|
||
{
|
||
TString query;
|
||
query << "DELETE FROM TFF0100F WHERE P1_KEYPRGINVIO = '" << key << "';\n";
|
||
query << "DELETE FROM TFF0200F WHERE P2_KEYPRGINVIO = '" << key << "';\n";
|
||
query << "DELETE FROM TFF0300F WHERE P3_KEYPRGINVIO = '" << key << "';\n";
|
||
query << "DELETE FROM TFF0400F WHERE P4_KEYPRGINVIO = '" << key << "';\n";
|
||
query << "DELETE FROM TFF0700F WHERE P7_KEYPRGINVIO = '" << key << "';\n";
|
||
query << "DELETE FROM TFF2200F WHERE PL_KEYPRGINVIO = '" << key << "';\n";
|
||
query << "DELETE FROM TFF3100F WHERE PH_KEYPRGINVIO = '" << key << "';\n";
|
||
return xvt_sql_execute(_db, query, NULL, NULL) >= 0;
|
||
}
|
||
|
||
void TTrFa_app::main_loop()
|
||
{
|
||
// Sposto SSA
|
||
if(!copySSA()) return;
|
||
|
||
TTrFa_mask msk("tf0100a");
|
||
|
||
while (msk.run() == K_ENTER)
|
||
{
|
||
if(msk.checkNotEmpty())
|
||
{
|
||
// Sistemo tutti i flag prima di inviare
|
||
msk.theFinalCheckDown();
|
||
send(&msk);
|
||
//ini_set_string(CONFIG_DITTA, "tf", "LastSend", ++TDate(msk.get(F_DATAFIN)));
|
||
}
|
||
}
|
||
}
|
||
|
||
bool TTrFa_app::destroy()
|
||
{
|
||
xvt_sql_close(_db); _db = NULL;
|
||
return TSkeleton_application::destroy();
|
||
}
|
||
|
||
int tf0100(int argc, char* argv[])
|
||
{
|
||
TTrFa_app t2t;
|
||
t2t.run(argc, argv, TR("Trasferimento Fatture Elettroniche"));
|
||
return 0;
|
||
} |