Corretta generazione fatture P.A.

git-svn-id: svn://10.65.10.50/branches/R_10_00@23090 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
guy 2015-05-15 08:47:38 +00:00
parent 882301feaf
commit 10e094b7e8
5 changed files with 173 additions and 67 deletions

View File

@ -35,20 +35,26 @@ 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");
numdoc.cut(0) << doc.get_date(DOC_DATADOC).date2ansi() << '/'
<< doc.numerazione() << '/' << doc.numero();
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)
{
TString16 key; key.format("C|%ld", doc.get_long(DOC_CODCF));
TString8 key; key.format("C|%ld", doc.get_long(DOC_CODCF));
cess = cache().get(LF_CFVEN, key, CFV_PADESTIN);
CHECK(cess.full(), "Destinatario fattura P.A. non valido");
numdoc.cut(0) << doc.get_date(DOC_DATADOC).date2ansi() << '/'
<< doc.get(DOC_CODNUM) << '/' << doc.get(DOC_NDOC);
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();
}
@ -167,6 +173,38 @@ TJava_profile::TJava_profile(const char* path) : _path(path), _dirty(false)
}
}
/////////////////////////////////////////////////////////////////////////////////////
// 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
/////////////////////////////////////////////////////////////////////////////////////
@ -321,7 +359,7 @@ const TString& TPaf_record::var2str(const TVariant& var) const
return tmp;
}
// Elimina il record in base ai cmapi chiave
// Elimina il record in base ai campi chiave
bool TPaf_record::remove()
{
TString256 query;
@ -462,7 +500,7 @@ void TPA_mask::fill()
TProgress_monitor pi(n, NULL);
for (bool okc = clifo_pa.move_first(); okc; okc = clifo_pa.move_next())
{
if (!pi.addstatus(1))
if (!pi.add_status())
break;
query.cut(0);
@ -555,6 +593,7 @@ bool TPA_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
class TDoc2Paf : public TSkeleton_application
{
TAnagrafica _ditta;
TString16 _cofi;
TFilename _dbname;
private:
@ -568,6 +607,7 @@ protected:
bool parse_sconto(const TString& formula, TToken_string& sconti) 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
bool elabora(TDocumentoEsteso& doc);
bool elabora(const TRectype& rec);
@ -660,26 +700,6 @@ const char* TDoc2Paf::descrizione(const TRiga_documento& rdoc) const
return rdoc.get(RDOC_DESCR);
}
struct TAncestor : public TObject
{
TString16 _numdoc;
TDate _datadoc;
TAncestor(const TRectype& rdoc);
};
TAncestor::TAncestor(const TRectype& rdoc)
{
TToken_string kdoc;
kdoc = rdoc.get(RDOC_PROVV);
kdoc.add(rdoc.get(RDOC_ANNO));
kdoc.add(rdoc.get(RDOC_CODNUM));
kdoc.add(rdoc.get(RDOC_NDOC));
const TRectype& doc = cache().get(LF_DOC, kdoc);
_numdoc.format("%d/%s/%ld", doc.get_int(DOC_ANNO), (const char*)doc.get(DOC_CODNUM), doc.get_long(DOC_NDOC));
_datadoc = doc.get_date(DOC_DATADOC);
}
const TRectype* TDoc2Paf::find_parent_row(const TRectype& rdoc) const
{
const long id = rdoc.get_long(RDOC_DAIDRIGA);
@ -724,10 +744,24 @@ int TDoc2Paf::find_ancestors(const TRiga_documento& rdoc, TArray& ancestors) con
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);
}
bool TDoc2Paf::elabora(TDocumentoEsteso& doc)
{
TString8 hfatt; // Codice univoco di 6 caratteri dell'ufficio P.A.
TString80 bfatt; // Codice univoco di 20 caratteri del documento
TString20 bfatt; // Codice univoco di 20 caratteri del documento
if (!chiave_paf(doc, hfatt, bfatt))
return false;
@ -741,7 +775,7 @@ bool TDoc2Paf::elabora(TDocumentoEsteso& doc)
paf0100f.remove();
paf0100f.set("P1_TRASMITTPAESE", paese);
paf0100f.set("P1_TRASMITTCOD", _ditta.partita_IVA());
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)
@ -791,7 +825,13 @@ bool TDoc2Paf::elabora(TDocumentoEsteso& doc)
paf0200f.set("P2_SEDEPROV", _ditta.provincia_residenza());
paf0200f.set("P2_SEDENAZ", paese);
paf0200f.set("P2_GESTIONE", "D");
paf0200f.insert();
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));
@ -804,18 +844,26 @@ bool TDoc2Paf::elabora(TDocumentoEsteso& doc)
paf0200f.set("P2_ISCRREAUFF", unloc.get("13->"COM_PROVCOM));
}
}
TISAM_recordset anagiu("USE ANAGIU\nFROM CODANAGR=#CODICE\nTO CODANAGR=#CODICE");
anagiu.set_var("#CODICE", firm.get(NDT_CODANAGR));
if (anagiu.move_first())
if (_ditta.giuridica())
{
paf0200f.set("P2_ISCRREACAP", anagiu.get(ANG_CAPSOC));
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>
TAnagrafica cliente(doc.clifor());
TPaf_record paf0400f("PAF0400F");
paf0400f.set("P4_KEYHEADERFATT", hfatt);
@ -858,7 +906,10 @@ bool TDoc2Paf::elabora(TDocumentoEsteso& doc)
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());
paf0700f.set("P7_NUMERO", doc.numero());
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();
@ -902,8 +953,20 @@ bool TDoc2Paf::elabora(TDocumentoEsteso& doc)
paf2700f.set("PQ_KEYBODYFATT", bfatt);
paf2700f.remove();
paf2700f.set("PQ_IMPTOTDOC", doc.totale_doc());
paf2700f.set("PQ_CAUSALE", doc.tipo().descrizione());
// paf2700f.set("PQ_ART73", true);
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>
@ -935,18 +998,17 @@ bool TDoc2Paf::elabora(TDocumentoEsteso& doc)
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())
{
TString80 conkey;
conkey.format("%c%06ld%s", tcon, doc.codcf(), (const char*)con);
const TRectype& con = cache().get("&CON", conkey);
datadoc = con.get_date("D0");
datadoc = cco(doc).get_date("D0");
}
else
{
@ -1267,6 +1329,9 @@ bool TDoc2Paf::genera_xml()
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());
@ -1292,30 +1357,15 @@ bool TDoc2Paf::genera_xml()
tmp = PABASE"\\SiaggPACAMPO.jar";
tmp.make_absolute_path();
const int ssa_err = xvt_dongle_sa_test("FATTPA.pa");
if (ssa_err != 0)
{
TString80 msg;
switch (ssa_err)
{
case -100: msg = TR("File .ssa non valido o non trovato"); break;
case -101: msg = TR("Prodotto non trovato"); break;
case -103: msg = TR("Prodotto scaduto"); break;
case -201: msg = TR("Modulo non trovato"); break;
case -203: msg = TR("Modulo scaduto"); break;
default : break;
}
warning_box(FR("Non risulta attivo il modulo 'pa' del prodotto 'FATTPA'.\nErrore %d: %s"), ssa_err, (const char*)msg);
}
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);
xvt_sys_sleep(3000);
xvt_fsys_set_dir(&old_dir);
if (!good)
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;
}
@ -1351,8 +1401,11 @@ void TDoc2Paf::main_loop()
}
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();
TProgress_monitor pi(sht.items(), NULL);
ndocs = 0;
@ -1519,11 +1572,18 @@ bool TDoc2Paf::create()
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();
}

View File

@ -1,5 +1,6 @@
#define F_DATAINI 201
#define F_SHOWALL 202
#define F_COFI 203
#define F_DOCS 210
#define S_SELECTED 101

View File

@ -17,9 +17,15 @@ BEGIN
PROMPT 40 0 "Mostra anche i documenti già inviati"
END
STRING F_COFI 16
BEGIN
PROMPT 1 1 "Codice fiscale di chi effettua la trasmissione "
CHECKTYPE REQUIRED
END
SPREADSHEET F_DOCS
BEGIN
PROMPT 0 1 ""
PROMPT 0 2 ""
ITEM "@1"
ITEM "Anno"
ITEM "Cod.\nNum.@4"

View File

@ -6,7 +6,11 @@
#define F_CON_RAGSOC 112
#define F_CON_CODICE 103
#define F_CON_DESCRIZIONE 113
#define F_CON_DATA 121
#define F_CON_DATA 104
#define F_CON_RIFAMM 105
#define F_CON_CAUS1 121
#define F_CON_CAUS2 122
#define F_CON_CAUS3 123
#endif

View File

@ -6,7 +6,7 @@ ENDPAGE
PAGE "Contratti per PA" 0 2 0 0
GROUPBOX DLG_NULL 78 7
GROUPBOX DLG_NULL 78 5
BEGIN
PROMPT 1 0 "@bEstremi contratto/convenzione/ordine P.A."
END
@ -78,9 +78,15 @@ BEGIN
KEY 1
END
GROUPBOX DLG_NULL 78 5
BEGIN
PROMPT 1 5 "@bDati contratto/convenzione/ordine P.A."
END
STRING F_CON_DESCRIZIONE 70 50
BEGIN
PROMPT 2 4 "Descrizione "
PROMPT 2 6 "Descrizione "
FIELD S0
USE &CON KEY 2 SELECT (CODTAB[1,1]==#F_CON_TIPO)&&(STR(CODTAB[2,7]=#F_CON_CODCF))
JOIN LF_CLIFO INTO TIPOCF=CODTAB[1,1] CODCF=CODTAB[2,7]
@ -97,10 +103,39 @@ END
DATA F_CON_DATA
BEGIN
PROMPT 2 5 "Data "
PROMPT 2 7 "Data "
FIELD D0
END
STRING F_CON_RIFAMM 20
BEGIN
PROMPT 24 7 "Riferimento amministrazione "
FIELD S4
END
GROUPBOX DLG_NULL 78 5
BEGIN
PROMPT 1 10 "@bCausale"
END
STRING F_CON_CAUS1 50
BEGIN
PROMPT 14 11 ""
FIELD S1
END
STRING F_CON_CAUS2 50
BEGIN
PROMPT 14 12 ""
FIELD S2
END
STRING F_CON_CAUS3 50
BEGIN
PROMPT 14 13 ""
FIELD S3
END
ENDPAGE
ENDMASK