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; }