campo-sirio/pa/pa0100.cpp

1788 lines
50 KiB
C++
Raw Blame History

#include <applicat.h>
#include <automask.h>
#include <execp.h>
#include <golem.h>
#include <progind.h>
#include <reputils.h>
#include <tabutil.h>
#include <utility.h>
#include <agasys.h>
#include "../ve/velib05.h"
#include "../cg/cglib03.h"
#include "pa0.h"
#include "pa0100a.h"
#include "../fe/felib.h"
#include <anagiu.h>
#include <comuni.h>
#include <cfven.h>
#include <nditte.h>
#include <unloc.h>
#include "../cg/cfban.h"
/////////////////////////////////////////////////////////////////////////////////////
// Globals
/////////////////////////////////////////////////////////////////////////////////////
static XVT_SQLDB _db = NULL; // PAF sqlite db
/////////////////////////////////////////////////////////////////////////////////////
// Utilities
/////////////////////////////////////////////////////////////////////////////////////
// Crea la coppia di chiavi per il db PAF a partire da un documento vero e proprio
static bool chiave_paf(const TDocumento& doc, TString& cess, TString& numdoc)
{
cess = doc.clifor().vendite().get(CFV_PADESTIN);
CHECK(cess.full(), "Destinatario fattura P.A. non valido");
const TCodice_numerazione& codnum = doc.codice_numerazione();
const long ndoc = doc.numero();
TString16 fullnumdoc; codnum.complete_num(ndoc, fullnumdoc);
numdoc.cut(0) << doc.get(DOC_ANNO) << '/' << codnum.codice() << '/' << fullnumdoc;
return cess.full();
}
// Crea la coppia di chiavi per il db PAF a partire da un semplice record di testata documento
static bool chiave_paf(const TRectype& doc, TString& cess, TString& numdoc)
{
const long codcf = doc.get_long(DOC_CODCF);
TString8 key; key.format("C|%ld", codcf);
cess = cache().get(LF_CFVEN, key, CFV_PADESTIN);
CHECK(cess.full(), "Destinatario fattura P.A. non valido");
const TCodice_numerazione& codnum = cached_numerazione(doc.get(DOC_CODNUM));
const long ndoc = doc.get_long(DOC_NDOC);
TString16 fullnumdoc; codnum.complete_num(ndoc, fullnumdoc);
numdoc.cut(0) << doc.get(DOC_ANNO) << '/' << codnum.codice() << '/' << fullnumdoc;
return cess.full();
}
// Cerca una stringa all'interno di una SLIST (Potrebbe diventare una funzione di XVT.h)
static SLIST_ELT xvt_slist_find_str(SLIST list, const char* str)
{
SLIST_ELT e = NULL;
for (e = xvt_slist_get_first(list); e; e = xvt_slist_get_next(list, e))
{
const char* val = xvt_slist_get(list, e, NULL);
if (xvt_str_compare_ignoring_case(str, val) == 0)
break;
}
return e;
}
// Aggiorna il file dst se pi<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;
}
/////////////////////////////////////////////////////////////////////////////////////
// TJava_profile
/////////////////////////////////////////////////////////////////////////////////////
class TJava_profile : public TObject
{
TFilename _path;
TString_array _row;
bool _dirty;
protected:
const TString& path2prop(const char* path) const;
public:
void set(const char* key, const char* value);
void save();
TJava_profile(const char* path);
~TJava_profile() { if (_dirty) save(); }
};
// Converte una stringa in un percorso per un file profile di Java
const TString& TJava_profile::path2prop(const char* path) const
{
TString percorso;
for (const char* c = path; *c; c++)
{
if (*c == ':' || is_slash(*c))
percorso << '\\';
percorso << *c;
}
return get_tmp_string() = percorso;
}
void TJava_profile::set(const char* key, const char* value)
{
_dirty = true;
FOR_EACH_ARRAY_ROW(_row, r, line)
{
if (line->starts_with(key, true))
{
const int equal = line->find('=');
if (equal > 0)
{
line->cut(equal + 1);
*line << path2prop(value);
return;
}
}
}
TToken_string* prop = new TToken_string(50, '=');
prop->add(key); prop->add(path2prop(value));
_row.add(prop);
}
void TJava_profile::save()
{
ofstream out(_path);
if (out.good())
{
FOR_EACH_ARRAY_ROW(_row, r, line) if (line->full())
out << *line << endl;
_dirty = false;
}
else
cantwrite_box(_path);
}
TJava_profile::TJava_profile(const char* path) : _path(path), _dirty(false)
{
TScanner s(_path);
while (!s.eof())
{
const TString& line = s.line();
if (line.full())
_row.add(new TToken_string(line, '='));
else
break;
}
}
/////////////////////////////////////////////////////////////////////////////////////
// TAncestor
/////////////////////////////////////////////////////////////////////////////////////
struct TAncestor : public TObject
{
TString20 _numdoc;
TDate _datadoc;
TAncestor(const TRectype& rdoc);
};
TAncestor::TAncestor(const TRectype& rdoc)
{
const int anno = rdoc.get_int(RDOC_ANNO);
const TString4 codnum = rdoc.get(RDOC_CODNUM);
const long ndoc = rdoc.get_long(RDOC_NDOC);
const TCodice_numerazione& num = cached_numerazione(codnum);
TToken_string kdoc;
kdoc = rdoc.get(RDOC_PROVV);
kdoc.add(anno);
kdoc.add(codnum);
kdoc.add(ndoc);
const TRectype& doc = cache().get(LF_DOC, kdoc);
TString16 numdoc; num.complete_num(ndoc, numdoc);
_numdoc.format("%d/%s/%s", anno, (const char*)codnum, (const char*)numdoc);
_datadoc = doc.get_date(DOC_DATADOC);
}
/////////////////////////////////////////////////////////////////////////////////////
// TPaf_record
/////////////////////////////////////////////////////////////////////////////////////
// Contenitore di campi di un record di database SQLite
class TPaf_record : public TObject
{
TString8 _table;
TToken_string _key;
TAssoc_array _fields;
protected:
void copy(const TPaf_record& rec) { _table = rec._table; _key = rec._key; _fields = rec._fields; }
const TString& var2str(const TString& fld, const TVariant& var) const;
public:
void reset() { _fields.destroy(); }
void set(const char* fld, const TVariant& var);
void set(const char* fld, long var);
void set(const char* fld, const char* var);
void set(const char* fld, const real& var);
void set(const char* fld, const TString& var);
void set(const char* fld, const TDate& var);
void set(const char* fld, bool var);
const TVariant& get(const char* fld) const;
bool insert();
bool remove();
bool search();
bool search(const char* k1, const char* k2, const char* k3 = NULL);
virtual TObject* dup() const { return new TPaf_record(*this); }
virtual bool ok() const { return _table.not_empty(); }
TPaf_record& operator=(const TPaf_record& rec) { copy(rec); return *this; }
TPaf_record(const TPaf_record& rec) { copy(rec); }
TPaf_record(const char* table);
};
// Imposta il valore di un campo variant
void TPaf_record::set(const char* fld, const TVariant& var)
{
CHECK(fld && *fld, "Null field name");
if (var.is_null())
{
_fields.remove(fld);
}
else
{
TVariant* obj = (TVariant*)_fields.objptr(fld);
if (obj != NULL)
*obj = var;
else
_fields.add(fld, new TVariant(var));
}
}
// Imposta il valore di un campo intero
void TPaf_record::set(const char* fld, long val)
{
const TVariant var(val);
set(fld, var);
}
// Imposta il valore di un campo stringa
void TPaf_record::set(const char* fld, const char* val)
{
if (val == NULL)
set(fld, NULL_VARIANT);
else
{
const TVariant var(val);
set(fld, var);
}
}
// Imposta il valore di un campo stringa
void TPaf_record::set(const char* fld, const TString& val)
{
const TVariant var(val);
set(fld, var);
}
// Imposta il valore di un campo numerico
void TPaf_record::set(const char* fld, const real& val)
{
const TVariant var(val);
set(fld, var);
}
// Imposta il valore di un campo data in formato ISO
void TPaf_record::set(const char* fld, const TDate& val)
{
if (val.ok())
{
const TVariant var(val);
set(fld, var);
}
else
set(fld, "");
}
// Imposta il valore di un campo booleano
void TPaf_record::set(const char* fld, bool var)
{
set(fld, var ? "SI" : "NO");
}
// Legge il valore di un campo variant
const TVariant& TPaf_record::get(const char* fld) const
{
const TVariant* var = (const TVariant*)_fields.objptr(fld);
return var ? *var : NULL_VARIANT;
}
// Converte un variant in una stringa valida per SQLite
const TString& TPaf_record::var2str(const TString& fldname, const TVariant& var) const
{
const TFieldtypes vt = var.type();
if (vt == _realfld)
{
const TCurrency v(var.as_real(), "", ZERO, fldname.find("PRZ")>0 || fldname.find("PREZZO")>0);
TString& tmp = get_tmp_string();
tmp << '\'' << v.string() << '\''; tmp.replace(',','.');
return tmp;
}
if (vt == _datefld)
{
TString& tmp = get_tmp_string();
tmp << '\'' << var.as_date().string(full, '-', full, full, amg_date) << '\'';
return tmp;
}
const TString& str = var.as_string();
bool apici = vt == _alfafld;
if (apici && str[0] != '0' && real::is_natural(str))
apici = false;
if (!apici)
return str;
TString& tmp = get_tmp_string();
tmp = str;
for (int a = str.rfind('\''); a >= 0; a--)
{
if (tmp[a] == '\'')
tmp.insert("'", a);
}
tmp.insert("'", 0);
tmp << '\'';
return tmp;
}
// Elimina il record in base ai campi chiave
bool TPaf_record::remove()
{
TString256 query;
query << "DELETE FROM " << _table << " WHERE ";
int nkf = 0;
FOR_EACH_TOKEN(_key, fld)
{
const TVariant& var = get(fld);
if (!var.is_null())
{
if (nkf++ > 0)
query << " AND ";
query << fld << '=' << var2str(fld, var) ;
}
}
CHECKS(nkf >= 2, "Can't remove partial key on table ", (const char*)_table);
query << ';';
return xvt_sql_execute(_db, query, NULL, 0L) > 0;
}
// Callback per la sottostante funzione search()
static int paf_search_record(void* jolly, int cols, char** values, char** names)
{
TPaf_record& rec = *(TPaf_record*)jolly;
for (int i = 0; i < cols; i++)
rec.set(names[i], values[i]);
return 0;
}
// Carica un record in base ai campi chiave
bool TPaf_record::search()
{
CHECKS(_fields.items() >= _key.items(), "Can't search partial key on table ", _table);
TString256 query;
query << "SELECT * FROM " << _table << " WHERE ";
FOR_EACH_TOKEN(_key, fld)
{
const TVariant& var = get(fld);
if (!var.is_null())
query << fld << '=' << var2str(fld, var) << " AND ";
}
query.rtrim(5);
query << ';';
return xvt_sql_execute(_db, query, paf_search_record, this) == 1;
}
// Carica un record in base ad un massimo di 3 campi chiave
bool TPaf_record::search(const char* k1, const char* k2, const char* k3)
{
_fields.destroy();
set(_key.get(0), k1);
set(_key.get(1), k2);
if (k3 && *k3)
set(_key.get(2), k3);
return search();
}
// Aggiunge un record al db
bool TPaf_record::insert()
{
CHECKS(_fields.items() > _key.items(), "Can't insert empty record on table ", _table);
TString query, values;
query << "INSERT INTO " << _table << "\n(";
FOR_EACH_ASSOC_OBJECT(_fields, obj, fld, itm)
{
const TVariant& var = get(fld);
if (!var.is_null())
{
query << fld << ',';
values << var2str(fld, var) << ',';
}
}
query.rtrim(1); values.rtrim(1);
query << ")\nVALUES (" << values << ");";
return xvt_sql_execute(_db, query, NULL, 0L) == 1;
}
// Crea un record della tabella data ed imposta i nomi dei campi chiave
TPaf_record::TPaf_record(const char* table) : _table(table), _key(15, ',')
{
_key = ini_get_string("./paf.ini", table, "INDEX_1");
if (_key.empty())
{
// Cerco di costruire i nomi della chiave cercando la K, come in P1_KEYHEADERFATT
TConfig cfg("paf.ini", table);
TAssoc_array& fields = cfg.list_variables();
FOR_EACH_ASSOC_STRING(fields, obj, key, str)
{
if (key[3] == 'K')
_key.add(key);
}
}
CHECKS(!_key.empty_items(), "Invalid primary key for table ", table);
}
/////////////////////////////////////////////////////////////////////////////////////
// TPa_mask
/////////////////////////////////////////////////////////////////////////////////////
class TPA_mask : public TAutomask
{
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
void fill();
void init();
bool is_fattura(const TRectype& doc) const;
public:
TPA_mask() : TAutomask("pa0100a") { }
};
bool TPA_mask::is_fattura(const TRectype& doc) const
{
const TTipo_documento& td = cached_tipodoc(doc.get(DOC_TIPODOC));
if (!td.is_fattura()) // Tengo per buone solo le fatture e le note di credito
return false;
const TCodice_numerazione& cn = cached_numerazione(doc.get(DOC_CODNUM));
return cn.tipo() == 2 && !cn.get_bool("B10"); // Controlla se fattura provvisioria esclusa da P.A.
}
void TPA_mask::fill()
{
TSheet_field& docs = sfield(F_DOCS);
TString_array& sht = docs.rows_array();
docs.hide();
sht.destroy();
// Seleziona tutti i clienti che sono pubbliche amministrazioni (PADESTIN!='')
TString query;
query << "USE 17 SELECT PADESTIN!=''"
<< "\nJOIN 20 INTO TIPOCF=TIPOCF CODCF==CODCF"
<< "\nFROM TIPOCF=C\nTO TIPOCF=C";
TISAM_recordset clifo_pa(query);
const TRecnotype n = clifo_pa.items();
if (n > 0)
{
const TDate dal = get(F_DATAINI);
const bool hide_processed = !get_bool(F_SHOWALL);
// Record di controllo per eventuali elaborazioni precedenti
TString hfatt(8), bfatt(20);
TPaf_record paf0100f("PAF0100F");
TProgress_monitor pi(n, NULL);
for (bool okc = clifo_pa.move_first(); okc; okc = clifo_pa.move_next())
{
if (!pi.add_status())
break;
query.cut(0);
query << "USE 33 KEY 2\nSELECT (BETWEEN(STATO,2,8))";
query << "\nFROM TIPOCF=C CODCF=#CLIENTE PROVV=D ANNO=" << dal.year() << " DATADOC=" << dal.date2ansi()
<< "\nTO TIPOCF=C CODCF=#CLIENTE PROVV=D";
TISAM_recordset doc_pa(query);
doc_pa.set_var("#CLIENTE", clifo_pa.get(CLI_CODCF));
const TRectype& doc = doc_pa.cursor()->curr();
for (bool okd = doc_pa.move_first(); okd; okd = doc_pa.move_next())
{
const TTipo_documento& td = cached_tipodoc(doc.get(DOC_TIPODOC));
if (!td.is_fattura()) // Tengo per buone solo le fatture e le note di credito
continue;
bool sent = false;
if (chiave_paf(doc, hfatt, bfatt))
{
if (paf0100f.search(hfatt, bfatt))
{
sent = paf0100f.get("P1_GESTIONE").as_string() == "X";
if (sent && hide_processed)
continue;
}
}
TToken_string* row = new TToken_string;
*row = sent ? " " : "X";
row->add(doc_pa.get(DOC_ANNO).as_int(), 1);
row->add(doc_pa.get(DOC_CODNUM).as_string());
row->add(doc_pa.get(DOC_NDOC).as_int());
row->add(doc_pa.get(DOC_DATADOC).as_date());
row->add(clifo_pa.get(CFV_CODCF).as_int());
row->add(clifo_pa.get("20."CLI_RAGSOC).as_string());
row->add(clifo_pa.get(CFV_PADESTIN).as_string());
row->add(clifo_pa.get(CFV_PARIFAMM).as_string());
row->add(clifo_pa.get("20."CLI_COFI).as_string());
bool split = clifo_pa.get("20."CLI_SPLITPAY).as_bool();
if (split)
{
const long numreg = doc_pa.get(DOC_NUMREG).as_int();
if (numreg > 0)
{
const TRectype& mov = cache().get(LF_MOV, numreg);
split = is_split_payment(mov);
}
}
row->add(split ? "X" : " ");
const bool attach = !doc_pa.get("COLL_GOLEM").is_empty();
row->add(attach ? "X" : " ");
sht.add(row);
}
}
}
docs.force_update();
docs.show();
}
bool TPA_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case F_DATAINI:
if (e == fe_init)
o.set(ini_get_string(CONFIG_DITTA, "pa", "LastXML", "31-03-2015")); else
if (e == fe_modify)
fill(); else
if (e == fe_close)
ini_set_string(CONFIG_DITTA, "pa", "LastXML", o.get());
break;
case F_SHOWALL:
if (e == fe_modify)
fill();
break;
case F_DOCS:
if (e == fe_init)
fill();
if (e == se_query_add || e == se_query_del)
return false;
break;
case DLG_USER:
if (e == fe_button && jolly > 0)
{
TSheet_field& docs = sfield(F_DOCS);
TToken_string& row = docs.row(docs.selected());
TRectype doc(LF_DOC);
doc.put(DOC_PROVV, 'D');
doc.put(DOC_ANNO, row.get(1));
doc.put(DOC_CODNUM, row.get());
doc.put(DOC_NDOC, row.get());
if (doc.edit())
fill();
}
break;
default: break;
}
return true;
}
/////////////////////////////////////////////////////////////////////////////////////
// TDoc2Paf
/////////////////////////////////////////////////////////////////////////////////////
class TDoc2Paf : public TSkeleton_application
{
TAnagrafica _ditta;
TString16 _cofi;
TFilename _dbname;
TLog_report* _log;
TString _logpaf;
private:
int parse_line(const TString& line, TString& var, TString& val) const;
bool create_table(TScanner& paf, const TString& table);
const TRectype* find_parent_row(const TRectype& rdoc) const;
int find_ancestors(const TRiga_documento& rdoc, TArray& ancestors) const;
protected:
bool parse_sconto(const TString& formula, TToken_string& sconti) const;
bool get_bnp_iban(const TString& abi, const TString& cab, int prg, TString& iban) const;
bool get_bank(const TDocumento& doc, TString& iban, TString& abi, TString& cab, TString& istituto) const;
const char* descrizione(const TRiga_documento& rdoc) const;
const TRectype& cco(const TRectype& doc) const; // Contratto/Convenzione/Offerta
void log(int severity, const char* msg);
bool show_log();
void set_IVA(const TRiga_documento& rdoc, TPaf_record& paf) const;
bool elabora(TDocumentoEsteso& doc);
bool elabora(const TRectype& rec);
bool elabora(const TDoc_key& key);
bool elabora(const TFilename& ini);
bool genera_xml();
public:
virtual bool create();
virtual bool destroy();
virtual void main_loop();
TDoc2Paf() : _log(NULL) {}
};
bool TDoc2Paf::parse_sconto(const TString& formula, TToken_string& sconti) const
{
sconti.cut(0);
int start = 0;
for (int i = 0; ; i++)
{
const char c = formula[i];
if (c == '+' || c == '-' || c < ' ')
{
if (i > 0)
{
TString8 tok = formula.sub(start, i);
tok.replace(',', '.');
const real perc = tok;
if (!perc.is_zero())
sconti.add(tok);
}
if (c < ' ')
break;
start = i;
}
}
return sconti.full();
}
bool TDoc2Paf::get_bnp_iban(const TString& abi, const TString& cab, int nprog, TString& iban) const
{
TTable bnp("BNP");
TString16 key;
key << abi << cab;
if (nprog > 0)
{
TString4 sprog; sprog.format("%02d", nprog);
key << sprog;
}
bnp.put("CODTAB", key);
int err = bnp.read(_isgteq);
if (err == NOERR && !bnp.get("CODTAB").starts_with(abi))
err = _iskeynotfound;
if (err == NOERR)
iban = bnp.get("S3");
return err == NOERR;
}
bool TDoc2Paf::get_bank(const TDocumento& doc, TString& iban, TString& abi, TString& cab, TString& istituto) const
{
bool found = false;
abi = doc.get(DOC_CODABIP);
cab = doc.get(DOC_CODCABP);
int prg = doc.get_int(DOC_PROGBNP);
found = abi.full() && cab.full();
if (found)
get_bnp_iban(abi, cab, prg, iban);
if (!found) // Se non trovo banca sul DOC la cerco su CFBAN
{
TToken_string key;
key.add("C"); key.add(doc.codcf()); key.add("N"); key.add(1);
const TRectype& cfban = cache().get(LF_CFBAN, key);
if (!cfban.empty())
{
abi = cfban.get(CFBAN_ABI);
cab = cfban.get(CFBAN_CAB);
prg = cfban.get_int(CFBAN_PROGPR);
found = abi.full() && cab.full();
iban = cfban.get(CFBAN_IBAN);
if (found && iban.blank())
get_bnp_iban(abi, cab, prg, iban);
}
}
if (!found) // Se non trovo banca su CFBAN la cerco su CFVEN
{
const TRectype& cfven = doc.clifor().vendite();
abi = cfven.get(CFV_CODABIPR);
cab = cfven.get(CFV_CODCABPR);
found = abi.full() && cab.full();
if (found)
get_bnp_iban(abi, cab, 0, iban);
}
if (found)
istituto = cache().get("%BAN", abi, "S0");
return found;
}
const char* TDoc2Paf::descrizione(const TRiga_documento& rdoc) const
{
if (rdoc.get_bool(RDOC_DESCLUNGA))
{
TString tmp;
tmp << rdoc.get(RDOC_DESCR) << rdoc.get(RDOC_DESCEST);
tmp.replace('\n', ' '); tmp.strip_double_spaces(); tmp.trim();
TParagraph_string para(tmp, 100);
return para.get(0);
}
return rdoc.get(RDOC_DESCR);
}
const TRectype* TDoc2Paf::find_parent_row(const TRectype& rdoc) const
{
const long id = rdoc.get_long(RDOC_DAIDRIGA);
if (id > 0L)
{
TToken_string key;
key.add(rdoc.get(RDOC_DACODNUM));
if (key.full())
{
key.add(rdoc.get(RDOC_DAANNO));
key.add(rdoc.get(RDOC_DAPROVV));
key.add(rdoc.get(RDOC_DANDOC));
for (int r = 0; ; r++)
{
if (r == 0)
key.add(id, 4);
else
key.add(r, 4);
const TRectype& rec = cache().get(LF_RIGHEDOC, key);
if (r > 0 && rec.empty())
break;
if (rec.get_long(RDOC_IDRIGA) == id)
return &rec;
}
}
}
return NULL;
}
int TDoc2Paf::find_ancestors(const TRiga_documento& rdoc, TArray& ancestors) const
{
if (rdoc.is_articolo())
{
for (const TRectype* prdoc = find_parent_row(rdoc); prdoc != NULL; prdoc = find_parent_row(*prdoc))
{
const TCodice_numerazione& cn = cached_numerazione(prdoc->get(RDOC_CODNUM));
const int td = cn.tipo();
if (td > 0 && ancestors.objptr(td) == NULL)
ancestors.add(new TAncestor(*prdoc), td);
}
}
return ancestors.items();
}
const TRectype& TDoc2Paf::cco(const TRectype& doc) const
{
TString80 conkey;
const TString& con = doc.get(DOC_CONTRATTO);
if (con.full())
{
char tcon = doc.get_char(DOC_MODPAG);
if (tcon < 'C') tcon = 'C';
conkey.format("%c%6ld%s", tcon, doc.get_long(DOC_CODCF), (const char*)con);
}
return cache().get("&CON", conkey);
}
void TDoc2Paf::log(int severity, const char* msg)
{
if (severity < 0)
{
_logpaf = msg;
} else
if (_log == NULL)
{
_log = new TLog_report;
if (_logpaf.full())
{
TString txt;
txt << _logpaf << ": " << msg;
_log->log(severity, txt);
}
else
_log->log(severity, msg);
}
}
bool TDoc2Paf::show_log()
{
bool ok = true;
if (_log)
{
_log->preview();
delete _log;
_log = NULL;
ok = noyes_box(TR("Si desidera procedere con la generazione file xml?"));
}
return ok;
}
void TDoc2Paf::set_IVA(const TRiga_documento& rdoc, TPaf_record& paf) const
{
const TRectype& ai = cache().get("%IVA", rdoc.get(RDOC_CODIVA));
const real aliquota = ai.get("R0");
paf.set("PI_ALIQUOTAIVA", aliquota);
if (aliquota.is_zero())
{
const TString& tipo = ai.get("S1");
const char* natura = "N2"; // Non soggetto
if (tipo == "NI") natura = "N3"; else // Non imponibile
if (tipo == "ES") natura = "N4"; // Esente
paf.set("PI_NATURA", natura);
}
}
bool TDoc2Paf::elabora(TDocumentoEsteso& doc)
{
TString8 hfatt; // Codice univoco di 6 caratteri dell'ufficio P.A.
TString20 bfatt; // Codice univoco di 20 caratteri del documento
if (!chiave_paf(doc, hfatt, bfatt))
return false;
log(-1, bfatt);
const TFirm& firm = prefix().firm();
const char* const paese = "IT";
// <DatiTrassmissione>
TPaf_record paf0100f("PAF0100F");
paf0100f.set("P1_KEYHEADERFATT", hfatt);
paf0100f.set("P1_KEYBODYFATT", bfatt);
paf0100f.remove();
paf0100f.set("P1_TRASMITTPAESE", paese);
paf0100f.set("P1_TRASMITTCOD", _cofi);
paf0100f.set("P1_PRGINVIO", ""); // Ci pensa SiAggPA
paf0100f.set("P1_FMTTRASMISS", "SDI11"); // SDI11 si usa dal 2015 per lo split payment (prima era SDI10)
paf0100f.set("P1_CODDEST", hfatt);
TString80 tel; tel << firm.get(NDT_PTEL) << firm.get(NDT_TEL);
paf0100f.set("P1_TELEFONO", tel);
paf0100f.set("P1_MAIL", firm.get(NDT_MAIL));
paf0100f.set("P1_GESTIONE", "D");
paf0100f.insert();
// </DatiTrassmissione>
// <CedentePrestatore>
TPaf_record paf0200f("PAF0200F");
paf0200f.set("P2_KEYHEADERFATT", hfatt);
paf0200f.set("P2_KEYBODYFATT", bfatt);
paf0200f.remove();
if (_ditta.partita_IVA().full())
{
paf0200f.set("P2_FISCIVAPAESE", paese); // Sempre IT
paf0200f.set("P2_FISCIVACOD", _ditta.partita_IVA());
}
paf0200f.set("P2_CODFISCALE", _ditta.codice_fiscale());
if (_ditta.fisica())
{
paf0200f.set("P2_ANANOME", _ditta.nome());
paf0200f.set("P2_ANACOGNOME", _ditta.cognome());
}
else
{
paf0200f.set("P2_ANADENOMIN", _ditta.ragione_sociale());
}
const char* regime_fiscale = "RF01";
if (doc.get_bool(DOC_IVAXCASSA))
{
// Supponiamo volume d'affari > 200000, altrimenti sarebbe RF17
regime_fiscale = "RF16";
}
paf0200f.set("P2_REGFISCALE", regime_fiscale);
// DatiSede
paf0200f.set("P2_SEDEIND", _ditta.via_residenza());
paf0200f.set("P2_SEDENRCIVICO", _ditta.civico_residenza());
paf0200f.set("P2_SEDECAP", _ditta.CAP_residenza());
paf0200f.set("P2_SEDECOMUNE", _ditta.comune_residenza());
paf0200f.set("P2_SEDEPROV", _ditta.provincia_residenza());
paf0200f.set("P2_SEDENAZ", paese);
paf0200f.set("P2_GESTIONE", "D");
TAnagrafica cliente(doc.clifor());
TString rifamm = cco(doc).get("S4");
if (rifamm.blank())
rifamm = doc.clifor().vendite().get(CFV_PARIFAMM);
paf0200f.set("P2_RIFAMMINISTR", rifamm);
TISAM_recordset unloc("USE UNLOC\nJOIN COMUNI INTO COM==COMCCIAA\nFROM CODDITTA=#DITTA\nTO CODDITTA=#DITTA");
unloc.set_var("#DITTA", firm.get(NDT_CODDITTA));
if (unloc.move_first())
{
const TString& numrea = unloc.get(ULC_NUMCCIAA).as_string();
if (numrea.full())
{
paf0200f.set("P2_ISCRREANUM", numrea);
paf0200f.set("P2_ISCRREAUFF", unloc.get("13->"COM_PROVCOM));
}
}
if (_ditta.giuridica())
{
TISAM_recordset anagiu("USE ANAGIU\nFROM CODANAGR=#CODICE\nTO CODANAGR=#CODICE");
anagiu.set_var("#CODICE", firm.get(NDT_CODANAGR));
if (anagiu.move_first())
{
paf0200f.set("P2_ISCRREACAP", anagiu.get(ANG_CAPSOC));
const int ss = anagiu.get(ANG_STATOSOC).as_int();
paf0200f.set("P2_ISCRREASLIQUID", (ss==2 || ss==3) ? "LS" : "LN");
}
}
else
paf0200f.set("P2_ISCRREASLIQUID", "LN");
paf0200f.insert();
// </CedentePrestatore>
// <CessionarioCommittente>
TPaf_record paf0400f("PAF0400F");
paf0400f.set("P4_KEYHEADERFATT", hfatt);
paf0400f.set("P4_KEYBODYFATT", bfatt);
paf0400f.remove();
if (cliente.partita_IVA().full())
{
paf0400f.set("P4_FISCIVAPAESE", paese);
paf0400f.set("P4_FISCIVACOD", cliente.partita_IVA());
}
paf0400f.set("P4_CODFISC", cliente.codice_fiscale());
if (cliente.fisica())
{
paf0400f.set("P4_ANANOME", cliente.nome());
paf0400f.set("P4_ANACOGNOME", cliente.cognome());
}
else
{
paf0400f.set("P4_ANADENOM", cliente.ragione_sociale());
}
// DatiSede
paf0400f.set("P4_SEDEIND", cliente.via_residenza());
paf0400f.set("P4_SEDENRCIVICO", cliente.civico_residenza());
paf0400f.set("P4_SEDECAP", cliente.CAP_residenza());
paf0400f.set("P4_SEDECOMUNE", cliente.comune_residenza());
paf0400f.set("P4_SEDEPROV", cliente.provincia_residenza());
paf0400f.set("P4_SEDENAZ", "IT");
paf0400f.set("P4_GESTIONE", "D");
paf0400f.insert();
// </CessionarioCommittente>
// <DatiGenerali>
TPaf_record paf0700f("PAF0700F");
paf0700f.set("P7_KEYHEADERFATT", hfatt);
paf0700f.set("P7_KEYBODYFATT", bfatt);
paf0700f.remove();
paf0700f.set("P7_TIPODOC", doc.is_nota_credito() ? "TD04" : "TD01");
paf0700f.set("P7_DIVISA", "EUR"); // Aggiungere codice ISO 4217 a tabella divise (%VAL)
paf0700f.set("P7_DATA", doc.data());
const TCodice_numerazione& codnum = doc.codice_numerazione();
TString20 numdoc; codnum.complete_num(doc.numero(), numdoc);
paf0700f.set("P7_NUMERO", numdoc);
paf0700f.set("P7_GESTIONE", "D");
paf0700f.insert();
// <ScontoMaggiorazione>
TPaf_record paf0900f("PAF0900F");
paf0900f.set("P9_KEYHEADERFATT", hfatt);
paf0900f.set("P9_KEYBODYFATT", bfatt);
paf0900f.remove();
TString80 sconto_expr = doc.get(DOC_SCONTOPERC);
TToken_string sconti;
if (parse_sconto(sconto_expr, sconti))
{
long nlin_sconto = 0;
FOR_EACH_TOKEN(sconti, str)
{
const real sconto = str;
if (!sconto.is_zero()) // Precauzione inutile
{
paf0900f.set("P9_RIFNUMLINEA", ++nlin_sconto);
if (sconto > ZERO)
{
paf0900f.set("P9_TIPOSCONTO", "SC");
paf0900f.set("P9_PERCSCONTO", sconto);
}
else
{
paf0900f.set("P9_TIPOSCONTO", "MG");
paf0900f.set("P9_PERCSCONTO", -sconto);
}
paf0900f.set("P9_GESTIONE", "D");
paf0900f.insert();
}
}
}
// </ScontoMaggiorazione>
// <DatiGenerali>
TPaf_record paf2700f("PAF2700F");
paf2700f.set("PQ_KEYHEADERFATT", hfatt);
paf2700f.set("PQ_KEYBODYFATT", bfatt);
paf2700f.remove();
paf2700f.set("PQ_IMPTOTDOC", doc.totale_doc());
const TRectype& cont_conv_off = cco(doc);
TString causale = cont_conv_off.get("S1");
if (causale.full())
{
causale << ' ' << cont_conv_off.get("S2");
causale << ' ' << cont_conv_off.get("S3");
causale.strip_double_spaces();
causale.cut(200);
}
else
causale = doc.tipo().descrizione();
paf2700f.set("PQ_CAUSALE", causale);
// paf2700f.set("PQ_ART73", true);
paf2700f.set("PQ_GESTIONE", "D");
paf2700f.insert();
// </DatiGenerali>
// Azzera contratti
TPaf_record paf1000f("PAF1000F");
paf1000f.set("P0_KEYHEADERFATT", hfatt);
paf1000f.set("P0_KEYBODYFATT", bfatt);
paf1000f.remove();
// Azzera convenzioni
TPaf_record paf1100f("PAF1100F");
paf1100f.set("PA_KEYHEADERFATT", hfatt);
paf1100f.set("PA_KEYBODYFATT", bfatt);
paf1100f.remove();
// Azzera ordini
TPaf_record paf1200f("PAF1200F");
paf1200f.set("PB_KEYHEADERFATT", hfatt);
paf1200f.set("PB_KEYBODYFATT", bfatt);
paf1200f.remove();
// Azzera DDT
TPaf_record paf1600f("PAF1600F");
paf1600f.set("PF_KEYHEADERFATT", hfatt);
paf1600f.set("PF_KEYBODYFATT", bfatt);
paf1600f.remove();
const TString16 cup = doc.get(DOC_CUP);
const TString16 cig = doc.get(DOC_CIG);
const TString80 com = doc.get(DOC_CODCMS);
TString80 con = doc.get(DOC_CONTRATTO);
if (con.full() || cup.full() || cig.full())
{
char tcon = doc.get_char(DOC_MODPAG);
if (tcon < 'C') tcon = 'C';
TDate datadoc; // Data contratto non obbligatoria
if (con.full())
{
datadoc = cco(doc).get_date("D0");
}
else
{
// IdDocumento obbligatorio
con = cig;
if (con.blank())
con = cup;
}
if (tcon == 'O')
{
paf1000f.set("P0_RIFNUMLINEA", 0L);
paf1000f.set("P0_IDDOC", con);
paf1000f.set("P0_DATADOC", datadoc);
paf1000f.set("P0_COMMCONVENZ", com);
paf1000f.set("P0_CODCUP", cup);
paf1000f.set("P0_CODCIG", cig);
paf1000f.set("P0_GESTIONE", "D");
paf1000f.insert();
} else
if (tcon == 'C')
{
paf1100f.set("PA_RIFNUMLINEA", 0L);
paf1100f.set("PA_IDDOC", con);
paf1100f.set("PA_DATADOCU", datadoc);
paf1100f.set("PA_COMMCONVENZ", com);
paf1100f.set("PA_CODCUP", cup);
paf1100f.set("PA_CODCIG", cig);
paf1000f.set("PA_GESTIONE", "D");
paf1100f.insert();
}
else
{
paf1200f.set("PB_RIFNUMLINEA", 0L);
paf1200f.set("PB_IDDOC", con);
paf1200f.set("PB_DATADOCO", datadoc);
paf1200f.set("PB_COMMCONVENZ", com);
paf1200f.set("PB_CODCUP", cup);
paf1200f.set("PB_CODCIG", cig);
paf1200f.set("PB_GESTIONE", "D");
paf1200f.insert();
}
}
if (cup.blank() && cig.blank())
log(1, "CIG e CUP assenti");
// <DatiBeniServizi>
TPaf_record paf1800f("PAF1800F");
paf1800f.set("PI_KEYHEADERFATT", hfatt);
paf1800f.set("PI_KEYBODYFATT", bfatt);
paf1800f.remove(); // Cancella tutte le righe documento
TPaf_record paf2000f("PAF2000F");
paf2000f.set("PJ_KEYHEADERFATT", hfatt);
paf2000f.set("PJ_KEYBODYFATT", bfatt);
paf2000f.remove(); // Cancella tutti gli sconti di riga
long riga = 0;
FOR_EACH_PHYSICAL_RDOC(doc, r, rdoc)
{
paf1800f.reset();
paf1800f.set("PI_KEYHEADERFATT", hfatt);
paf1800f.set("PI_KEYBODYFATT", bfatt);
paf1800f.set("PI_NUMEROLINEA", ++riga);
paf1800f.set("PI_DESCRIZIONE", descrizione(*rdoc));
paf1800f.set("PI_ALIQUOTAIVA", "22.00"); // Altrimenti scarta le righe di descrizione
if (rdoc->is_merce())
{
paf1800f.set("PI_UNITAMISURA", rdoc->get(RDOC_UMQTA));
const real qta = rdoc->get(RDOC_QTA);
if (qta.is_zero())
{
TString msg; msg.format("La riga merce %d ha quantit<69> nulla", riga);
log(1, msg);
}
if (qta >= ZERO)
{
paf1800f.set("PI_QUANTITA", qta);
paf1800f.set("PI_PREZZOUNIT", rdoc->prezzo(false, false));
}
else
{
paf1800f.set("PI_QUANTITA", -qta);
paf1800f.set("PI_PREZZOUNIT", -rdoc->prezzo(false, false));
}
paf1800f.set("PI_PRZTOTALE", rdoc->importo(false, false));
set_IVA(*rdoc, paf1800f);
/*
const TDate data = doc.get(DOC_DATADOC);
paf1800f.set("PI_DTINIZIOPER", data);
paf1800f.set("PI_DTFINEPER", data);
*/
// <ScontoMaggiorazione>
sconto_expr = rdoc->get(RDOC_SCONTO);
if (parse_sconto(sconto_expr, sconti))
{
long nlin_sconto = 0;
FOR_EACH_TOKEN(sconti, str)
{
const real perc = str;
if (!perc.is_zero())
{
paf2000f.set("PJ_KEYNLINEA", (long)r);
paf2000f.set("PJ_KEYNPROGR", ++nlin_sconto);
if (perc > ZERO)
{
paf2000f.set("PJ_TIPOSCONTO", "SC");
paf2000f.set("PJ_PERCSCONTO", perc);
}
else
{
paf2000f.set("PJ_TIPOSCONTO", "MG");
paf2000f.set("PJ_PERCSCONTO", -perc);
}
paf2000f.set("PJ_GESTIONE", "D");
paf2000f.insert();
}
}
}
// </ScontoMaggiorazione>
TArray ancestors; find_ancestors(*rdoc, ancestors);
for (int i = ancestors.last(); i > 0; i = ancestors.pred(i))
{
const TAncestor& a = (const TAncestor&)ancestors[i];
if (i == 1)
{
TPaf_record paf1600f("PAF1600F");
paf1600f.reset();
paf1600f.set("PF_KEYHEADERFATT", hfatt);
paf1600f.set("PF_KEYBODYFATT", bfatt);
paf1600f.set("PF_RIFNUMLINEA", (long)r);
paf1600f.set("PF_NUMDDDT", a._numdoc);
paf1600f.set("PF_DATADDT", a._datadoc);
paf1600f.set("PF_GESTIONE", "D");
paf1600f.insert();
} else
if (i == 3)
{
TPaf_record paf1000f("PAF1000F");
paf1000f.set("P0_KEYHEADERFATT", hfatt);
paf1000f.set("P0_KEYBODYFATT", bfatt);
paf1000f.set("P0_RIFNUMLINEA", (long)r);
paf1000f.set("P0_IDDOC", a._numdoc);
paf1000f.set("P0_DATADOC", a._datadoc);
paf1000f.set("P0_COMMCONVENZ", com);
paf1000f.set("P0_CODCUP", cup);
paf1000f.set("P0_CODCIG", cig);
paf1000f.set("P0_GESTIONE", "D");
paf1000f.insert();
}
}
} else
if (rdoc->is_spese())
{
const TSpesa_prest& sp = rdoc->spesa();
const real imp = rdoc->importo(true, false);
real qta = UNO;
if (sp.is_tipo())
{
paf1800f.set("PI_UNITAMISURA", rdoc->get(RDOC_UMQTA));
qta = rdoc->get_real(RDOC_QTA);
if (qta.is_zero())
{
TString msg; msg.format("La riga spese a quantit<69> %d ha quantit<69> nulla (campo %s)", riga, (const char*)rdoc->field_qta());
log(1, msg);
qta = UNO;
}
paf1800f.set("PI_QUANTITA", qta);
}
real prz = imp;
if (qta != UNO)
{
prz = rdoc->prezzo(true, false);
if (prz.is_zero() && !imp.is_zero())
{
const TPrice price(imp / qta);
prz = price.get_value();
}
}
paf1800f.set("PI_PREZZOUNIT", prz);
paf1800f.set("PI_PRZTOTALE", imp);
set_IVA(*rdoc, paf1800f);
} else
if (rdoc->is_prestazione())
{
paf1800f.set("PI_UNITAMISURA", rdoc->get(RDOC_UMQTA));
real qta = rdoc->get(RDOC_QTA); if (qta.is_zero()) qta = UNO;
paf1800f.set("PI_QUANTITA", qta);
paf1800f.set("PI_PREZZOUNIT", rdoc->prezzo(false, false));
paf1800f.set("PI_PRZTOTALE", rdoc->importo(true, false));
set_IVA(*rdoc, paf1800f);
}
paf1800f.set("PI_GESTIONE", "D");
paf1800f.insert();
}
// </DatiBeniServizi>
// <DatiRiepilogo>
TPaf_record paf2200f("PAF2200F");
paf2200f.set("PL_KEYHEADERFATT", hfatt);
paf2200f.set("PL_KEYBODYFATT", bfatt);
paf2200f.remove(); // Cancella tutte le righe di riepilogo IVA
const char* eiva = "I"; // Esigibilit<69> IVA: Immediata, Differita, Split payment
if (doc.is_split_payment())
eiva = "S"; else
if (doc.get_bool(DOC_LIQDIFF) || doc.get_bool(DOC_IVAXCASSA))
eiva = "D";
long num_riep = 0;
TAssoc_array& tiva = doc.tabella_iva(false);
FOR_EACH_ASSOC_OBJECT(tiva, obj, key, itm)
{
const TRiepilogo_iva& riva = *(const TRiepilogo_iva*)itm;
const real aliquota = riva.cod_iva().percentuale();
paf2200f.set("PL_KEYNPROGR", ++num_riep);
paf2200f.set("PL_ALIQUOTAIVA", aliquota);
if (aliquota.is_zero())
{
const TString& tipo = riva.cod_iva().tipo();
const char* natura = "N2"; // Non soggetto
if (tipo == "NI") natura = "N3"; else // Non imponibile
if (tipo == "ES") natura = "N4"; // Esente
paf2200f.set("PL_NATURA", natura);
}
paf2200f.set("PL_IMPONIBILE", riva.imponibile());
paf2200f.set("PL_IMPOSTA", riva.imposta());
paf2200f.set("PL_ESIGIVA", eiva);
if (*eiva == 'S')
paf2200f.set("PL_RIFNORMATIVO", "Scissione pagamenti art.17-ter DPR 633/72");
else
paf2200f.set("PL_RIFNORMATIVO", riva.cod_iva().descrizione());
paf2200f.set("PL_GESTIONE", "D");
paf2200f.insert();
}
// </DatiRiepilogo>
// <DatiPagamento>
TPaf_record paf2400f("PAF2400F");
paf2400f.set("PN_KEYHEADERFATT", hfatt);
paf2400f.set("PN_KEYBODYFATT", bfatt);
paf2400f.remove(); // Cancella i dati pagamento
TPagamento& pag = doc.pagamento();
doc.scadenze_recalc(); // Ricalcola array delle rate
TString_array& scad = doc.scadenze();
const int nrate = scad.items(); // Conta rate generate
const char* rateazione = nrate > 1 ? "TP01" : "TP02"; // A rate (TP01) o una soluzione(TP02)?
paf2400f.set("PN_CONDPAGAMENTO", rateazione);
paf2400f.set("PN_GESTIONE", "D");
paf2400f.insert();
TPaf_record paf2500f("PAF2500F");
paf2500f.set("PO_KEYHEADERFATT", hfatt);
paf2500f.set("PO_KEYBODYFATT", bfatt);
paf2500f.remove(); // Cancella tutte le rate
// Imposto i campi uguali per tutte le rate
paf2500f.set("PO_CONDPAGAMENTO", rateazione); // Condizione di pagamento PA
paf2500f.set("PO_CODICEPAGAM", pag.code()); // Condizione di pagamento CAMPO
TString80 iban, istituto;
TString8 abi, cab;
if (get_bank(doc, iban, abi, cab, istituto))
{
paf2500f.set("PO_ISTFINANZ", istituto);
paf2500f.set("PO_IBAN", iban);
paf2500f.set("PO_ABI", abi);
paf2500f.set("PO_CAB", cab);
}
if (cab.blank())
log(2, TR("Non sono presenti ABI, CAB, IBAN per il pagamento")); else
if (iban.blank())
log(1, TR("Non <20> presente il codice IBAN per il pagamento"));
for (int nr = 0; nr < nrate; nr++)
{
paf2500f.set("PO_KEYNPROGR", long(nr+1)); // Numero rata
const char* mod_pag = "MP01"; // Modalit<69> di pagamento
const int n = nr < pag.n_rate() ? nr : 0; // Si assicura che il numero riga sia accettabile
switch (pag.tipo_rata(n))
{
case _bonfico: mod_pag = "MP05"; break; // bonifico
case _rid : mod_pag = "MP09"; break; // RID
case _ric_ban: mod_pag = "MP12"; break; // RIBA
default : mod_pag = "MP01"; break; // contanti
}
paf2500f.set("PO_MODALITAPAGAM", mod_pag);
TToken_string& riga = scad.row(nr); // Data|Importo
paf2500f.set("PO_DATASCADENZA", TDate(riga.get(0))); // Data scadenza
paf2500f.set("PO_IMPORTO", real(riga.get())); // Importo rata
paf2500f.set("PO_GESTIONE", "D");
paf2500f.insert();
}
TPaf_record paf2600f("PAF2600F");
paf2600f.set("PP_KEYHEADERFATT", hfatt);
paf2600f.set("PP_KEYBODYFATT", bfatt);
paf2600f.remove(); // Cancella eventuali allegati
TToken_string allegati(doc.get("COLL_GOLEM"),'\n');
if (allegati.full())
{
long nprogr = 0; // Numero di file allegati
TFilename fname;
FOR_EACH_TOKEN(allegati, row)
{
const TToken_string entry(row);
if (entry.get(0, fname) && fname.exist())
{
paf2600f.set("PP_KEYNPROGR", ++nprogr);
paf2600f.set("PP_NOMEATTACHMENT", fname.name());
paf2600f.set("PP_ATTACHMENT", fname);
fname.upper(); // serve estensione maiuscola
paf2600f.set("PP_FMTATTACHMENT", fname.ext());
paf2600f.insert();
}
}
}
// </DatiPagamento>
return true;
}
bool TDoc2Paf::elabora(const TRectype& rec)
{
bool done = false;
TDocumentoEsteso doc;
if (doc.read(rec) == NOERR)
{
xvt_sql_begin(_db);
done = elabora(doc);
if (done)
xvt_sql_commit(_db);
else
xvt_sql_rollback(_db);
}
return done;
}
bool TDoc2Paf::elabora(const TDoc_key& key)
{
TRectype rec(LF_DOC);
rec.put(DOC_PROVV, key.provv());
rec.put(DOC_ANNO, key.anno());
rec.put(DOC_CODNUM, key.codnum());
rec.put(DOC_NDOC, key.ndoc());
return elabora(rec);
}
bool TDoc2Paf::elabora(const TFilename& ini)
{
TConfig cfg(ini, "33");
const int anno = cfg.get_int(DOC_ANNO);
const long ndoc = cfg.get_long(DOC_NDOC);
const TFixed_string codnum(cfg.get(DOC_CODNUM)); // lascio sapientemente per ultima la get di una stringa
const TDoc_key key(anno, codnum, ndoc);
return elabora(key);
}
bool TDoc2Paf::genera_xml()
{
#define PABASE "SiaggPA"
TFilename tmp;
// Copia eventuali protezioni software
TString_array files;
if (list_files(PABASE"/*.ssa", files) == 0)
{
list_files("*.ssa", files);
FOR_EACH_ARRAY_ROW(files, i, row)
{
tmp = PABASE; tmp.add(*row);
xvt_fsys_fupdate(*row, tmp);
}
}
files.destroy();
if (list_files(PABASE"/*.ssa", files) != 1)
warning_box(FR("Nella cartella %s deve essere presente esattamente un file .ssa"), PABASE);
TFilename home;
xvt_sys_get_env("USERPROFILE", home.get_buffer(), home.size());
home.add("SoftwareSirio"); home.add(PABASE);
if (!dexist(home))
make_dir(home);
tmp = home; tmp.add("config.properties");
xvt_fsys_fupdate(PABASE"/config.properties", tmp);
tmp = home; tmp.add("configGUI.properties");
xvt_fsys_fupdate(PABASE"/configGUI.properties", tmp);
if (tmp.exist())
{
TJava_profile prop(tmp);
prop.set("percorso", _dbname.path());
prop.set("nomePAF", _dbname);
}
else
cantread_box(tmp);
tmp = PABASE"\\SiaggPACAMPO.jar";
tmp.make_absolute_path();
DIRECTORY old_dir; xvt_fsys_get_dir(&old_dir);
DIRECTORY new_dir; xvt_fsys_convert_str_to_dir(tmp.path(), &new_dir);
xvt_fsys_set_dir(&new_dir);
const bool good = goto_url(tmp);
if (good)
xvt_sys_sleep(3000);
else
error_box(FR("Impossibile eseguire Java -jar %s"), (const char*)tmp);
xvt_fsys_set_dir(&old_dir);
return good;
}
void TDoc2Paf::main_loop()
{
int ndocs = 0;
for (int a = 1; a < argc(); a++)
{
TFilename ini = argv(a);
if (ini.starts_with("-i", true) || ini.starts_with("/i", true))
ini.ltrim(2);
if (ini.exist() && elabora(ini))
ndocs++;
else
{
if (ini.find('*') >= 0 || ini.find('?') >= 0)
{
TString_array f; list_files(ini, f);
FOR_EACH_ARRAY_ROW(f, r, row)
{
ini = *row;
if (ini.exist() && elabora(ini))
ndocs++;
}
}
}
}
if (ndocs > 0)
{
if (show_log())
genera_xml();
return;
}
TPA_mask mask;
mask.set(F_COFI, _cofi);
while (mask.run() == K_ENTER)
{
_cofi = mask.get(F_COFI);
TString_array& sht = mask.sfield(F_DOCS).rows_array();
if (!sht.empty())
{
TProgress_monitor pi(sht.items(), NULL);
ndocs = 0;
FOR_EACH_ARRAY_ROW(sht, r, riga)
{
if (riga->starts_with("X"))
{
const int anno = riga->get_int(1);
const long ndoc = riga->get_long(3);
const TFixed_string codnum(riga->get(2)); // lascio sapientemente per ultima la get di una stringa
const TDoc_key key(anno, codnum, ndoc);
if (elabora(key))
ndocs++;
}
if (!pi.add_status(1))
break;
}
message_box(FR("Sono stati elaborati %d documenti"), ndocs);
}
if (ndocs > 0 && show_log())
genera_xml();
}
}
int TDoc2Paf::parse_line(const TString& line, TString& var, TString& val) const
{
if (line.blank())
return 0;
if (line[0] == '[')
{
var = line.mid(1);
var.rtrim(1);
val.cut(0);
return 1;
}
const int equal = line.find('=');
if (equal < 6)
return 0;
var = line.left(equal); var.trim();
val = line.mid(equal+1); val.trim();
return 2;
}
bool TDoc2Paf::create_table(TScanner& paf, const TString& table)
{
TString query, var, val;
if (xvt_sql_table_exists(_db, table))
{
SLIST fields = xvt_sql_list_fields(_db, table);
while (!paf.eof())
{
const TString& line = paf.line();
const int n = parse_line(line, var, val);
if (n <= 0)
break;
if (var.starts_with("INDEX_"))
break;
if (xvt_slist_find_str(fields, var) == NULL)
{
query.cut(0) << "ALTER TABLE " << table << " ADD COLUMN " << var << ' ' << val << " NOT NULL";
if (val.find("INT") >= 0 || val.find("NUM") >= 0)
query << " DEFAULT 0";
else
query << " DEFAULT ''";
query << ";";
xvt_sql_execute(_db, query, NULL, NULL); // Create table
}
}
xvt_slist_destroy(fields);
}
else
{
query << "CREATE TABLE " << table << " (";
while (!paf.eof())
{
const TString& line = paf.line();
const int n = parse_line(line, var, val);
if (n <= 0)
break;
if (n == 1)
{
paf.push(line);
break;
}
if (var.starts_with("INDEX_"))
{
query.rtrim(1); // toglie ultima ,
query << ");";
xvt_sql_execute(_db, query, NULL, NULL); // Create table
query.cut(0);
query << "CREATE UNIQUE INDEX "
<< table << "_1 ON " << table
<< " (" << val << ");";
xvt_sql_execute(_db, query, NULL, NULL); // Create index
break;
}
else
{
query << "\n " << var << ' ' << val << " NOT NULL";
if (val.find("INT") >= 0 || val.find("NUM") >= 0)
query << " DEFAULT 0";
else
query << " DEFAULT ''";
query << ",";
}
}
}
return true;
}
bool TDoc2Paf::create()
{
open_files(LF_TAB, LF_TABCOM, LF_TABMOD, LF_ANAG,
LF_CLIFO, LF_CFVEN, LF_CFBAN, LF_NDITTE,
LF_DOC, LF_RIGHEDOC, 0);
TRectype cfven(LF_CFVEN);
if (cfven.type(CFV_PARIFAMM) != _alfafld)
return error_box(TR("Database non convertito per fatturazione P.A."));
_ditta.init(LF_NDITTE, prefix().get_codditta());
_dbname = prefix().get_studio(); // base direcotry
_dbname.add("sql"); make_dir(_dbname);
TString16 d; d.format("PAF%05ld.db", prefix().get_codditta());
_dbname.add(d);
_db = xvt_sql_open(_dbname, user(), "", _dbname.path());
if (_db == NULL)
return false;
const TFilename ini = "paf.ini";
bool ok = ini.exist();
if (ok)
{
xvt_sql_begin(_db);
TScanner paf(ini);
while (ok && !paf.eof())
{
const TString& p = paf.line();
if (p.starts_with("[PA") && p.ends_with("F]"))
{
TString16 table = p; table.strip("[]");
ok = create_table(paf, table);
}
}
if (ok)
{
TPaf_record panum("PANUM00F");
panum.set("PJNKEY", "00001");
if (!panum.search())
{
panum.set("PJNINV", "0000000000");
panum.insert();
}
xvt_sql_commit(_db);
}
else
xvt_sql_rollback(_db);
}
else
return cantread_box(ini);
_cofi = ini_get_string(CONFIG_DITTA, "pa", "TRASMITTCOD");
if (_cofi.blank())
_cofi = _ditta.codice_fiscale();
return ok && TSkeleton_application::create();
}
bool TDoc2Paf::destroy()
{
if (_cofi.full())
ini_set_string(CONFIG_DITTA, "pa", "TRASMITTCOD", _cofi);
xvt_sql_close(_db); _db = NULL;
return TSkeleton_application::destroy();
}
int pa0100(int argc, char* argv[])
{
TDoc2Paf d2p;
d2p.run(argc, argv, TR("Fatturazione P.A."));
return 0;
}