diff --git a/build/Ba2.vcxproj b/build/Ba2.vcxproj index 4a4c8d194..67c7c14f6 100644 --- a/build/Ba2.vcxproj +++ b/build/Ba2.vcxproj @@ -118,7 +118,7 @@ Disabled - ..\src\include;..\src\xvaga;%(AdditionalIncludeDirectories) + ..\src\include;..\src\xvaga;..\src\xvtdb;%(AdditionalIncludeDirectories) _DEBUG;WIN32;__LONGDOUBLE__;_WINDOWS;%(PreprocessorDefinitions) MultiThreadedDebug false diff --git a/build/lv0.vcxproj b/build/lv0.vcxproj index d1b7c4399..41c17ad39 100644 --- a/build/lv0.vcxproj +++ b/build/lv0.vcxproj @@ -98,6 +98,9 @@ true $(IntDir)$(TargetName).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)" + diff --git a/build/lv1.vcxproj b/build/lv1.vcxproj index 35a9b97f9..dc6336412 100644 --- a/build/lv1.vcxproj +++ b/build/lv1.vcxproj @@ -100,6 +100,9 @@ $(IntDir)$(TargetName).xml + + "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)" + diff --git a/build/lv2.vcxproj b/build/lv2.vcxproj index 5c811d7aa..91a6b9c2f 100644 --- a/build/lv2.vcxproj +++ b/build/lv2.vcxproj @@ -97,6 +97,9 @@ true $(IntDir)$(TargetName).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)" + diff --git a/build/lv3.vcxproj b/build/lv3.vcxproj index 4e887a543..5f773b397 100644 --- a/build/lv3.vcxproj +++ b/build/lv3.vcxproj @@ -98,6 +98,9 @@ true $(IntDir)$(TargetName).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)" + diff --git a/build/lv4.vcxproj b/build/lv4.vcxproj index 3165b06f8..72a884b4e 100644 --- a/build/lv4.vcxproj +++ b/build/lv4.vcxproj @@ -101,6 +101,9 @@ $(IntDir)$(TargetName).xml + + "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)" + diff --git a/cd/test/cg0768.txt b/cd/test/cg0768.txt new file mode 100644 index 000000000..4e384a59f --- /dev/null +++ b/cd/test/cg0768.txt @@ -0,0 +1,5 @@ +cg2.exe + +Aggiunta chiusura automatica maschera fppro +Disattivata multiselezione fattura dallo sheet dell fppro +Corretto messaggio di errore se si sta inserendo manualmente i dati diff --git a/cd/test/cg0768a.ini b/cd/test/cg0768a.ini new file mode 100644 index 000000000..3e9c34920 --- /dev/null +++ b/cd/test/cg0768a.ini @@ -0,0 +1,94 @@ +[Main] +Demo=0 + +[cg1] +Edit_23 = cg2 -0 +File(8) = cg2.exe|X +Patch = 768 +Versione = 21511200 + +[cg99] +Kill(0) = bastndo.msk|x +Kill(1) = batblbu.msk|x +Kill(2) = bastzon.msk|x +Kill(3) = bastesc.msk|x +Kill(4) = bastscc.msk|x +Kill(5) = bastvet.msk|x +Kill(6) = bastcve.msk|x +Kill(7) = batbntb.msk|x +Kill(8) = bastndo.rep|x +Kill(9) = batbvet.msk|x +Kill(10) = batbcve.msk|x +Kill(11) = batbndo.msk|x +Kill(12) = bastpor.msk|x +Kill(13) = batbind.msk|x +Kill(14) = batbtit.msk|x +Kill(15) = bastntb.rep|x +Kill(16) = batbleg.msk|x +Kill(17) = bastcco.rep|x +Kill(18) = bastmsp.rep|x +Kill(19) = bastreg.rep|x +Kill(20) = bastcco.msk|x +Kill(21) = bastmsp.msk|x +Kill(22) = bastnot.msk|x +Kill(23) = batbcam.msk|x +Kill(24) = bastpor.rep|x +Kill(25) = batbpdb.msk|x +Kill(26) = batbins.msk|x +Kill(27) = bastscc.rep|x +Kill(28) = bastvet.rep|x +Kill(29) = bastpdb.msk|x +Kill(30) = batbesc.msk|x +Kill(31) = bastleg.msk|x +Kill(32) = bastivd.msk|x +Kill(33) = batbdpn.msk|x +Kill(34) = bastdpn.rep|x +Kill(35) = batbmsp.msk|x +Kill(36) = bastdpn.msk|x +Kill(37) = bastcve.rep|x +Kill(38) = bastesc.rep|x +Kill(39) = batbdel.msk|x +Kill(40) = bastver.rep|x +Kill(41) = bastcam.msk|x +Kill(42) = batbreg.msk|x +Kill(43) = bastivd.rep|x +Kill(44) = batbnot.msk|x +Kill(45) = bastntb.msk|x +Kill(46) = bastreg.msk|x +Kill(47) = batbzon.msk|x +Kill(48) = batbtra.msk|x +Kill(49) = bastcfi.msk|x +Kill(50) = bastarb.rep|x +Kill(51) = bastarb.msk|x +Kill(52) = bastpdb.rep|x +Kill(53) = cgtbcon.msk|x +Kill(54) = batbver.msk|x +Kill(55) = batblia.msk|x +Kill(56) = bastnot.rep|x +Kill(57) = batbinl.msk|x +Kill(58) = bastver.msk|x +Kill(59) = batbcco.msk|x +Kill(60) = bastcam.rep|x +Kill(61) = bastcfi.rep|x +Kill(62) = batbscc.msk|x +Kill(63) = batbcfi.msk|x +Kill(64) = bastzon.rep|x +Kill(65) = batbivd.msk|x +Kill(66) = batbpor.msk|x +Kill(67) = bastleg.rep|x +Kill(68) = batblia.msk|x +Kill(69) = batbarb.msk|x + +[cg] +Data = 11-04-2019 +Descrizione = Contabilita' Generale +Dischi = 1 +Moduli = ba +OEM = +Patch = 768 +PostProcess = bainst -0 CG +PreProcess = +Prezzo(1) = +Prezzo(2) = +Versione = 21511200 + diff --git a/cd/test/cg0768a1.zip b/cd/test/cg0768a1.zip new file mode 100644 index 000000000..34e72bc60 Binary files /dev/null and b/cd/test/cg0768a1.zip differ diff --git a/cd/test/cg0770.txt b/cd/test/cg0770.txt new file mode 100644 index 000000000..b4d08e0bb --- /dev/null +++ b/cd/test/cg0770.txt @@ -0,0 +1,4 @@ +cg2.exe + +- Corretti controllo modulo FP +- Corretto caricamento campo PROTFPPRO sulle maschere diff --git a/cd/test/cg0770a.ini b/cd/test/cg0770a.ini new file mode 100644 index 000000000..cfc1b0734 --- /dev/null +++ b/cd/test/cg0770a.ini @@ -0,0 +1,94 @@ +[Main] +Demo=0 + +[cg1] +Edit_23 = cg2 -0 +File(8) = cg2.exe|X +Patch = 0770 +Versione = 21511200 + +[cg99] +Kill(0) = bastreg.rep|x +Kill(1) = batbpdb.msk|x +Kill(2) = bastleg.msk|x +Kill(3) = bastmsp.rep|x +Kill(4) = bastpor.rep|x +Kill(5) = batbesc.msk|x +Kill(6) = bastscc.rep|x +Kill(7) = batbdpn.msk|x +Kill(8) = batbins.msk|x +Kill(9) = bastivd.msk|x +Kill(10) = bastntb.rep|x +Kill(11) = bastmsp.msk|x +Kill(12) = batbtit.msk|x +Kill(13) = bastcco.msk|x +Kill(14) = bastcco.rep|x +Kill(15) = batbcam.msk|x +Kill(16) = batbleg.msk|x +Kill(17) = bastnot.msk|x +Kill(18) = batbndo.msk|x +Kill(19) = batbcve.msk|x +Kill(20) = batbind.msk|x +Kill(21) = bastpor.msk|x +Kill(22) = batbcco.msk|x +Kill(23) = batbivd.msk|x +Kill(24) = bastver.msk|x +Kill(25) = bastzon.rep|x +Kill(26) = bastleg.rep|x +Kill(27) = batbpor.msk|x +Kill(28) = bastcfi.msk|x +Kill(29) = batblia.msk|x +Kill(30) = bastcfi.rep|x +Kill(31) = batbtra.msk|x +Kill(32) = batbver.msk|x +Kill(33) = bastcam.rep|x +Kill(34) = batbinl.msk|x +Kill(35) = batbcfi.msk|x +Kill(36) = bastnot.rep|x +Kill(37) = batbscc.msk|x +Kill(38) = batbdel.msk|x +Kill(39) = bastntb.msk|x +Kill(40) = bastarb.msk|x +Kill(41) = bastesc.rep|x +Kill(42) = batbnot.msk|x +Kill(43) = bastarb.rep|x +Kill(44) = batbzon.msk|x +Kill(45) = cgtbcon.msk|x +Kill(46) = bastreg.msk|x +Kill(47) = bastpdb.rep|x +Kill(48) = bastpdb.msk|x +Kill(49) = batbmsp.msk|x +Kill(50) = bastcam.msk|x +Kill(51) = bastvet.rep|x +Kill(52) = bastdpn.rep|x +Kill(53) = bastver.rep|x +Kill(54) = bastcve.rep|x +Kill(55) = bastivd.rep|x +Kill(56) = bastdpn.msk|x +Kill(57) = batbreg.msk|x +Kill(58) = batbarb.msk|x +Kill(59) = batblia.msk|x +Kill(60) = batbvet.msk|x +Kill(61) = bastndo.rep|x +Kill(62) = batblbu.msk|x +Kill(63) = bastndo.msk|x +Kill(64) = bastvet.msk|x +Kill(65) = bastscc.msk|x +Kill(66) = bastesc.msk|x +Kill(67) = bastzon.msk|x +Kill(68) = batbntb.msk|x +Kill(69) = bastcve.msk|x + +[cg] +Data = 15-04-2019 +Descrizione = Contabilita' Generale +Dischi = 1 +Moduli = ba +OEM = +Patch = 770 +PostProcess = bainst -0 CG +PreProcess = +Prezzo(1) = +Prezzo(2) = +Versione = 21511200 + diff --git a/cd/test/cg0770a1.zip b/cd/test/cg0770a1.zip new file mode 100644 index 000000000..53ee3bb54 Binary files /dev/null and b/cd/test/cg0770a1.zip differ diff --git a/cd/test/fp0766.txt b/cd/test/fp0766.txt new file mode 100644 index 000000000..b2a04f9d2 --- /dev/null +++ b/cd/test/fp0766.txt @@ -0,0 +1,3 @@ +fp0.exe + +- Corretto calcolo ritenuta \ No newline at end of file diff --git a/cd/test/fp0766a.ini b/cd/test/fp0766a.ini new file mode 100644 index 000000000..2092adf5c --- /dev/null +++ b/cd/test/fp0766a.ini @@ -0,0 +1,19 @@ +[Main] +Demo=0 + +[fp1] +File(0) = fp0.exe|X +Patch = 766 +Versione = 21511200 + +[fp] +Data = 09-04-2019 +Descrizione = Fattura Elettronica +Dischi = 1 +Moduli = cg,ve +OEM = +Patch = 766 +PostProcess = +PreProcess = +Versione = 21511200 + diff --git a/cd/test/fp0766a1.zip b/cd/test/fp0766a1.zip new file mode 100644 index 000000000..9e4724660 Binary files /dev/null and b/cd/test/fp0766a1.zip differ diff --git a/cd/test/fp0776.txt b/cd/test/fp0776.txt new file mode 100644 index 000000000..b9507f8f0 --- /dev/null +++ b/cd/test/fp0776.txt @@ -0,0 +1,3 @@ +/sql/fp0/fp0106.sql + +Aggiornamento database \ No newline at end of file diff --git a/cd/test/fp0776a.ini b/cd/test/fp0776a.ini new file mode 100644 index 000000000..b0e6013a7 --- /dev/null +++ b/cd/test/fp0776a.ini @@ -0,0 +1,19 @@ +[Main] +Demo=0 + +[fp1] +File(0) = sql/fp0/fp0106.sql|X +Patch = 0776 +Versione = 21511200 + +[fp] +Data = 29-04-2019 +Descrizione = Fattura Elettronica +Dischi = 1 +Moduli = cg,ve +OEM = +Patch = 776 +PostProcess = +PreProcess = +Versione = 21511200 + diff --git a/cd/test/fp0776a1.zip b/cd/test/fp0776a1.zip new file mode 100644 index 000000000..1c6ffb61d Binary files /dev/null and b/cd/test/fp0776a1.zip differ diff --git a/cd/test/fp0778.txt b/cd/test/fp0778.txt new file mode 100644 index 000000000..fc3419898 --- /dev/null +++ b/cd/test/fp0778.txt @@ -0,0 +1,3 @@ +fp0.exe + +Aggiunto ulteriore controllo sconto in testata per chi mette 0 \ No newline at end of file diff --git a/cd/test/fp0778a.ini b/cd/test/fp0778a.ini new file mode 100644 index 000000000..a67050419 --- /dev/null +++ b/cd/test/fp0778a.ini @@ -0,0 +1,19 @@ +[Main] +Demo=0 + +[fp1] +File(1) = fp0.exe|X +Patch = 0778 +Versione = 21511200 + +[fp] +Data = 29-04-2019 +Descrizione = Fattura Elettronica +Dischi = 1 +Moduli = cg,ve +OEM = +Patch = 778 +PostProcess = +PreProcess = +Versione = 21511200 + diff --git a/cd/test/fp0778a1.zip b/cd/test/fp0778a1.zip new file mode 100644 index 000000000..f5462b423 Binary files /dev/null and b/cd/test/fp0778a1.zip differ diff --git a/cd/test/tf0764a1.zip b/cd/test/tf0764a1.zip index 7a5e189d9..cfe91e27f 100644 Binary files a/cd/test/tf0764a1.zip and b/cd/test/tf0764a1.zip differ diff --git a/cd/test/ve0772.txt b/cd/test/ve0772.txt new file mode 100644 index 000000000..b835423b0 --- /dev/null +++ b/cd/test/ve0772.txt @@ -0,0 +1,6 @@ +vetbatr.msk +vetbspp.msk +vetbprs.msk +vetbrss.msk + +- Sistemate maschere tabelle spese prestazioni risorse e attrezzature \ No newline at end of file diff --git a/cd/test/ve0772a.ini b/cd/test/ve0772a.ini new file mode 100644 index 000000000..36e8754dd --- /dev/null +++ b/cd/test/ve0772a.ini @@ -0,0 +1,132 @@ +[Main] +Demo=0 + +[ve1] +File(197) = vetbatr.msk|X +File(214) = vetbprs.msk|X +File(219) = vetbrss.msk|X +File(221) = vetbspp.msk|X +Patch = 772 +Versione = 21511200 + +[ve99] +Kill(0) = batbcld.msk|x +Kill(1) = bastspp.rep|x +Kill(2) = basttri.msk|x +Kill(3) = batbeld.msk|x +Kill(4) = ve7700a.msk|x +Kill(5) = batbspt.msk|x +Kill(6) = ve7300a.msk|x +Kill(7) = bastcra.rep|x +Kill(8) = batbfca.msk|x +Kill(9) = bastgcg.rep|x +Kill(10) = bastabe.rep|x +Kill(11) = batbpro.msk|x +Kill(12) = bastgca.msk|x +Kill(13) = ve7400a.msk|x +Kill(14) = batbtag.msk|x +Kill(15) = batbtri.msk|x +Kill(16) = baststd.msk|x +Kill(17) = baststd.rep|x +Kill(18) = batbrfc.msk|x +Kill(19) = ve7200a.msk|x +Kill(20) = batbmre.msk|x +Kill(21) = bastctr.msk|x +Kill(22) = batbcau.msk|x +Kill(23) = ve7400a.ini|x +Kill(24) = basteld.rep|x +Kill(25) = batbrfa.msk|x +Kill(26) = bastcaa.rep|x +Kill(27) = ve7701a.ini|x +Kill(28) = bastfrd.rep|x +Kill(29) = batbgcg.msk|x +Kill(30) = bastums.rep|x +Kill(31) = bastgca.rep|x +Kill(32) = basttri.rep|x +Kill(33) = batbfrr.msk|x +Kill(34) = batbums.msk|x +Kill(35) = bastimb.rep|x +Kill(36) = bastfca.msk|x +Kill(37) = bastfrr.msk|x +Kill(38) = batbbnp.msk|x +Kill(39) = bastasf.msk|x +Kill(40) = bastnum.msk|x +Kill(41) = bastfca.rep|x +Kill(42) = ve7400conf.ini|x +Kill(43) = ve7500a.msk|x +Kill(44) = bastgmc.msk|x +Kill(45) = bastfrm.rep|x +Kill(46) = batbfsa.msk|x +Kill(47) = basttip.rep|x +Kill(48) = batbstd.msk|x +Kill(49) = bastcau.msk|x +Kill(50) = bastrfa.msk|x +Kill(51) = bastnum.rep|x +Kill(52) = bastubi.msk|x +Kill(53) = ve7600a.msk|x +Kill(54) = ve7100a.msk|x +Kill(55) = batbprs.msk|x +Kill(56) = batbspp.msk|x +Kill(57) = batbcaa.msk|x +Kill(58) = bastrfc.msk|x +Kill(59) = bastimb.msk|x +Kill(60) = bastums.msk|x +Kill(61) = batbctr.msk|x +Kill(62) = batbfid.msk|x +Kill(63) = bastspp.msk|x +Kill(64) = batbubi.msk|x +Kill(65) = bastctr.rep|x +Kill(66) = bastubi.rep|x +Kill(67) = basttag.msk|x +Kill(68) = bastcaa.msk|x +Kill(69) = bastfrr.rep|x +Kill(70) = bastcau.rep|x +Kill(71) = batbtip.msk|x +Kill(72) = basteld.msk|x +Kill(73) = bastgcg.msk|x +Kill(74) = ve7200a.frm|x +Kill(75) = bastprs.rep|x +Kill(76) = bastbnp.msk|x +Kill(77) = batbgsa.msk|x +Kill(78) = batbasf.msk|x +Kill(79) = efstbnp.rep|x +Kill(80) = eftbbnp.msk|x +Kill(81) = basttag.rep|x +Kill(82) = batbgca.msk|x +Kill(83) = ve7.exe|x +Kill(84) = ve7300a.frm|x +Kill(85) = batbfrm.msk|x +Kill(86) = bastrfc.rep|x +Kill(87) = batbnum.msk|x +Kill(88) = bastcra.msk|x +Kill(89) = bastfrd.msk|x +Kill(90) = bastprs.msk|x +Kill(91) = batbcra.msk|x +Kill(92) = bastasf.rep|x +Kill(93) = bastabe.msk|x +Kill(94) = batbgmc.msk|x +Kill(95) = bastbnp.rep|x +Kill(96) = efstbnp.msk|x +Kill(97) = batbabe.msk|x +Kill(98) = batbacr.msk|x +Kill(99) = batbimb.msk|x +Kill(100) = batbfrd.msk|x +Kill(101) = batbprv.msk|x +Kill(102) = bastgmc.rep|x +Kill(103) = bastfrm.msk|x +Kill(104) = basttip.msk|x +Kill(105) = bastrfa.rep|x + +[ve] +Data = 16-04-2019 +Descrizione = Vendite +Dischi = 1 +Moduli = ba,cg9,pr9,mg9,sv9,in9,ef9 +OEM = +Patch = 772 +PostProcess = bainst -0 VE +PreProcess = +Prezzo(1) = +Prezzo(2) = +Versione = 21511200 + diff --git a/cd/test/ve0772a1.zip b/cd/test/ve0772a1.zip new file mode 100644 index 000000000..3aa04c713 Binary files /dev/null and b/cd/test/ve0772a1.zip differ diff --git a/cd/test/ve0774.txt b/cd/test/ve0774.txt new file mode 100644 index 000000000..e1b90d16b --- /dev/null +++ b/cd/test/ve0774.txt @@ -0,0 +1,5 @@ +ve0.exe +ve1.exe +vetbtip.msk + +Aggiunto flag sui tipi documento per non esporre la dicitura stampa non valida ai fini fiscali per Fatturazione Elettronica diff --git a/cd/test/ve0774a.ini b/cd/test/ve0774a.ini new file mode 100644 index 000000000..b890e19be --- /dev/null +++ b/cd/test/ve0774a.ini @@ -0,0 +1,131 @@ +[Main] +Demo=0 + +[ve1] +File(0) = ve0.exe|X +File(19) = ve1.exe|X +File(225) = vetbtip.msk|X +Patch = 0774 +Versione = 21511200 + +[ve99] +Kill(0) = batbimb.msk|x +Kill(1) = batbacr.msk|x +Kill(2) = bastfrd.msk|x +Kill(3) = bastbnp.rep|x +Kill(4) = bastcra.msk|x +Kill(5) = batbgmc.msk|x +Kill(6) = batbabe.msk|x +Kill(7) = efstbnp.msk|x +Kill(8) = batbfrm.msk|x +Kill(9) = batbcra.msk|x +Kill(10) = ve7300a.frm|x +Kill(11) = bastprs.msk|x +Kill(12) = batbnum.msk|x +Kill(13) = bastabe.msk|x +Kill(14) = bastrfc.rep|x +Kill(15) = bastasf.rep|x +Kill(16) = basttag.rep|x +Kill(17) = eftbbnp.msk|x +Kill(18) = ve7.exe|x +Kill(19) = batbgca.msk|x +Kill(20) = ve7200a.msk|x +Kill(21) = batbrfa.msk|x +Kill(22) = bastgca.rep|x +Kill(23) = batbrfc.msk|x +Kill(24) = basteld.rep|x +Kill(25) = bastums.rep|x +Kill(26) = ve7701a.ini|x +Kill(27) = batbfrr.msk|x +Kill(28) = bastcaa.rep|x +Kill(29) = basttri.rep|x +Kill(30) = batbtri.msk|x +Kill(31) = bastctr.msk|x +Kill(32) = batbtag.msk|x +Kill(33) = batbmre.msk|x +Kill(34) = baststd.rep|x +Kill(35) = ve7400a.ini|x +Kill(36) = baststd.msk|x +Kill(37) = batbcau.msk|x +Kill(38) = batbpro.msk|x +Kill(39) = bastabe.rep|x +Kill(40) = ve7400a.msk|x +Kill(41) = bastgca.msk|x +Kill(42) = bastimb.msk|x +Kill(43) = bastctr.rep|x +Kill(44) = batbtip.msk|x +Kill(45) = bastrfc.msk|x +Kill(46) = batbubi.msk|x +Kill(47) = bastcau.rep|x +Kill(48) = basttag.msk|x +Kill(49) = bastgcg.msk|x +Kill(50) = bastubi.rep|x +Kill(51) = basteld.msk|x +Kill(52) = bastcau.msk|x +Kill(53) = batbprs.msk|x +Kill(54) = batbctr.msk|x +Kill(55) = batbstd.msk|x +Kill(56) = ve7100a.msk|x +Kill(57) = bastums.msk|x +Kill(58) = batbcaa.msk|x +Kill(59) = bastspp.msk|x +Kill(60) = batbspp.msk|x +Kill(61) = batbfid.msk|x +Kill(62) = bastasf.msk|x +Kill(63) = bastfrm.rep|x +Kill(64) = bastnum.rep|x +Kill(65) = batbbnp.msk|x +Kill(66) = bastgmc.msk|x +Kill(67) = bastrfa.msk|x +Kill(68) = basttip.rep|x +Kill(69) = ve7600a.msk|x +Kill(70) = batbfsa.msk|x +Kill(71) = bastubi.msk|x +Kill(72) = batbgcg.msk|x +Kill(73) = bastimb.rep|x +Kill(74) = bastfca.rep|x +Kill(75) = bastfrd.rep|x +Kill(76) = batbums.msk|x +Kill(77) = bastnum.msk|x +Kill(78) = bastfrr.msk|x +Kill(79) = ve7500a.msk|x +Kill(80) = bastfca.msk|x +Kill(81) = ve7400conf.ini|x +Kill(82) = efstbnp.rep|x +Kill(83) = batbasf.msk|x +Kill(84) = bastfrr.rep|x +Kill(85) = bastprs.rep|x +Kill(86) = bastcaa.msk|x +Kill(87) = ve7200a.frm|x +Kill(88) = batbgsa.msk|x +Kill(89) = bastbnp.msk|x +Kill(90) = bastrfa.rep|x +Kill(91) = basttip.msk|x +Kill(92) = batbprv.msk|x +Kill(93) = batbfrd.msk|x +Kill(94) = bastfrm.msk|x +Kill(95) = bastgmc.rep|x +Kill(96) = bastgcg.rep|x +Kill(97) = batbfca.msk|x +Kill(98) = bastspp.rep|x +Kill(99) = batbcld.msk|x +Kill(100) = batbspt.msk|x +Kill(101) = ve7700a.msk|x +Kill(102) = batbeld.msk|x +Kill(103) = basttri.msk|x +Kill(104) = bastcra.rep|x +Kill(105) = ve7300a.msk|x + +[ve] +Data = 16-04-2019 +Descrizione = Vendite +Dischi = 1 +Moduli = ba,cg9,pr9,mg9,sv9,in9,ef9 +OEM = +Patch = 774 +PostProcess = bainst -0 VE +PreProcess = +Prezzo(1) = +Prezzo(2) = +Versione = 21511200 + diff --git a/cd/test/ve0774a1.zip b/cd/test/ve0774a1.zip new file mode 100644 index 000000000..76b6087d3 Binary files /dev/null and b/cd/test/ve0774a1.zip differ diff --git a/src/ba/ba2900.cpp b/src/ba/ba2900.cpp index 52239e77f..faffa4b7b 100644 --- a/src/ba/ba2900.cpp +++ b/src/ba/ba2900.cpp @@ -8,9 +8,33 @@ #include #include "ba2900.h" +#include +//#include "tsdb.h" +#include "codeb.h" +#include "reputils.h" #define TABELLE_CAMPO 171 +void check_range_tab(TMask& msk) +{ + if (msk.get_int(F_FROMTAB) == 7466) + { + msk.show(F_MYRANGE); + msk.set(F_FROMTAB, 2); + } + else + { + if (msk.get_int(F_FROMTAB) < 2) + msk.set(F_FROMTAB, 2); + if (msk.get_int(F_FROMTAB) > prefix().items()) + msk.set(F_FROMTAB, prefix().items()); + if (msk.get_int(F_TOTAB) < msk.get_int(F_FROMTAB)) + msk.set(F_TOTAB, msk.get_int(F_FROMTAB)); + if (msk.get_int(F_TOTAB) > prefix().items()) + msk.set(F_TOTAB, prefix().items()); + } +} + class TMSSQLExport_msk : public TAutomask { protected: @@ -18,6 +42,7 @@ protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TMSSQLExport_msk(); + ~TMSSQLExport_msk(); }; long TMSSQLExport_msk::handler(WINDOW task, EVENT* ep) @@ -40,7 +65,21 @@ bool TMSSQLExport_msk::on_field_event(TOperable_field& o, TField_event e, long j if (e == se_query_add || e == se_query_del) return false; */ + case CHK_ONLYTAB: + if (e == fe_modify) + { + get_bool(CHK_ONLYTAB) ? enable(F_FROMTAB) : disable(F_FROMTAB); + get_bool(CHK_ONLYTAB) ? enable(F_TOTAB) : disable(F_TOTAB); + } + break; + case CHK_EXPORTTABLES: + if (e == fe_modify) + { + get_bool(CHK_EXPORTTABLES) ? enable(CHK_ONLYTAB) : disable(CHK_ONLYTAB); + break; + } default: + check_range_tab(*this); break; } return true; @@ -51,38 +90,66 @@ TMSSQLExport_msk::TMSSQLExport_msk() : TAutomask("ba2900a") set(F_DSN, ini_get_string(CONFIG_DITTA, "Campo_MSSQL_Export", "DSN")); set(F_USR, ini_get_string(CONFIG_DITTA, "Campo_MSSQL_Export", "User")); set(F_PWD, ini_get_string(CONFIG_DITTA, "Campo_MSSQL_Export", "Password")); - set(CHK_CREATEGEN, "X"); + //set(CHK_CREATEGEN, "X"); set(CHK_CREATETABLES, "X"); - set(CHK_EXPORTGEN, "X"); + //set(CHK_EXPORTGEN, "X"); set(CHK_EXPORTTABLES, "X"); + set(F_FROMTAB, 2); + set(F_TOTAB, prefix().items()); +} + +TMSSQLExport_msk::~TMSSQLExport_msk() +{ + ini_set_string(CONFIG_DITTA, "Campo_MSSQL_Export", "DSN", TMask::get(F_DSN)); + ini_set_string(CONFIG_DITTA, "Campo_MSSQL_Export", "User", TMask::get(F_USR)); + ini_set_string(CONFIG_DITTA, "Campo_MSSQL_Export", "Password", TMask::get(F_PWD)); } class TMSSQLExport_app : public TSkeleton_application { protected: - TToken_string tables; - TString DSN, usr, psw; + TToken_string _tables; + TString _DSN, _usr, _psw; + SSimple_query* _db; + TMSSQLExport_msk* _msk; + TLog_report* _log; + TString _logstr; + + bool _visual; const TString toEscape (TString val) const; // Prende una stringa e sistema i caratteri di escape const TString toDate (TString val) const; // Prende una stringa e la trasforma in una data di mssql const TString queryToNull (TString val) const; // Da una query sostituisce tutti i valori vuoti ('') con null //***************************************************************** - bool emptyTables() const; - bool exportGen() const; - bool exportTables() const; - bool createGen() const; - bool createTables() const; - bool createIndexes() const; + bool empty_tables() const; + bool rko_gen() const; + bool expor_gen() const; + bool file_valid(int logicnum) const; + int export_tables(); + bool create_gen() const; + static TString tab_name(int logicnum, TString& ditta_name); + void set_range_tab(int& logicnum, int& endtab) const; + bool create_tables() const; + bool create_indexes() const; + bool rko_outta_nowhere(const char* table_name) const; + bool empty_tables(const char* table_name) const; // Funzioni di esportazione bool dir_gen() const; bool trc_gen() const; - bool exportManager(const TString generalErrors) const; + bool export_manager(const TString generalErrors) const; + bool show_log(); + void log(int severity, const char* msg); public: + bool my_range(); virtual void main_loop(); - void setTable(TToken_string s) { tables = s; } - bool setParameters(TString dsn, TString utente, TString password); - bool checkParameters(const TString& DSN, const TString& usr, const TString& psw) { TODBC_recordset connTest(""); return connTest.connect(DSN, usr, psw) ? setParameters(DSN, usr, psw) : false; } - bool testFieldSeq(int val, int arr[]) const; + void set_table(TToken_string s) { _tables = s; } + bool set_parameters(TString dsn, TString utente, TString password); + bool connect(const TString& _DSN, const TString& _usr, const TString& _psw); + //bool checkParameters() { TODBC_recordset connTest(""); return connTest.connect(_DSN, _usr, _psw) ? set_parameters(_DSN, _usr, _psw) : false; } + bool test_field_seq(int val, int arr[]) const; + bool create_gen_ms() const; + TMSSQLExport_app() : _visual(false) { } + ~TMSSQLExport_app() { delete _db; } }; // Funzioni Utility **************************************************************************************************************************** @@ -137,31 +204,31 @@ const TString TMSSQLExport_app::toDate(TString val) const } -bool TMSSQLExport_app::setParameters(TString dsn, TString utente, TString password) +bool TMSSQLExport_app::set_parameters(TString dsn, TString utente, TString password) { // Salvo i parametri - ini_set_string(CONFIG_DITTA, "Campo_MSSQL_Export", "DSN", dsn); + ini_set_string(CONFIG_DITTA, "Campo_MSSQL_Export", "_DSN", dsn); ini_set_string(CONFIG_DITTA, "Campo_MSSQL_Export", "User", utente); ini_set_string(CONFIG_DITTA, "Campo_MSSQL_Export", "Password", password); - DSN = dsn; - usr = utente; - psw = password; + _DSN = dsn; + _usr = utente; + _psw = password; return true; } -bool TMSSQLExport_app::emptyTables() const +bool TMSSQLExport_app::empty_tables() const { TODBC_recordset sqlset(""); TString table; - if (!sqlset.connect(DSN, usr, psw)) + if (!sqlset.connect(_DSN, _usr, _psw)) return false; - for (int i = 0; i < tables.size(); i++) + for (int i = 0; i < _tables.size(); i++) { TString theQuery; // The query: una tabella (donna) per cui uccidere - tables.get(i, table); + _tables.get(i, table); theQuery << "DELETE FROM "<< table << ";"; sqlset.exec(theQuery); } @@ -170,8 +237,34 @@ bool TMSSQLExport_app::emptyTables() const return true; } +bool TMSSQLExport_app::rko_gen() const +{ + TString query; + query << + "DROP TABLE [dir_gen];"; + if (!_db->sq_set_exec(query)) + return false; + + query.cut(0) << + "DROP TABLE [trc_gen];"; + if (!_db->sq_set_exec(query)) + return false; + + query.cut(0) << + "DROP TABLE [trc_keydes];"; + if (!_db->sq_set_exec(query)) + return false; + + query.cut(0) << + "DROP TABLE [trc_recfdes];"; + if (!_db->sq_set_exec(query)) + return false; + + return _db->sq_commit(); +} + // Controllo che il valore passato sia > e diverso da quelli presenti nell'array -bool TMSSQLExport_app::testFieldSeq(int val, int arr[]) const +bool TMSSQLExport_app::test_field_seq(int val, int arr[]) const { for (int i = 0; i < MKFields; i++) if(val == arr[i] || val < arr[i]) return false; @@ -179,12 +272,80 @@ bool TMSSQLExport_app::testFieldSeq(int val, int arr[]) const } // Main Program ***************************************************************************************************************************************************************** -bool TMSSQLExport_app::createGen() const +bool TMSSQLExport_app::create_gen_ms() const { - TODBC_recordset sqlset(""); - // Controllo la connessione di nuovo per essere scrupolosi - if (!sqlset.connect(DSN, usr, psw)) + + rko_gen(); + TString query; + query << + "IF OBJECT_ID('dbo.dir_gen', 'U') IS NOT NULL DROP TABLE dbo.dir_gen;\n" << + "CREATE TABLE[dbo].[dir_gen](\n" << + "[_ID_][int] IDENTITY(1, 1) NOT NULL,\n" << + "[NUMERO][int] NOT NULL,\n" << + "[SYSNAME] VARCHAR(MAX) NOT NULL,\n" << + "[EOD][int] NULL,\n" << + "[EOX][int] NULL,\n" << + "[FLAGS][int] NULL,\n" << + "[LENR][int] NULL,\n" << + "[DES] VARCHAR(MAX) NULL,\n" << + "[CALC] VARCHAR(MAX) NULL,\n" << + "[GENPROMPT] VARCHAR(MAX) NULL,\n" << + "PRIMARY KEY CLUSTERED\n" << + "([_ID_] ASC) WITH\n" << + "(PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON[PRIMARY]\n" << + ") ON[PRIMARY] TEXTIMAGE_ON[PRIMARY];"; + + if (!_db->sq_set_exec(query)) return false; + + query.cut(0) << + "IF OBJECT_ID('dbo.trc_gen', 'U') IS NOT NULL DROP TABLE dbo.trc_gen;\n" << + "CREATE TABLE[dbo].[trc_gen](\n" << + "[_ID_][int] IDENTITY(1, 1) NOT NULL,\n" << + "[NFields][int] NOT NULL,\n" << + "[SortFd] VARCHAR(MAX) NULL,\n" << + "[NKeys][int] NOT NULL,\n" << + "[logicname][int] NOT NULL\n" << + ") ON[PRIMARY] TEXTIMAGE_ON[PRIMARY];"; + + if (!_db->sq_set_exec(query)) + return false; + + query.cut(0) << + "IF OBJECT_ID('dbo.trc_keydes', 'U') IS NOT NULL DROP TABLE dbo.trc_keydes;\n" << + "CREATE TABLE[dbo].[trc_keydes](\n" << + "[_ID_][int] IDENTITY(1, 1) NOT NULL,\n" << + "[DupKeys][int] NOT NULL,\n" << + "[NkFields][int] NOT NULL,\n" << + "[FieldSeq] VARCHAR(MAX) NULL,\n" << + "[FromCh] VARCHAR(MAX) NULL,\n" << + "[ToCh] VARCHAR(MAX) NULL,\n" << + "[logicname][int] NOT NULL\n" << + ") ON[PRIMARY] TEXTIMAGE_ON[PRIMARY];"; + + if (!_db->sq_set_exec(query)) + return false; + + query.cut(0) << + "IF OBJECT_ID('dbo.trc_recfdes', 'U') IS NOT NULL DROP TABLE dbo.trc_recfdes;\n" << + "CREATE TABLE[dbo].[trc_recfdes](\n" << + "[_ID_][int] IDENTITY(1, 1) NOT NULL,\n" << + "[Name] VARCHAR(MAX) NOT NULL,\n" << + "[TypeF][int] NOT NULL,\n" << + "[Len][int] NULL,\n" << + "[Dec][int] NULL,\n" << + "[RecOff][int] NULL,\n" << + "[logicname][int] NOT NULL\n" << + ") ON[PRIMARY] TEXTIMAGE_ON[PRIMARY];"; + + if (!_db->sq_set_exec(query)) + return false; + + return _db->sq_commit(); + +} +bool TMSSQLExport_app::create_gen() const +{ ifstream queryFile; // stream dei files con le query // Prima le tabelle gen @@ -200,7 +361,7 @@ bool TMSSQLExport_app::createGen() const gensql << aganaye; } queryFile.close(); - if(sqlset.exec(gensql) != 1) // EXEC + if(!_db->sq_exec(gensql)) // EXEC return false; } else @@ -211,94 +372,107 @@ bool TMSSQLExport_app::createGen() const } // Committo la creazione iniziale delle tabelle custom fondamentali per il passaggio a DB di Campo - return sqlset.commit() != -1; + return _db->sq_commit(); } -bool TMSSQLExport_app::createTables() const + +TString TMSSQLExport_app::tab_name(int logicnum, TString& ditta_name) { - TODBC_recordset sqlset(""); - // Controllo la connessione di nuovo per essere scrupolosi - if (!sqlset.connect(DSN, usr, psw)) - return false; - ifstream queryFile; // stream dei files con le query - - // Le tabelle comuni - TFilename studio("sql\\studiosql.sql"); - queryFile.open(studio); - if(queryFile.is_open()) + const TString& table = logic2table(logicnum); + const bool studio_tab = TDir(logicnum).is_com(); + return TString("[") << (!studio_tab ? ditta_name : "") << table << "]"; +} + +void TMSSQLExport_app::set_range_tab(int& logicnum, int& endtab) const +{ + logicnum = 2; + endtab = prefix().items(); + if (_msk->get_bool(CHK_ONLYTAB)) { - TString studiosql; // Qua metterò le query - while(!queryFile.eof()) - { - char aganaye[10000]; - queryFile.getline(aganaye, 10000); // Sei stronzo se fai una riga con più di 10.000 caratteri - studiosql << aganaye; - } - queryFile.close(); - if(sqlset.exec(studiosql) != 1) // EXEC - return false; + check_range_tab(*_msk); + logicnum = _msk->get_int(F_FROMTAB); + endtab = _msk->get_int(F_TOTAB); + endtab++; } - else +} + +bool TMSSQLExport_app::connect(const TString& _DSN, const TString& _usr, const TString& _psw) +{ + if (_db == nullptr) + _db = new SSimple_query(); + bool connected = _db->sq_is_connect(); + if (!connected) { - TString msg("Errore apertura file "); msg << studio; - message_box(msg); - return false; + _db->sq_set_con_option("UseAPI", "OLEDB"); + connected = _db->sq_connect(_DSN, _usr, _psw, TSDB_MSSQL) == NOERR; } + return connected; +} - /************************************************************************************************ - * Le tabelle di ditta, caso particolare: * - * In questi file è presente una sequenza di escape (%%%%%) che andrà sostituita con la ditta, * - * quindi prima leggo tutto e poi sostituisco * - ************************************************************************************************/ - TFilename ditta("sql\\dittesql.sql"); - TString appsql; - queryFile.open(ditta); +bool TMSSQLExport_app::create_tables() const +{ + bool ok = true; + TString ditta_name; ditta_name << prefix().name() << "_"; + TString last_col_name = " "; - // Creo il cursore delle ditte - TRelation relTDitte(LF_NDITTE); - TCursor curDitte(&relTDitte); - int itemsDitte = curDitte.items(); + int logicnum; + int endtab; + set_range_tab(logicnum, endtab); - if(queryFile.is_open()) + for(; logicnum < endtab && ok; logicnum++) { - while(!queryFile.eof()) + last_col_name = " "; + const RecDes& rd = prefix().get_recdes(logicnum); + TString table_name = tab_name(logicnum, ditta_name); + TString column_name; + bool last_err = false; + // Droppo la tabella prima di crearla + rko_outta_nowhere(table_name); + // Create new table + if (rd.NFields == 0) + continue; + TString sql; sql.cut(0) << "CREATE TABLE " << table_name << "(\n"; + sql << "[_ID_][int] IDENTITY(1, 1) NOT NULL,\n"; + for (int i = 0; i < rd.NFields; i++) { - char aganaye[10000]; - queryFile.getline(aganaye, 10000); // Sei stronzo se fai una riga con più di 10.000 caratteri - appsql << aganaye; - } - for(curDitte = 0; curDitte.pos() < curDitte.items(); ++curDitte) - { - TRectype dittaCurr = curDitte.curr(); - TString nomeDitta(dittaCurr.get("CODDITTA")); - for (int i = 0, applen = nomeDitta.len(); i < 5 - applen; i++) - nomeDitta.insert("0"); - // Non esiste nulla che rimpiazzi tutte occorrenze (stringhe) in una TString, quindi mi faccio io l'algoritmo - TString queryFirm(appsql); - int lastpos = queryFirm.find("%%%%%", 0); - while(lastpos != -1) + + if (i > 0 && !last_err) sql << ",\n"; + column_name.cut(0) << "[" << rd.Fd[i].Name << "] "; + if (column_name == last_col_name) { - // Siccome so che ci sono 5 caratteri faccio che farlo a mano da vero gangster - queryFirm[lastpos] = nomeDitta[0]; - queryFirm[lastpos + 1] = nomeDitta[1]; - queryFirm[lastpos + 2] = nomeDitta[2]; - queryFirm[lastpos + 3] = nomeDitta[3]; - queryFirm[lastpos + 4] = nomeDitta[4]; - lastpos = queryFirm.find("%%%%%", lastpos); // find(x, lastpos) si velocizza partendo già dalla ultima posizione trovata - } - if(sqlset.exec(queryFirm) != 1) // EXEC - return false; + last_err = true; + continue; + } + last_err = false; + last_col_name = column_name; + sql << column_name; + switch (rd.Fd[i].TypeF) + { + case _charfld: + case _alfafld: + sql << "VARCHAR(" << rd.Fd[i].Len << ")"; + break; + case _memofld: + sql << "VARCHAR(MAX)"; break; + case _datefld: + sql << "DATE"; break; + case _boolfld: + sql << "BIT DEFAULT 0"; break; + case _realfld: + case _wordfld: + case _intfld: + case _longfld: + case _intzerofld: + case _longzerofld: + default: sql << "NUMERIC(" << rd.Fd[i].Len << "," << rd.Fd[i].Dec << ")"; break; + } } - queryFile.close(); + sql << "\n);"; + + ok = _db->sq_set_exec(sql) && _db->sq_commit(); + TString err = _db->sq_get_string_error(); + TString err2 = _db->sq_get_text_error(); } - else - { - TString msg("Errore apertura file "); msg << ditta; - message_box(msg); - return false; - } - - // Committo la creazione iniziale delle tabelle custom fondamentali per il passaggio a DB di Campo - return sqlset.commit() != -1 && createIndexes(); + return ok; } /* @@ -306,10 +480,10 @@ bool TMSSQLExport_app::createTables() const * Sintassi: CREATE NONCLUSTERED INDEX nome_indice ON nome_tabella (colonna1 [ASC | DESC], colonna2 [ASC | DESC][,...n]) * */ -bool TMSSQLExport_app::createIndexes() const +bool TMSSQLExport_app::create_indexes() const { TODBC_recordset sqlset(""); - if (!sqlset.connect(DSN, usr, psw)) + if (!sqlset.connect(_DSN, _usr, _psw)) return "Connessione fallita!"; int items = TABELLE_CAMPO; // Numero totale di tabelle COpenDir((int)_manulock, NORDIR); // Apro dir.gen @@ -392,42 +566,191 @@ bool TMSSQLExport_app::createIndexes() const return true; } -bool TMSSQLExport_app::exportGen() const +bool TMSSQLExport_app::rko_outta_nowhere(const char* table_name) const { - return dir_gen() && trc_gen(); + _db->sq_set_exec(TString().cut(0) << "DROP TABLE " << table_name << ';'); + return _db->sq_commit(); } -bool TMSSQLExport_app::exportTables() const +bool TMSSQLExport_app::empty_tables(const char* table_name) const +{ + const bool ok = _db->sq_set_exec(TString().cut(0) << "DELETE FROM " << table_name << ';'); + return ok && _db->sq_commit(); +} + +bool TMSSQLExport_app::expor_gen() const +{ + return rko_gen() && create_gen_ms() && dir_gen() && trc_gen(); +} + +bool TMSSQLExport_app::file_valid(int logicnum) const +{ + TFilename filename; + const TIsam_handle isam_handle = prefix().open_isamfile(logicnum, filename, false, true); + const TCodeb_handle fhnd = isam_handle > 0 ? prefix().get_handle(isam_handle, 1) : isam_handle; + const int trcreclen = prefix().get_reclen(logicnum); + const int dbfreclen = DB_reclen(fhnd); + return dbfreclen == trcreclen; +} + +const TString to_escape(const TString& val) +{ + TString& app = get_tmp_string(); + for (int k = 0; k < val.len(); k++) + { + switch (val[k]) + { + case '\'': + app << "''"; + break; + default: + app << val[k]; + break; + } + } + return app; +} + +const TString query_to_null(TString& val) +{ + int lastpos = val.find("(\'\'", 0); // Devo trovarne uno tra virgole + while (lastpos != -1) + { + lastpos++; + val[lastpos] = ' '; + val[lastpos + 1] = ' '; + val.insert("NULL", lastpos); + lastpos = val.find(",\'\'", lastpos); + } + lastpos = val.find(",\'\'", 0); // Devo trovarne uno tra virgole + while (lastpos != -1) + { + lastpos++; + val[lastpos] = ' '; + val[lastpos + 1] = ' '; + val.insert("NULL", lastpos); + lastpos = val.find(",\'\'", lastpos); + } + + return val; +} + +int TMSSQLExport_app::export_tables() { // Innanzitutto svuoto le tabelle - if(!emptyTables()) return false; - TODBC_recordset sqlset(""); - if (!sqlset.connect(DSN, usr, psw)) - return "Connessione fallita!"; - try + bool check = true; + TString ditta_name; ditta_name << prefix().name() << "_"; + + int logicnum; + int endtab; + set_range_tab(logicnum, endtab); + int last_tab_err = -1; + + for (; logicnum < endtab && check; logicnum++) { - bool wat = false; - // Inizio con dir.gen - TString generalErrors; - exportManager(generalErrors); + empty_tables(logic2table(logicnum)); + TString nome_tab = tab_name(logicnum, ditta_name); + const RecDes& rd = prefix().get_recdes(logicnum); + if (prefix().get_recdes(logicnum).NKeys <= 0) + { + log(2, TString("Il file ") << logicnum << " non esiste"); + continue; + } + TLocalisamfile table(logicnum); + if(!file_valid(logicnum)) + { + log(2, TString("Impossibile esportare il file ") << logicnum << ". Lunghezza record incoerente."); + continue; + } + + TString queryF, queryV; + TProgress_monitor p(table.items(), TString("Esportazione tabella ") << logic2table(logicnum)); + bool export_status = true; + bool ok = table.first() == NOERR; + for (; ok && export_status; ok = table.next() == NOERR) + { + if (_visual && !p.add_status()) + return logicnum; + queryF.cut(0) << "INSERT INTO " << nome_tab << " ("; + queryV.cut(0) << "("; + for (int k = 0; k < rd.NFields; k++) + { + queryF << "[" << rd.Fd[k].Name << "]"; + if (table.get(rd.Fd[k].Name).empty()) // Vuoto, causa errori se non controllato + queryV << "''"; + else + { + switch (rd.Fd[k].TypeF) + { + case _intfld: + case _wordfld: + case _intzerofld: + queryV << "'" << table.get_int(rd.Fd[k].Name) << "'"; + break; + + case _longfld: + case _longzerofld: + queryV << "'" << table.get_long(rd.Fd[k].Name) << "'"; + break; + + // Real + case _realfld: + queryV << "'" << table.get_real(rd.Fd[k].Name).string() << "'"; + break; + + case _datefld: + queryV << "'" << table.get_date(rd.Fd[k].Name).date2ansi() << "'"; + break; + + case _boolfld: + if (table.get_bool(rd.Fd[k].Name)) + queryV << "'1'"; + else + queryV << "'0'"; + break; + + case _charfld: + case _alfafld: + default: + queryV << "'" << to_escape(table.get(rd.Fd[k].Name)) << "'"; + break; + } + } + + if (k + 1 < rd.NFields) // Modo più comodo + { + queryF << ","; + queryV << ","; + } + } + + + queryV << ")"; + queryF << ") VALUES " << queryV; + //export_status &= _db->sq_set_exec(query_to_null(queryF)); + if(!_db->sq_set_exec(query_to_null(queryF), false)) + { + if (last_tab_err != logicnum) + { + log(2, TString("Errore esportazione tabella ") << logicnum << "\n\tQuery:" << queryF); + last_tab_err = logicnum; + } + else + log(2, TString("\tQuery: ") << queryF); + log(2, _db->sq_get_string_error()); + log(2, _db->sq_get_text_error()); + } + } + check = export_status && _db->sq_commit(); } - catch (TString orrore) - { - message_box(orrore); - return false; - } - return true; + return check ? 0 : -1; } bool TMSSQLExport_app::dir_gen() const { - TODBC_recordset sqlset("", true); - // Controllo la connessione - if (!sqlset.connect(DSN, usr, psw)) - return false; - int items = TABELLE_CAMPO; // Numero totale di tabelle - TString msg("Esportazione elenco directory"); + const int items = prefix().items()-1; // Numero totale di tabelle + const TString msg("Esportazione elenco directory"); COpenDir((int)_manulock, NORDIR); // Apro dir.gen TProgress_monitor p(items, msg); for (int i = 1; i <= items && !p.is_cancelled(); i++) @@ -438,30 +761,26 @@ bool TMSSQLExport_app::dir_gen() const CGetFile(i, &d, _nolock, NORDIR); TString sqlQuery; sqlQuery - << "INSERT INTO DIR_GEN (NUMERO,SYSNAME,EOD,EOX,FLAGS,LENR,DES,CALC,GENPROMPT) VALUES ('" + << "INSERT INTO DIR_GEN (NUMERO,SYSNAME,EOD,EOX,LENR,FLAGS,DES,CALC,GENPROMPT) VALUES ('" << i << "','" << d.SysName << "','" << d.EOD << "','" << d.EOX << "','" - << d.Flags << "','" << d.LenR << "','" + << d.Flags << "','" << toEscape(d.Des) << "','" << toEscape(d.FCalc) << "','" << toEscape(d.GenPrompt) << "')"; - if(sqlset.exec(queryToNull(sqlQuery)) != 1) + if(!_db->sq_set_exec(queryToNull(sqlQuery), false)) return false; } - return sqlset.commit() == -1 ? false : true; + return _db->sq_commit(); } bool TMSSQLExport_app::trc_gen() const { - TODBC_recordset sqlset("", true); - // Controllo la connessione - if (!sqlset.connect(DSN, usr, psw)) - return false; - int items = TABELLE_CAMPO; // Numero totale di tabelle - TString msg("Esportazione tracciati record"); + const int items = prefix().items()-1; // Numero totale di tabelle + const TString msg("Esportazione tracciati record"); COpenDir((int)_manulock, NORDIR); // Apro dir.gen TProgress_monitor p(items-1, msg); for (int i = 2; i <= items && !p.is_cancelled(); i++) @@ -487,7 +806,7 @@ bool TMSSQLExport_app::trc_gen() const << SortFd << "','" << d.NKeys << "','" << i << "')"; - if(sqlset.exec(queryToNull(sqlQueryTrc)) != 1) + if(!_db->sq_set_exec(queryToNull(sqlQueryTrc), false)) return false; // Poi trc_recfdes @@ -496,15 +815,14 @@ bool TMSSQLExport_app::trc_gen() const RecFieldDes r = d.Fd[j]; TString sqlQueryRFD; sqlQueryRFD - << "INSERT INTO TRC_RECFDES (NumField, Name,TypeF,Len,Dec,RecOff,logicname) VALUES ('" - << j << "','" + << "INSERT INTO TRC_RECFDES (Name,TypeF,Len,Dec,RecOff,logicname) VALUES ('" << r.Name << "','" << (int)r.TypeF << "','" << r.Len << "','" << r.Dec << "','" << r.RecOff << "','" << i << "')"; - if(sqlset.exec(queryToNull(sqlQueryRFD)) != 1) + if(!_db->sq_set_exec(queryToNull(sqlQueryRFD), false)) return false; } @@ -540,18 +858,18 @@ bool TMSSQLExport_app::trc_gen() const << FromCh << "','" << ToCh << "','" << i << "')"; - if(sqlset.exec(queryToNull(sqlQueryKD)) != 1) + if(!_db->sq_set_exec(queryToNull(sqlQueryKD), false)) return false; } } - return sqlset.commit() == -1 ? false : true; + return _db->sq_commit(); } -bool TMSSQLExport_app::exportManager(TString generalErrors) const +bool TMSSQLExport_app::export_manager(TString generalErrors) const { TODBC_recordset sqlset("", true); // Controllo la connessione - if (!sqlset.connect(DSN, usr, psw)) + if (!sqlset.connect(_DSN, _usr, _psw)) return false; COpenDir((int)_manulock, NORDIR); // Apro dir.gen @@ -662,31 +980,116 @@ bool TMSSQLExport_app::exportManager(TString generalErrors) const return true; } +bool TMSSQLExport_app::show_log() +{ + if (_log) + { + _log->preview(); + delete _log; + _log = NULL; + } + return true; +} + +void TMSSQLExport_app::log(int severity, const char* msg) +{ + if (_log == nullptr) + { + _log = new TLog_report; + // Tento l'eliminazione del file + std::remove("ba_export.log"); + } + if (severity < 0) + { + _logstr = msg; + } + else + { + static TString txt; + txt.cut(0); + if (_logstr.full()) + { + txt << _logstr << ": " << msg; + } + else + txt << msg; + _log->log(severity, txt); + // Scrivo anche su file + std::filebuf fb; + fb.open("ba_export.log", std::ios::out | std::ios::app); + std::ostream os(&fb); + os << txt << std::endl; + fb.close(); + } +} + +bool TMSSQLExport_app::my_range() +{ + TString myrange(_msk->get(F_MYRANGE)); + if (myrange.empty()) + return false; + TToken_string range_tok(myrange, ','); + if(range_tok.items() > 0) + { + TToken_string one_range(range_tok.get(0), '-'); + _msk->set(F_FROMTAB, one_range.get(0)); + one_range.items() == 0 ? _msk->set(F_TOTAB, one_range.get(0)) : _msk->set(F_TOTAB, one_range.get(1)); + range_tok.destroy(0); + TString rewrite; + for(int i=0; i < range_tok.items(); i++) + { + if (i > 0) + rewrite << ","; + rewrite << range_tok.get(); + } + _msk->set(F_MYRANGE, rewrite); + } + return !TString(_msk->get(F_MYRANGE)).empty(); // se vuoto anche solo la prima volta interrompo il loop +} + void TMSSQLExport_app::main_loop() { - TMSSQLExport_msk m; - while (m.run() == K_ENTER) + TMSSQLExport_msk msk; + _msk = &msk; + + while (msk.run() == K_ENTER) { - const TString& DSN = m.get(F_DSN); - const TString& usr = m.get(F_USR); - const TString& psw = m.get(F_PWD); +#ifdef DBG + const TString& _DSN = "TESTCAMPO2012\\MSSQLSERVER2019@campo13"; + const TString& _usr = "campo"; + const TString& _psw = "campo"; +#else + const TString& _DSN = msk.get(F_DSN); + const TString& _usr = msk.get(F_USR); + const TString& _psw = msk.get(F_PWD); +#endif + _visual = true; // Chiamo la funzione globale esporta - if(checkParameters(DSN, usr, psw)) + if(connect(_DSN, _usr, _psw)) { - // Per comodità utilizzo gli AND short circuits, solo se i bool danno true eseguo la funzione dopo! - if(m.get_bool(CHK_CREATEGEN)) - if(!createGen()) - message_box("ERROR: Creazione tabelle gen fallita"); - if(m.get_bool(CHK_CREATETABLES)) - if(!createTables()) - message_box("ERROR: Creazione tabelle campo fallita"); - if(m.get_bool(CHK_EXPORTGEN)) - if (!exportGen()) - message_box("CERROR: Esportazione tabelle gen fallita"); - if(m.get_bool(CHK_EXPORTTABLES)) - if(!exportTables()) - message_box("ERROR: Esportazione tabelle campo fallita"); - message_box("Migrazione effettuata correttamente!"); + bool loop; + do + { + loop = my_range(); + // Per comodità utilizzo gli AND short circuits, solo se i bool danno true eseguo la funzione dopo! + if (msk.get_bool(CHK_CREATEGEN)) + if (!create_gen_ms()) + message_box("ERROR: Creazione tabelle gen fallita"); + if (msk.get_bool(CHK_CREATETABLES)) + if (!create_tables()) + message_box("ERROR: Creazione tabelle campo fallita"); + if (msk.get_bool(CHK_EXPORTGEN)) + if (!expor_gen()) + message_box("CERROR: Esportazione tabelle gen fallita"); + if (msk.get_bool(CHK_EXPORTTABLES)) + { + int err; + if ((err = export_tables())) + message_box(TString("ERROR: Esportazione tabelle campo fallita") << (err >= 2? TString(":\n Errorre tabella ") << err : "")); + } + message_box("Migrazione effettuata correttamente!"); + } while (loop); + show_log(); } else message_box("Fallita connessione"); @@ -698,7 +1101,7 @@ int ba2900(int argc, char* argv[]) { TMSSQLExport_app app; // Imposto le tabelle da utilizzare - app.setTable("TRC_GEN|TRC_KEYDES|TRC_RECFDES"); + app.set_table("TRC_GEN|TRC_KEYDES|TRC_RECFDES"); app.run(argc, argv, TR("Migrazione DB a MSSQL")); return 0; } diff --git a/src/ba/ba2900.h b/src/ba/ba2900.h index 50e8ba146..ff7625366 100644 --- a/src/ba/ba2900.h +++ b/src/ba/ba2900.h @@ -5,3 +5,8 @@ #define CHK_CREATETABLES 254 #define CHK_EXPORTGEN 255 #define CHK_EXPORTTABLES 256 + +#define CHK_ONLYTAB 257 +#define F_FROMTAB 258 +#define F_TOTAB 259 +#define F_MYRANGE 260 \ No newline at end of file diff --git a/src/ba/ba2900a.uml b/src/ba/ba2900a.uml index 9111466ee..782f4a825 100644 --- a/src/ba/ba2900a.uml +++ b/src/ba/ba2900a.uml @@ -10,7 +10,7 @@ PAGE "Trasferimento DB su MSSQL" 0 2 0 0 STRING F_DSN 260 50 BEGIN - PROMPT 1 0 "ODBC DSN " + PROMPT 1 1 "ODBC DSN " CHECKTYPE REQUIRED END @@ -30,6 +30,7 @@ END BOOLEAN CHK_CREATEGEN BEGIN PROMPT 1 5 "Elimina e ricrea tutte le tabelle gen, Attenzione! I dati presenti verranno eliminati!" + FLAGS "" END BOOLEAN CHK_CREATETABLES @@ -40,6 +41,7 @@ END BOOLEAN CHK_EXPORTGEN BEGIN PROMPT 1 7 "Esporta tabelle gen" + FLAGS "" END BOOLEAN CHK_EXPORTTABLES @@ -47,6 +49,29 @@ BEGIN PROMPT 1 8 "Esporta tabelle dati" END +BOOLEAN CHK_ONLYTAB +BEGIN + PROMPT 1 9 "Esporta/crea tabelle in un intervallo" +END + +NUMBER F_FROMTAB 4 0 +BEGIN + PROMPT 1 10 "Da " + FLAGS "D" +END + +NUMBER F_TOTAB 3 0 +BEGIN + PROMPT 10 10 "A " + FLAGS "D" +END + +STRING F_MYRANGE 50 +BEGIN + PROMPT 1 11 "MY RANGE " + FLAGS "H" +END + END ENDPAGE diff --git a/src/cg/cg2100.cpp b/src/cg/cg2100.cpp index ada90eaf6..5a1b57487 100755 --- a/src/cg/cg2100.cpp +++ b/src/cg/cg2100.cpp @@ -123,7 +123,7 @@ TMask* TPrimanota_application::load_mask(int n) ism.set_handler(309, sheet_clifo_handler); ism.set_handler(CG_RATEO, sheet_rateo_handler); ism.set_handler(CG_RISCONTO, sheet_risconto_handler); - if (!(fexist("fp0.exe") && !fp_settings().get_db_indirizzo().empty() && !fp_settings().is_f8())) + if (!is_fp(m)) m->hide(F_PROTFPPRO); else { @@ -1049,7 +1049,7 @@ void TPrimanota_application::init_modify_mode(TMask& m) m.enable(F_BOLLACODCLI, causale().tipo_doc() == "BD"); m.enable(F_BOLLARAGCLI, causale().tipo_doc() == "BD"); } - if(!m.field(F_PROTFPPRO).hidden()) + if(m.find_by_id(F_PROTFPPRO) != NULL && !m.field(F_PROTFPPRO).hidden()) m.set(F_PROTFPPRO, mov.get(MOV_PROGFPPRO)); } @@ -1564,14 +1564,14 @@ int TPrimanota_application::rewrite(const TMask& m) return err; } -void TPrimanota_application::clean_fppro() const +void TPrimanota_application::clean_fppro() { TMask& msk = curr_mask(); const KEY last_key = msk.last_key(); // Controlli: solo in mod modifica; che abbia fp (no F8); che non sono in salvataggio if (_mode != MODE_MOD - || !is_fp() + || !is_fp(&msk) || last_key != 127 && last_key != K_SAVE) return; @@ -1586,12 +1586,17 @@ void TPrimanota_application::clean_fppro() const fp_db().sq_commit(); } -bool TPrimanota_application::is_fp() +bool TPrimanota_application::is_fp(TMask* m) { - return fexist("fp0.exe") && !fp_settings().get_db_indirizzo().empty() && !fp_settings().is_f8(); + static bool is_set_fpcheck = false; + if (!is_set_fpcheck) + { + _isfp = has_module(FPAUT) && !fp_settings().get_db_indirizzo().empty() && !fp_settings().is_f8(); + is_set_fpcheck = true; + } + return _isfp; } - bool TPrimanota_application::remove() { const bool ok = TRelation_application::remove(); @@ -2336,13 +2341,13 @@ void TPrimanota_application::mask2ini(const TMask& msk, TConfig& ini) } } -int TPrimanota_application::save_fppro() const +int TPrimanota_application::save_fppro() { TMask& msk = curr_mask(); const KEY last = msk.last_key(); // Provo a vedere se hanno l'FP: se c'è l'indirizzo controllo che non sia F8 se non c'è non hanno l'FP - if (!is_fp()) + if (!is_fp(&msk)) return pro_nofp; if (!fp_db().sq_is_connect()) { @@ -2379,7 +2384,7 @@ int TPrimanota_application::save_fppro() const TLocalisamfile clifo(LF_CAUSALI); clifo.setkey(1); clifo.put("CODCAUS", msk.get(F_CODCAUS)); - if (clifo.read() != NOERR && clifo.get("TIPODOC") != "FA") + if (clifo.read() != NOERR || clifo.get("TIPODOC") != "FA") return pro_notsaved; if (last != K_SAVE) { // Se sto uscendo avvertimento di non salvataggio e salto message_box("La registrazione del movimento non verrà salvata sul database."); @@ -2430,7 +2435,10 @@ int TPrimanota_application::save_fppro() const const int n = fp_db().sq_items(); if (n != 1) { - message_box("Attenzione non è stato possibile indentificare\nil documento con una specifica fattura in ingresso.\nSi prega di riportare i dati dei documenti selezionandolo con l'apposito sistema di aggancio alle fatture di ingresso"); + message_box(TString("Attenzione,") << "al movimento non è stato abbinato nessun documento elettronico.\n" << + "Per conserntire una corretta archiviazione sostitutiva si consiglia di non confermare la registrazione e di procedere\n" << + "all'identificazione del fornitore tramite il monitor fatture passive.\n" << + "In caso di documento escluso dalla fatturazione elettronica ignorate questo messaggio."); return pro_notsaved; } const int numreg = fp_db().sq_get_int("PZ_NUMREGCONT"); diff --git a/src/cg/cg2102.cpp b/src/cg/cg2102.cpp index 00c72da07..a71d09c4e 100755 --- a/src/cg/cg2102.cpp +++ b/src/cg/cg2102.cpp @@ -3451,38 +3451,6 @@ bool TPrimanota_application::protiva_handler(TMask_field& f, KEY key) return ok; } -bool TPrimanota_application::fppro_mask(TMask_field& f, KEY key) -{ - if (!is_fp() || key != K_SPACE && key != K_TAB) - return true; - - TMask& cg_msk = f.mask(); - TMask* msk = new TMask("cg2fppro"); - msk->set_handler(DLG_CONFIG, fppro_handler); - msk->set_handler(DLG_LINK, fppro_ok_handler); - msk->set(F_CODCLIFORS, cg_msk.get(F_CODCLIFOR)); - msk->set(F_COFIS, cg_msk.get(F_COFI)); - msk->set(F_STATOPAIVS, cg_msk.get(F_STATOPAIV)); - msk->set(F_PIVAS, cg_msk.get(F_PIVA)); - - if(load_fppro_mask(msk)) - { - msk->run(); - // Riporto dati FPPRO su maschera Prima Nota - cg_msk.set(F_NUMDOCEXT, msk->get(F_NUMEROI)); - cg_msk.set(F_NUMDOC, TString(msk->get(F_NUMEROI)).right(7)); - cg_msk.set(F_DATADOC, msk->get(F_DATAI)); - cg_msk.set(F_TOTALE, msk->get(F_TOTDOCI)); - cg_msk.set(F_PROTFPPRO, msk->get(F_PROTFPPROI)); - cg_msk.set(F_PROKEY, msk->get(F_FPPROKEYSI)); - cg_msk.set(F_ANNORIF, cg_msk.get(F_ANNOIVA)); - } - - delete msk; - return true; -} - - // Handler of the F_RITFIS // Certified 100% bool TPrimanota_application::ritfis_handler(TMask_field& f, KEY key) @@ -3857,17 +3825,41 @@ bool TPrimanota_application::quadratura_handler(TMask_field& f, KEY key) return true; } -bool TPrimanota_application::load_fppro_mask(TMask* msk, KEY k) +bool TPrimanota_application::fppro_mask(TMask_field& f, KEY key) +{ + TMask& cg_msk = f.mask(); + if (!app().get_isfp() || key != K_SPACE && key != K_TAB) + return true; + auto msk = std::make_shared(cg_msk); + + //load_list(msk, key); + //if(load_fppro_mask(msk)) + if (msk->load_fppro_mask(msk.get())) + { + msk->run(); + // Riporto dati FPPRO su maschera Prima Nota + cg_msk.set(F_NUMDOCEXT, msk->get(F_NUMEROI)); + cg_msk.set(F_NUMDOC, TString(msk->get(F_NUMEROI)).right(7)); + cg_msk.set(F_DATADOC, msk->get(F_DATAI)); + cg_msk.set(F_TOTALE, msk->get(F_TOTDOCI)); + cg_msk.set(F_PROTFPPRO, msk->get(F_PROTFPPROI)); + cg_msk.set(F_PROKEY, msk->get(F_FPPROKEYSI)); + cg_msk.set(F_ANNORIF, cg_msk.get(F_ANNOIVA)); + } + + return true; +} + +bool TPro_msk::load_fppro_mask(TMask* msk, KEY k) { // Provo a vedere se hanno l'FP: se c'è l'indirizzo controllo che non sia F8 se non c'è non hanno l'FP - if (k != 32 || !is_fp()) + if (k != 32) return false; if (!fp_db().sq_is_connect()) { message_box("Attenzione connessione al database non riuscita.\nImpossibile collegarsi ai documenti in entrata."); return false; } - const int forn = msk->get_int(F_CODCLIFORS); if (forn == 0) { @@ -3932,14 +3924,14 @@ bool TPrimanota_application::load_fppro_mask(TMask* msk, KEY k) return true; } -bool TPrimanota_application::fppro_handler(TMask_field& f, KEY k) +bool TPro_msk::fppro_handler(TMask_field& f, KEY k) { TMask& msk = f.mask(); const bool load = load_fppro_mask(&msk, k); return load; } -bool TPrimanota_application::fppro_ok_handler(TMask_field& f, KEY k) +bool TPro_msk::fppro_ok_handler(TMask_field& f, KEY k) { if (k != 32) return true; @@ -3969,10 +3961,43 @@ bool TPrimanota_application::fppro_ok_handler(TMask_field& f, KEY k) row->add("", 0); } sf.force_update(); - if(ok) - message_box("Dati caricati.\nChiudere la maschera per tornare alla prima nota."); - else + if(!ok) message_box("Nessun documento selezionato."); - //msk.stop_run(20334); + msk.stop_run(20334); return true; -} \ No newline at end of file +} + +void TPro_msk::fppro_selfatt() const +{ + const TMask& mask = *this; + TSheet_field& sf = mask.sfield(F_SHEETFPPROS); + sf.hide(); + FOR_EACH_SHEET_ROW(sf, nr, row) + { + if (*row->get(0) == 'X') + row->add("", 0); + } + sf.force_update(); + sf.show(); +} + +bool TPro_msk::on_field_event(TOperable_field& o, TField_event e, long jolly) +{ + if (o.dlg() == F_SELFPPROS) + { + if(e == fe_modify) + fppro_selfatt(); + } + + return true; +} + +TPro_msk::TPro_msk(TMask& cg_msk) : TAutomask("cg2fppro"), _parent_mask(cg_msk) +{ + TMask::set_handler(DLG_CONFIG, fppro_handler); + TMask::set_handler(DLG_LINK, fppro_ok_handler); + TMask::set(F_CODCLIFORS, cg_msk.get(F_CODCLIFOR)); + TMask::set(F_COFIS, cg_msk.get(F_COFI)); + TMask::set(F_STATOPAIVS, cg_msk.get(F_STATOPAIV)); + TMask::set(F_PIVAS, cg_msk.get(F_PIVA)); +} diff --git a/src/cg/cg2102.h b/src/cg/cg2102.h index d8d39a381..b36a780fc 100755 --- a/src/cg/cg2102.h +++ b/src/cg/cg2102.h @@ -32,6 +32,10 @@ #ifndef __CG2100_H #include "cg2100.h" #endif + +#include + +class TPro_msk; class TDati_mov_auto; enum CGMaskType { _query = 0, _no_iva = 1, _iva = 2, _occas = 3}; @@ -89,7 +93,8 @@ class TPrimanota_application : public TRelation_application TEsercizi_contabili _esercizi; // Tabella degli esercizi contabili TAssoc_array _colori; // Colori delle righe - + bool _isfp; + static bool showpartite_handler(TMask_field& f, KEY k); static bool speserimb_handler(TMask_field& f, KEY k); static bool altrespese_handler(TMask_field& f, KEY k); @@ -172,11 +177,9 @@ class TPrimanota_application : public TRelation_application // Handlers per aggancio FPPRO // Bottone per maschera FPPRO static bool fppro_mask(TMask_field& f, KEY key); - // Bottone carica documenti in maschera FPPRO - static bool fppro_handler(TMask_field& f, KEY k); - // Bottone riporta doc FPPRO in testata Prima Nota - static bool fppro_ok_handler(TMask_field& f, KEY k); - + static void fppromask_set_handl(TMask* msk); + static void load_list(TMask* msk, KEY k); + void reset_sheet_row(TSheet_field& s, int n); int crea_somma_spese(TImporto& imp); void update_saldo_riga(int r); @@ -192,15 +195,13 @@ protected: // TApplication virtual void mask2ini(const TMask& msk, TConfig& ini); // Metodi per aggancio FPPRO (solo su operazioni di Fattura di Acquisto) - // Carica documenti FPPRO sulla maschera - static bool load_fppro_mask(TMask* msk, KEY k = 32); // Salvo dati fornitore e registrazione contabile sul db FPPRO - int save_fppro() const; + int save_fppro(); // Salva sul movimento il riferimento al documento in FPPRO bool save_dbmov() const; // Pulisce il mov e db dai firerimenti FPPRO (in MODE_MOD per edit/delete) - void clean_fppro() const; - static bool is_fp(); + void clean_fppro(); + bool is_fp(TMask* m); virtual bool save(bool check_dirty); bool get_mask_swap_file(TFilename& name) const; @@ -344,6 +345,7 @@ public: static char row_type(const TToken_string& s); static bool iva_notify(TSheet_field& s, int r, KEY key); static bool cg_notify(TSheet_field& s, int r, KEY key); + bool get_isfp() const { return _isfp; } TMask * mask(CGMaskType type) { return _msk[type]; } @@ -363,11 +365,31 @@ public: TSheet_field& pags() const; TString_array& pag_rows() { return _pag_rows; } TImporto get_cgs_imp(int n) const; + TPrimanota_application(); virtual ~TPrimanota_application() { } }; +class TPro_msk : public TAutomask +{ + TMask& _parent_mask; + // Handlers per aggancio FPPRO + // Bottone carica documenti in maschera FPPRO + static bool fppro_handler(TMask_field& f, KEY k); + // Bottone riporta doc FPPRO in testata Prima Nota + static bool fppro_ok_handler(TMask_field& f, KEY k); + // Non permette la selezione multipla + void fppro_selfatt() const; + bool on_field_event(TOperable_field& o, TField_event e, long jolly) override; +public: + //bool is_fp(); + // Carica documenti FPPRO sulla maschera + static bool load_fppro_mask(TMask* msk, KEY k = 32); + TPro_msk() = delete; + TPro_msk(TMask& cg_msk); +}; + #ifndef __EXTRA__ inline TPrimanota_application& app() { return (TPrimanota_application&)main_app(); } diff --git a/src/fp/fp1200.cpp b/src/fp/fp1200.cpp index eba58207d..919bf382a 100644 --- a/src/fp/fp1200.cpp +++ b/src/fp/fp1200.cpp @@ -395,7 +395,11 @@ void TMancati_app::main_loop() const TFixed_string codnum(riga->get(mask.sfield(F_DOCS).cid2index(S_CODNUM))); const TFixed_string tipodoc(riga->get(mask.sfield(F_DOCS).cid2index(S_TIPODOC))); const long codcf = riga->get_long(mask.sfield(F_DOCS).cid2index(S_CLIENTE)); +#ifdef DBG + const TString mail = "spalacino@sirio-is.it"; +#else const TString mail = riga->get(mask.sfield(F_DOCS).cid2index(S_DOCMAIL)); +#endif bool accord = TString(riga->get(mask.sfield(F_DOCS).cid2index(S_BYMAIL))) == "X"; TString ragsoc = riga->get(mask.sfield(F_DOCS).cid2index(S_RAGSOC)); bool sent = TString(riga->get(mask.sfield(F_DOCS).cid2index(S_SENT))) == "X"; diff --git a/src/fp/fplib01.cpp b/src/fp/fplib01.cpp index 342f64cc9..69d649004 100644 --- a/src/fp/fplib01.cpp +++ b/src/fp/fplib01.cpp @@ -1267,9 +1267,7 @@ void TDoc_fp::add_ritenuta(const TDocumentoEsteso& doc, const TSpesa_prest& sp, paf0700f.set("P7_TIPORITENUTA", _rec_clifo.get_char(CLI_TIPOPERS) == 'F' ? "RT01" : "RT02"); TString doc_imponibile = doc.imponibile().string(); - const real imponibile = doc.ritenute(); - - paf0700f.set("P7_IMPORTORIT", converti_prezzo(imponibile * sp.perc() / CENTO)); + paf0700f.set("P7_IMPORTORIT", converti_prezzo(doc.ritenute())); paf0700f.set("P7_ALIQUOTARIT", sp.perc()); static TString caus_la; caus_la.cut(0); caus_la << sp.get("S14"); @@ -2009,7 +2007,7 @@ bool TDoc_fp::doc_to_paf(TDocumentoEsteso& doc) // Riga sconto di testata // Se è presente uno sconto in testata devo sottrarlo come riga sconto o lo SDI urla - if(doc.get(DOC_SCONTOPERC).full()) + if(doc.get(DOC_SCONTOPERC).full() && doc.get(DOC_SCONTOPERC) != "0") { TAssoc_array& tiva = doc.tabella_iva(false); FOR_EACH_ASSOC_OBJECT(tiva, obj, key, itm) diff --git a/src/fp/fplib03.cpp b/src/fp/fplib03.cpp index 1e4d320b6..29e0f6bd1 100644 --- a/src/fp/fplib03.cpp +++ b/src/fp/fplib03.cpp @@ -69,7 +69,7 @@ bool TFp_mail_sender::send(const TString& msg) const int pdf_exist = pdf.exist(); if (pdf_exist) - ok = spotlite_send_mail(pdf); // -> Invio mail con PDF già esistente + ok = spotlite_send_mail(pdf, msg); // -> Invio mail con PDF già esistente else if (genera_pdf()) // Genero pdf se non esiste già (in tempdir) { // Manda già un messaggio di errore generazione se fallisce la generazione TFilename newf_pdf; newf_pdf << _pdf_path << _pdf_name; diff --git a/src/fp/sql/fp0106.sql b/src/fp/sql/fp0106.sql new file mode 100644 index 000000000..ff18e6ae1 Binary files /dev/null and b/src/fp/sql/fp0106.sql differ diff --git a/src/ve/velib.h b/src/ve/velib.h index 9fdc20911..6161f1ea3 100755 --- a/src/ve/velib.h +++ b/src/ve/velib.h @@ -361,6 +361,7 @@ public: bool allega_documenti() const { return get_bool("B10"); } bool auto_add() const { return get_bool("B11"); } bool invio_xml() const { return get_bool("B13"); } + bool esponi_dicitura_fe() const { return !get_bool("B14"); } const TString& stringa_descrizione_documento() const { return _str_desc_doc; } const TString& stringa_descrizione_riga() const { return _str_desc_rdoc; } @@ -891,6 +892,7 @@ public: void set_fields(TAuto_variable_rectype & rec); void update_esenzione(); void set_riga_esenzione(); + bool esponi_dicitura(); void set_riga_valfisc(); const TRiga_documento& get_riga_esenzione() const { return *_esenzione; } bool ha_riga_sconto() const { return _sconto != NULL; } diff --git a/src/ve/velib03.cpp b/src/ve/velib03.cpp index 0db9501bd..af5adca52 100755 --- a/src/ve/velib03.cpp +++ b/src/ve/velib03.cpp @@ -1079,7 +1079,7 @@ void TDocumento::set_riga_esenzione() 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(tipo().esponi_dicitura_fe() && is_fattura() && tipo().tipo_doc_sdi().full() && data() >= anno_fatt_elett) { if (_valfisc == nullptr) _valfisc = new TRiga_documento(this, "05"); diff --git a/src/ve/vetbtip.h b/src/ve/vetbtip.h index 563a316db..80c6d65d4 100755 --- a/src/ve/vetbtip.h +++ b/src/ve/vetbtip.h @@ -116,6 +116,7 @@ #define F_IVA_NI 504 #define F_IVA_NS 505 +#define F_ESPONIDIC 510 #define FT_GOLEM 511 #define F_ADDROW 512 #define F_QUADRO 513 diff --git a/src/ve/vetbtip.uml b/src/ve/vetbtip.uml index dad4de822..305e37b75 100755 --- a/src/ve/vetbtip.uml +++ b/src/ve/vetbtip.uml @@ -1284,7 +1284,7 @@ BEGIN FIELD S3[4,4] END -GROUPBOX DLG_NULL 62 3 +GROUPBOX DLG_NULL 62 4 BEGIN PROMPT 1 8 "@bStampa documenti avanzata" END @@ -1295,9 +1295,15 @@ BEGIN FIELD B10 END +BOOLEAN F_ESPONIDIC +BEGIN + PROMPT 2 10 "Non esporre dicitura fattura di cortesia per FP" + FIELD B14 +END + BOOLEAN F_ADDROW BEGIN - PROMPT 2 11 "Crea 10 righe vuote in inserimento" + PROMPT 38 4 "Crea 10 righe vuote in inserimento" FIELD B11 END