diff --git a/build/fp0.vcxproj b/build/fp0.vcxproj
index b803d6022..937c2ac40 100644
--- a/build/fp0.vcxproj
+++ b/build/fp0.vcxproj
@@ -97,13 +97,6 @@
true
.\..\debug/tf0.bsc
-
-
-
-
-
- "C:\Program Files (x86)\Windows Kits\10\bin\10.0.16299.0\x64\signtool.exe" sign /a /s MY /n "Sirio Informatica e Sistemi SPA" /fd sha256 /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp /v "$(TargetPath)"
-
@@ -147,13 +140,6 @@
true
.\..\release/tf0.bsc
-
-
-
-
-
- "C:\Program Files (x86)\Windows Kits\10\bin\10.0.16299.0\x64\signtool.exe" sign /a /s MY /n "Sirio Informatica e Sistemi SPA" /fd sha256 /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp /v "$(TargetPath)"
-
@@ -196,19 +182,18 @@
+
+ true
+
-
- true
- true
-
+
true
- true
diff --git a/build/fplib.vcxproj.filters b/build/fplib.vcxproj.filters
new file mode 100644
index 000000000..e6b867b3a
--- /dev/null
+++ b/build/fplib.vcxproj.filters
@@ -0,0 +1,21 @@
+
+
+
+
+ {72a9ea2f-8fbe-4546-96f3-21a4de35bf0e}
+
+
+ {afa0f493-bfe6-4bd2-add2-3256306ed9c5}
+
+
+
+
+ Headers
+
+
+
+
+ Sources
+
+
+
\ No newline at end of file
diff --git a/cd/test/fp0614.txt b/cd/test/fp0614.txt
deleted file mode 100644
index 98885b12f..000000000
--- a/cd/test/fp0614.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-fp0.exe
-fp0100a.msk
-fp0300a.msk
-
-- Aggiunto filtro codice numerazione
-- Sistemata configurazione per gestione allegati
-- Aggiunto esportazione documento come pdf nell'xml
-- Aggiunta funzione che gestisce gli allegati
\ No newline at end of file
diff --git a/cd/test/fp0614a.ini b/cd/test/fp0614a.ini
deleted file mode 100644
index 1fc83863c..000000000
--- a/cd/test/fp0614a.ini
+++ /dev/null
@@ -1,21 +0,0 @@
-[Main]
-Demo=0
-
-[fp1]
-File(0) = fp0.exe|X
-File(1) = fp0100a.msk|X
-File(3) = fp0300a.msk|X
-Patch = 0614
-Versione = 21511200
-
-[fp]
-Data = 31-07-2018
-Descrizione = Fattura Elettronica
-Dischi = 1
-Moduli = cg,ve
-OEM =
-Patch = 614
-PostProcess =
-PreProcess =
-Versione = 21511200
-
diff --git a/cd/test/fp0614a1.zip b/cd/test/fp0614a1.zip
deleted file mode 100644
index 6be915ea6..000000000
Binary files a/cd/test/fp0614a1.zip and /dev/null differ
diff --git a/cd/test/ve0614.txt b/cd/test/ve0614.txt
deleted file mode 100644
index 19f8a741c..000000000
--- a/cd/test/ve0614.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-ve1.exe
-cg0200a.msk
-cg0.exe
-
-Aggiunta nuova stampa che salva su file la fattura senza anteprima per fatturazione elettronica
\ No newline at end of file
diff --git a/cd/test/ve0614a.ini b/cd/test/ve0614a.ini
deleted file mode 100644
index c72891272..000000000
--- a/cd/test/ve0614a.ini
+++ /dev/null
@@ -1,139 +0,0 @@
-[Main]
-Demo=0
-
-[ve1]
-File(11) = ve1.exe|X
-Patch = 0614
-Versione = 21511200
-
-[ve99]
-Kill(0) = batbimb.msk|x
-Kill(1) = batbacr.msk|x
-Kill(2) = bastfrd.msk|x
-Kill(3) = bastbnp.rep|x
-Kill(4) = bastcra.msk|x
-Kill(5) = batbgmc.msk|x
-Kill(6) = batbabe.msk|x
-Kill(7) = efstbnp.msk|x
-Kill(8) = batbfrm.msk|x
-Kill(9) = batbcra.msk|x
-Kill(10) = ve7300a.frm|x
-Kill(11) = bastprs.msk|x
-Kill(12) = batbnum.msk|x
-Kill(13) = bastabe.msk|x
-Kill(14) = bastrfc.rep|x
-Kill(15) = bastasf.rep|x
-Kill(16) = basttag.rep|x
-Kill(17) = eftbbnp.msk|x
-Kill(18) = ve7.exe|x
-Kill(19) = batbgca.msk|x
-Kill(20) = ve7200a.msk|x
-Kill(21) = batbrfa.msk|x
-Kill(22) = bastgca.rep|x
-Kill(23) = batbrfc.msk|x
-Kill(24) = basteld.rep|x
-Kill(25) = bastums.rep|x
-Kill(26) = ve7701a.ini|x
-Kill(27) = batbfrr.msk|x
-Kill(28) = bastcaa.rep|x
-Kill(29) = basttri.rep|x
-Kill(30) = batbtri.msk|x
-Kill(31) = bastctr.msk|x
-Kill(32) = batbtag.msk|x
-Kill(33) = batbmre.msk|x
-Kill(34) = baststd.rep|x
-Kill(35) = ve7400a.ini|x
-Kill(36) = baststd.msk|x
-Kill(37) = batbcau.msk|x
-Kill(38) = batbpro.msk|x
-Kill(39) = bastabe.rep|x
-Kill(40) = ve7400a.msk|x
-Kill(41) = bastgca.msk|x
-Kill(42) = bastimb.msk|x
-Kill(43) = bastctr.rep|x
-Kill(44) = batbtip.msk|x
-Kill(45) = bastrfc.msk|x
-Kill(46) = batbubi.msk|x
-Kill(47) = bastcau.rep|x
-Kill(48) = basttag.msk|x
-Kill(49) = bastgcg.msk|x
-Kill(50) = bastubi.rep|x
-Kill(51) = basteld.msk|x
-Kill(52) = bastcau.msk|x
-Kill(53) = batbprs.msk|x
-Kill(54) = batbctr.msk|x
-Kill(55) = batbstd.msk|x
-Kill(56) = ve7100a.msk|x
-Kill(57) = bastums.msk|x
-Kill(58) = batbcaa.msk|x
-Kill(59) = bastspp.msk|x
-Kill(60) = batbspp.msk|x
-Kill(61) = batbfid.msk|x
-Kill(62) = bastasf.msk|x
-Kill(63) = bastfrm.rep|x
-Kill(64) = bastnum.rep|x
-Kill(65) = batbbnp.msk|x
-Kill(66) = bastgmc.msk|x
-Kill(67) = bastrfa.msk|x
-Kill(68) = basttip.rep|x
-Kill(69) = ve7600a.msk|x
-Kill(70) = batbfsa.msk|x
-Kill(71) = bastubi.msk|x
-Kill(72) = batbgcg.msk|x
-Kill(73) = bastimb.rep|x
-Kill(74) = bastfca.rep|x
-Kill(75) = bastfrd.rep|x
-Kill(76) = batbums.msk|x
-Kill(77) = bastnum.msk|x
-Kill(78) = bastfrr.msk|x
-Kill(79) = ve7500a.msk|x
-Kill(80) = bastfca.msk|x
-Kill(81) = ve7400conf.ini|x
-Kill(82) = efstbnp.rep|x
-Kill(83) = batbasf.msk|x
-Kill(84) = bastfrr.rep|x
-Kill(85) = bastprs.rep|x
-Kill(86) = bastcaa.msk|x
-Kill(87) = ve7200a.frm|x
-Kill(88) = batbgsa.msk|x
-Kill(89) = bastbnp.msk|x
-Kill(90) = bastrfa.rep|x
-Kill(91) = basttip.msk|x
-Kill(92) = batbprv.msk|x
-Kill(93) = batbfrd.msk|x
-Kill(94) = bastfrm.msk|x
-Kill(95) = bastgmc.rep|x
-Kill(96) = bastgcg.rep|x
-Kill(97) = batbfca.msk|x
-Kill(98) = bastspp.rep|x
-Kill(99) = batbcld.msk|x
-Kill(100) = batbspt.msk|x
-Kill(101) = ve7700a.msk|x
-Kill(102) = batbeld.msk|x
-Kill(103) = basttri.msk|x
-Kill(104) = bastcra.rep|x
-Kill(105) = ve7300a.msk|x
-
-[cg9]
-Edit_19 = cg0 -0
-Edit_20 = cg0 -1
-Edit_26 = cg0 -4
-Edit_5 = cg0 -5
-File(127) = cg0.exe|X
-File(129) = cg0200a.msk|X
-Patch = 612
-Versione = 21511200
-
-[ve]
-Data = 31-07-2018
-Descrizione = Vendite
-Dischi = 1
-Moduli = ba,cg9,pr9,mg9,sv9,in9,ef9
-OEM =
-Patch = 614
-PostProcess = bainst -0 VE
-PreProcess =
-Prezzo(1) =
-Prezzo(2) =
-Versione = 21511200
-
diff --git a/cd/test/ve0614a1.zip b/cd/test/ve0614a1.zip
deleted file mode 100644
index d6b0d9d4d..000000000
Binary files a/cd/test/ve0614a1.zip and /dev/null differ
diff --git a/src/fp/fp0100.cpp b/src/fp/fp0100.cpp
index 7ceb34419..035c2cb91 100644
--- a/src/fp/fp0100.cpp
+++ b/src/fp/fp0100.cpp
@@ -14,6 +14,8 @@
class TParametri_mask : public TAutomask
{
+private:
+ void load_all();
protected:
void tipi_import();
static TMask& get_tmp_msk(const char* title);
@@ -22,18 +24,38 @@ protected:
public:
TParametri_mask(const char* n);
+ void save_all() const;
};
TParametri_mask::TParametri_mask(const char * n) : TAutomask(n)
+{
+ load_all();
+}
+
+void TParametri_mask::save_all() const
+{
+ ini_set_string(CONFIG_DITTA, "fp", "ip", get(F_INDIRIZZO));
+ ini_set_string(CONFIG_DITTA, "fp", "db", get(F_DATABASE));
+ ini_set_string(CONFIG_DITTA, "fp", "usr", get(F_USER));
+ ini_set_string(CONFIG_DITTA, "fp", "psw", encode(get(F_PASSWORD)));
+ ini_set_string(CONFIG_DITTA, "fp", "flddest", get(F_FLDDEST));
+ ini_set_string(CONFIG_DITTA, "fp", "fldusrdest", get(F_FLDUSRDEST));
+ ini_set_string(CONFIG_DITTA, "fp", "cofitras", get(F_COFI));
+ ini_set_bool(CONFIG_DITTA, "fp", "gestioneallegati", get(F_ESPORTAALLEG));
+ ini_set_bool(CONFIG_DITTA, "fp", "allegafatt", get(F_ESPORTADOC));
+}
+
+void TParametri_mask::load_all()
{
set(F_INDIRIZZO, ini_get_string(CONFIG_DITTA, "fp", "ip"));
set(F_DATABASE, ini_get_string(CONFIG_DITTA, "fp", "db"));
set(F_USER, ini_get_string(CONFIG_DITTA, "fp", "usr"));
- set(F_PASSWORD, decode(ini_get_string(CONFIG_DITTA, "fp", "psw") ));
+ set(F_PASSWORD, decode(ini_get_string(CONFIG_DITTA, "fp", "psw")));
set(F_FLDDEST, ini_get_string(CONFIG_DITTA, "fp", "flddest"));
set(F_FLDUSRDEST, ini_get_string(CONFIG_DITTA, "fp", "fldusrdest"));
-
-
+ set(F_COFI, ini_get_string(CONFIG_DITTA, "fp", "cofitras"));
+ set(F_ESPORTAALLEG, ini_get_bool(CONFIG_DITTA, "fp", "gestioneallegati"));
+ set(F_ESPORTADOC, ini_get_bool(CONFIG_DITTA, "fp", "allegafatt"));
}
void TParametri_mask::tipi_import()
@@ -173,6 +195,20 @@ bool TParametri_mask::on_field_event(TOperable_field& o, TField_event e, long jo
}
}
break;
+ case F_ESPORTAALLEG:
+ {
+ const bool esporta = get_bool(F_ESPORTAALLEG);
+ field(F_FLDDEST).check_type(esporta ? CHECK_REQUIRED : CHECK_NONE);
+ field(F_FLDUSRDEST).check_type(esporta ? CHECK_REQUIRED : CHECK_NONE);
+ field(F_ESPORTADOC).enable(esporta);
+ if (e == fe_modify && !esporta)
+ {
+ set(F_FLDDEST, "");
+ set(F_FLDUSRDEST, "");
+ set(F_ESPORTADOC, "");
+ }
+ }
+ break;
default:
break;
}
@@ -210,13 +246,7 @@ void TParametri_ditta::main_loop()
SSimple_query s(ad, usr, psw, TSDB_MSSQL);
if (s.sq_is_connect())
{
-
- ini_set_string(CONFIG_DITTA, "fp", "ip", ip);
- ini_set_string(CONFIG_DITTA, "fp", "db", db);
- ini_set_string(CONFIG_DITTA, "fp", "usr", usr);
- ini_set_string(CONFIG_DITTA, "fp", "psw", encode(psw));
- ini_set_string(CONFIG_DITTA, "fp", "flddest", pm.get(F_FLDDEST));
- ini_set_string(CONFIG_DITTA, "fp", "fldusrdest", pm.get(F_FLDUSRDEST));
+ pm.save_all();
message_box("Dati salvati correttamente!");
}
else
diff --git a/src/fp/fp0100a.h b/src/fp/fp0100a.h
index 0205a7f81..3fdd14a1f 100644
--- a/src/fp/fp0100a.h
+++ b/src/fp/fp0100a.h
@@ -4,6 +4,9 @@
#define F_PASSWORD 104
#define F_FLDDEST 105
#define F_FLDUSRDEST 106
+#define F_COFI 107
+#define F_ESPORTAALLEG 108
+#define F_ESPORTADOC 109
#define F_SETPATCH 201
#define F_ENPTYTABLE 202
diff --git a/src/fp/fp0100a.uml b/src/fp/fp0100a.uml
index 352e7e53c..84da19f00 100644
--- a/src/fp/fp0100a.uml
+++ b/src/fp/fp0100a.uml
@@ -3,17 +3,21 @@
TOOLBAR "topbar" 0 0 0 2
#include
+/*
+
BUTTON DLG_ELABORA 2 2
BEGIN
PROMPT 1 1 "Imp. Tipi Doc"
PICTURE TOOL_ELABORA
FLAGS "HD"
END
+*/
+
ENDPAGE
PAGE "Configurazione FP" 0 2 0 0
-GROUPBOX DLG_NULL 78 10
+GROUPBOX DLG_NULL 78 8
BEGIN
PROMPT 1 1 "@BDatabase"
END
@@ -47,19 +51,44 @@ BEGIN
CHECKTYPE REQUIRED
END
+GROUPBOX DLG_NULL 78 3
+BEGIN
+ PROMPT 1 7 "@BTrasmittente"
+END
+
+STRING F_COFI 16
+BEGIN
+ PROMPT 2 8 "Codice fiscale trasmittente "
+ CHECKTYPE REQUIRED
+END
+
+GROUPBOX DLG_NULL 78 6
+BEGIN
+ PROMPT 1 10 "@BConfigurazione Allegati"
+END
+
+BOOLEAN F_ESPORTAALLEG
+BEGIN
+ PROMPT 2 11 "Abilita esportazione allegati"
+END
+
+BOOLEAN F_ESPORTADOC
+BEGIN
+ PROMPT 2 12 "Allega pdf documento nell'XML"
+ FLAGS "D"
+END
+
STRING F_FLDDEST 300 50
BEGIN
- PROMPT 2 6 "Destinazione Server "
- CHECKTYPE REQUIRED
- FLAGS "M"
+ PROMPT 2 13 "Destinazione Server "
+ FLAGS ""
END
STRING F_FLDUSRDEST 300 50
BEGIN
- PROMPT 2 7 "Destinazione User "
+ PROMPT 2 14 "Destinazione User "
DSELECT
- CHECKTYPE REQUIRED
- FLAGS "M"
+ FLAGS ""
END
ENDPAGE
diff --git a/src/fp/fp0200.cpp b/src/fp/fp0200.cpp
index 73c5add88..e1eb8ad53 100644
--- a/src/fp/fp0200.cpp
+++ b/src/fp/fp0200.cpp
@@ -1,1757 +1,6 @@
#include "fp0.h"
-#include "fp0200b.h"
-
-#include
-#include
-#include
-#include
-
-#include "../ve/velib05.h"
-#include "../cg/cglib03.h"
-
-#include "../fe/felib.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include "../cg/cfban.h"
-
-/////////////////////////////////////////////////////////////////////////////////////
-// Utilities
-/////////////////////////////////////////////////////////////////////////////////////
-
-SSimple_query& db()
-{
- static SSimple_query* db = new SSimple_query();
- return *db;
-}
-
-// 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();
-}
-
-
-/////////////////////////////////////////////////////////////////////////////////////
-// 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 db().sq_set_exec(query);
-}
-
-// 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 << ';';
- // TODO: Da controllare
- // return xvt_sql_execute(_db, query, paf_search_record, this) == 1;
- return db().sq_set_exec(query);
-}
-
-// Carica un record in base ad un massimo di 3 campi chiave
-bool TPaf_record::search(const char* k1, const char* k2, const char* k3)
-{
- _fields.destroy();
-
- set(_key.get(0), k1);
- set(_key.get(1), k2);
- if (k3 && *k3)
- set(_key.get(2), k3);
-
- return search();
-}
-
-// 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;
- return db().sq_set_exec(query);
-}
-
-// 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("fp0200a") { }
-};
-
-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;
- case DLG_ALL:
- {
- if (e == fe_button)
- {
- TSheet_field& docs = sfield(F_DOCS);
- TString_array& sht = docs.rows_array();
- const int items = sht.items();
-
- if (items > 0)
- {
- const TString4 select = *(sht.row(0).get(0)) == 'X' ? "" : "X";
- for (int i = 0; i < items; i++)
- sht.row(i).add(select, 0);
- docs.force_update();
- }
- }
- }
- 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();
- const char * natura(const TString& codiva) const;
- void set_IVA(const TString& codiva, TPaf_record& paf) const;
- 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;
-}
-
-
-const char * TDoc2Paf::natura(const TString& codiva) const
-{
- const TRectype& ai = cache().get("%IVA", codiva);
- TString & natura = get_tmp_string(4);
-
- natura = ai.get("S12");
- if (natura.blank())
- {
- const int tipo_iva11 = ai.get_int("S2");
- const bool revcharge = tipo_iva11 >= 31 && tipo_iva11 <= 38;
- const TString& tipo = ai.get("S1");
- const int tipo_vendite = ai.get_int("S7");
-
- // N1 escluse ex art 15
- if (tipo_vendite == 5)
- natura = "N5"; // regime del margine
- else
- if (revcharge)
- natura = "N6"; // Inversione contabile (REVERSE CHARGE)
- else
- if (tipo == "NS")
- natura = "N2"; // Non soggetto
- else
- if (tipo == "NI")
- natura = "N3"; // Non imponibile
- else
- if (tipo == "ES")
- natura = "N4"; // Esente
- }
- return natura;
-}
-
-void TDoc2Paf::set_IVA(const TString& codiva, TPaf_record& paf) const
-{
- const TRectype& ai = cache().get("%IVA", codiva);
- const real aliquota = ai.get("R0");
- paf.set("PI_ALIQUOTAIVA", aliquota);
- if (codiva.full())
- {
- if (aliquota.is_zero())
- paf.set("PI_NATURA", natura(codiva));
- else
- paf.set("PI_NATURA", "");
- }
-}
-
-void TDoc2Paf::set_IVA(const TRiga_documento& rdoc, TPaf_record& paf) const
-{
- const TString8 codiva(rdoc.get(RDOC_CODIVA));
- const TRectype& ai = cache().get("%IVA", codiva);
- const real aliquota = ai.get("R0");
- paf.set("PI_ALIQUOTAIVA", aliquota);
- if (codiva.full())
- {
- if (aliquota.is_zero())
- paf.set("PI_NATURA", natura(codiva));
- else
- paf.set("PI_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";
- TCausale caus = TCausale(doc.tipo().causale(), doc.anno());
-
- //
- 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();
- //
-
- //
- 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();
-
- //
-
- //
-
- 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();
- //
-
- //
- 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();
-
- //
- 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();
- }
- }
- }
- //
-
- //
- 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();
- //
-
- // 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");
-
- //
-
- 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;
- TString16 codivadefault;
- {
- FOR_EACH_PHYSICAL_RDOC(doc, r, rdoc)
- {
- codivadefault = rdoc->get(RDOC_CODIVA);
- if (codivadefault.full())
- break;
- }
- }
- 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
-
-
- set_IVA(codivadefault, paf1800f);
-
- 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à 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(true, false));
- }
- paf1800f.set("PI_PRZTOTALE", rdoc->importo(true, false));
- set_IVA(*rdoc, paf1800f);
-
- /*
- const TDate data = doc.get(DOC_DATADOC);
- paf1800f.set("PI_DTINIZIOPER", data);
- paf1800f.set("PI_DTFINEPER", data);
- */
-
- //
-
- 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();
- }
- }
- }
- //
-
- 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à %d ha quantità 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();
- }
- //
-
- //
- 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à 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())
- paf2200f.set("PL_NATURA", natura(riva.cod_iva().codice()));
-
- 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();
- }
- //
-
- //
- 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 è 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à 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();
- }
- }
- }
-
- //
-
- return true;
-}
-
-bool TDoc2Paf::elabora(const TRectype& rec)
-{
- bool done = false;
- TDocumentoEsteso doc;
- if (doc.read(rec) == NOERR)
- {
- // TODO: Da controllare
- // xvt_sql_begin(_db);
- done = elabora(doc);
- if (done)
- done = db().sq_commit();
- else
- db().sq_rollback();
- }
- 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);
- if (prop.get("percorso").blank())
- 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());
- TString ad = ini_get_string(CONFIG_DITTA, "fp", "ip"); ad << "@" << ini_get_string(CONFIG_DITTA, "fp", "db");
- db().sq_connect(
- ad,
- ini_get_string(CONFIG_DITTA, "fp", "usr"),
- decode(ini_get_string(CONFIG_DITTA, "fp", "psw")),
- TSDB_MSSQL
- );
- db().sq_set_autocommit(false);
- if (db().sq_is_connect())
- return false;
-
- const TFilename ini = "paf.ini";
- bool ok = ini.exist();
- if (ok)
- {
- // TODO: Controllare begin
- // 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();
- }
-
- db().sq_commit();
- }
- else
- db().sq_rollback();
- }
- 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);
-
- return TSkeleton_application::destroy();
-}
int fp0200(int argc, char* argv[])
{
- //TFp_app t2t;
- //t2t.run(argc, argv, TR("Trasferimento Fatture Elettroniche"));
return 0;
}
\ No newline at end of file
diff --git a/src/fp/fp0300.cpp b/src/fp/fp0300.cpp
index 59eca595c..39b78c525 100644
--- a/src/fp/fp0300.cpp
+++ b/src/fp/fp0300.cpp
@@ -1,31 +1,17 @@
#include
#include
#include
-#include
-#include
+#include "fplib01.h"
#include
-#include
-#include
-#include
-#include
+#include
#include "../ve/velib05.h"
#include "../cg/cglib03.h"
+#include "../fe/felib.h"
#include "fp0.h"
#include "fp0300a.h"
-#include "../fe/felib.h"
-#include "fplib01.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include "../cg/cfban.h"
-
/////////////////////////////////////////////////////////////////////////////////////
// Globals
@@ -34,376 +20,6 @@
#define LEN_HFATT 20
#define LEN_BFATT 50
-#define FLD_TIPO_SDI "S3[37,40]"
-
-/////////////////////////////////////////////////////////////////////////////////////
-// Utilities
-/////////////////////////////////////////////////////////////////////////////////////
-
-/*
- * HFATT: tipocf(1) + codcf(6)
- * BFATT: datadoc(8) + tipodoc_SDI(4) + numdoc(7)
- */
-
-// Crea la coppia di chiavi per il db PAF a partire da un documento vero e proprio
-static bool chiave_paf(const TDocumento& doc, TString& hfatt, TString& bfatt)
-{
- hfatt.cut(0);
- if (doc.clifor().occasionale())
- hfatt << "O" << doc.get("OCFPI");
- else
- hfatt << doc.clifor().tipo() << doc.clifor().codice();
- CHECK(hfatt.full(), "Destinatario fattura P.A. non valido");
-
- const TCodice_numerazione& codnum = doc.codice_numerazione();
- const long ndoc = doc.numero();
- TString16 fullnumdoc;
- codnum.complete_num(ndoc, fullnumdoc);
-
- bfatt.cut(0) << doc.get_date(DOC_DATADOC).date2ansi() << '/' << doc.tipo().tipo_doc_sdi() << '/' << fullnumdoc;
- return hfatt.full() && bfatt.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& hfatt, TString& bfatt)
-{
- TDocumento d(doc);
- chiave_paf(d, hfatt, bfatt);
- return hfatt.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ù 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;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////
-// TAncestor
-/////////////////////////////////////////////////////////////////////////////////////
-
-struct TAncestor : public TObject
-{
- TString20 _numdoc;
- TDate _datadoc;
-
- TAncestor(const TRectype& rdoc);
-};
-
-TAncestor::TAncestor(const TRectype& rdoc)
-{
- const int anno = rdoc.get_int(RDOC_ANNO);
- const TString4 codnum = rdoc.get(RDOC_CODNUM);
- const long ndoc = rdoc.get_long(RDOC_NDOC);
- const TCodice_numerazione& num = cached_numerazione(codnum);
-
- TToken_string kdoc;
- kdoc = rdoc.get(RDOC_PROVV);
- kdoc.add(anno);
- kdoc.add(codnum);
- kdoc.add(ndoc);
- const TRectype& doc = cache().get(LF_DOC, kdoc);
-
- TString16 numdoc;
- num.complete_num(ndoc, numdoc);
- _numdoc.format("%d/%s/%s", anno, static_cast(codnum), static_cast(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;
- const TVariant& get(const char* fld) 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 TString sq_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");
-}
-
-const TString TPaf_record::sq_get(const char* fld) const
-{
- return db().sq_get(fld);
-}
-
-// Legge il valore di un campo variant
-const TVariant& TPaf_record::get(const char* fld) const
-{
- const TVariant* var = (const TVariant*)_fields.objptr(fld);
- return var ? *var : NULL_VARIANT;
-}
-
-// Converte un variant in una stringa valida per SQLite
-const TString& TPaf_record::var2str(const TString& fldname, const TVariant& var) const
-{
- const TFieldtypes vt = var.type();
- 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 db().sq_set_exec(query);
-}
-
-// Carica un record in base ai campi chiave
-bool TPaf_record::search()
-{
- CHECKS(_fields.items() > 0, "Can't search with empty key on table ", static_cast(_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;
- // TODO: Valutare
- return db().sq_set_exec(query);
-}
-
-// Carica un record in base ad un massimo di 3 campi chiave
-bool TPaf_record::search(const char* k1, const char* k2, const char* k3)
-{
- _fields.destroy();
-
- set(_key.get(0), k1);
- set(_key.get(1), k2);
- if (k3 && *k3)
- set(_key.get(2), k3);
-
- return search();
-}
-
-// 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 db().sq_set_exec(query);
-}
-
-// Crea un record della tabella data ed imposta i nomi dei campi chiave
-TPaf_record::TPaf_record(const char* table) : _table(table), _key(15, ',')
-{
- TString q;
- q << "SELECT col.[name] FROM sys.columns AS col \
- inner JOIN sys.index_columns AS idx on col.[object_id] = idx.[object_id] AND col.[column_id] = idx.[column_id] \
- inner join sys.indexes as K on idx.[index_id] = K.[index_id] \
- where K.[name] = '" << table << "_KEY' \
- AND idx.[object_id] = object_id('" << table << "') \
- ORDER BY index_column_id ASC";
- for (bool ok = db().sq_set_exec(q); ok; ok = db().sq_next())
- {
- _key.add(db().sq_get("name"));
- }
- CHECKS(!_key.empty_items(), "Invalid primary key for table ", table);
-}
-
/////////////////////////////////////////////////////////////////////////////////////
// TPa_mask
/////////////////////////////////////////////////////////////////////////////////////
@@ -439,6 +55,26 @@ bool TPA_mask::is_fattura(const TRectype& doc) const
return cn.tipo() == 2 && !cn.get_bool("B10"); // Controlla se fattura provvisioria esclusa da P.A.
}
+TString& add_filter(const TString& field, const TString& from, const TString& to)
+{
+ TString& query = get_tmp_string();
+ const TString qf = field.find('.') < 0 ? field : field.sub(field.find('.') + 1);
+
+ if (from.full() && to.full())
+ {
+ query << "&&(BETWEEN(" << field << ", #DA" << qf << ", #A" << qf << "))";
+ }
+ else if (from.full())
+ {
+ query << "&&(" << field << ">=#DA" << qf << ")";
+ }
+ else if (to.full())
+ {
+ query << "&&(" << field << "<=#A" << qf << ")";
+ }
+
+ return query;
+}
void TPA_mask::fill()
{
@@ -461,18 +97,9 @@ void TPA_mask::fill()
query << "USE 33 " <<
"SELECT (BETWEEN(33.DATADOC,#DADATADOC,#ADATADOC))&&(33.TIPOCF=='C')";
- if(get(F_DATIPODOC).full() && get(F_ATIPODOC).full())
- {
- query << "&&(BETWEEN(33.TIPODOC, #DATIPODOC, #ATIPODOC))";
- }
- else if(get(F_DATIPODOC).full())
- {
- query << "&&(33.TIPODOC>=#DATIPODOC)";
- }
- else if (get(F_ATIPODOC).full())
- {
- query << "&&(33.TIPODOC<=#ATIPODOC)";
- }
+
+ query << add_filter("33.TIPODOC", get(F_DATIPODOC), get(F_ATIPODOC));
+
query << "\nJOIN 20 INTO TIPOCF==TIPOCF CODCF==CODCF \n" <<
"JOIN 17 TO 33 INTO TIPOCF==TIPOCF CODCF==CODCF \n" <<
"JOIN %TIP TO 33 ALIAS 400 INTO CODTAB==TIPODOC";
@@ -488,13 +115,10 @@ void TPA_mask::fill()
TProgress_monitor pi(rec.items(), NULL);
- // Setto variabili di errore
- static bool first;
- static bool show;
- static bool ask;
+ bool first, show, ask = !((show = (first = true)));
- first = show = true;
- ask = false;
+ // Disabilito la colonna del codice ufficio
+ docs.enable_column(docs.cid2index(S_UFFICIO), false);
for (bool okc = rec.move_first(); okc; okc = rec.move_next())
{
@@ -542,12 +166,16 @@ void TPA_mask::fill()
rif = "XXXXXXX";
else
{
- disable(DLG_OK);
-
+ // Segno la riga errata
+ if (first)
+ {
+ // Abilito la colonna del codice ufficio per segnalare l'errore
+ docs.enable_column(docs.cid2index(S_UFFICIO));
+ }
+ docs.set_back_and_fore_color(COLOR_RED, COLOR_WHITE, rec.current_row(), docs.cid2index(S_UFFICIO));
+
if (show)
{
- // Segno la riga errata
- docs.set_back_and_fore_color(COLOR_RED, COLOR_WHITE, rec.cursor()->pos());
TString msg; msg << "Trovata fattura " << rec.get(DOC_CODNUM).as_string() << "/" << rec.get(DOC_TIPODOC).as_string() << "/" << rec.get(DOC_NDOC).as_int() << " senza nessun codice destinatario/pec, Continuare?";
const bool force_stop = !yesno_box(msg);
if (!first && !ask && !force_stop)
@@ -566,6 +194,8 @@ void TPA_mask::fill()
}
}
}
+ if(rif.full())
+ docs.set_back_and_fore_color(COLOR_WHITE, COLOR_BLACK, rec.cursor()->pos(), docs.cid2index(S_UFFICIO));
row.add(rif);
row.add(rec.get("17." CFV_PARIFAMM).as_string());
row.add(rec.get("20." CLI_COFI).as_string());
@@ -586,7 +216,6 @@ void TPA_mask::fill()
row.add(attach ? "X" : " ");
row.add(!td.invio_xml() ? "X" : "");
- sht.add(row);
}
docs.force_update();
@@ -703,1112 +332,27 @@ bool TPA_mask::checkNotEmpty()
class TDoc2Paf : public TSkeleton_application
{
- TAnagrafica _ditta;
- TString16 _cofi;
- TFilename _dbname;
- TLog_report* _log;
- TString _logpaf;
- TString _def_fld;
- TString _def_usr_fld;
-
-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();
- const char* natura(const TString& codiva) const;
- static void set_IVA(const TString& codiva, TPaf_record& paf);
- static void set_IVA(const TRiga_documento& rdoc, TPaf_record& paf);
- static const bool add_row_art(const TString codice_tipo, const TString& codice_valore, TPaf_record& paf);
-
-
- 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)
- {
- }
+ TDoc2Paf() {}
};
-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()
-{
- if (_log)
- {
- _log->preview();
- delete _log;
- _log = NULL;
- }
- return true;
-}
-
-
-const char* TDoc2Paf::natura(const TString& codiva) const
-{
- return cache().get("%IVA", codiva, "S12");
-}
-
-void TDoc2Paf::set_IVA(const TString& codiva, TPaf_record& paf)
-{
- // É necessario il cast a real?
- paf.set("PI_ALIQUOTAIVA", static_cast(cache().get("%IVA", codiva, "R0")));
- paf.set("PI_NATURA", cache().get("%IVA", codiva, "S12"));
-}
-
-void TDoc2Paf::set_IVA(const TRiga_documento& rdoc, TPaf_record& paf)
-{
- set_IVA(rdoc.get(RDOC_CODIVA), paf);
-}
-
-const bool TDoc2Paf::add_row_art(const TString codice_tipo, const TString& codice_valore, TPaf_record& paf)
-{
- static long riga_art = 0;
- paf.set("PY_KEYNLINAR", ++riga_art);
- paf.set("PY_TIPOARTICOLO", codice_tipo);
- paf.set("PY_VALOREARTICOLO", codice_valore);
- const bool ok = paf.insert();
-#ifdef DBG
- if(!ok)
- error_box("Allah al bar!");
-#endif
- return ok;
-}
-
-
-bool TDoc2Paf::elabora(TDocumentoEsteso& doc)
-{
- TString8 hfatt; // Codice univoco di 6 caratteri dell'ufficio P.A. o di 7 caratteri per un privato
- TString20 bfatt; // Codice univoco di 20 caratteri del documento
-
- TAnagrafica clifo(doc.clifor().tipo(), doc.clifor().codice());
-
- TString8 coddest = doc.clifor().vendite().get("PADESTIN");
- TString pec = doc.clifor().get("PEC");
- bool enapec = false;
- if(coddest.empty())
- {
- // Controllo se ha la pec
- if (pec.full())
- {
- coddest = "0000000";
- enapec = true;
- }
- // Controllo se è straniero
- else if(clifo.estero())
- {
- coddest = "XXXXXXX";
- }
- else
- return false;
- }
-
- const bool privato = coddest.len() != 6;
- bool ok = true;
-
- if (!chiave_paf(doc, hfatt, bfatt))
- return false;
- log(-1, bfatt);
-
- const TFirm& firm = prefix().firm();
- const char* const paese = "IT";
- TCausale caus = TCausale(doc.tipo().causale(), doc.anno());
-
- //
- 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_FMTTRASMISS", privato? "FPR12" : "FPA12"); // SDI11 si usa dal 2015 per lo split payment (prima era SDI10)
-
- paf0100f.set("P1_CODDEST", coddest);
- 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");
- ok &= paf0100f.insert();
- //
-
- if (enapec)
- {
- //
- TPaf_record paf3200f("PAF3200F");
- paf3200f.set("PU_KEYHEADERFATT", hfatt);
- paf3200f.set("PU_KEYBODYFATT", bfatt);
- paf3200f.remove();
- paf3200f.set("PU_PEC", pec);
- ok &= paf3200f.insert();
- //
- }
-
- //
- 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", _ditta.stato_partita_IVA());
- paf0200f.set("P2_FISCIVACOD", _ditta.partita_IVA());
- }
- paf0200f.set("P2_CODFISCALE", _ditta.codice_fiscale());
- if (_ditta.fisica())
- {
- paf0200f.set("P2_ANANOME", _ditta.nome());
- paf0200f.set("P2_ANACOGNOME", _ditta.cognome());
- }
- else
- {
- paf0200f.set("P2_ANADENOMIN", _ditta.ragione_sociale());
- }
-
- paf0200f.set("P2_REGFISCALE", doc.tipo().reg_fisc());
-
- // DatiSede
- paf0200f.set("P2_SEDEIND", _ditta.via_residenza());
- paf0200f.set("P2_SEDENRCIVICO", _ditta.civico_residenza());
- paf0200f.set("P2_SEDECAP", _ditta.CAP_residenza());
- paf0200f.set("P2_SEDECOMUNE", _ditta.comune_residenza());
- paf0200f.set("P2_SEDEPROV", _ditta.provincia_residenza());
- paf0200f.set("P2_SEDENAZ", paese);
- paf0200f.set("P2_GESTIONE", "D");
-
- TAnagrafica cliente(doc.clifor());
-
- TString rifamm = cco(doc).get("S4");
- if (rifamm.blank())
- rifamm = doc.clifor().vendite().get(CFV_PARIFAMM);
- paf0200f.set("P2_RIFAMMINISTR", rifamm);
-
- paf0200f.set("P2_ISCRREASOCIOU", _ditta.sociounico() == 'S' ? "SU" : "SM");
-
- TISAM_recordset unloc("USE UNLOC\nJOIN COMUNI INTO COM==COMCCIAA\nFROM CODDITTA=#DITTA\nTO CODDITTA=#DITTA");
- unloc.set_var("#DITTA", 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");
-
- ok &= paf0200f.insert();
-
- //
-
- //
-
- 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", cliente.stato_partita_IVA());
- 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", cliente.stato_residenza_ISO());
- paf0400f.set("P4_GESTIONE", "D");
- ok &= paf0400f.insert();
- //
-
- //
- TPaf_record paf0700f("PAF0700F");
- paf0700f.set("P7_KEYHEADERFATT", hfatt);
- paf0700f.set("P7_KEYBODYFATT", bfatt);
- paf0700f.remove();
- paf0700f.set("P7_TIPODOC", doc.tipo().tipo_doc_sdi());
- 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");
-
- //
- if(doc.get_real("BOLLI") > ZERO)
- {
- paf0700f.set("P7_IMPORTOBOLLO", doc.get("BOLLI"));
- }
- //
-
- //
- // Non la mettiamo!
- //
-
- // Non inserisco più adesso il paf0700f ma lo faccio alla fine (per inserire le ritenute)
-
- //
- 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");
- ok &= paf0900f.insert();
- }
- }
- }
- //
-
- //
- 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");
- ok &= paf2700f.insert();
- //
-
- // Azzera DDT
- TPaf_record paf1600f("PAF1600F");
- paf1600f.set("PF_KEYHEADERFATT", hfatt);
- paf1600f.set("PF_KEYBODYFATT", bfatt);
- paf1600f.remove();
-
- // Fuori dallo scope per dopo
- const TString16 cup = doc.get(DOC_CUP);
- const TString16 cig = doc.get(DOC_CIG);
- const TString80 com = doc.get(DOC_CODCMS);
-
- if (!privato)
- {
- // 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();
-
- 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");
- ok &= 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");
- ok &= 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");
- ok &= paf1200f.insert();
- }
- }
-
- if (cup.blank() && cig.blank())
- log(1, "CIG e CUP assenti");
- }
- //
-
- 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
-
- TPaf_record paf1900f("PAF1900F");
- paf1900f.set("PY_KEYHEADERFATT", hfatt);
- paf1900f.set("PY_KEYBODYFATT", bfatt);
- paf1900f.remove(); // Cancella tutte le righe articoli del documento
-
-
- long riga = 0;
- TString16 codivadefault;
- {
- FOR_EACH_PHYSICAL_RDOC(doc, r, rdoc)
- {
- codivadefault = rdoc->get(RDOC_CODIVA);
- if (codivadefault.full())
- break;
- }
- }
- 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
-
- //
- long riga_art = 0;
- TArticolo& art = rdoc->articolo();
- if (art.ok())
- {
- paf1900f.reset();
- paf1900f.set("PY_KEYHEADERFATT", hfatt);
- paf1900f.set("PY_KEYBODYFATT", bfatt);
- paf1900f.set("PY_KEYNLINEA", riga);
-
- TString& tmp = get_tmp_string();
-
- if (art.codice().full())
- {
- tmp.cut(0) << art.codice(); // Fixed_string di merda
- ok &= add_row_art("Codice interno", tmp, paf1900f);
- }
- if (rdoc->tipo().codice() == "14")
- {
- ok &= add_row_art("Codice cliente", rdoc->get("CODARTALT"), paf1900f);
- }
- }
- //
-
-
- set_IVA(codivadefault, paf1800f);
-
- 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à 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(true, false));
- }
- paf1800f.set("PI_PRZTOTALE", rdoc->importo(true, false));
- set_IVA(*rdoc, paf1800f);
-
- /*
- const TDate data = doc.get(DOC_DATADOC);
- paf1800f.set("PI_DTINIZIOPER", data);
- paf1800f.set("PI_DTFINEPER", data);
- */
-
- //
-
- 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_KEYNLINAR", ++nlin_sconto);
- if (perc > ZERO)
- {
- paf2000f.set("PJ_TIPOSCONTO", "SC");
- paf2000f.set("PJ_PERCSCONTO", perc);
- }
- else
- {
- paf2000f.set("PJ_TIPOSCONTO", "MG");
- paf2000f.set("PJ_PERCSCONTO", -perc);
- }
- paf2000f.set("PJ_GESTIONE", "D");
- ok &= paf2000f.insert();
- }
- }
- }
- //
-
-
- /*
- * Ogni riga si può rifare a un DDT/Ordine diverso, per questo devo inserire i dati da qua e non in testata
- */
- TArray ancestors;
- find_ancestors(*rdoc, ancestors);
- for (int i = ancestors.last(); i > 0; i = ancestors.pred(i))
- {
- 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");
- ok &= 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);
- if (!privato)
- {
- paf1000f.set("P0_COMMCONVENZ", com);
- paf1000f.set("P0_CODCUP", cup);
- paf1000f.set("P0_CODCIG", cig);
- }
- paf1000f.set("P0_GESTIONE", "D");
- ok &= 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à %d ha quantità 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);
-
- // Controllo se è una ritenuta fiscale
- //
- if(sp.tipo_ritenuta() == 'F')
- {
- paf0700f.set("P7_TIPORITENUTA", cliente.fisica() ? "RT01" : "RT02");
- paf0700f.set("P7_IMPORTORIT", doc.imponibile() * sp.perc() / CENTO);
- paf0700f.set("P7_ALIQUOTARIT", TCodiceIVA(sp.cod_iva()).percentuale());
- paf0700f.set("P7_CAUSPAGAM", cache().get("CA7", to_tstring(sp.caus_770()), "S2"));
- }
- //
- }
- 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");
- ok &= paf1800f.insert();
- }
- //
-
-
- //
- /*
- * Non valorizziamo nulla al momento in quanto su Campo i dati obbligatori non ci sono/non sono obbligatori
- TString cod_vettore = doc.get("CODVETT1");
- // É una fattura accompagnatoria!
- if(cod_vettore.full())
- {
- }
- */
- //
-
- // Salvo la testata
- ok &= paf0700f.insert();
-
- //
- 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à 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_ALIQUOTAIVA", aliquota);
- if (aliquota.is_zero())
- paf2200f.set("PL_NATURA", natura(riva.cod_iva().codice()));
-
- 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");
- ok &= paf2200f.insert();
- }
- //
-
- //
- 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 = pag.cond_pag_sdi(); // A rate (TP01) o una soluzione(TP02)?
- paf2400f.set("PN_RIGA", ZERO); // Al momento non gestiamo più tipologie di pagamento per documento
- paf2400f.set("PN_CONDPAGAMENTO", rateazione);
- paf2400f.set("PN_GESTIONE", "D");
- ok &= 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 è presente il codice IBAN per il pagamento"));
-
- for (int nr = 0; nr < nrate; nr++)
- {
- paf2500f.set("PO_RIGA", long(nr + 1)); // Numero rata
- int rp = nr < pag.n_rate() ? nr : 0;
- static TString key_class; key_class.cut(0) << pag.tipo_rata(rp) << pag.ulc_rata(rp);
-#ifdef DBG
- bool tolla = true;
- TString pop = cache().get("%CLR", key_class, "S12");
- bool aaaa = true;
-#endif
- paf2500f.set("PO_MODALITAPAGAM", cache().get("%CLR", key_class, "S12")); // Si assicura che il numero riga sia accettabile
-
- 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");
- ok &= 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())
- {
- static TString dest_path;
- static TString dest_usr_path;
-
- dest_path.cut(0) << _def_fld << fname.name();
- dest_usr_path.cut(0) << _def_usr_fld << fname.name();
-
- if(!fcopy(fname, dest_usr_path))
- {
- if (yesno_box("Errore critico nel copiare il file %s, si desidera continuare?", fname.name()))
- continue;
- else
- return false;
- }
-
- // Provo a copiare il file
- paf2600f.set("PP_NUMEROLINEA", ++nprogr);
- paf2600f.set("PP_NOMEATTACHMENT", fname.name());
- paf2600f.set("PP_ATTACHMENT", dest_path);
- fname.upper(); // serve estensione maiuscola
- paf2600f.set("PP_FMTATTACHMENT", fname.ext());
- ok &= paf2600f.insert();
- }
- }
-
- }
- //
-
- // Tabella di non invio XML
- TPaf_record pafw300f("PAFW300F");
- pafw300f.set("PW_KEYPRGINVIO", hfatt);
- pafw300f.set("PW_KEYHEADERFATT", bfatt);
- pafw300f.remove(); // Cancella eventuali allegati
- const TTipo_documento& td = cached_tipodoc(doc.get(DOC_TIPODOC));
- TString codsdi = !td.invio_xml() ? "**********" : (enapec ? pec : coddest);
- pafw300f.set("PW_CODSDI", codsdi);
- ok &= pafw300f.insert();
-
-
- return ok;
-}
-
-bool TDoc2Paf::elabora(const TRectype& rec)
-{
- TDocumentoEsteso doc;
- if (doc.read(rec) == NOERR)
- {
- return elabora(doc) ? db().sq_commit() : db().sq_rollback();
- }
- return false;
-}
-
-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);
-}
-
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)
- {
- show_log();
- //if (show_log())
- //genera_xml();
- return;
- }
-
TPA_mask mask;
- mask.set(F_COFI, _cofi);
while (mask.run() == K_ENTER)
{
- _cofi = mask.get(F_COFI);
-
- _def_fld = ini_get_string(CONFIG_DITTA, "fp", "flddest");
- if(!_def_fld.ends_with("\\"))
- {
- _def_fld << "\\";
- }
-
- _def_usr_fld = ini_get_string(CONFIG_DITTA, "fp", "fldusrdest", "");
- if(_def_usr_fld.empty())
- {
- _def_usr_fld = _def_fld;
- }
- else if (!_def_usr_fld.ends_with("\\"))
- {
- _def_usr_fld << "\\";
- }
-
TString_array& sht = mask.sfield(F_DOCS).rows_array();
+ TDoc_fp elab;
+ //elab.set_cache_insert(true);
if (!sht.empty())
{
- TProgress_monitor pi(sht.items(), NULL);
+ TProgress_monitor pi(sht.items(), "Esportazione Fatture");
ndocs = 0;
FOR_EACH_ARRAY_ROW(sht, r, riga)
{
@@ -1818,23 +362,23 @@ void TDoc2Paf::main_loop()
const long ndoc = riga->get_long(mask.sfield(F_DOCS).cid2index(S_NDOC));
const TFixed_string codnum(riga->get(mask.sfield(F_DOCS).cid2index(S_CODNUM))); // lascio sapientemente per ultima la get di una stringa
const TDoc_key key(anno, codnum, ndoc);
- if (elabora(key))
+ if (elab.doc_to_paf(key))
ndocs++;
}
if (!pi.add_status(1))
break;
}
- if (ndocs > 0)
- {
- db().sq_set_exec("UPDATE PAF0100F SET P1_GESTIONE = 'P' WHERE P1_GESTIONE = 'D'");
- db().sq_commit();
- }
-
- message_box(FR("Sono stati elaborati %d documenti"), ndocs);
}
-
if (ndocs > 0)
- show_log();
+ {
+ if (elab.commit() > 0)
+ {
+ message_box(FR("Sono stati elaborati %d documenti"), ndocs);
+ }
+ else
+ error_box("Errore durante il salvataggio");
+ elab.show_log();
+ }
}
}
@@ -1845,24 +389,15 @@ bool TDoc2Paf::create()
LF_DOC, LF_RIGHEDOC, 0);
TRectype cfven(LF_CFVEN);
- if (cfven.type(CFV_PARIFAMM) != _alfafld)
+ if (cfven.length(CFV_PADESTIN) != 7) // Nuova lunghezza per privati
return error_box(TR("Database non convertito per fatturazione F.P."));
- _ditta.init(LF_NDITTE, prefix().get_codditta());
-
- _cofi = ini_get_string(CONFIG_DITTA, "fp", "TRASMITTCOD");
- if (_cofi.blank())
- _cofi = _ditta.codice_fiscale();
-
return check_tables() && TSkeleton_application::create();
}
bool TDoc2Paf::destroy()
{
- if (_cofi.full())
- ini_set_string(CONFIG_DITTA, "fp", "TRASMITTCOD", _cofi);
-
db().sq_disconnect();
return TSkeleton_application::destroy();
}
diff --git a/src/fp/fp0300a.h b/src/fp/fp0300a.h
index edf4ab1d1..2db5f221a 100644
--- a/src/fp/fp0300a.h
+++ b/src/fp/fp0300a.h
@@ -2,9 +2,10 @@
#define F_DATAINI 301
#define F_DATAEND 302
#define F_FATTSEL 303
-#define F_COFI 304
+#define F_DACODNUM 304
#define F_DATIPODOC 305
-#define F_ATIPODOC 306
+#define F_ACODNUM 306
+#define F_ATIPODOC 307
#define END_MASK 399
#define F_DOCS 201
diff --git a/src/fp/fp0300a.uml b/src/fp/fp0300a.uml
index 9e67ab5c6..acf26e6e3 100644
--- a/src/fp/fp0300a.uml
+++ b/src/fp/fp0300a.uml
@@ -21,7 +21,7 @@ BEGIN
CHECKTYPE REQUIRED
END
-RADIOBUTTON F_FATTSEL 25
+RADIOBUTTON F_FATTSEL 100
BEGIN
PROMPT 1 1 "Fatture da visualizzare"
ITEM "|Da inviare"
@@ -30,17 +30,28 @@ BEGIN
ITEM "X|XML Generato"
ITEM "E|In errore"
ITEM "N|Accettate"
+ FLAGS "Z"
END
-STRING F_COFI 16
+STRING F_DACODNUM 4
BEGIN
- PROMPT 30 1 "Codice fiscale trasmittente "
- CHECKTYPE REQUIRED
+ PROMPT 1 4 "Da Numerazione"
+ FIELD CODNUM
+ HELP "Codice numerazione"
+ USE %NUM
+ INPUT CODTAB F_DACODNUM
+ DISPLAY "Codice" CODTAB
+ DISPLAY "Descrizione@50" S0
+ OUTPUT F_DACODNUM CODTAB
+ CHECKTYPE FORCED
+ FLAG "UPA"
+ WARNING "Numerazione assente"
+ KEY 1 2
END
STRING F_DATIPODOC 4
BEGIN
- PROMPT 30 2 "Da tipo doc "
+ PROMPT 30 4 "Da tipo doc "
FIELD TIPODOC
HELP "Codice tipo documento"
USE %TIP
@@ -54,9 +65,25 @@ BEGIN
FLAG "UP"
END
+STRING F_ACODNUM 4
+BEGIN
+ PROMPT 1 5 "A Numerazione "
+ FIELD CODNUM
+ HELP "Codice numerazione"
+ USE %NUM
+ INPUT CODTAB F_ACODNUM
+ DISPLAY "Codice" CODTAB
+ DISPLAY "Descrizione@50" S0
+ OUTPUT F_ACODNUM CODTAB
+ CHECKTYPE FORCED
+ FLAG "UPA"
+ WARNING "Numerazione assente"
+ KEY 1 2
+END
+
STRING F_ATIPODOC 4
BEGIN
- PROMPT 30 3 "A tipo doc "
+ PROMPT 30 5 "A tipo doc "
FIELD TIPODOC
HELP "Codice tipo documento"
USE %TIP
diff --git a/src/fp/fplib01.cpp b/src/fp/fplib01.cpp
index 748836b87..c711f133c 100644
--- a/src/fp/fplib01.cpp
+++ b/src/fp/fplib01.cpp
@@ -7,6 +7,21 @@
#include
#include "text.h"
#include
+#include
+#include
+#include
+
+#include "../fe/felib.h"
+#include "../cg/cglib03.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "../cg/cfban.h"
+#include "modaut.h"
void set_connection(SSimple_query& s)
{
@@ -33,7 +48,12 @@ SSimple_query& db()
return *db;
}
-string getline(ifstream& f);
+string getline(ifstream& f)
+{
+ string app;
+ getline(f, app);
+ return app;
+}
bool check_tables()
{
@@ -98,9 +118,1454 @@ bool check_tables()
return true;
}
-string getline(ifstream& f)
+/*
+* HFATT: tipocf(1) + codcf(6)
+* BFATT: datadoc(8) + tipodoc_SDI(4) + numdoc(7)
+*/
+
+// Crea la coppia di chiavi per il db PAF a partire da un documento vero e proprio
+bool chiave_paf(const TDocumento& doc, TString& hfatt, TString& bfatt)
{
- string app;
- getline(f, app);
- return app;
-}
\ No newline at end of file
+ hfatt.cut(0);
+ if (doc.clifor().occasionale())
+ hfatt << "O" << doc.get("OCFPI");
+ else
+ hfatt << doc.clifor().tipo() << doc.clifor().codice();
+ CHECK(hfatt.full(), "Destinatario fattura P.A. non valido");
+
+ const TCodice_numerazione& codnum = doc.codice_numerazione();
+ const long ndoc = doc.numero();
+ TString16 fullnumdoc;
+ codnum.complete_num(ndoc, fullnumdoc);
+
+ bfatt.cut(0) << doc.get_date(DOC_DATADOC).date2ansi() << '/' << doc.tipo().tipo_doc_sdi() << '/' << fullnumdoc;
+ return hfatt.full() && bfatt.full();
+}
+
+// Crea la coppia di chiavi per il db PAF a partire da un semplice record di testata documento
+bool chiave_paf(const TRectype& doc, TString& hfatt, TString& bfatt)
+{
+ TDocumento d(doc);
+ chiave_paf(d, hfatt, bfatt);
+ return hfatt.full();
+}
+
+/***************************************************************************
+ * TPaf_record
+ ***************************************************************************/
+
+// Imposta il valore di un campo variant
+void TPaf_record::set(const char* fld, const TVariant& var)
+{
+ CHECK(fld && *fld, "Null field name");
+
+ if (var.is_null())
+ {
+ _fields.remove(fld);
+ }
+ else
+ {
+ TVariant* obj = (TVariant*)_fields.objptr(fld);
+ if (obj != NULL)
+ *obj = var;
+ else
+ _fields.add(fld, new TVariant(var));
+ }
+}
+
+// Imposta il valore di un campo intero
+void TPaf_record::set(const char* fld, long val)
+{
+ const TVariant var(val);
+ set(fld, var);
+}
+
+// Imposta il valore di un campo stringa
+void TPaf_record::set(const char* fld, const char* val)
+{
+ if (val == NULL)
+ set(fld, NULL_VARIANT);
+ else
+ {
+ const TVariant var(val);
+ set(fld, var);
+ }
+}
+
+// Imposta il valore di un campo stringa
+void TPaf_record::set(const char* fld, const TString& val)
+{
+ const TVariant var(val);
+ set(fld, var);
+}
+
+// Imposta il valore di un campo numerico
+void TPaf_record::set(const char* fld, const real& val)
+{
+ const TVariant var(val);
+ set(fld, var);
+}
+
+// Imposta il valore di un campo data in formato ISO
+void TPaf_record::set(const char* fld, const TDate& val)
+{
+ if (val.ok())
+ {
+ const TVariant var(val);
+ set(fld, var);
+ }
+ else
+ set(fld, "");
+}
+
+// Imposta il valore di un campo booleano
+void TPaf_record::set(const char* fld, bool var)
+{
+ set(fld, var ? "SI" : "NO");
+}
+
+const TString TPaf_record::sq_get(const char* fld) const
+{
+ return db().sq_get(fld);
+}
+
+// Legge il valore di un campo variant
+const TVariant& TPaf_record::get(const char* fld) const
+{
+ const TVariant* var = (const TVariant*)_fields.objptr(fld);
+ return var ? *var : NULL_VARIANT;
+}
+
+// Converte un variant in una stringa valida per SQLite
+const TString& TPaf_record::var2str(const TString& fldname, const TVariant& var) const
+{
+ const TFieldtypes vt = var.type();
+ 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;
+}
+
+TString& TPaf_record::remove_string()
+{
+ TString& query = get_tmp_string().cut(0);
+ query << "DELETE FROM " << _table << " WHERE ";
+ int nkf = 0;
+ FOR_EACH_TOKEN(_key, fld)
+ {
+ const TVariant& var = get(fld);
+ if (!var.is_null())
+ {
+ if (nkf++ > 0)
+ query << " AND ";
+ query << fld << '=' << var2str(fld, var);
+ }
+ }
+ CHECKS(nkf >= 2, "Can't remove partial key on table ", (const char*)_table);
+ query << ';';
+ return query;
+}
+
+
+// Elimina il record in base ai campi chiave
+bool TPaf_record::remove()
+{
+ return db().sq_set_exec(remove_string());
+}
+
+// Carica un record in base ai campi chiave
+bool TPaf_record::search()
+{
+ CHECKS(_fields.items() > 0, "Can't search with empty key on table ", static_cast(_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;
+ // TODO: Valutare
+ return db().sq_set_exec(query);
+}
+
+// Carica un record in base ad un massimo di 3 campi chiave
+bool TPaf_record::search(const char* k1, const char* k2, const char* k3)
+{
+ _fields.destroy();
+
+ set(_key.get(0), k1);
+ set(_key.get(1), k2);
+ if (k3 && *k3)
+ set(_key.get(2), k3);
+
+ return search();
+}
+
+TString & TPaf_record::insert_string()
+{
+ CHECKS(_fields.items() >= _key.items(), "Can't insert empty record on table ", _table);
+
+ TString& query = get_tmp_string().cut(0), values = get_tmp_string().cut(0);
+ query << "INSERT INTO " << _table << "\n(";
+ FOR_EACH_ASSOC_OBJECT(_fields, obj, fld, itm)
+ {
+ const TVariant& var = get(fld);
+ if (!var.is_null())
+ {
+ query << fld << ',';
+ values << var2str(fld, var) << ',';
+ }
+ }
+ query.rtrim(1);
+ values.rtrim(1);
+ query << ")\nVALUES (" << values << ");";
+ return query;
+}
+
+// Aggiunge un record al db
+bool TPaf_record::insert()
+{
+ return db().sq_set_exec(insert_string());
+}
+
+// Crea un record della tabella data ed imposta i nomi dei campi chiave
+TPaf_record::TPaf_record(const char* table) : _table(table), _key(15, ',')
+{
+ TString q;
+ q << "SELECT col.[name] FROM sys.columns AS col \
+ inner JOIN sys.index_columns AS idx on col.[object_id] = idx.[object_id] AND col.[column_id] = idx.[column_id] \
+ inner join sys.indexes as K on idx.[index_id] = K.[index_id] \
+ where K.[name] = '" << table << "_KEY' \
+ AND idx.[object_id] = object_id('" << table << "') \
+ ORDER BY index_column_id ASC";
+ for (bool ok = db().sq_set_exec(q); ok; ok = db().sq_next())
+ {
+ _key.add(db().sq_get("name"));
+ }
+ CHECKS(!_key.empty_items(), "Invalid primary key for table ", table);
+}
+
+/***************************************************************************
+ * TAncestor
+ ***************************************************************************/
+
+struct TAncestor : public TObject
+{
+ TString20 _numdoc;
+ TDate _datadoc;
+
+ TAncestor(const TRectype& rdoc);
+};
+
+TAncestor::TAncestor(const TRectype& rdoc)
+{
+ const int anno = rdoc.get_int(RDOC_ANNO);
+ const TString4 codnum = rdoc.get(RDOC_CODNUM);
+ const long ndoc = rdoc.get_long(RDOC_NDOC);
+ const TCodice_numerazione& num = cached_numerazione(codnum);
+
+ TToken_string kdoc;
+ kdoc = rdoc.get(RDOC_PROVV);
+ kdoc.add(anno);
+ kdoc.add(codnum);
+ kdoc.add(ndoc);
+ const TRectype& doc = cache().get(LF_DOC, kdoc);
+
+ TString16 numdoc;
+ num.complete_num(ndoc, numdoc);
+ _numdoc.format("%d/%s/%s", anno, static_cast(codnum), static_cast(numdoc));
+ _datadoc = doc.get_date(DOC_DATADOC);
+}
+
+/***************************************************************************
+ * TDoc_fp
+ ***************************************************************************/
+
+bool TDoc_fp::parse_sconto(const TString& formula, TToken_string& sconti) const
+{
+ sconti.cut(0);
+ int start = 0;
+ for (int i = 0; ; i++)
+ {
+ const char c = formula[i];
+ if (c == '+' || c == '-' || c < ' ')
+ {
+ if (i > 0)
+ {
+ TString8 tok = formula.sub(start, i);
+ tok.replace(',', '.');
+ const real perc = tok;
+ if (!perc.is_zero())
+ sconti.add(tok);
+ }
+ if (c < ' ')
+ break;
+ start = i;
+ }
+ }
+ return sconti.full();
+}
+
+bool TDoc_fp::get_bnp_iban(const TString& abi, const TString& cab, int nprog, TString& iban)
+{
+ TTable bnp("BNP");
+ TString16 key;
+ key << abi << cab;
+ if (nprog > 0)
+ {
+ TString4 sprog;
+ sprog.format("%02d", nprog);
+ key << sprog;
+ }
+ bnp.put("CODTAB", key);
+ int err = bnp.read(_isgteq);
+ if (err == NOERR && !bnp.get("CODTAB").starts_with(abi))
+ err = _iskeynotfound;
+ if (err == NOERR)
+ iban = bnp.get("S3");
+
+ return err == NOERR;
+}
+
+bool TDoc_fp::get_bank(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* TDoc_fp::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* TDoc_fp::find_parent_row(const TRectype& rdoc) const
+{
+ const long id = rdoc.get_long(RDOC_DAIDRIGA);
+ if (id > 0L)
+ {
+ TToken_string key;
+ key.add(rdoc.get(RDOC_DACODNUM));
+ if (key.full())
+ {
+ key.add(rdoc.get(RDOC_DAANNO));
+ key.add(rdoc.get(RDOC_DAPROVV));
+ key.add(rdoc.get(RDOC_DANDOC));
+ for (int r = 0; ; r++)
+ {
+ if (r == 0)
+ key.add(id, 4);
+ else
+ key.add(r, 4);
+ const TRectype& rec = cache().get(LF_RIGHEDOC, key);
+ if (r > 0 && rec.empty())
+ break;
+ if (rec.get_long(RDOC_IDRIGA) == id)
+ return &rec;
+ }
+ }
+ }
+ return NULL;
+}
+
+int TDoc_fp::find_ancestors(const TRiga_documento& rdoc, TArray& ancestors) const
+{
+ if (rdoc.is_articolo())
+ {
+ for (const TRectype* prdoc = find_parent_row(rdoc); prdoc != NULL; prdoc = find_parent_row(*prdoc))
+ {
+ const TCodice_numerazione& cn = cached_numerazione(prdoc->get(RDOC_CODNUM));
+ const int td = cn.tipo();
+ if (td > 0 && ancestors.objptr(td) == NULL)
+ ancestors.add(new TAncestor(*prdoc), td);
+ }
+ }
+ return ancestors.items();
+}
+
+bool TDoc_fp::insert(TPaf_record& p)
+{
+ bool ok;
+ if(_cache_insert)
+ {
+ _query.push_back(p.insert_string());
+ ok = true;
+ }
+ else
+ {
+ ok = p.insert();
+ }
+ return ok;
+}
+
+bool TDoc_fp::remove(TPaf_record& p)
+{
+ bool ok;
+ if (_cache_insert)
+ {
+ _query.push_back(p.remove_string());
+ ok = true;
+ }
+ else
+ {
+ ok = p.remove();
+ }
+ return ok;
+}
+
+bool TDoc_fp::save_paf()
+{
+ bool ok = true;
+ if (_cache_insert)
+ {
+ string query;
+ for (auto i = _query.begin(); i != _query.end(); ++i)
+ query += *i;
+ ok = db().sq_set_exec(query);
+ }
+ return ok;
+}
+
+const TRectype& TDoc_fp::cco(const TRectype& doc) const
+{
+ TString80 conkey;
+ const TString& con = doc.get(DOC_CONTRATTO);
+ if (con.full())
+ {
+ char tcon = doc.get_char(DOC_MODPAG);
+ if (tcon < 'C') tcon = 'C';
+ conkey.format("%c%6ld%s", tcon, doc.get_long(DOC_CODCF), (const char*)con);
+ }
+ return cache().get("&CON", conkey);
+}
+
+void TDoc_fp::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 TDoc_fp::show_log()
+{
+ if (_log)
+ {
+ _log->preview();
+ delete _log;
+ _log = NULL;
+ }
+ return true;
+}
+
+const int TDoc_fp::commit()
+{
+ int r = 0;
+ if (_to_commit)
+ {
+ if(db().sq_set_exec("UPDATE PAF0100F SET P1_GESTIONE = 'P' WHERE P1_GESTIONE = 'D'") && db().sq_commit())
+ {
+ r = 1;
+ }
+ else
+ {
+ r = -1;
+ log(3, db().sq_get_string_error());
+ }
+ }
+ _to_commit = false;
+ return r;
+}
+
+
+const char* TDoc_fp::natura(const TString& codiva) const
+{
+ return cache().get("%IVA", codiva, "S12");
+}
+
+void TDoc_fp::set_IVA(const TString& codiva, TPaf_record& paf)
+{
+ // É necessario il cast a real?
+ paf.set("PI_ALIQUOTAIVA", static_cast(cache().get("%IVA", codiva, "R0")));
+ paf.set("PI_NATURA", cache().get("%IVA", codiva, "S12"));
+}
+
+void TDoc_fp::set_IVA(const TRiga_documento& rdoc, TPaf_record& paf)
+{
+ set_IVA(rdoc.get(RDOC_CODIVA), paf);
+}
+
+bool TDoc_fp::add_row_art(const TString codice_tipo, const TString& codice_valore, TPaf_record& paf)
+{
+ static long riga_art = 0;
+ paf.set("PY_KEYNLINAR", ++riga_art);
+ paf.set("PY_TIPOARTICOLO", codice_tipo);
+ paf.set("PY_VALOREARTICOLO", codice_valore);
+ const bool ok = insert(paf);
+#ifdef DBG
+ if (!ok)
+ error_box("Allah al bar!");
+#endif
+ return ok;
+}
+
+bool TDoc_fp::add_row_alleg(TFilename& file, long& nprogr, TPaf_record& paf)
+{
+ static TString dest_path;
+ static TString dest_usr_path;
+ bool ok = false;
+
+ dest_path.cut(0) << _def_fld << file.name();
+ dest_usr_path.cut(0) << _def_usr_fld << file.name();
+ if (!fcopy(file, dest_usr_path))
+ {
+ return yesno_box("Errore critico nel copiare il file %s, si desidera continuare?", file.name());
+ }
+
+ // Provo a copiare il file
+ paf.set("PP_NUMEROLINEA", ++nprogr);
+ paf.set("PP_NOMEATTACHMENT", file.name());
+ paf.set("PP_ATTACHMENT", dest_path);
+ file.upper(); // serve estensione maiuscola
+ paf.set("PP_FMTATTACHMENT", file.ext());
+ ok = insert(paf);
+
+ return ok;
+}
+
+
+bool TDoc_fp::doc_to_paf(TDocumentoEsteso& doc)
+{
+ TString8 hfatt; // Codice univoco di 6 caratteri dell'ufficio P.A. o di 7 caratteri per un privato
+ TString20 bfatt; // Codice univoco di 20 caratteri del documento
+
+ TAnagrafica clifo(doc.clifor().tipo(), doc.clifor().codice());
+
+ TString8 coddest = doc.clifor().vendite().get("PADESTIN");
+ TString pec = doc.clifor().get("PEC");
+ bool enapec = false;
+ if (coddest.empty())
+ {
+ // Controllo se ha la pec
+ if (pec.full())
+ {
+ coddest = "0000000";
+ enapec = true;
+ }
+ // Controllo se è straniero
+ else if (clifo.estero())
+ {
+ coddest = "XXXXXXX";
+ }
+ else
+ return false;
+ }
+
+ const bool privato = coddest.len() != 6;
+ bool ok = true;
+
+ if (!chiave_paf(doc, hfatt, bfatt))
+ return false;
+ log(-1, bfatt);
+
+ const TFirm& firm = prefix().firm();
+ const char* const paese = "IT";
+ TCausale caus = TCausale(doc.tipo().causale(), doc.anno());
+
+ //
+ TPaf_record paf0100f("PAF0100F");
+ paf0100f.set("P1_KEYHEADERFATT", hfatt);
+ paf0100f.set("P1_KEYBODYFATT", bfatt);
+ remove(paf0100f);
+
+ paf0100f.set("P1_TRASMITTPAESE", paese);
+ paf0100f.set("P1_TRASMITTCOD", _cofi);
+ paf0100f.set("P1_FMTTRASMISS", privato ? "FPR12" : "FPA12"); // SDI11 si usa dal 2015 per lo split payment (prima era SDI10)
+
+ paf0100f.set("P1_CODDEST", coddest);
+ TString80 tel;
+ tel << 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");
+ ok &= insert(paf0100f);
+ //
+
+ if (enapec)
+ {
+ //
+ TPaf_record paf3200f("PAF3200F");
+ paf3200f.set("PU_KEYHEADERFATT", hfatt);
+ paf3200f.set("PU_KEYBODYFATT", bfatt);
+ remove(paf3200f);
+ paf3200f.set("PU_PEC", pec);
+ ok &= insert(paf3200f);
+ //
+ }
+
+ //
+ TPaf_record paf0200f("PAF0200F");
+ paf0200f.set("P2_KEYHEADERFATT", hfatt);
+ paf0200f.set("P2_KEYBODYFATT", bfatt);
+ remove(paf0200f);
+
+ if (_ditta.partita_IVA().full())
+ {
+ paf0200f.set("P2_FISCIVAPAESE", _ditta.stato_partita_IVA());
+ paf0200f.set("P2_FISCIVACOD", _ditta.partita_IVA());
+ }
+ paf0200f.set("P2_CODFISCALE", _ditta.codice_fiscale());
+ if (_ditta.fisica())
+ {
+ paf0200f.set("P2_ANANOME", _ditta.nome());
+ paf0200f.set("P2_ANACOGNOME", _ditta.cognome());
+ }
+ else
+ {
+ paf0200f.set("P2_ANADENOMIN", _ditta.ragione_sociale());
+ }
+
+ paf0200f.set("P2_REGFISCALE", doc.tipo().reg_fisc());
+
+ // DatiSede
+ paf0200f.set("P2_SEDEIND", _ditta.via_residenza());
+ paf0200f.set("P2_SEDENRCIVICO", _ditta.civico_residenza());
+ paf0200f.set("P2_SEDECAP", _ditta.CAP_residenza());
+ paf0200f.set("P2_SEDECOMUNE", _ditta.comune_residenza());
+ paf0200f.set("P2_SEDEPROV", _ditta.provincia_residenza());
+ paf0200f.set("P2_SEDENAZ", paese);
+ paf0200f.set("P2_GESTIONE", "D");
+
+ TAnagrafica cliente(doc.clifor());
+
+ TString rifamm = cco(doc).get("S4");
+ if (rifamm.blank())
+ rifamm = doc.clifor().vendite().get(CFV_PARIFAMM);
+ paf0200f.set("P2_RIFAMMINISTR", rifamm);
+
+ paf0200f.set("P2_ISCRREASOCIOU", _ditta.sociounico() == 'S' ? "SU" : "SM");
+
+ TISAM_recordset unloc("USE UNLOC\nJOIN COMUNI INTO COM==COMCCIAA\nFROM CODDITTA=#DITTA\nTO CODDITTA=#DITTA");
+ unloc.set_var("#DITTA", 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");
+
+ ok &= insert(paf0200f);
+
+ //
+
+ //
+
+ TPaf_record paf0400f("PAF0400F");
+ paf0400f.set("P4_KEYHEADERFATT", hfatt);
+ paf0400f.set("P4_KEYBODYFATT", bfatt);
+ remove(paf0400f);
+
+ if (cliente.partita_IVA().full())
+ {
+ paf0400f.set("P4_FISCIVAPAESE", cliente.stato_partita_IVA());
+ paf0400f.set("P4_FISCIVACOD", cliente.partita_IVA());
+ }
+ paf0400f.set("P4_CODFISC", cliente.codice_fiscale());
+
+ 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", cliente.stato_residenza_ISO());
+ paf0400f.set("P4_GESTIONE", "D");
+ ok &= insert(paf0400f);
+ //
+
+ //
+ TPaf_record paf0700f("PAF0700F");
+ paf0700f.set("P7_KEYHEADERFATT", hfatt);
+ paf0700f.set("P7_KEYBODYFATT", bfatt);
+ remove(paf0700f);
+ paf0700f.set("P7_TIPODOC", doc.tipo().tipo_doc_sdi());
+ 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");
+
+ //
+ if (doc.get_real("BOLLI") > ZERO)
+ {
+ paf0700f.set("P7_IMPORTOBOLLO", doc.get("BOLLI"));
+ }
+ //
+
+ //
+ // Non la mettiamo!
+ //
+
+ // Non inserisco più adesso il paf0700f ma lo faccio alla fine (per inserire le ritenute)
+
+ //
+ TPaf_record paf0900f("PAF0900F");
+ paf0900f.set("P9_KEYHEADERFATT", hfatt);
+ paf0900f.set("P9_KEYBODYFATT", bfatt);
+ remove(paf0900f);
+
+ 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");
+ ok &= insert(paf0900f);
+ }
+ }
+ }
+ //
+
+ //
+ TPaf_record paf2700f("PAF2700F");
+ paf2700f.set("PQ_KEYHEADERFATT", hfatt);
+ paf2700f.set("PQ_KEYBODYFATT", bfatt);
+ remove(paf2700f);
+ paf2700f.set("PQ_IMPTOTDOC", doc.totale_doc());
+
+ const TRectype& cont_conv_off = cco(doc);
+ TString causale = cont_conv_off.get("S1");
+ if (causale.full())
+ {
+ causale << ' ' << cont_conv_off.get("S2");
+ causale << ' ' << cont_conv_off.get("S3");
+ causale.strip_double_spaces();
+ causale.cut(200);
+ }
+ else
+ causale = doc.tipo().descrizione();
+ paf2700f.set("PQ_CAUSALE", causale);
+ // paf2700f.set("PQ_ART73", true);
+ paf2700f.set("PQ_GESTIONE", "D");
+ ok &= insert(paf2700f);
+ //
+
+ // Azzera DDT
+ TPaf_record paf1600f("PAF1600F");
+ paf1600f.set("PF_KEYHEADERFATT", hfatt);
+ paf1600f.set("PF_KEYBODYFATT", bfatt);
+ remove(paf1600f);
+
+ // Fuori dallo scope per dopo
+ const TString16 cup = doc.get(DOC_CUP);
+ const TString16 cig = doc.get(DOC_CIG);
+ const TString80 com = doc.get(DOC_CODCMS);
+
+ if (!privato)
+ {
+ // Azzera contratti
+ TPaf_record paf1000f("PAF1000F");
+ paf1000f.set("P0_KEYHEADERFATT", hfatt);
+ paf1000f.set("P0_KEYBODYFATT", bfatt);
+ remove(paf1000f);
+
+ // Azzera convenzioni
+ TPaf_record paf1100f("PAF1100F");
+ paf1100f.set("PA_KEYHEADERFATT", hfatt);
+ paf1100f.set("PA_KEYBODYFATT", bfatt);
+ remove(paf1100f);
+
+ // Azzera ordini
+ TPaf_record paf1200f("PAF1200F");
+ paf1200f.set("PB_KEYHEADERFATT", hfatt);
+ paf1200f.set("PB_KEYBODYFATT", bfatt);
+ remove(paf1200f);
+
+ TString80 con = doc.get(DOC_CONTRATTO);
+ if (con.full() || cup.full() || cig.full())
+ {
+ char tcon = doc.get_char(DOC_MODPAG);
+ if (tcon < 'C') tcon = 'C';
+
+ TDate datadoc; // Data contratto non obbligatoria
+ if (con.full())
+ {
+ datadoc = cco(doc).get_date("D0");
+ }
+ else
+ {
+ // IdDocumento obbligatorio
+ con = cig;
+ if (con.blank())
+ con = cup;
+ }
+
+ if (tcon == 'O')
+ {
+ paf1000f.set("P0_RIFNUMLINEA", 0L);
+ paf1000f.set("P0_IDDOC", con);
+ paf1000f.set("P0_DATADOC", datadoc);
+ paf1000f.set("P0_COMMCONVENZ", com);
+ paf1000f.set("P0_CODCUP", cup);
+ paf1000f.set("P0_CODCIG", cig);
+ paf1000f.set("P0_GESTIONE", "D");
+ ok &= insert(paf1000f);
+ }
+ else if (tcon == 'C')
+ {
+ paf1100f.set("PA_RIFNUMLINEA", 0L);
+ paf1100f.set("PA_IDDOC", con);
+ paf1100f.set("PA_DATADOCU", datadoc);
+ paf1100f.set("PA_COMMCONVENZ", com);
+ paf1100f.set("PA_CODCUP", cup);
+ paf1100f.set("PA_CODCIG", cig);
+ paf1000f.set("PA_GESTIONE", "D");
+ ok &= insert(paf1100f);
+ }
+ else
+ {
+ paf1200f.set("PB_RIFNUMLINEA", 0L);
+ paf1200f.set("PB_IDDOC", con);
+ paf1200f.set("PB_DATADOCO", datadoc);
+ paf1200f.set("PB_COMMCONVENZ", com);
+ paf1200f.set("PB_CODCUP", cup);
+ paf1200f.set("PB_CODCIG", cig);
+ paf1200f.set("PB_GESTIONE", "D");
+ ok &= insert(paf1200f);
+ }
+ }
+
+ if (cup.blank() && cig.blank())
+ log(1, "CIG e CUP assenti");
+ }
+ //
+
+ TPaf_record paf1800f("PAF1800F");
+ paf1800f.set("PI_KEYHEADERFATT", hfatt);
+ paf1800f.set("PI_KEYBODYFATT", bfatt);
+ remove(paf1800f); // Cancella tutte le righe documento
+
+ TPaf_record paf2000f("PAF2000F");
+ paf2000f.set("PJ_KEYHEADERFATT", hfatt);
+ paf2000f.set("PJ_KEYBODYFATT", bfatt);
+ remove(paf2000f); // Cancella tutti gli sconti di riga
+
+ TPaf_record paf1900f("PAF1900F");
+ paf1900f.set("PY_KEYHEADERFATT", hfatt);
+ paf1900f.set("PY_KEYBODYFATT", bfatt);
+ remove(paf1900f); // Cancella tutte le righe articoli del documento
+
+
+ long riga = 0;
+ TString16 codivadefault;
+ {
+ FOR_EACH_PHYSICAL_RDOC(doc, r, rdoc)
+ {
+ codivadefault = rdoc->get(RDOC_CODIVA);
+ if (codivadefault.full())
+ break;
+ }
+ }
+ 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
+
+ //
+ long riga_art = 0;
+ TArticolo& art = rdoc->articolo();
+ if (art.ok())
+ {
+ paf1900f.reset();
+ paf1900f.set("PY_KEYHEADERFATT", hfatt);
+ paf1900f.set("PY_KEYBODYFATT", bfatt);
+ paf1900f.set("PY_KEYNLINEA", riga);
+
+ TString& tmp = get_tmp_string();
+
+ if (art.codice().full())
+ {
+ tmp.cut(0) << art.codice(); // Fixed_string di merda
+ ok &= add_row_art("Codice interno", tmp, paf1900f);
+ }
+ if (rdoc->tipo().codice() == "14")
+ {
+ ok &= add_row_art("Codice cliente", rdoc->get("CODARTALT"), paf1900f);
+ }
+ }
+ //
+
+
+ set_IVA(codivadefault, paf1800f);
+
+ 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à 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(true, false));
+ }
+ paf1800f.set("PI_PRZTOTALE", rdoc->importo(true, false));
+ set_IVA(*rdoc, paf1800f);
+
+ /*
+ const TDate data = doc.get(DOC_DATADOC);
+ paf1800f.set("PI_DTINIZIOPER", data);
+ paf1800f.set("PI_DTFINEPER", data);
+ */
+
+ //
+
+ 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_KEYNLINAR", ++nlin_sconto);
+ if (perc > ZERO)
+ {
+ paf2000f.set("PJ_TIPOSCONTO", "SC");
+ paf2000f.set("PJ_PERCSCONTO", perc);
+ }
+ else
+ {
+ paf2000f.set("PJ_TIPOSCONTO", "MG");
+ paf2000f.set("PJ_PERCSCONTO", -perc);
+ }
+ paf2000f.set("PJ_GESTIONE", "D");
+ ok &= insert(paf2000f);
+ }
+ }
+ }
+ //
+
+
+ /*
+ * Ogni riga si può rifare a un DDT/Ordine diverso, per questo devo inserire i dati da qua e non in testata
+ */
+ TArray ancestors;
+ find_ancestors(*rdoc, ancestors);
+ for (int i = ancestors.last(); i > 0; i = ancestors.pred(i))
+ {
+ 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");
+ ok &= insert(paf1600f);
+ //
+ }
+ 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);
+ if (!privato)
+ {
+ paf1000f.set("P0_COMMCONVENZ", com);
+ paf1000f.set("P0_CODCUP", cup);
+ paf1000f.set("P0_CODCIG", cig);
+ }
+ paf1000f.set("P0_GESTIONE", "D");
+ ok &= insert(paf1000f);
+ //
+ }
+ }
+
+ }
+ 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à %d ha quantità 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);
+
+ // Controllo se è una ritenuta fiscale
+ //
+ if (sp.tipo_ritenuta() == 'F')
+ {
+ paf0700f.set("P7_TIPORITENUTA", cliente.fisica() ? "RT01" : "RT02");
+ paf0700f.set("P7_IMPORTORIT", doc.imponibile() * sp.perc() / CENTO);
+ paf0700f.set("P7_ALIQUOTARIT", TCodiceIVA(sp.cod_iva()).percentuale());
+ paf0700f.set("P7_CAUSPAGAM", cache().get("CA7", to_tstring(sp.caus_770()), "S2"));
+ }
+ //
+ }
+ 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");
+ ok &= insert(paf1800f);
+ }
+ //
+
+
+ //
+ /*
+ * Non valorizziamo nulla al momento in quanto su Campo i dati obbligatori non ci sono/non sono obbligatori
+ TString cod_vettore = doc.get("CODVETT1");
+ // É una fattura accompagnatoria!
+ if(cod_vettore.full())
+ {
+ }
+ */
+ //
+
+ // Salvo la testata
+ ok &= insert(paf0700f);
+
+ //
+ TPaf_record paf2200f("PAF2200F");
+ paf2200f.set("PL_KEYHEADERFATT", hfatt);
+ paf2200f.set("PL_KEYBODYFATT", bfatt);
+ remove(paf2200f); // Cancella tutte le righe di riepilogo IVA
+
+ const char* eiva = "I"; // Esigibilità 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_ALIQUOTAIVA", aliquota);
+ if (aliquota.is_zero())
+ paf2200f.set("PL_NATURA", natura(riva.cod_iva().codice()));
+
+ 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");
+ ok &= insert(paf2200f);
+ }
+ //
+
+ //
+ TPaf_record paf2400f("PAF2400F");
+ paf2400f.set("PN_KEYHEADERFATT", hfatt);
+ paf2400f.set("PN_KEYBODYFATT", bfatt);
+ remove(paf2400f); // Cancella i dati pagamento
+
+ TPagamento& pag = doc.pagamento();
+ doc.scadenze_recalc(); // Ricalcola array delle rate
+ TString_array& scad = doc.scadenze();
+ const int nrate = scad.items(); // Conta rate generate
+ const char* rateazione = pag.cond_pag_sdi(); // A rate (TP01) o una soluzione(TP02)?
+ paf2400f.set("PN_RIGA", ZERO); // Al momento non gestiamo più tipologie di pagamento per documento
+ paf2400f.set("PN_CONDPAGAMENTO", rateazione);
+ paf2400f.set("PN_GESTIONE", "D");
+ ok &= insert(paf2400f);
+
+ TPaf_record paf2500f("PAF2500F");
+ paf2500f.set("PO_KEYHEADERFATT", hfatt);
+ paf2500f.set("PO_KEYBODYFATT", bfatt);
+ remove(paf2500f); // Cancella tutte le rate
+
+ // Imposto i campi uguali per tutte le rate
+ paf2500f.set("PO_CONDPAGAMENTO", rateazione); // Condizione di pagamento PA
+ paf2500f.set("PO_CODICEPAGAM", pag.code()); // Condizione di pagamento CAMPO
+
+ 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 è presente il codice IBAN per il pagamento"));
+
+ for (int nr = 0; nr < nrate; nr++)
+ {
+ paf2500f.set("PO_RIGA", long(nr + 1)); // Numero rata
+ int rp = nr < pag.n_rate() ? nr : 0;
+ static TString key_class; key_class.cut(0) << pag.tipo_rata(rp) << pag.ulc_rata(rp);
+#ifdef DBG
+ bool tolla = true;
+ TString pop = cache().get("%CLR", key_class, "S12");
+ bool aaaa = true;
+#endif
+ paf2500f.set("PO_MODALITAPAGAM", cache().get("%CLR", key_class, "S12")); // Si assicura che il numero riga sia accettabile
+
+ 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");
+ ok &= insert(paf2500f);
+ }
+
+ if (_gestioneallegati)
+ {
+ TPaf_record paf2600f("PAF2600F");
+ paf2600f.set("PP_KEYHEADERFATT", hfatt);
+ paf2600f.set("PP_KEYBODYFATT", bfatt);
+ remove(paf2600f); // Cancella eventuali allegati
+ long nprogr = 0; // Numero di file allegati
+ // Se abilitato stampo il documento e lo allego
+ if (_allegafattura)
+ {
+ //ve1 - 2 FPA 2017 D 202 P D / uADMIN
+ TFilename rep;
+ int filter = dongle().active(RSAUT) ? 2 : 1;
+ while (filter > 0 && !doc.tipo().main_print_profile(rep, filter))
+ filter--;
+ if (filter > 0)
+ {
+ // Costruisco la chiamata
+ TString commandline = "ve1 -";
+ if (filter == 2)
+ commandline << 2; // Esiste il nuovo report :-)
+ else
+ commandline << 0; // Esiste il vecchio form :-(
+
+ commandline << ' ' << doc.get(DOC_CODNUM) << ' ' << doc.get(DOC_ANNO)
+ << ' ' << doc.get(DOC_PROVV) << ' ' << doc.get(DOC_NDOC) << " X P"; // X: stampa su disco, P: provvisorio
+ TExternal_app interattivo(commandline);
+ if (interattivo.run() != NOERR)
+ {
+ TString msgerr = "Fallita generazione PDF documento ";
+ msgerr << doc.get(DOC_CODNUM) << ' ' << doc.get(DOC_ANNO)
+ << ' ' << doc.get(DOC_PROVV) << ' ' << doc.get(DOC_NDOC);
+ error_box(msgerr);
+ }
+ else
+ {
+ TFilename pdf; pdf.tempdir();
+ pdf << SLASH << doc.get(DOC_ANNO) << '_' << doc.get(DOC_CODNUM) << '_' << doc.get(DOC_NDOC) << ".pdf";
+ if (!pdf.exist() && !yesno_box("Attenzione! Non è stato possibile creare il pdf, continuare?"))
+ {
+ return false;
+ }
+ if (!add_row_alleg(pdf, nprogr, paf2600f))
+ return false;
+ }
+ }
+ }
+
+ TToken_string allegati(doc.get("COLL_GOLEM"), '\n');
+ bool load_allegati = true;
+ if (allegati.full())
+ {
+ if (_def_fld.empty())
+ {
+ TString msgerr; msgerr << "Errore: il documento " << bfatt << " ha degli allegati ma nella configurazione non è stato impostato come trametterli\nCaricare il documento senza allegati?";
+ load_allegati = false;
+ if (!yesno_box(msgerr))
+ return false;
+ }
+ else
+ {
+
+ TFilename fname;
+ FOR_EACH_TOKEN(allegati, row)
+ {
+ const TToken_string entry(row);
+ if (entry.get(0, fname) && fname.exist())
+ {
+ if (!add_row_alleg(fname, nprogr, paf2600f))
+ return false;
+ }
+ }
+ }
+ }
+ }
+ //
+
+ // Tabella di non invio XML
+ TPaf_record pafw300f("PAFW300F");
+ pafw300f.set("PW_KEYHEADERFATT", hfatt);
+ pafw300f.set("PW_KEYBODYFATT", bfatt);
+ remove(pafw300f); // Cancella eventuali allegati
+ const TTipo_documento& td = cached_tipodoc(doc.get(DOC_TIPODOC));
+ const TString codsdi = !td.invio_xml() ? "**********" : (enapec ? pec : coddest);
+ pafw300f.set("PW_CODSDI", codsdi);
+ ok &= insert(pafw300f);
+
+ return _to_commit = (ok && save_paf());
+}
+
+bool TDoc_fp::doc_to_paf(const TRectype& rec)
+{
+ TDocumentoEsteso doc;
+ if (doc.read(rec) == NOERR)
+ {
+ return doc_to_paf(doc) ? db().sq_commit() : db().sq_rollback();
+ }
+ return false;
+}
+
+bool TDoc_fp::doc_to_paf(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 doc_to_paf(rec);
+}
+
+bool TDoc_fp::doc_to_paf(const TFilename& ini)
+{
+ TConfig cfg(ini, "33");
+ const int anno = cfg.get_int(DOC_ANNO);
+ const long ndoc = cfg.get_long(DOC_NDOC);
+ const TFixed_string codnum(cfg.get(DOC_CODNUM)); // lascio sapientemente per ultima la get di una stringa
+ const TDoc_key key(anno, codnum, ndoc);
+ return doc_to_paf(key);
+}
+
+TDoc_fp::TDoc_fp() : _log(nullptr), _cache_insert(false)
+{
+ _ditta.init(LF_NDITTE, prefix().get_codditta());
+ _cofi = ini_get_string(CONFIG_DITTA, "fp", "cofitras");
+
+ if (_cofi.blank())
+ _cofi = _ditta.codice_fiscale();
+
+ _gestioneallegati = ini_get_bool(CONFIG_DITTA, "fp", "gestioneallegati");
+ _allegafattura = ini_get_bool(CONFIG_DITTA, "fp", "allegafatt");
+
+ _def_fld = ini_get_string(CONFIG_DITTA, "fp", "flddest");
+ if (!_def_fld.ends_with("\\"))
+ {
+ _def_fld << "\\";
+ }
+
+ _def_usr_fld = ini_get_string(CONFIG_DITTA, "fp", "fldusrdest", "");
+ if (_def_usr_fld.empty())
+ {
+ _def_usr_fld = _def_fld;
+ }
+ else if (!_def_usr_fld.ends_with("\\"))
+ {
+ _def_usr_fld << "\\";
+ }
+}
+
+TDoc_fp::~TDoc_fp()
+{
+ commit();
+}
diff --git a/src/fp/fplib01.h b/src/fp/fplib01.h
index 15dc287c6..bb7912b94 100644
--- a/src/fp/fplib01.h
+++ b/src/fp/fplib01.h
@@ -5,9 +5,125 @@
#include
#include
+#include "../ve/velib05.h"
+#include "../fe/felib.h"
+#include
+#include
+
#define SQL_FLD "sql/"
+// Ritorna la connessione al DB paf secondo i parametri impostati nel programma di configurazione
SSimple_query& db();
+// Controlla il livello di patch installato e aggiorna le tabelle se necessario
bool check_tables();
+// Genera la chiave per i paf
+bool chiave_paf(const TDocumento& doc, TString& hfatt, TString& bfatt);
+bool chiave_paf(const TRectype& doc, TString& hfatt, TString& bfatt);
+
+
+// Contenitore di campi di un record di database MSSQLServer
+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;
+ const TVariant& get(const char* fld) 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 TString sq_get(const char* fld) const;
+
+ TString& insert_string();
+ bool insert();
+ TString& remove_string();
+ 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);
+};
+
+// Gestione PAF
+class TDoc_fp
+{
+private:
+ TAnagrafica _ditta;
+ TString16 _cofi;
+ TFilename _dbname;
+ TLog_report* _log;
+ TString _logpaf;
+ bool _gestioneallegati;
+ bool _allegafattura;
+ TString _def_fld;
+ TString _def_usr_fld;
+ bool _to_commit;
+ bool _cache_insert;
+ vector _query;
+
+ 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;
+ bool insert(TPaf_record& p);
+ bool remove(TPaf_record& p);
+ bool save_paf();
+
+protected:
+ bool parse_sconto(const TString& formula, TToken_string& sconti) const;
+static bool get_bnp_iban(const TString& abi, const TString& cab, int prg, TString& iban);
+ 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);
+ const char* natura(const TString& codiva) const;
+ static void set_IVA(const TString& codiva, TPaf_record& paf);
+ static void set_IVA(const TRiga_documento& rdoc, TPaf_record& paf);
+ bool add_row_art(const TString codice_tipo, const TString& codice_valore, TPaf_record& paf);
+ bool add_row_alleg(TFilename& file, long& nprogr, TPaf_record& paf);
+
+public:
+ bool doc_to_paf(TDocumentoEsteso& doc);
+ bool doc_to_paf(const TRectype& rec);
+ bool doc_to_paf(const TDoc_key& key);
+ bool doc_to_paf(const TFilename& ini);
+ // Mostra il log a fine esecuzione
+ bool show_log();
+ const int commit();
+ void set_cache_insert(const bool v) { _cache_insert = v; }
+
+ TDoc_fp();
+ ~TDoc_fp();
+};
+
+
#endif // __FPLIB01_H