diff --git a/build/fp.sln b/build/fp.sln
index 0db597406..8a1c85d07 100644
--- a/build/fp.sln
+++ b/build/fp.sln
@@ -15,6 +15,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AgaLib", "AgaLib.vcxproj",
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tflib", "tflib.vcxproj", "{7BF6939E-DFCD-49ED-B0A8-EDB68DDCE6D5}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fp1", "fp1.vcxproj", "{A539BCC1-D08F-4D78-A8EA-65560F4A60CD}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C575788B-0BE4-4F68-B9C9-3C204EC04E07} = {C575788B-0BE4-4F68-B9C9-3C204EC04E07}
+ {7BF6939E-DFCD-49ED-B0A8-EDB68DDCE6D5} = {7BF6939E-DFCD-49ED-B0A8-EDB68DDCE6D5}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -37,6 +43,10 @@ Global
{7BF6939E-DFCD-49ED-B0A8-EDB68DDCE6D5}.Debug|Win32.Build.0 = Debug|Win32
{7BF6939E-DFCD-49ED-B0A8-EDB68DDCE6D5}.Release|Win32.ActiveCfg = Release|Win32
{7BF6939E-DFCD-49ED-B0A8-EDB68DDCE6D5}.Release|Win32.Build.0 = Release|Win32
+ {A539BCC1-D08F-4D78-A8EA-65560F4A60CD}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A539BCC1-D08F-4D78-A8EA-65560F4A60CD}.Debug|Win32.Build.0 = Debug|Win32
+ {A539BCC1-D08F-4D78-A8EA-65560F4A60CD}.Release|Win32.ActiveCfg = Release|Win32
+ {A539BCC1-D08F-4D78-A8EA-65560F4A60CD}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/build/fp0.vcxproj b/build/fp0.vcxproj
index 7c40b413f..b5d69d573 100644
--- a/build/fp0.vcxproj
+++ b/build/fp0.vcxproj
@@ -195,7 +195,8 @@
- true
+ false
+ true
@@ -205,7 +206,7 @@
- true
+ false
diff --git a/build/fp1.vcxproj b/build/fp1.vcxproj
new file mode 100644
index 000000000..6660b7522
--- /dev/null
+++ b/build/fp1.vcxproj
@@ -0,0 +1,209 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {A539BCC1-D08F-4D78-A8EA-65560F4A60CD}
+ fp
+ 10.0.17763.0
+
+
+
+ Application
+ false
+ v141
+
+
+ Application
+ false
+ v141
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.30319.1
+ ..\exe\
+ ..\obj\$(SolutionName)\$(ProjectName)\
+ true
+ ..\exe\
+ ..\obj\$(SolutionName)\$(ProjectName)\
+ false
+ false
+ false
+ false
+ false
+
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ true
+ true
+ Win32
+ .\..\debug/tf0.tlb
+
+
+
+
+ Disabled
+ ..\src\xvtdb\;..\src\cg;..\src\include;..\src\xvaga;%(AdditionalIncludeDirectories)
+ _DEBUG;WIN32;__LONGDOUBLE__;_WINDOWS;%(PreprocessorDefinitions)
+ false
+ MultiThreadedDebug
+ true
+ Level3
+ true
+ ProgramDatabase
+
+
+
+
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ 0x0410
+ ..\wx28X\include;%(AdditionalIncludeDirectories)
+
+
+ %(AdditionalDependencies)
+ true
+ %(IgnoreSpecificDefaultLibraries)
+ true
+ Windows
+ false
+
+
+ MachineX86
+
+
+ true
+ .\..\debug/tf0.bsc
+
+
+
+
+
+
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ true
+ true
+ Win32
+ .\..\release/tf0.tlb
+
+
+
+
+ MaxSpeed
+ Default
+ ..\src\xvtdb\;..\src\cg;..\src\include;..\src\xvaga;%(AdditionalIncludeDirectories)
+ NDEBUG;WIN32;_WINDOWS;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+ true
+ .\..\release/tf0.pch
+ Level3
+ true
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ 0x0410
+ ..\wx28X\include;%(AdditionalIncludeDirectories)
+
+
+ $(OutDir)$(TargetName)$(TargetExt)
+ true
+ Windows
+
+
+ MachineX86
+ 12.0
+ false
+ %(AdditionalDependencies)
+
+
+ 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)"
+
+
+
+
+ Document
+ true
+
+
+ Document
+ true
+
+
+ Document
+ true
+
+
+ Document
+ true
+
+
+
+
+ ..\libraries\wx28X\include;%(AdditionalIncludeDirectories)
+ ..\libraries\wx28X\include;%(AdditionalIncludeDirectories)
+
+
+
+
+ {2d38a763-3d74-4338-9362-b891784ec90e}
+
+
+ {a1ce9743-a597-4f92-b55a-345a366c9e55}
+
+
+ {0042619a-6b7c-4d3d-9cd9-9bdd8d200c15}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Document
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build/fp1.vcxproj.filters b/build/fp1.vcxproj.filters
new file mode 100644
index 000000000..16854163a
--- /dev/null
+++ b/build/fp1.vcxproj.filters
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+ {8b9b8072-7920-4b49-896b-f632e5ac1415}
+
+
+ {aa4d5fac-6242-4e34-8b78-263ec3e4d15f}
+
+
+ {d7227be8-6583-4473-895f-595f8a48a8cb}
+
+
+ {06bc8aeb-f506-4c2e-85fb-bdeb92f2c77e}
+
+
+
+
+ Sources
+
+
+ Sources
+
+
+ Sources
+
+
+ Sources
+
+
+ Sources
+
+
+
+
+ Headers
+
+
+ Headers
+
+
+
+
+ Masks
+
+
+
+
+ Libraries
+
+
+
\ No newline at end of file
diff --git a/build/fplib.vcxproj b/build/fplib.vcxproj
index ab9f3a374..ecd9fda37 100644
--- a/build/fplib.vcxproj
+++ b/build/fplib.vcxproj
@@ -173,7 +173,9 @@
-
+
+ true
+
diff --git a/cd/test/fp0728.txt b/cd/test/fp0728.txt
new file mode 100644
index 000000000..6d95708db
--- /dev/null
+++ b/cd/test/fp0728.txt
@@ -0,0 +1,7 @@
+fpmenu.men
+fp0.exe
+fp1.exe
+fp1100a.msk
+
+- Aggiunto programma stampa elenco bolli in fattura
+- Data una ripulita al menu fp
diff --git a/cd/test/fp0728a.ini b/cd/test/fp0728a.ini
new file mode 100644
index 000000000..3c4b1cdf9
--- /dev/null
+++ b/cd/test/fp0728a.ini
@@ -0,0 +1,22 @@
+[Main]
+Demo=0
+
+[fp1]
+File(0) = fp0.exe|X
+File(6) = fp1.exe|X
+File(7) = fp1100a.msk|X
+File(8) = fpmenu.men|X
+Patch = 728
+Versione = 21511200
+
+[fp]
+Data = 12-03-2019
+Descrizione = Fattura Elettronica
+Dischi = 1
+Moduli = cg,ve
+OEM =
+Patch = 728
+PostProcess =
+PreProcess =
+Versione = 21511200
+
diff --git a/cd/test/fp0728a1.zip b/cd/test/fp0728a1.zip
new file mode 100644
index 000000000..44b5c22e5
Binary files /dev/null and b/cd/test/fp0728a1.zip differ
diff --git a/cd/test/tf0728.txt b/cd/test/tf0728.txt
new file mode 100644
index 000000000..8ff49d746
--- /dev/null
+++ b/cd/test/tf0728.txt
@@ -0,0 +1,6 @@
+tf0.exe
+tf0100a.msk
+tf0400a.msk
+
+Sistemati filtri per esterometro
+Aggiunta visualizzazione fatture non inviate in trasferimento fatture
diff --git a/cd/test/tf0728a.ini b/cd/test/tf0728a.ini
new file mode 100644
index 000000000..429304b6f
--- /dev/null
+++ b/cd/test/tf0728a.ini
@@ -0,0 +1,21 @@
+[Main]
+Demo=0
+
+[tf1]
+File(0) = tf0.exe|X
+File(1) = tf0100a.msk|X
+File(4) = tf0400a.msk|X
+Patch = 0728
+Versione = 21511200
+
+[tf]
+Data = 11-03-2019
+Descrizione = Trasferimento fatture
+Dischi = 1
+Moduli = cg
+OEM =
+Patch = 728
+PostProcess =
+PreProcess =
+Versione = 21511200
+
diff --git a/cd/test/tf0728a1.zip b/cd/test/tf0728a1.zip
new file mode 100644
index 000000000..5c437b123
Binary files /dev/null and b/cd/test/tf0728a1.zip differ
diff --git a/cd/test/ve0728.txt b/cd/test/ve0728.txt
new file mode 100644
index 000000000..3005f288d
--- /dev/null
+++ b/cd/test/ve0728.txt
@@ -0,0 +1,5 @@
+ve1.exe
+cg0.exe
+cgmenu.men
+
+Aggiunta riga valenza fiscale nella stampa del documento
\ No newline at end of file
diff --git a/cd/test/ve0728a.ini b/cd/test/ve0728a.ini
new file mode 100644
index 000000000..3317381f2
--- /dev/null
+++ b/cd/test/ve0728a.ini
@@ -0,0 +1,139 @@
+[Main]
+Demo=0
+
+[ve1]
+File(19) = ve1.exe|X
+Patch = 728
+Versione = 21511200
+
+[ve99]
+Kill(0) = batbimb.msk|x
+Kill(1) = batbacr.msk|x
+Kill(2) = batbums.msk|x
+Kill(3) = batbeld.msk|x
+Kill(4) = bastnum.msk|x
+Kill(5) = basttri.msk|x
+Kill(6) = batbfrm.msk|x
+Kill(7) = batbcra.msk|x
+Kill(8) = bastfrd.rep|x
+Kill(9) = bastcra.rep|x
+Kill(10) = ve7600a.msk|x
+Kill(11) = ve7300a.msk|x
+Kill(12) = bastfca.rep|x
+Kill(13) = batbspt.msk|x
+Kill(14) = basttip.rep|x
+Kill(15) = ve7700a.msk|x
+Kill(16) = bastimb.msk|x
+Kill(17) = baststd.msk|x
+Kill(18) = bastfrr.msk|x
+Kill(19) = ve7500a.msk|x
+Kill(20) = efstbnp.rep|x
+Kill(21) = batbtri.msk|x
+Kill(22) = batbrfa.msk|x
+Kill(23) = batbasf.msk|x
+Kill(24) = basteld.rep|x
+Kill(25) = bastasf.rep|x
+Kill(26) = batbmre.msk|x
+Kill(27) = ve7200a.msk|x
+Kill(28) = batbfrr.msk|x
+Kill(29) = bastrfc.rep|x
+Kill(30) = batbprv.msk|x
+Kill(31) = bastums.rep|x
+Kill(32) = bastcaa.msk|x
+Kill(33) = batbgca.msk|x
+Kill(34) = bastfca.msk|x
+Kill(35) = ve7.exe|x
+Kill(36) = ve7400conf.ini|x
+Kill(37) = bastctr.msk|x
+Kill(38) = bastrfa.rep|x
+Kill(39) = bastfrr.rep|x
+Kill(40) = batbfrd.msk|x
+Kill(41) = ve7200a.frm|x
+Kill(42) = bastfrm.rep|x
+Kill(43) = batbpro.msk|x
+Kill(44) = bastcau.msk|x
+Kill(45) = bastums.msk|x
+Kill(46) = basteld.msk|x
+Kill(47) = batbubi.msk|x
+Kill(48) = bastubi.rep|x
+Kill(49) = ve7400a.ini|x
+Kill(50) = batbtip.msk|x
+Kill(51) = basttri.rep|x
+Kill(52) = bastimb.rep|x
+Kill(53) = basttag.msk|x
+Kill(54) = bastasf.msk|x
+Kill(55) = bastrfa.msk|x
+Kill(56) = batbfid.msk|x
+Kill(57) = ve7100a.msk|x
+Kill(58) = batbspp.msk|x
+Kill(59) = bastrfc.msk|x
+Kill(60) = batbctr.msk|x
+Kill(61) = bastabe.rep|x
+Kill(62) = ve7300a.frm|x
+Kill(63) = batbcaa.msk|x
+Kill(64) = batbgcg.msk|x
+Kill(65) = bastprs.msk|x
+Kill(66) = bastubi.msk|x
+Kill(67) = bastgmc.msk|x
+Kill(68) = batbfsa.msk|x
+Kill(69) = batbstd.msk|x
+Kill(70) = bastnum.rep|x
+Kill(71) = bastgcg.msk|x
+Kill(72) = batbtag.msk|x
+Kill(73) = batbrfc.msk|x
+Kill(74) = batbnum.msk|x
+Kill(75) = ve7701a.ini|x
+Kill(76) = eftbbnp.msk|x
+Kill(77) = bastabe.msk|x
+Kill(78) = bastgca.rep|x
+Kill(79) = batbbnp.msk|x
+Kill(80) = basttag.rep|x
+Kill(81) = bastspp.msk|x
+Kill(82) = bastctr.rep|x
+Kill(83) = batbcau.msk|x
+Kill(84) = batbprs.msk|x
+Kill(85) = bastcaa.rep|x
+Kill(86) = bastcau.rep|x
+Kill(87) = bastgca.msk|x
+Kill(88) = ve7400a.msk|x
+Kill(89) = baststd.rep|x
+Kill(90) = batbabe.msk|x
+Kill(91) = efstbnp.msk|x
+Kill(92) = bastcra.msk|x
+Kill(93) = batbgmc.msk|x
+Kill(94) = bastfrd.msk|x
+Kill(95) = bastbnp.rep|x
+Kill(96) = basttip.msk|x
+Kill(97) = bastprs.rep|x
+Kill(98) = bastspp.rep|x
+Kill(99) = batbcld.msk|x
+Kill(100) = bastfrm.msk|x
+Kill(101) = batbgsa.msk|x
+Kill(102) = bastgmc.rep|x
+Kill(103) = bastbnp.msk|x
+Kill(104) = bastgcg.rep|x
+Kill(105) = batbfca.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(173) = cgmenu.men|X
+Patch = 716
+Versione = 21511200
+
+[ve]
+Data = 12-03-2019
+Descrizione = Vendite
+Dischi = 1
+Moduli = ba,cg9,pr9,mg9,sv9,in9,ef9
+OEM =
+Patch = 728
+PostProcess = bainst -0 VE
+PreProcess =
+Prezzo(1) =
+Prezzo(2) =
+Versione = 21511200
+
diff --git a/cd/test/ve0728a1.zip b/cd/test/ve0728a1.zip
new file mode 100644
index 000000000..92f993234
Binary files /dev/null and b/cd/test/ve0728a1.zip differ
diff --git a/src/ba/bastiva.rep b/src/ba/bastiva.rep
index 5e42d6527..8cc94a184 100755
--- a/src/ba/bastiva.rep
+++ b/src/ba/bastiva.rep
@@ -1,82 +1,90 @@
-
-
+
+
-
-
+
+
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
-
-
-
-
+
+
+
+
CODTAB
-
+
S0
-
+
R0
-
+
+
+ S12
+
+
S1
@@ -86,7 +94,8 @@
-
+
+
S6
@@ -97,22 +106,10 @@
-
+
I0
-
- S2
-
-
- S9
-
-
- S10
-
-
- S11
-
-
+
S3
@@ -121,16 +118,16 @@
-
+
S4
-
+
-
+
S5
@@ -141,28 +138,40 @@
-
+
B3
-
+
B4
-
+
B2
-
+
+ S2
+
+
+ S9
+
+
+ S10
+
+
+ S11
+
+
-
-
-
+
+
+
#SYSTEM.DATE
-
+
#PAGE
-
+
-
+
USE %IVA
FROM CODTAB=#FROM
TO CODTAB=#TO
diff --git a/src/fp/fp0.cpp b/src/fp/fp0.cpp
index 215e7eba1..0c89b13a1 100644
--- a/src/fp/fp0.cpp
+++ b/src/fp/fp0.cpp
@@ -11,7 +11,7 @@ int main(int argc, char** argv)
case 1: rt = fp0200(argc, argv); break; // Inserimento massivo PEC e Cod Sdi clifo
case 2: rt = fp0300(argc, argv); break; // Gestione fatture attive (PAA, Ex Fattura PA)
case 3: rt = fp0400(argc, argv); break; // Monitor fatture passive
- //case 4: rt = fp0500(argc, argv); break; // Elenco mancate consegna
+ case 4: rt = fp0500(argc, argv); break; // Elenco mancate consegna
default: rt = fp0100(argc, argv); break; // Configurazione
}
return rt;
diff --git a/src/fp/fp0.h b/src/fp/fp0.h
index c08010ca7..e2d05fe11 100644
--- a/src/fp/fp0.h
+++ b/src/fp/fp0.h
@@ -1,10 +1,10 @@
-#ifndef __TF0_H
-#define __TF0_H
+#ifndef __FP0_H
+#define __FP0_H
int fp0100(int argc, char* argv[]);
int fp0200(int argc, char* argv[]);
int fp0300(int argc, char* argv[]);
int fp0400(int argc, char* argv[]);
-//int fp0500(int argc, char* argv[]);
+int fp0500(int argc, char* argv[]);
#endif
diff --git a/src/fp/fp0500.cpp b/src/fp/fp0500.cpp
index 744337660..1ac1f9d2c 100644
--- a/src/fp/fp0500.cpp
+++ b/src/fp/fp0500.cpp
@@ -190,13 +190,14 @@ void TMancati_mask::fill()
if(!check_doc_filter(doc))
continue;
- if (!chiave_paf(doc, hfatt, bfatt) || !paf0100f.search(nullptr, hfatt, bfatt) || paf0100f.sq_get("P1_GESTIONE") != "N" && paf0100f.sq_get("P1_ERREST") != "M")
+ if (!chiave_paf(doc, hfatt, bfatt) || !paf0100f.search(nullptr, hfatt, bfatt) || paf0100f.sq_get("P1_GESTIONE") != "N")
{
continue;
}
- if (filter_selected == "" && paf0100f.sq_get("P1_ERRINT") != MANCATA_SEND
+ if (paf0100f.sq_get("P1_ERREST") == "M" && (
+ filter_selected.empty() && paf0100f.sq_get("P1_ERRINT") != MANCATA_SEND
|| filter_selected == "S" && paf0100f.sq_get("P1_ERRINT") == MANCATA_SEND
- || filter_selected == "A")
+ || filter_selected == "A") )
{
TToken_string& row = docs.row(-1);
diff --git a/src/fp/fp1.cpp b/src/fp/fp1.cpp
new file mode 100644
index 000000000..8a8248282
--- /dev/null
+++ b/src/fp/fp1.cpp
@@ -0,0 +1,16 @@
+#include
+#include "fp1.h"
+
+int main(int argc, char** argv)
+{
+ int rt = -1;
+ const int r = (argc > 1) ? atoi( &argv[1][1] ) : 1;
+
+ // Stampe fatturazione elettronica
+ switch (r)
+ {
+ default: rt = fp1100(argc, argv); break; // Stampa bolli fatture
+ }
+ return rt;
+}
+
diff --git a/src/fp/fp1.h b/src/fp/fp1.h
new file mode 100644
index 000000000..082a309e1
--- /dev/null
+++ b/src/fp/fp1.h
@@ -0,0 +1,6 @@
+#ifndef __FP1_H
+#define __FP1_H
+
+int fp1100(int argc, char* argv[]);
+
+#endif
diff --git a/src/fp/fp1100.cpp b/src/fp/fp1100.cpp
new file mode 100644
index 000000000..6d4648239
--- /dev/null
+++ b/src/fp/fp1100.cpp
@@ -0,0 +1,178 @@
+#include
+#include
+#include
+#include
+#include // ID Bottoni
+
+#include "fp1.h"
+#include "fp1100a.h"
+#include
+#include "recset.h"
+#include "progind.h"
+#include "../ve/velib.h"
+#include "fplib.h"
+
+class TBolliinfatt_mask : public TAutomask
+{
+protected:
+ bool on_field_event(TOperable_field& o, TField_event e, long jolly) override;
+ void fill();
+public:
+ TBolliinfatt_mask() : TAutomask("fp1100a"){};
+};
+
+bool TBolliinfatt_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
+{
+ switch (o.dlg())
+ {
+ case DLG_EXPORT:
+ if (e == fe_button)
+ {
+ TSheet_field& sf = sfield(F_DOCS);
+ if(sf.items() > 0)
+ {
+ sf.esporta();
+ }
+ else
+ {
+ warning_box("Impossibile esportare una tabella vuota!");
+ }
+ }
+ break;
+ case DLG_RECALC:
+ if (e == fe_button)
+ fill();
+ 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(2));
+ doc.put(DOC_TIPODOC, row.get(3));
+ doc.put(DOC_NDOC, row.get(5));
+ if (doc.edit())
+ fill();
+ }
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+void TBolliinfatt_mask::fill()
+{
+ TSheet_field& docs = sfield(F_DOCS);
+ TString_array& sht = docs.rows_array();
+ docs.hide();
+
+ sht.destroy();
+
+ TDate dal = get_date(F_DADATA);
+ TDate al = get_date(F_ADATA);
+
+ if(!dal.ok())
+ {
+ dal = TDate(01, 01, 2019);
+ set(F_DADATA, dal);
+ }
+
+ if(!al.ok())
+ {
+ al = TDate(TODAY);
+ set(F_ADATA, al);
+ }
+
+ // Record di controllo per eventuali elaborazioni precedenti
+ TString hfatt, bfatt;
+
+ TString query;
+
+ query << "USE 33 KEY 3 \n" <<
+ "SELECT 33.TIPOCF==\"C\"" <<
+ TISAM_recordset::add_between_filter(DOC_CODNUM, get(F_DACODNUM), get(F_ACODNUM)) <<
+ " \n" <<
+ "JOIN 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 \n" <<
+ "FROM DATADOC=#DADATADOC \n" <<
+ "TO DATADOC=#ADATADOC";
+
+ TISAM_recordset rec(query);
+
+ rec.set_var("#DADATADOC", dal);
+ rec.set_var("#ADATADOC", al);
+ rec.set_var("#DACODNUM", get(F_DACODNUM));
+ rec.set_var("#ACODNUM", get(F_ACODNUM));
+
+ TProgress_monitor pi(rec.items(), nullptr);
+
+ for (bool okc = rec.move_first(); okc; okc = rec.move_next())
+ {
+ if (!pi.add_status())
+ break;
+ const TRectype& doc = rec.cursor()->curr();
+ const TTipo_documento& td = cached_tipodoc(doc.get(DOC_TIPODOC));
+
+ bool sent = false;
+ if (chiave_paf(doc, hfatt, bfatt))
+ {
+ TString qry_paf7 = "SELECT PAF0700F.P7_IMPORTOBOLLO, PAF0100F.P1_GESTIONE FROM PAF0700F JOIN PAF0100F ON P7_KEYPRGINVIO = P1_KEYPRGINVIO AND P7_KEYHEADERFATT = P1_KEYHEADERFATT AND P7_KEYBODYFATT = P1_KEYBODYFATT WHERE P7_KEYHEADERFATT = '";
+ qry_paf7 << hfatt << "' AND P7_KEYBODYFATT = '" << bfatt << "' AND P7_IMPORTOBOLLO > 0";
+ if (!fp_db().sq_set_exec(qry_paf7) || (fp_db().sq_get("P1_GESTIONE") != "N" && (fp_settings().is_f8() ? fp_db().sq_get("P1_GESTIONE") != "X" : true)))
+ {
+ continue;
+ }
+ }
+
+ TToken_string& row = docs.row(-1);
+ row.add(rec.get(DOC_ANNO).as_int());
+ row.add(rec.get(DOC_CODNUM).as_string());
+ row.add(rec.get(DOC_TIPODOC).as_string());
+ if (!rec.get(DOC_TIPODOCSDI).is_empty())
+ row.add(rec.get(DOC_TIPODOCSDI).as_string());
+ else
+ row.add(td.tipo_doc_sdi());
+ row.add(rec.get(DOC_NDOC).as_int());
+ row.add(rec.get(DOC_DATADOC).as_date());
+ row.add(rec.get("33.TOTDOC").as_real());
+ row.add(rec.get("33.IMPOSTE").as_real());
+ row.add(rec.get(CFV_CODCF).as_int());
+ row.add(rec.get("20." CLI_RAGSOC).as_string());
+ row.add(fp_db().sq_get("P7_IMPORTOBOLLO"));
+ row.add(rec.get(DOC_ADDBOLLI).as_string());
+ }
+
+ if(docs.items() == 0)
+ {
+ warning_box("Non sono stati trovati documenti con i filtri scelti.");
+ }
+
+ docs.force_update();
+ docs.show();
+}
+
+class TBolliinfatt_app : public TSkeleton_application
+{
+public:
+ virtual void main_loop() override;
+};
+
+void TBolliinfatt_app::main_loop()
+{
+ TBolliinfatt_mask pm;
+ while (pm.run() == K_ENTER)
+ {
+ }
+}
+
+int fp1100(int argc, char* argv[])
+{
+ TBolliinfatt_app appc;
+ appc.run(argc, argv, TR("Bolli in fattura FP"));
+ return 0;
+}
\ No newline at end of file
diff --git a/src/fp/fp1100a.h b/src/fp/fp1100a.h
new file mode 100644
index 000000000..3995ded1b
--- /dev/null
+++ b/src/fp/fp1100a.h
@@ -0,0 +1,20 @@
+#define F_DADATA 201
+#define F_ADATA 202
+#define F_DACODNUM 203
+#define F_DATIPODOC 204
+#define F_ACODNUM 205
+#define F_ATIPODOC 206
+#define F_DOCS 207
+
+#define S_ANNO 101
+#define S_CODNUM 102
+#define S_TIPODOC 103
+#define S_CODSDI 104
+#define S_NDOC 105
+#define S_DATADOC 106
+#define S_TOTDOC 107
+#define S_IMPOSTADOC 108
+#define S_CLIENTE 109
+#define S_RAGSOC 110
+#define S_BOLLO 111
+#define S_ADDEBITO 112
\ No newline at end of file
diff --git a/src/fp/fp1100a.uml b/src/fp/fp1100a.uml
new file mode 100644
index 000000000..3d717ff2d
--- /dev/null
+++ b/src/fp/fp1100a.uml
@@ -0,0 +1,172 @@
+#include "fp1100a.h"
+
+TOOLBAR "topbar" 0 0 0 2
+
+BUTTON DLG_RECALC 2 2
+BEGIN
+ PROMPT 1 1 "~Carica"
+ PICTURE TOOL_CONVERT
+END
+
+BUTTON DLG_EXPORT 2 2
+BEGIN
+ PROMPT 1 1 "~Excel"
+ PICTURE TOOL_EXCEL
+END
+
+#include
+
+ENDPAGE
+
+PAGE "Filtri" 0 2 0 0
+
+DATE F_DADATA
+BEGIN
+ PROMPT 1 1 "Data iniziale"
+ CHECKTYPE REQUIRED
+END
+
+DATE F_ADATA
+BEGIN
+ PROMPT 50 1 "Data finale "
+ VALIDATE DATE_CMP_FUNC >= F_DADATA
+ WARNING "La data finale non può essere minore della data iniziale"
+ CHECKTYPE REQUIRED
+END
+
+STRING F_DACODNUM 4
+BEGIN
+ PROMPT 1 2 "Da numerazione "
+ HELP "Da codice numerazione"
+ USE %NUM
+ INPUT CODTAB F_DACODNUM
+ DISPLAY "Codice" CODTAB
+ DISPLAY "Descrizione@50" S0
+ OUTPUT F_DACODNUM CODTAB
+ FLAG "UPA"
+ CHECKTYPE FORCED
+ WARNING "Numerazione assente"
+ KEY 1 2
+END
+
+STRING F_ACODNUM 4
+BEGIN
+ PROMPT 50 2 "A numerazione "
+ HELP "Da codice numerazione"
+ USE %NUM
+ INPUT CODTAB F_ACODNUM
+ DISPLAY "Codice" CODTAB
+ DISPLAY "Descrizione@50" S0
+ OUTPUT F_ACODNUM CODTAB
+ FLAG "UPA"
+ CHECKTYPE FORCED
+ WARNING "Numerazione assente"
+ KEY 1 2
+END
+
+SPREADSHEET F_DOCS
+BEGIN
+ PROMPT 0 5 ""
+ ITEM "Anno"
+ ITEM "Cod.\nNum.@4"
+ ITEM "Tipo\nDoc@4"
+ ITEM "Tipo SDI@4"
+ ITEM "Num.\nDoc.@7"
+ ITEM "Data\nDoc.@10"
+ ITEM "Totale\nDoc.@10"
+ ITEM "Imposta\nDoc.@10"
+ ITEM "Cliente"
+ ITEM "Ragione Sociale@50"
+ ITEM "Bollo"
+ ITEM "Addebito"
+END
+
+ENDPAGE
+ENDMASK
+
+PAGE "Documento" -1 -1 80 6
+
+NUMBER S_ANNO 4
+BEGIN
+ PROMPT 1 1 "Anno "
+END
+
+STRING S_CODNUM 4
+BEGIN
+ PROMPT 25 1 "Numerazione "
+END
+
+STRING S_TIPODOC 4
+BEGIN
+ PROMPT 46 1 "Tipo Documento "
+END
+
+STRING S_CODSDI 4
+BEGIN
+ PROMPT 1 2 "Tipo Doc SDI"
+END
+
+NUMBER S_NDOC 7
+BEGIN
+ PROMPT 25 2 "Numero "
+END
+
+DATE S_DATADOC
+BEGIN
+ PROMPT 46 2 "Data "
+END
+
+NUMBER S_TOTDOC 15 2
+BEGIN
+ PROMPT 1 3 "Totale Doc. "
+END
+
+NUMBER S_IMPOSTADOC 15 2
+BEGIN
+ PROMPT 46 3 "Imposta "
+END
+
+NUMBER S_CLIENTE 6
+BEGIN
+ PROMPT 1 4 "Cliente "
+END
+
+STRING S_RAGSOC 50
+BEGIN
+ PROMPT 25 4 ""
+END
+
+NUMBER S_BOLLO 4 2
+BEGIN
+ PROMPT 1 5 "Importo bollo"
+END
+
+BOOLEAN S_ADDEBITO
+BEGIN
+ PROMPT 20 5 "Addebito cliente"
+END
+
+ENDPAGE
+
+TOOLBAR "Documento" 0 0 0 2
+
+BUTTON DLG_OK 2 2
+BEGIN
+ PROMPT 1 1 ""
+END
+
+BUTTON DLG_USER 2 2
+BEGIN
+ PROMPT 1 1 "Collega"
+ PICTURE TOOL_LINK
+END
+
+
+BUTTON DLG_CANCEL 2 2
+BEGIN
+ PROMPT 1 1 ""
+END
+
+ENDPAGE
+
+ENDMASK
\ No newline at end of file
diff --git a/src/fp/fpmenu.men b/src/fp/fpmenu.men
index 0f4fc6faf..d1cce2a0f 100644
--- a/src/fp/fpmenu.men
+++ b/src/fp/fpmenu.men
@@ -3,8 +3,24 @@ Caption = "Trasferimento Fatture"
Picture =
Module = fp
Flags = ""
-Item_01 = "Configurazione", "fp0 -0", ""+
+Item_01 = "Manutenzione modulo", [FPMENU_003]
Item_02 = "Invio fatture", "fp0 -2", ""
-Item_03 = "Monitor Mancata Consegna", "fp0 -4", ""
-Item_04 = "Monitor Fatture Passive", "fp0 -3", ""
-Item_05 = "Inserimento riferimenti C/F", "fp0 -1", ""
\ No newline at end of file
+Item_03 = "Monitor Fatture Passive", "fp0 -3", ""
+Item_04 = "Stampe", [FPMENU_002]
+
+
+[FPMENU_002]
+Caption = "Stampe"
+Picture =
+Module = fp
+Flags = ""
+Item_01 = "Elenco Mancata Consegna", "fp0 -4", ""
+Item_02 = "Elenco bolli in fattura", "fp1 -0", ""
+
+[FPMENU_003]
+Caption = "Manutenzione"
+Picture =
+Module = fp
+Flags = ""
+Item_01 = "Configurazione", "fp0 -0", "", 10210
+Item_02 = "Inserimento riferimenti C/F", "fp0 -1", ""
\ No newline at end of file
diff --git a/src/include/odbcrset.cpp b/src/include/odbcrset.cpp
index 5c3f70548..0518bcf56 100755
--- a/src/include/odbcrset.cpp
+++ b/src/include/odbcrset.cpp
@@ -3,6 +3,7 @@
#include
#include
#include
+#include "tsdb.h"
///////////////////////////////////////////////////////////
// TODBC_connections
@@ -740,6 +741,8 @@ TRecordset* create_recordset(const TString& sql)
rex = new TCSV_recordset(sql); else
if (sql.starts_with("AS400", true))
rex = new TAS400_recordset(sql);
+ //if (sql.starts_with("CONNECT", true))
+ //rex = new TDB_recordset(sql);
else
rex = new TSQL_recordset(sql);
}
diff --git a/src/include/recset.cpp b/src/include/recset.cpp
index 16705e563..0ccc0d68a 100755
--- a/src/include/recset.cpp
+++ b/src/include/recset.cpp
@@ -1652,6 +1652,36 @@ const TString& TISAM_recordset::driver_version() const
return tmp;
}
+TString& TISAM_recordset::add_between_filter(const TString& field, const TString& from_val, const TString& to_val,
+ TString from_fld, TString to_fld)
+{
+ // Se from_fld e to_fld sono vuoti vengono valorizzati con il nome del campo preceduti da #DA e #A
+ if (from_fld.empty() || to_fld.empty())
+ {
+ const TString qf = field.find('.') < 0 ? field : field.sub(field.find('.') + 1);
+ if (from_fld.empty())
+ from_fld << "#DA" << qf;
+ if (to_fld.empty())
+ to_fld << "#A" << qf;
+ }
+
+ TString& ret = get_tmp_string();
+ if (from_val.full() && to_val.full())
+ {
+ ret << "&&(BETWEEN(" << field << ", " << from_fld << ", " << to_fld << "))";
+ }
+ else if (from_val.full())
+ {
+ ret << "&&(" << field << ">=" << from_fld << ")";
+ }
+ else if (to_val.full())
+ {
+ ret << "&&(" << field << "<=" << to_fld << ")";
+ }
+
+ return ret;
+}
+
TISAM_recordset::TISAM_recordset(const char* use)
: _relation(NULL), _cursor(NULL)
{
diff --git a/src/include/recset.h b/src/include/recset.h
index a8473e968..05ea83e69 100755
--- a/src/include/recset.h
+++ b/src/include/recset.h
@@ -167,6 +167,13 @@ public:
virtual const TString& driver_version() const;
virtual const TString& query_text() const { return _use; }
+ // Utility
+ /* Ritorna un filtro che può essere:
+ * from_val && to_val: field between
+ * solo from_from: field >= from_val
+ * solo to_from: field <= to_val */
+ static TString& add_between_filter(const TString& field, const TString& from_val, const TString& to_val, TString from_fld = "", TString to_fld = "");
+
TISAM_recordset(const char* use);
virtual ~TISAM_recordset();
};
@@ -181,5 +188,4 @@ const TString& logic2table(int logic_num);
int table2logic(const TString& name);
TRecordset* create_recordset(const TString& sql);
-
#endif
diff --git a/src/include/tsdb.cpp b/src/include/tsdb.cpp
index 129ee790b..895c21a7b 100644
--- a/src/include/tsdb.cpp
+++ b/src/include/tsdb.cpp
@@ -1,4 +1,5 @@
#include
+#include
/******************************************************************************
@@ -36,3 +37,222 @@ TString SSimple_query::sq_get(TString& field, bool rtrim)
{
return sq_get(static_cast(field), rtrim);
}
+
+TString SSimple_query::sq_get(unsigned int column, bool rtrim)
+{
+ return _rec.get(column);
+}
+
+unsigned SSimple_query::sq_get_num_fields() const
+{
+ return _rec.get_num_fields();
+}
+
+void TDB_recordset::reset()
+{
+ _items = 0;
+ _current_row = -1;
+ _columns_loaded = false;
+}
+
+/* La query può iniziare con la stringa di connessione così fatta:
+ * CONNECT(server, user, psw, driver = "MSSQL") il driver può essere omesso
+ * Se c'è la estraggo, setto la connessione e prendo la vera query
+ * Se no setto direttamente la query
+ */
+void TDB_recordset::set(const char* sql)
+{
+ TString real_query = "";
+
+ // Guardo se la query inizia con la stringa di connessione
+ if(TString(sql).starts_with("CONNECT(", true))
+ {
+ TString query(sql);
+ int pos_EOCon = query.find(')'); // End Of Conn
+ const TString conn_str = query.sub(0, ++pos_EOCon);
+ set_connection(conn_str);
+
+ real_query << query.sub(pos_EOCon);
+ }
+ else
+ real_query << sql;
+
+ if (!_freezed || _sql != sql)
+ reset();
+ _sql.cut(0) << real_query;
+ if (_sql.find("SELECT") >= 0 || _sql.find("select") >= 0)
+ find_and_reset_vars();
+ _rec->sq_set(_sql);
+}
+
+void TDB_recordset::set_connection(const char* conn_str) const
+{
+ TString pn(conn_str);
+ TString srv = "", usr = "", pwd = "", drv = "";
+
+ int first_pos = pn.find("(", 0);
+ int last_pos = pn.find(",", first_pos);
+ int i;
+
+ for (i = 0; last_pos != -1; last_pos = pn.find(",", first_pos + 1), i++) {
+ switch (i)
+ {
+ case 0:
+ srv = pn.sub(first_pos + 1, last_pos);
+ break;
+ case 1:
+ usr = pn.sub(first_pos + 1, last_pos);
+ break;
+ case 2:
+ pwd = pn.sub(first_pos + 1, last_pos);
+ break;
+ case 3:
+ drv = pn.sub(first_pos + 1, last_pos);
+ default:
+ break;
+ }
+ first_pos = last_pos;
+ }
+
+ // Guardo se ho valorizzato almeno i primi 3 elementi della connect
+ // Se non valorizzo l'ultimo metto come default MSSQL Server
+ if (i == 2)
+ connect(srv.ltrim(), usr.ltrim(), pwd.ltrim(), TSDB_MSSQL);
+ else if(i == 3)
+ connect(srv.ltrim(), usr.ltrim(), pwd.ltrim(), str_to_driver(drv.ltrim()));
+}
+
+int TDB_recordset::connect(const char * db, const char * user, const char * pass, const TT_driver tipo_db) const
+{
+ return _rec->sq_connect(db, user, pass, tipo_db);
+}
+
+TT_driver TDB_recordset::str_to_driver(const char* tipo_db)
+{
+ if (_stricmp(tipo_db, "") != 0)
+ return TSDB_undefined;
+ //! ODBC
+ if (_stricmp(tipo_db, "ODBC") == 0)
+ return TSDB_ODBC;
+ //! Oracle
+ if (_stricmp(tipo_db, "Oracle") == 0)
+ return TSDB_Oracle;
+ //! Microsoft SQL Server
+ if (_stricmp(tipo_db, "MSSQL") == 0)
+ return TSDB_MSSQL;
+ //! InterBase or Firebird
+ if (_stricmp(tipo_db, "InterBase") == 0)
+ return TSDB_InterBase;
+ //! SQLBase
+ if (_stricmp(tipo_db, "SQLBase") == 0)
+ return TSDB_SQLBase;
+ //! IBM DB2
+ if (_stricmp(tipo_db, "DB2") == 0)
+ return TSDB_DB2;
+ //! Informix
+ if (_stricmp(tipo_db, "Informix") == 0)
+ return TSDB_Informix;
+ //! Sybase ASE
+ if (_stricmp(tipo_db, "Sybase") == 0)
+ return TSDB_Sybase;
+ //! MySQL
+ if (_stricmp(tipo_db, "MySQL") == 0)
+ return TSDB_MySQL;
+ //! PostgreSQL
+ if (_stricmp(tipo_db, "PostgreSQL") == 0)
+ return TSDB_PostgreSQL;
+ //! SQLite
+ if (_stricmp(tipo_db, "SQLite") == 0)
+ return TSDB_SQLite;
+ //! SQL Anywere
+ if (_stricmp(tipo_db, "SQLAnywhere") == 0)
+ return TSDB_SQLAnywhere;
+ return TSDB_undefined;
+}
+
+int TDB_recordset::connect(const char* db, const char* user, const char* pass, const char* tipo_db) const
+{
+ return _rec->sq_connect(db, user, pass, str_to_driver(tipo_db));
+}
+
+TRecnotype TDB_recordset::items() const
+{
+ if(!_rec->sq_is_loaded() && _items == 0)
+ _rec->sq_exec();
+ auto& i = const_cast(_items);
+ i = _rec->sq_items();
+ return i;
+
+}
+
+bool TDB_recordset::move_to(TRecnotype pos)
+{
+ const TRecnotype tot = items();
+ _current_row = pos;
+
+ if (_freezed && _loaded)
+ {
+ if (pos < 0)
+ _current_row = 0;
+ if (pos > tot)
+ _current_row = tot;
+ return true;
+ }
+
+ return _rec->sq_go(pos);
+}
+
+const TArray* TDB_recordset::row(TRecnotype n)
+{
+ static TRecnotype last_n = -1;
+
+ if(n >= 0 && n < _rec->sq_items())
+ {
+ if (n == last_n && !_row.empty()) // Richiedo sempre la stessa riga
+ return &_row;
+ if (move_to(n))
+ {
+ const unsigned ncol = _rec->sq_get_num_fields();
+ last_n = n;
+
+ for (unsigned i = 0; i < ncol; i++)
+ _row.add(_rec->sq_get(i, false));
+ return &_row;
+ }
+ }
+
+ _row.destroy();
+ return &_row;
+}
+
+void TDB_recordset::requery()
+{
+ _items = 0;
+}
+
+unsigned TDB_recordset::columns() const
+{
+ return _rec->sq_get_num_fields();
+}
+
+const TVariant& TDB_recordset::get(unsigned int column) const
+{
+ static TVariant field = NULL_VARIANT;
+ static unsigned int last_get = 0;
+ if(column != last_get || field == NULL_VARIANT)
+ {
+ last_get = column;
+ field = _rec->sq_get(column);
+ return field;
+ }
+ return field;
+}
+
+TDB_recordset::TDB_recordset(const char* sql, const bool freezed) : _freezed(freezed), _loaded(false)
+{
+ set(sql);
+ _current_row = -1;
+ _rec = new SSimple_query();
+ _items = 0;
+ set(sql);
+}
diff --git a/src/include/tsdb.h b/src/include/tsdb.h
index 88fd226c6..ecbe4e667 100644
--- a/src/include/tsdb.h
+++ b/src/include/tsdb.h
@@ -20,7 +20,7 @@
* Descrizione: *
* La seguente libreria ha due scopi: *
* - Implementare una serie di funzioni che emulino interamente il funzionamento attuale di campo in Visual FoxPro su MSQL *
- * - Creare delle nuove API per gestire il database in MSQL con cui verranno riscritti i programmi *
+ * - Creare delle nuove API per gestire il database in MSSQL con cui verranno riscritti i programmi *
* Librerie esterne utilizzate: *
* - SQLAPI++ (Permette la gestione dei più famosi DB attualmente esistenti) *
********************************************************************************************************************************/
@@ -28,8 +28,8 @@
#ifndef __TSDB_H
#define __TSDB_H
-#ifndef __XVTDB_H
-#include
+#ifndef __XVTDB_H
+#include
#endif
@@ -51,6 +51,7 @@
#endif // !__REAL_H
#define CHIAVE_ID_ "_ID_"
+#include "recset.h"
/********************************************************************************
* SSimpleQuery (Sirio Simple Query) *
@@ -71,13 +72,6 @@ protected:
//SSimpleQuery(P_CONN_VOID &c, const char * query = "", bool ex = false);
public:
- /**< Costruttore, non inizializza nulla, da caricare successivamente */
- SSimple_query() = default;
- /**< Costruttore, Accetta in ingresso dei parametri per la connessione, volendo è anche possibile impostare una query ed eseguirla. Attenzione! Non risponde se la query ha avuto un esito positivo o negativo! */
- SSimple_query(const char* db, const char* user, const char* pass, const TT_driver tipo_db, const char * query = "", const bool ex = false, const bool freezed = false) : _rec(db, user, pass, tipo_db, query, ex, freezed) {}
- //SSimpleQuery(const TString& db, const TString& user, const TString& pass, TT_driver tipoDb, const char * query = "", const bool ex = false, const bool freezed = false) : _rec(db, user, pass, tipoDb, query, ex, freezed) {}
- /**< Distruttore */
- virtual ~SSimple_query() = default;
// Connection functions
/**< Eseguo la connessione */
@@ -91,7 +85,7 @@ public:
/**< Imposto il tipo di client che utilizzo */
void sq_set_client(int client) { _rec.set_client(static_cast(client)); }
void sq_set_client(const TT_driver client) { _rec.set_client(client); }
- // Imposto una opzione generica dellla connessione
+ // Imposto una opzione generica della connessione
void sq_set_con_option(const char* opt) { _rec.set_con_option(opt); }
/**< Abilito/Disabilito l'autocommit, (disabilitato di default) */
void sq_set_autocommit(const bool ac) { _rec.set_autocommit(ac); }
@@ -119,7 +113,7 @@ public:
/** Ritorno il numero di elementi nella query */
const long sq_items() { return _rec.items(); }
- // Conguration
+ // Configuration
/**< Imposta la query ricevuta come (const char *) nel recordset */
const bool sq_set(const char* query) { return _rec.set(query); }
/**< Imposta la query ricevuta come (string) nel recordset */
@@ -138,9 +132,9 @@ public:
const bool sq_next() { return _rec.next(); }
/**< Si sposta indietro di un record, in caso di esito negativo valorizza _stringError e _codeError */
const bool sq_prev() { return _rec.prev(); }
- /**< Si sposta avanti di un record, in caso di esito negativo valorizza _stringError e _codeError */
- const bool sq_first() { return _rec.first(); }
/**< Si sposta al primo record, in caso di esito negativo valorizza _stringError e _codeError */
+ const bool sq_first() { return _rec.first(); }
+ /**< Si sposta all'ultimo record, in caso di esito negativo valorizza _stringError e _codeError */
const bool sq_last() { return _rec.last(); }
/**< Si sposta alla posizione n, in caso di esito negativo valorizza _stringError e _codeError */
const bool sq_go(const int new_pos) { return _rec.go(new_pos); }
@@ -171,8 +165,12 @@ public:
TString sq_get(const string& field, bool rtrim = true);
/**< Ritorna il valore nel campo (field) passato come (TString) in formato (const char *) */
TString sq_get(TString& field, bool rtrim = true);
+ /**< Ritorna il valore della colonna numero (column) passato come (unsigned int) */
+ TString sq_get(unsigned int column, bool rtrim = true);
/**< Ritorna il valore nel campo (field) in formato (char) */
const char sq_get_char(const char* field) { return _rec.get_char(field); }
+ /**< Ritorna il numero di campi dopo l'ultimo comando di esecuzione effettuato; se il risultato esiste */
+ unsigned int sq_get_num_fields() const;
/**< Ritorna la posizione attuale */
const long sq_pos() const { return _rec.pos(); }
@@ -183,6 +181,56 @@ public:
const char* sq_get_string_error(const bool erase = true) { return _rec.get_string_error(erase); }
/**< Ritorno l'ultima stringa di errore segnalato in formato (const char *) */
const char* sq_get_text_error(const bool erase = true) { return _rec.get_text_error(erase); }
+
+ // Gestione freeze
+ /**< Controlla se il cursore è bloccato */
+ const bool is_freezed() const { return _rec.is_freezed(); }
+ /**< Congela il cursore */
+ void freeze() { _rec.freeze(); }
+ /**< Scongela il cursore */
+ void defrost() { _rec.defrost(); }
+
+ /**< Costruttore, non inizializza nulla, da caricare successivamente */
+ SSimple_query() = default;
+ /**< Costruttore, Accetta in ingresso dei parametri per la connessione, volendo è anche possibile impostare una query ed eseguirla. Attenzione! Non risponde se la query ha avuto un esito positivo o negativo! */
+ SSimple_query(const char* db, const char* user, const char* pass, const TT_driver tipo_db, const char * query = "", const bool ex = false, const bool freezed = false) : _rec(db, user, pass, tipo_db, query, ex, freezed) {}
+ //SSimpleQuery(const TString& db, const TString& user, const TString& pass, TT_driver tipoDb, const char * query = "", const bool ex = false, const bool freezed = false) : _rec(db, user, pass, tipoDb, query, ex, freezed) {}
+ /**< Distruttore */
+ virtual ~SSimple_query() = default;
+};
+
+class TDB_recordset : public TRecordset
+{
+ SSimple_query * _rec;
+ TString _sql;
+ TString _dsn, _usr, _pwd, _drv;
+
+ bool _freezed, _loaded, _columns_loaded{};
+ TRecnotype _items, _current_row;
+ TArray _row, _column;
+
+protected:
+ void reset();
+ void set(const char* sql);
+ // Parsa la stringa di connessione contenuta nella query
+ void set_connection(const char * conn_str) const;
+ int connect(const char * db, const char * user, const char * pass, const TT_driver tipo_db) const;
+ int connect(const char * db, const char * user, const char * pass, const char * tipo_db) const;
+ static TT_driver str_to_driver(const char* tipo_db);
+
+public:
+ TRecnotype items() const override; // Pure
+ bool move_to(TRecnotype pos) override; // Pure
+ TRecnotype current_row() const override { return _current_row; } // Pure
+ const TArray* row(TRecnotype n);
+ void requery() override; // da impl. Pure
+ const TString& query_text() const override { return _sql; };
+
+ unsigned int columns() const override; // Pure
+ //virtual const TRecordset_column_info& column_info(unsigned int column) const; // Pure
+ const TVariant& get(unsigned int column) const override; // Pure
+
+ TDB_recordset(const char * sql, bool freezed = false);
};
#endif
\ No newline at end of file
diff --git a/src/tf/tf0100a.uml b/src/tf/tf0100a.uml
index 7dff27fe2..e8afbec93 100644
--- a/src/tf/tf0100a.uml
+++ b/src/tf/tf0100a.uml
@@ -277,7 +277,6 @@ BEGIN
ITEM "Modificata@10"
ITEM "N.\nRegistraz.@10"
ITEM "Codici Errori@10"
-
END
ENDPAGE
diff --git a/src/tf/tf0101.cpp b/src/tf/tf0101.cpp
index 822997994..e88941979 100644
--- a/src/tf/tf0101.cpp
+++ b/src/tf/tf0101.cpp
@@ -39,33 +39,34 @@ bool TTrFa_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
o.set(TDate(TODAY));
break;
case DLG_ALL:
- if (e == fe_button)
- {
- TSheet_field& docs = sfield(F_RIGHE);
- TString_array& sht = docs.rows_array();
- const int items = sht.items();
-
- if (items > 0)
+ if (e == fe_button)
{
- 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();
+ TSheet_field& docs = sfield(F_RIGHE);
+ 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;
case DLG_PDF:
- {
- TMask cs_mask("Cambiamento stato movimenti", 1, 30, 5);
- cs_mask.add_button_tool(DLG_OK, "~Conferma", TOOL_OK);
- cs_mask.add_button_tool(DLG_CANCEL, "Annulla", TOOL_CANCEL);
- cs_mask.add_list(101, 0, "Da stato", 0, 0, 15, "", "X|I|N|F|E", "Da Inviare|Inviato|Disabilitato|Forzato|Errato");
- cs_mask.add_list(102, 0, "A stato", 0, 2, 15, "", "X|I|N|F|E", "Da Inviare|Inviato|Disabilitato|Forzato|Errato");
- if (cs_mask.run() == K_ENTER)
+ if(e == fe_button)
{
- update_stato(cs_mask.get(101), cs_mask.get(102));
+ TMask cs_mask("Cambiamento stato movimenti", 1, 30, 5);
+ cs_mask.add_button_tool(DLG_OK, "~Conferma", TOOL_OK);
+ cs_mask.add_button_tool(DLG_CANCEL, "Annulla", TOOL_CANCEL);
+ cs_mask.add_list(101, 0, "Da stato", 0, 0, 15, "", "X|I|N|F|E", "Da Inviare|Inviato|Disabilitato|Forzato|Errato");
+ cs_mask.add_list(102, 0, "A stato", 0, 2, 15, "", "X|I|N|F|E", "Da Inviare|Inviato|Disabilitato|Forzato|Errato");
+ if (cs_mask.run() == K_ENTER)
+ {
+ update_stato(cs_mask.get(101), cs_mask.get(102));
+ }
}
- }
break;
case F_RIGHE:
if (e == se_notify_add)
diff --git a/src/tf/tf0102.cpp b/src/tf/tf0102.cpp
index ace09695f..52eee4759 100644
--- a/src/tf/tf0102.cpp
+++ b/src/tf/tf0102.cpp
@@ -195,8 +195,8 @@ void TTrFa_cursors::reset_esterometro()
_paf_e = msk().get_bool(B_PAF_ESTERI);
_paa_ns = msk().get_bool(B_PAA_NOT_SENT);
_paa_s = msk().get_bool(B_PAA_SENT);
- _paa_sf = msk().get_bool(B_PAA_ESTERI);
- _paa_e = msk().get_bool(B_PAA_SOG_FAT);
+ _paa_e = msk().get_bool(B_PAA_ESTERI);
+ _paa_sf = msk().get_bool(B_PAA_SOG_FAT);
}
TTrFa_cursors::TTrFa_cursors(): _c_rmoviva(nullptr), _c_trasfatt(nullptr), _new_mov(false), _new_cust(false),
diff --git a/src/tf/tf0400.cpp b/src/tf/tf0400.cpp
index 2c86101d8..527aba14c 100644
--- a/src/tf/tf0400.cpp
+++ b/src/tf/tf0400.cpp
@@ -5,10 +5,15 @@
#include
#include
#include
-#include // cache()
+#include // cache()
#include "../fe/felib.h" // TAnagrafica
#include "modaut.h"
+typedef enum{
+ def_sfield = F_RIGHE, // Sheetfield di default (tutte le colonne)
+ not_send_sfield = F_NOTSEND // Sheetfield di breve (poche colonne per non inviate)
+} field;
+
/****************************************************************************************************
* TSpe_check_msk
****************************************************************************************************/
@@ -20,6 +25,8 @@ private:
bool _selected;
bool _has_fp;
+ TSheet_field& get_sfield(const int field);
+ void fill_ninvio();
void refresh();
void fill_no_filter();
void fill_diff();
@@ -63,10 +70,14 @@ bool TSpe_check_msk::on_field_event(TOperable_field& o, TField_event e, long jol
case DLG_EDIT:
if(e == fe_button)
{
- TSheet_field& sheet = sfield(F_RIGHE);
- if(sheet.items() > 0)
+ TSheet_field* sheet;
+ if(get_int(F_TIPOCONTROLLO) == 3)
+ sheet = &sfield(F_NOTSEND);
+ else
+ sheet = &sfield(F_RIGHE);
+ if(sheet->items() > 0)
{
- sheet.esporta();
+ sheet->esporta();
}
else
{
@@ -111,6 +122,94 @@ bool TSpe_check_msk::on_field_event(TOperable_field& o, TField_event e, long jol
return true;
}
+TSheet_field& TSpe_check_msk::get_sfield(const int field)
+{
+ TSheet_field* wrong, *right;
+ if (field == def_sfield)
+ {
+ wrong = &sfield(not_send_sfield);
+ right = &sfield(def_sfield);
+ enable(F_FLAG);
+ }
+ else
+ {
+ wrong = &sfield(def_sfield);
+ right = &sfield(not_send_sfield);
+ disable(F_FLAG);
+ }
+ wrong->hide();
+ if(wrong->items() > 0)
+ wrong->destroy();
+ right->hide();
+ if (right->items() > 0)
+ right->destroy();
+ return *right;
+}
+
+void TSpe_check_msk::fill_ninvio()
+{
+ TString query = "USE MOV\n";
+ query << R"(SELECT (23.REG!="")&&BETWEEN(23.DATAREG,#DADATAREG,#ADATAREG)&&(23.TIPO=")" << get(F_TIPOCF) << "\")";
+ if (get(F_CODCF).full())
+ query << "&&STR((23.CODCF=#CODCF))";
+
+ TISAM_recordset rset(query);
+
+ TDate dadatareg = get_date(F_DATAINI);
+ if (!dadatareg.ok())
+ {
+ dadatareg = TDate(01, 01, 2017);
+ set(F_DATAINI, dadatareg);
+ }
+
+ TDate adatareg = get_date(F_DATAFIN);
+ if (!adatareg.ok())
+ {
+ adatareg = TDate(TODAY);
+ set(F_DATAFIN, adatareg);
+ }
+
+ // Setto le variabili
+ rset.set_var("#DADATAREG", dadatareg);
+ rset.set_var("#ADATAREG", adatareg);
+ if (get(F_CODCF).full())
+ rset.set_var("#CODCF", get(F_CODCF));
+
+ int nrec = rset.items();
+
+ TSheet_field& s = get_sfield(F_NOTSEND);
+
+
+ if (nrec <= 0) return;
+
+ for (bool ok = rset.move_first(); ok; ok = rset.move_next())
+ {
+ // Devo prendere tutti quelli che non vanno bene di records
+
+ TRectype clifo = getCli(rset.get("23.TIPO").as_string(), rset.get("23.CODCF").as_string(), rset.get("23.OCCAS").as_string());
+ if (rset.get("23.TFINVIO").as_string() != "I")
+ {
+ TToken_string& row = s.row(-1);
+
+ row.add(rset.get("23.NUMREG").as_int(), 0);
+ row.add(rset.get("23.DATAREG").as_date());
+ row.add(rset.get("23.ANNOES").as_int());
+ row.add(rset.get("23.NUMDOC").as_int());
+ row.add(rset.get("23.NUMDOCEXT").as_int());
+
+ row.add(rset.get("23.TIPODOC").as_string());
+ row.add(rset.get("23.DESCR").as_string());
+ row.add(rset.get("23.CODCF").as_int());
+ row.add(rset.get("23.TOTDOC").as_real());
+ row.add(rev_charge(rset.get("NUMREG").as_string(), rset.get("23.DATAREG").as_date().year())), s.cid2index(A_REVERSE);
+ row.add(rset.get("23.TFINVIO").as_string().empty()? "X" : rset.get("23.TFINVIO").as_string());
+ }
+ }
+ s.force_update();
+ s.show();
+ enable_edit(false);
+}
+
void TSpe_check_msk::refresh()
{
switch(get_long(F_TIPOCONTROLLO))
@@ -123,6 +222,8 @@ void TSpe_check_msk::refresh()
break;
case 2:
fill_cust();
+ case 3:
+ fill_ninvio();
default:
break;
}
@@ -164,19 +265,12 @@ void TSpe_check_msk::fill_no_filter()
int nrec = rset.items();
- TSheet_field& s = sfield(F_RIGHE);
-
- if(s.items() > 0)
- s.destroy();
+ TSheet_field& s = get_sfield(F_RIGHE);
if(nrec <= 0) return;
- // Nascondo lo sheet
- s.hide();
for(bool ok = rset.move_first(); ok; ok = rset.move_next())
{
- // Devo prendere tutti quelli che non vanno bene di records
- if(check_record(&rset, _has_fp)) continue;
TRectype clifo = getCli(rset.get("23.TIPO").as_string(), rset.get("23.CODCF").as_string(), rset.get("23.OCCAS").as_string());
TToken_string& row = s.row(-1);
@@ -230,7 +324,7 @@ void TSpe_check_msk::fill_diff()
// Apro la tabella TRASFATT e per ogni record lo ricostruisco l'originale
TString query = "USE TRASFATT\n";
query << "SELECT BETWEEN(DATAREG,#DADATAREG,#ADATAREG)&&NUMREG<" << MOV_CUSTOM << "&&(TIPO=\"" << get(F_TIPOCF) << "\")";
- if(get(F_CODCF) != "")
+ if(get(F_CODCF).full())
query << "&&STR((CODCF=#CODCF))";
get_fil_flag(query);
@@ -253,18 +347,14 @@ void TSpe_check_msk::fill_diff()
// Setto le variabili
rset.set_var("#DADATAREG", dadatareg);
rset.set_var("#ADATAREG", adatareg);
- if(get(F_CODCF) != "")
+ if(get(F_CODCF).full())
rset.set_var("#CODCF", get(F_CODCF));
int nrec = rset.items();
- TSheet_field& s = sfield(F_RIGHE);
- if(s.items() > 0)
- s.destroy();
+ TSheet_field& s = get_sfield(F_RIGHE);
if(nrec <= 0) return;
- // Nascondo lo sheet
- s.hide();
TString nat;
@@ -407,7 +497,7 @@ void TSpe_check_msk::fill_cust()
{
TString query = "USE TRASFATT\n";
query << "SELECT BETWEEN(DATAREG,#DADATAREG,#ADATAREG)&&(TIPO=\"" << get(F_TIPOCF) << "\")";
- if(get(F_CODCF) != "")
+ if(get(F_CODCF).full())
query << "&&STR((CODCF=#CODCF))";
get_fil_flag(query);
@@ -431,7 +521,7 @@ void TSpe_check_msk::fill_cust()
// Setto le variabili
rset.set_var("#DADATAREG", dadatareg);
rset.set_var("#ADATAREG", adatareg);
- if(get(F_CODCF) != "")
+ if(get(F_CODCF).full())
rset.set_var("#CODCF", get(F_CODCF));
int nrec = rset.items();
@@ -625,6 +715,7 @@ void TSpe_check_msk::delete_all()
TSpe_check_msk::TSpe_check_msk() : TAutomask("tf0400a")
{
+ sfield(F_NOTSEND).hide();
_ditta.init(LF_NDITTE, prefix().get_codditta());
_selected = false;
}
diff --git a/src/tf/tf0400a.h b/src/tf/tf0400a.h
index 460c60a23..9b621ea49 100644
--- a/src/tf/tf0400a.h
+++ b/src/tf/tf0400a.h
@@ -1,10 +1,10 @@
-#define F_TIPOCONTROLLO 301
-#define F_FLAG 302
-#define F_DATAINI 303
-#define F_DATAFIN 304
-#define F_CODCF 305
-#define F_TIPOCF 306
-#define F_RAGSOC 307
+#define F_TIPOCONTROLLO 401
+#define F_FLAG 402
+#define F_DATAINI 403
+#define F_DATAFIN 404
+#define F_CODCF 405
+#define F_TIPOCF 406
+#define F_RAGSOC 407
#define F_RIGHE 201 // Sheet righe tf
@@ -30,4 +30,18 @@
#define A_REVERSE 120
#define A_AUTOFATT 121
#define A_SPEDITA 122
-#define A_NUMERO 123
\ No newline at end of file
+#define A_NUMERO 123
+
+#define F_NOTSEND 301
+
+#define B_NUMREG 101
+#define B_DATAREG 102
+#define B_ANNOES 103
+#define B_NUMDOC 104
+#define B_NUMDOCEXT 105
+#define B_TIPODOC 106
+#define B_DESC 107
+#define B_CODCF 108
+#define B_TOTDOC 109
+#define B_REVCHARGE 110
+#define B_TFINVIO 111
\ No newline at end of file
diff --git a/src/tf/tf0400a.uml b/src/tf/tf0400a.uml
index 2e38c5dca..b0ae91c6d 100644
--- a/src/tf/tf0400a.uml
+++ b/src/tf/tf0400a.uml
@@ -43,6 +43,7 @@ BEGIN
ITEM "0|Movimenti ignorati"
ITEM "1|Differenze Prima Nota/TF"
ITEM "2|Mostra tutti i movimenti modificati"
+ ITEM "3|Movimenti non inviati"
FLAGS ""
END
@@ -141,6 +142,23 @@ BEGIN
DEFAULT "*" // Impedisce il salvataggio su profilo .ini
END
+SPREADSHEET F_NOTSEND
+BEGIN
+ PROMPT 0 8 "Righe movimenti non inviati"
+ ITEM "Numero\n Reg.@7"
+ ITEM "Data\nReg.@8"
+ ITEM "Anno\nEs.@4"
+ ITEM "Numero\nDocumento@8"
+ ITEM "Numero\nDocum. Esteso@20"
+ ITEM "Tipo\nDocum.@5"
+ ITEM "Descrizione@40"
+ ITEM "Cod. C/F@6"
+ ITEM "Totale\nDocum.@18"
+ ITEM "Reverse\ncharge@5"
+ ITEM "INVIO@5"
+ FLAG "H"
+END
+
ENDPAGE
ENDMASK
@@ -383,5 +401,102 @@ BEGIN
END
ENDPAGE
+ENDMASK
+
+PAGE "NOTSEND" -1 -1 69 14
+
+NUMBER B_NUMREG 7 0
+BEGIN
+ PROMPT 0 0 "Numero Reg."
+ FLAG "D"
+END
+
+DATE B_DATAREG
+BEGIN
+ PROMPT 0 1 "Data Reg."
+ FLAG "D"
+END
+
+NUMBER B_ANNOES 4 0
+BEGIN
+ PROMPT 0 2 "Anno Es."
+ FLAG "D"
+END
+
+NUMBER B_NUMDOC 7 0
+BEGIN
+ PROMPT 0 3 "Numero Documento"
+ FLAG "D"
+END
+
+NUMBER B_NUMDOCEXT 50 0
+BEGIN
+ PROMPT 0 4 "Numero Docum. Esteso"
+ FLAG "D"
+END
+
+STRING B_TIPODOC 2
+BEGIN
+ PROMPT 0 5 "Tipo Docum."
+ FLAG "D"
+END
+
+STRING B_DESC 50
+BEGIN
+ PROMPT 0 6 "Descrizione"
+ FLAG "D"
+END
+
+NUMBER B_CODCF 6 0
+BEGIN
+ PROMPT 0 7 "Cod. C/F"
+ FLAG "D"
+END
+
+NUMBER B_TOTDOC 18 3
+BEGIN
+ PROMPT 0 8 "Totale Docum."
+ FLAG "D"
+END
+
+BOOLEAN B_REVCHARGE
+BEGIN
+ PROMPT 0 9 "Reverse charge"
+ FLAG "D"
+END
+
+STRING B_TFINVIO 1
+BEGIN
+ PROMPT 0 10 "INVIO"
+ FLAG "D"
+END
+
+ENDPAGE
+
+TOOLBAR "topbar" 0 0 0 2
+
+BUTTON DLG_OK 2 2
+BEGIN
+ PROMPT 1 1 ""
+END
+
+BUTTON DLG_USER 2 2
+BEGIN
+ PROMPT 2 1 "Collega"
+ PICTURE TOOL_LINK
+END
+
+BUTTON DLG_DELREC 2 2
+BEGIN
+ PROMPT 2 1 "Elimina"
+ PICTURE TOOL_DELREC
+END
+
+BUTTON DLG_CANCEL 2 2
+BEGIN
+ PROMPT 4 1 ""
+END
+
+ENDPAGE
ENDMASK
\ No newline at end of file
diff --git a/src/tf/tfutility.cpp b/src/tf/tfutility.cpp
index 102ca052a..da7d726e7 100644
--- a/src/tf/tfutility.cpp
+++ b/src/tf/tfutility.cpp
@@ -142,16 +142,16 @@ bool check_record(TISAM_recordset* rec, const bool mod_esterometro,
TRectype rdoc(LF_DOC);
static TLocalisamfile doc(LF_DOC);
rdoc.put(DOC_PROVV, rec->get("23.DPROVV").as_string());
- rdoc.put(DOC_PROVV, rec->get("23.DANNO").as_string());
- rdoc.put(DOC_PROVV, rec->get("23.DCODNUM").as_string());
- rdoc.put(DOC_PROVV, rec->get("23.DNDOC").as_string());
+ rdoc.put(DOC_ANNO, rec->get("23.DANNO").as_string());
+ rdoc.put(DOC_CODNUM, rec->get("23.DCODNUM").as_string());
+ rdoc.put(DOC_NDOC, rec->get("23.DNDOC").as_string());
- // Se riesco a generare la chiave, trovo il record e ha il flag di gestione in errore o un errore esterno, so che è stato inviato
+ // Se riesco a generare la chiave, trovo il record e non ha il flag di gestione in errore o un errore esterno, so che è stato inviato
const bool is_sent = rdoc.read(doc) == NOERR && chiave_paf(rdoc, hfatt, bfatt) && paf0100f.search(nullptr, hfatt, bfatt) && paf0100f.sq_get("P1_GESTIONE") != "E" && paf0100f.sq_get("P1_ERREST") != "*";
// Se voglio solo quelli inviati e non è stato inviato o
// voglio solo quelli non inviati ed è stato inviato, RUSPA!
- if ((is_sent && !paf_sent) || (is_sent && paf_not_sent))
+ if ((!is_sent && paf_sent) || (is_sent && paf_not_sent))
return false;
}
else
@@ -201,25 +201,25 @@ bool check_record(TISAM_recordset* rec, const bool mod_esterometro,
{
// Parte Sirio FP w/ WebApp
// Faccio controlli per evitare controlli
- if (paf_not_sent && paf_sent)
+ if (paa_not_sent && paa_sent)
{
return true;
}
- else if (paf_not_sent || paf_sent)
+ else if (paa_not_sent || paa_sent)
{
// Disabilitato, non si vuole implementare al momento
return false;
}
// Parte tirchi che non comprano la mia WebApp
// Solito controllo per evitare controlli
- else if (paf_sog_fat && paf_esteri)
+ else if (paa_sog_fat && paa_esteri)
{
return true;
}
else
{
const bool is_fatturabile = ana_cli.stato_partita_IVA() == "IT" || ana_cli.stato_partita_IVA() == "SM";
- if ((is_fatturabile && !paf_sog_fat) || (is_fatturabile && paf_esteri))
+ if ((is_fatturabile && !paa_sog_fat) || (is_fatturabile && paa_esteri))
return false;
}
}
diff --git a/src/ve/velib.h b/src/ve/velib.h
index 715927662..9fdc20911 100755
--- a/src/ve/velib.h
+++ b/src/ve/velib.h
@@ -748,8 +748,9 @@ class TDocumento : public TMultiple_rectype // velib03
TString8 _old_agente; // Agente originale
TString8 _old_agente1; // Secondo Agente originale
- TRiga_documento * _sconto; // Riga per lo sconto di testata
+ TRiga_documento * _sconto; // Riga per lo sconto di testata
TRiga_documento * _esenzione; // Riga per l' esenzione iva
+ TRiga_documento * _valfisc; // Riga di valenza fiscale per fatture 2019+
bool _dirty_deny;
@@ -820,7 +821,7 @@ public:
void sort_rows(const char * key);
int physical_rows() const { return body().rows(); }
- virtual int rows() const { return physical_rows() + (ha_riga_sconto() ? 1 : 0) + (ha_riga_esenzione() ? 1 : 0); }
+ virtual int rows() const { return physical_rows() + (ha_riga_sconto() ? 1 : 0) + (ha_riga_esenzione() ? 1 : 0) + (ha_riga_valfisc() ? 1 : 0); }
const TRiga_documento& operator[](int index) const { return (const TRiga_documento&)((TDocumento *)this)->row(index); }
TRiga_documento& operator[](int index) { return (TRiga_documento&)row(index); }
@@ -890,9 +891,11 @@ public:
void set_fields(TAuto_variable_rectype & rec);
void update_esenzione();
void set_riga_esenzione();
+ void set_riga_valfisc();
const TRiga_documento& get_riga_esenzione() const { return *_esenzione; }
bool ha_riga_sconto() const { return _sconto != NULL; }
bool ha_riga_esenzione() const { return _esenzione != NULL; }
+ bool ha_riga_valfisc() const { return _valfisc != NULL; }
void iva_esente(TString & codiva_es) const;
real spese_incasso(real &imp, int ndec, TTipo_importo netto = _lordo) const ;
diff --git a/src/ve/velib03.cpp b/src/ve/velib03.cpp
index 682958339..94701edbb 100755
--- a/src/ve/velib03.cpp
+++ b/src/ve/velib03.cpp
@@ -250,7 +250,7 @@ void TDocumento::init()
_codcf = new TRecfield(*this, DOC_CODCF);
_cod_occas = new TRecfield(*this, DOC_OCFPI);
- _sconto = _esenzione = NULL;
+ _sconto = _esenzione = _valfisc = NULL;
_stato_originale = ' ';
_dirty_deny = false;
@@ -306,6 +306,7 @@ TDocumento::~TDocumento()
if (_sconto != NULL) delete _sconto;
if (_esenzione != NULL) delete _esenzione;
+ if (_valfisc != NULL) delete _valfisc;
}
const TString& TDocumento::codiva_spese() const
@@ -819,8 +820,11 @@ void TDocumento::on_read(int err, word lockop)
_occas.zero();
set_riga_sconto();
- if (is_fattura())
- set_riga_esenzione();
+ if (is_fattura())
+ {
+ set_riga_esenzione();
+ set_riga_valfisc();
+ }
_stato_originale = stato();
#ifdef LIVE_STATISTICS
@@ -1004,15 +1008,15 @@ void TDocumento::set_riga_esenzione()
TString16 v_data_esenzione;
TString16 n_registrazione;
TString16 n_data_registrazione;
- bool multiPlaf = c.use_lettere() && get("PLAFOND").full(); // Gestione multiplafond su documento
- if (codes.codice().full() && !multiPlaf)
+ const bool multi_plaf = c.use_lettere() && get("PLAFOND").full(); // Gestione multiplafond su documento
+ if (codes.codice().full() && !multi_plaf)
{
get_protocolli_esenzione(v_esenzione, v_data_esenzione, n_registrazione, n_data_registrazione);
}
// Tradotto: se ha il cod. esenzione AND (i protocolli pieni OR multiplaf)
bool esente = codes.tipo().not_empty() && ((v_esenzione.not_empty() &&
v_data_esenzione.not_empty() && n_registrazione.not_empty() &&
- n_data_registrazione.not_empty()) || multiPlaf);
+ n_data_registrazione.not_empty()) || multi_plaf);
if (esente)
{
esente = false;
@@ -1054,7 +1058,7 @@ void TDocumento::set_riga_esenzione()
_esenzione = new TRiga_documento(this, _tipo_riga_es);
TString d = _des_esenz;
- if(multiPlaf)
+ if(multi_plaf)
{
d << " come dalle vostre dichiarazioni:\n";
TToken_string lePlafs(get("PLAFOND"), ',');
@@ -1076,6 +1080,19 @@ void TDocumento::set_riga_esenzione()
_esenzione->set_descr(d);
}
}
+
+void TDocumento::set_riga_valfisc()
+{
+ static TDate anno_fatt_elett = TDate(01, 01, 2019);
+ if(is_fattura() && tipo().tipo_doc_sdi().full() && data() >= anno_fatt_elett)
+ {
+ if (_valfisc == nullptr)
+ _valfisc = new TRiga_documento(this, "05");
+
+ // Uno \n all'inizio per staccarla dal resto, ATTENZIONE!!! Senza lo spazio iniziale scrive solo una parte di questo messaggio!
+ _valfisc->set_descr(" \nStampa priva di valenza giuridico-fiscale ai sensi dell'art.21 DPR 633/72, salvo per i soggetti non titolari di partita iva e/o non residenti ai sensi del comma 909 art.1 L.205/2017.");
+ }
+}
void TDocumento::dirty_fields()
{
@@ -1932,15 +1949,31 @@ TRiga_documento & TDocumento::row(int index)
r = &((TRiga_documento &) b.row(index, FALSE));
}
else
- {
- CHECKD((index == nrows + 1 && (_sconto != NULL || _esenzione != NULL)) || (index == nrows + 2 && _sconto != NULL && _esenzione != NULL),
- "Riga documento non esistente ", index);
- if (index == nrows + 1)
- {
- r = _sconto != NULL ? _sconto : _esenzione;
- } else
- if (index == nrows + 2)
- r = _esenzione;
+ {
+
+ CHECKD(index <= rows(), "Riga documento non esistente ", index);
+
+ switch (index - nrows)
+ {
+ case 1:
+ if (_sconto != NULL)
+ {
+ r = _sconto;
+ break;
+ }
+ case 2:
+ if (_esenzione != NULL)
+ {
+ r = _esenzione;
+ break;
+ }
+ case 3:
+ {
+ r = _valfisc;
+ break;
+ }
+ }
+
}
return *r;
}
@@ -2729,8 +2762,11 @@ TDocumento& TDocumento::copy(const TDocumento & d)
r.set_fields(((TAuto_variable_rectype &)d[i]));
}
set_riga_sconto();
- if (is_fattura())
- set_riga_esenzione();
+ if (is_fattura())
+ {
+ set_riga_esenzione();
+ set_riga_valfisc();
+ }
_occas = d.occas();
return *this;
}
diff --git a/src/xvtdb/xvtdb.cpp b/src/xvtdb/xvtdb.cpp
index 5d150a3bf..eaf8ee46d 100644
--- a/src/xvtdb/xvtdb.cpp
+++ b/src/xvtdb/xvtdb.cpp
@@ -65,6 +65,81 @@ TXvt_recordset::TXvt_recordset(const char* db, const char* user, const char* pas
}
}
+TT_driver TXvt_recordset::str_to_driver(const char* tipo_db)
+{
+ TT_driver tipoDb_driver = TSDB_undefined;
+ //! DBMS client is not specified
+ if (_stricmp(tipo_db, "") != 0)
+ tipoDb_driver = TSDB_undefined;
+ //! ODBC
+ else if (_stricmp(tipo_db, "ODBC") == 0)
+ tipoDb_driver = TSDB_ODBC;
+ //! Oracle
+ else if (_stricmp(tipo_db, "Oracle") == 0)
+ tipoDb_driver = TSDB_Oracle;
+ //! Microsoft SQL Server
+ else if (_stricmp(tipo_db, "MSSQL") == 0)
+ tipoDb_driver = TSDB_MSSQL;
+ //! InterBase or Firebird
+ else if (_stricmp(tipo_db, "InterBase") == 0)
+ tipoDb_driver = TSDB_InterBase;
+ //! SQLBase
+ else if (_stricmp(tipo_db, "SQLBase") == 0)
+ tipoDb_driver = TSDB_SQLBase;
+ //! IBM DB2
+ else if (_stricmp(tipo_db, "DB2") == 0)
+ tipoDb_driver = TSDB_DB2;
+ //! Informix
+ else if (_stricmp(tipo_db, "Informix") == 0)
+ tipoDb_driver = TSDB_Informix;
+ //! Sybase ASE
+ else if (_stricmp(tipo_db, "Sybase") == 0)
+ tipoDb_driver = TSDB_Sybase;
+ //! MySQL
+ else if (_stricmp(tipo_db, "MySQL") == 0)
+ tipoDb_driver = TSDB_MySQL;
+ //! PostgreSQL
+ else if (_stricmp(tipo_db, "PostgreSQL") == 0)
+ tipoDb_driver = TSDB_PostgreSQL;
+ //! SQLite
+ else if (_stricmp(tipo_db, "SQLite") == 0)
+ tipoDb_driver = TSDB_SQLite;
+ //! SQL Anywere
+ else if (_stricmp(tipo_db, "SQLAnywhere") == 0)
+ tipoDb_driver = TSDB_SQLAnywhere;
+ return tipoDb_driver;
+}
+
+int strcmp_ins(const char* str1, const char* str2)
+{
+ int len1 = strlen(str1) + 1;
+ int len2 = strlen(str2) + 1;
+ char * str1_up = new char[len1];
+ char * str2_up = new char[len2];
+
+ strcpy_s(str1_up, len1, str1);
+ strcpy_s(str2_up, len2, str2);
+
+ char *p = str1_up;
+ char *q = str2_up;
+ while (*p != '\0')
+ {
+ *p = toupper(*p);
+ p++;
+ }
+ while (*q != '\0')
+ {
+ *q = toupper(*q);
+ q++;
+ }
+ return strcmp(str1_up, str2_up);
+}
+
+TXvt_recordset::TXvt_recordset(const char* db, const char* user, const char* pass, const char* tipoDb,
+ const char* query, const bool ex, const bool freezed) : TXvt_recordset(db, user, pass, str_to_driver(tipoDb), query, ex, freezed)
+{
+}
+
TXvt_recordset::~TXvt_recordset()
{
try
@@ -574,6 +649,21 @@ const char* TXvt_recordset::get(const char* field)
}
}
+const char* TXvt_recordset::get(unsigned int field)
+{
+ try
+ {
+ return _RCS(_recset)->Field(field).asString();
+ }
+ catch(SAException &x)
+ {
+ _code_error = x.ErrNativeCode();
+ _GET_ERROR(x.ErrMessage(), _string_error);
+ _GET_ERROR(x.ErrText(), _string_error_full_text);
+ return '\0';
+ }
+}
+
char TXvt_recordset::get_char(const char* field)
{
try
@@ -589,6 +679,11 @@ char TXvt_recordset::get_char(const char* field)
}
}
+int TXvt_recordset::get_num_fields() const
+{
+ return _RCS(_recset)->FieldCount();
+}
+
long TXvt_recordset::get_code_error(bool erase)
{
long app = _code_error;
diff --git a/src/xvtdb/xvtdb.h b/src/xvtdb/xvtdb.h
index c6b62676b..a93187255 100644
--- a/src/xvtdb/xvtdb.h
+++ b/src/xvtdb/xvtdb.h
@@ -95,6 +95,9 @@ public:
TXvt_recordset();
/**< Costruttore, crea un oggetto dai parametri di connessione passati */
TXvt_recordset(const char* db, const char* user, const char* pass, TT_driver tipoDb, const char * query = "", const bool ex = false, const bool freezed = false);
+ static TT_driver str_to_driver(const char* tipo_db);
+ /**< Costruttore, crea un oggetto dai parametri di connessione passati, chiama costruttore con TT_driver */
+ TXvt_recordset(const char* db, const char* user, const char* pass, const char* tipoDb, const char * query = "", const bool ex = false, const bool freezed = false);
/**< Distruttore */
~TXvt_recordset();
@@ -192,8 +195,12 @@ public:
const char* get_date(const char* field);
/**< Ritorna il valore nel campo (field) passato in formato (const char *) */
const char* get(const char* field);
+ /**< Ritorna il valore del campo numero (field) passato, in formato (const char *) */
+ const char* get(unsigned int field);
/**< Ritorna il valore nel campo (field) in formato (char) */
char get_char(const char* field);
+ /**< Ritorna il numero di campi dopo l'ultimo comando di esecuzione effettuato; se il risultato esiste */
+ int get_num_fields() const;
/**< Ritorna la posizione attuale */
long pos() const { return _recno; }