158 Commits

Author SHA1 Message Date
Jonathan Jenne
902231ff86 Base: Version 1.3.2.0 2023-06-26 16:33:55 +02:00
Jonathan Jenne
e5b5c259d7 Base: Add ToURLQueryString function for dictionay 2023-06-26 16:33:36 +02:00
Jonathan Jenne
c5b6498f1b Jobs: Version 1.15.1.0 2023-06-26 16:32:09 +02:00
Jonathan Jenne
39a406bfaf Fix incorrect error message with more than one valid zugferd invoice 2023-06-26 14:50:07 +02:00
Jonathan Jenne
222176dfca Jobs: Version 1.15.0.0 2023-06-22 10:53:08 +02:00
Jonathan Jenne
2517db3d68 Interfaces: Version 1.12.0.0 2023-06-22 10:53:00 +02:00
Jonathan Jenne
c9437f4a5c Database: Remove TableCache 2023-06-22 10:51:52 +02:00
Jonathan Jenne
524c429de4 ZUGFeRD: Validate errors in xml and throw ValidationException 2023-06-22 10:51:43 +02:00
Jonathan Jenne
0da1eb55a9 Interfaces: Version 1.11.0.0 2023-06-21 13:10:16 +02:00
Jonathan Jenne
18b0d4cdaf Jobs: Fix zugferd email string typo 2023-06-21 13:09:32 +02:00
Jonathan Jenne
a05156a1a6 Interfaces: Rewrite ValidateZugferdDocument, add validation for invalid decimals 2023-06-21 13:09:11 +02:00
Jonathan Jenne
a19123dd03 Base: Version 1.3.1.0 2023-06-16 11:23:59 +02:00
Jonathan Jenne
1c5cc2e6fc Base: fix typo 2023-06-16 11:23:52 +02:00
Jonathan Jenne
7625f2d2e3 Base: fix typo 2023-06-16 10:35:14 +02:00
Jonathan Jenne
f2e275c8bd Base: add RetoreWindowSize 2023-06-16 10:32:50 +02:00
Jonathan Jenne
e156cc9d88 Interfaces: 1.10.5.1 2023-06-16 09:21:42 +02:00
Jonathan Jenne
cfef91059a Filesystem: 1.5.1.1 2023-06-16 09:21:08 +02:00
Jonathan Jenne
a4916ba25f EDMIAPI: Version 1.6.1.1 2023-06-16 09:20:48 +02:00
Jonathan Jenne
18374ba93d Database: Version 2.3.3.1 2023-06-16 09:20:23 +02:00
Jonathan Jenne
977f79b6a6 Base: Version 1.3.0.0 2023-06-16 09:20:01 +02:00
Jonathan Jenne
8c1a1af140 edmiapi: Improve error logging 2023-06-16 09:19:24 +02:00
Jonathan Jenne
36b38f0bd8 database: improve error loggging 2023-06-16 09:19:10 +02:00
Jonathan Jenne
c9c56ad720 Interfaces: Improve error logging 2023-06-16 09:18:48 +02:00
Jonathan Jenne
ab280ccabe File: attempt to fix GetVersionedFilenameWithFilecheck 2023-06-16 09:18:10 +02:00
Jonathan Jenne
b1114545a7 Add a lot of functions to Base 2023-06-16 09:16:49 +02:00
Jonathan Jenne
00cff028c9 Base: Add ScreenEx 2023-05-26 15:05:00 +02:00
Jonathan Jenne
76cba215fe Interfaces/Job: Add check for currencyId format in ZUGFeRD documents 2023-05-26 15:04:44 +02:00
Jonathan Jenne
f491d4dd24 Language: Add comments 2023-05-23 12:04:31 +02:00
Jonathan Jenne
e65a6fa1a4 Filesystem: Add GetHash / GetHashFromString methods 2023-05-23 12:04:10 +02:00
Jonathan Jenne
726bdd1b2d Base: Version 1.2.1.0 2023-05-23 12:03:38 +02:00
Jonathan Jenne
fd2ad3f056 Base: Rename classes 2023-05-23 12:03:22 +02:00
Jonathan Jenne
a856f5f1b3 Database: Version 2.3.3.0 2023-05-16 08:48:03 +02:00
Jonathan Jenne
5ced396e3f Base: Version 1.2.0.0 2023-05-16 08:47:35 +02:00
Jonathan Jenne
10d8e7749a Database: Fix Logging of errors with sql queries 2023-05-16 08:47:24 +02:00
Jonathan Jenne
cd3646dca0 Base: Add Language Module 2023-05-15 16:02:39 +02:00
0c1b070a90 Currency Wrapper windream 2023-04-26 15:18:11 +02:00
da9dd6dcd7 MS 2023-04-25 17:14:41 +02:00
dd4a4aad95 MS 2023-04-25 13:24:16 +02:00
Jonathan Jenne
98fd711ea0 Windream: Version 1.9.2.0 2023-04-11 10:05:42 +02:00
Jonathan Jenne
0008d0f3ba Use windream filecheck for VersionWMFilename 2023-04-11 10:05:28 +02:00
Jonathan Jenne
fb2e8a6f6c Filesystem: Version 1.5.1 2023-04-03 16:33:41 +02:00
Jonathan Jenne
2d2c09bdf4 Filesystem: restrict getversionedfilename to 100 tries 2023-04-03 16:33:14 +02:00
Jonathan Jenne
1c49054844 Add logging 2023-03-30 15:34:35 +02:00
Jonathan Jenne
c871b06cc2 EDMI.API: Version 1.6.1.0 2023-03-30 12:00:25 +02:00
Jonathan Jenne
1a860c9270 EDMI.API: DatabaseWithFallback does not use connection in some circumstances 2023-03-30 12:00:07 +02:00
Jonathan Jenne
88ac9e70b2 Windream: Version 1.9.1.0 2023-03-28 13:43:46 +02:00
Jonathan Jenne
6885bd2954 Windream: Handle unc paths in NormalizePath 2023-03-28 13:43:33 +02:00
Jonathan Jenne
4a221a9e1d Version 1.10.5.0 2023-03-02 14:21:00 +01:00
Jonathan Jenne
11ab322138 Interfaces/Zugferd: Fix errors in Zugferd 2.1.1 Schema 2023-03-02 14:20:26 +01:00
Jonathan Jenne
9cea30235d Interfaces: Version 1.10.4.0 2023-02-28 14:56:39 +01:00
Jonathan Jenne
f3afadc3b7 Interfaces: fix Zugferd exceptions 2023-02-28 14:56:01 +01:00
Jonathan Jenne
89fbc4e4ae Interfaces: Version 1.10.3.0 2023-02-28 14:12:56 +01:00
Jonathan Jenne
adf692629a Interfaces: Improve logging 2023-02-28 14:12:28 +01:00
Jonathan Jenne
f6f421ddd8 Interfaces: Version 1.10.2.0 2023-02-28 13:50:17 +01:00
Jonathan Jenne
2ced2f192f Jobs: Version 1.14.1.0 2023-02-28 13:50:03 +01:00
Jonathan Jenne
a80b943dc5 Interfaces/Jobs: add new method FilterPropertyMap 2023-02-28 13:49:16 +01:00
Jonathan Jenne
214edf22a5 Merge branch 'master' of http://git.dd:3000/AppStd/Modules 2023-02-28 11:42:55 +01:00
Jonathan Jenne
5ac3aaab54 Jobs: Version 1.14.0.0 2023-02-28 11:42:49 +01:00
Jonathan Jenne
1ab246fc46 Jobs/ZUGFeRD: Write Zugferd Specification to database 2023-02-28 11:42:20 +01:00
Jonathan Jenne
9fe177abd3 Interfaces: Add FileTooBig Error, Add note about future refactoring of GetPropertyValue 2023-02-23 16:23:26 +01:00
ed7aea5b72 Merge branch 'master' of http://git.dd:3000/AppStd/Modules 2023-02-22 12:03:53 +01:00
8e1c459a61 MS Config OverrideLang 2023-02-22 12:03:41 +01:00
Jonathan Jenne
f6acae9185 Language: Version 1.7.1 2023-02-22 11:07:43 +01:00
Jonathan Jenne
fd0876a1cb Language: Add FieldOrDefault method 2023-02-22 11:07:34 +01:00
Jonathan Jenne
ad5443adae Filesystem: fix typo 2023-02-02 13:30:37 +01:00
Jonathan Jenne
39a0c8b8ec Jobs: Version 1.13.0.0 2023-02-02 13:13:12 +01:00
Jonathan Jenne
46ce5342a0 Filesystem: Version 1.5.0 2023-02-02 13:12:41 +01:00
Jonathan Jenne
1013dd3c30 Jobs: Use TestFileSizeIsLessThanMaxFileSize 2023-02-02 13:11:41 +01:00
Jonathan Jenne
41bba8b214 Filesystem: Add TestFileSizeIsLessThanMaxFileSize 2023-02-02 13:11:16 +01:00
Jonathan Jenne
4ee519d8c6 Messaging: Remove Tls13 setting 2023-01-24 14:43:26 +01:00
Jonathan Jenne
d9690d270b Downgrade to 4.6.2 2023-01-24 14:35:09 +01:00
Jonathan Jenne
1c86b8091b Messaging: version 1.9.1 2023-01-23 09:27:59 +01:00
Jonathan Jenne
8738fd8300 Messaging: Make tls version configurable 2023-01-23 09:27:52 +01:00
Jonathan Jenne
27e3462b6e Jobs: Version 1.12.1.0 2023-01-12 14:37:50 +01:00
Jonathan Jenne
1d0688e995 Interfaces: Version 1.10.1.0 2023-01-12 14:37:39 +01:00
Jonathan Jenne
c1018d176e ZUGFeRD: Update for new version 2023-01-12 14:33:54 +01:00
3183b0ed31 MS 2023-01-03 16:03:51 +01:00
b33720c61e MS 2023-01-03 16:03:15 +01:00
Jonathan Jenne
baa661cb14 Jobs: Version 1.12.0.1 2022-12-23 13:29:46 +01:00
Jonathan Jenne
e5ec777d61 Jobs: Fix typo in importzugferdfiles 2022-12-23 13:29:01 +01:00
Jonathan Jenne
4dfe32ba33 Jobs: Fix typo in EmailStrings 2022-12-23 13:28:41 +01:00
Jonathan Jenne
65d58a2274 Zugferd: prepare loading different specs per document schema version 2022-12-21 14:02:44 +01:00
Jonathan Jenne
902c835c37 Jobs/zugferd: add fallback for missing values in GetEmailDataForMessageId 2022-12-21 10:17:31 +01:00
Jonathan Jenne
79cad24b3f Interfaces/zugferd: fix parameter error which leads to falsely allowing mails with two zugferd invoices 2022-12-21 10:16:50 +01:00
Jonathan Jenne
a9567a9d18 Jobs/zugferd: Include subject in rejection messages 2022-12-21 10:14:19 +01:00
Jonathan Jenne
0d207a25a5 Logging: Version 2.6.2.0 2022-12-16 13:52:43 +01:00
Jonathan Jenne
19f33dbb2c Fix json target 2022-12-16 13:52:33 +01:00
Jonathan Jenne
0ed5a164e8 Interfaces: Version 1.10.0.0 2022-12-16 09:30:52 +01:00
Jonathan Jenne
36dd27b26c Jobs: Version 1.12.0.0 2022-12-16 09:30:10 +01:00
Jonathan Jenne
3df54fa62c Jobs/Interfaces: add options for enabling / disabling zugferd schemas 2022-12-16 09:29:34 +01:00
Jonathan Jenne
67cdc580fa Merge branch 'master' of http://git.dd:3000/AppStd/Modules 2022-12-16 09:08:42 +01:00
Jonathan Jenne
c082222c80 Messaging: Add binding class 2022-12-16 09:04:14 +01:00
Jonathan Jenne
33a95ba46d Version 2.6.1.0 2022-12-16 09:03:41 +01:00
Jonathan Jenne
a00ad5a9c0 Logging: WIP Json logging 2022-12-16 09:03:21 +01:00
Jonathan Jenne
db1d3fb197 Interfaces: Version 1.9.1.0 2022-12-16 08:37:29 +01:00
Jonathan Jenne
d5e98c5de4 Interfaces: Prepare language attribute in ADUser 2022-12-16 08:36:56 +01:00
Jonathan Jenne
e717dffa54 Filesystem: Version 1.4.1.0 2022-12-16 08:35:37 +01:00
Jonathan Jenne
eae009e82d Filesystem: Add new method GetVersionedFilenameWithFileCheck 2022-12-16 08:35:06 +01:00
Jonathan Jenne
d74e0f304a Database: Version 2.3.1.0 2022-12-16 08:34:33 +01:00
Jonathan Jenne
2816b644da Database: Log all command parameters 2022-12-16 08:34:19 +01:00
Jonathan Jenne
b927e07141 Windream: Version 1.7.1 2022-12-16 08:33:39 +01:00
Jonathan Jenne
f5107a3d21 Windream: Fix normalized paths 2022-12-16 08:33:09 +01:00
75df258abf Ms 2022-12-15 15:57:50 +01:00
Jonathan Jenne
1ea73d9234 Windream: improve logging 2022-12-09 13:40:10 +01:00
Jonathan Jenne
d44ab2f087 Merge branch 'master' of http://git.dd:3000/AppStd/Modules 2022-12-09 13:31:08 +01:00
Jonathan Jenne
bd6d483867 Windream: Fix NewFolder 2022-12-09 13:31:01 +01:00
7b7b17b657 MS Push Windream 2022-12-09 13:30:44 +01:00
Jonathan Jenne
3883c0dad7 Messaging: Add general WCF code 2022-11-30 09:34:26 +01:00
Jonathan Jenne
078282c579 ZooFlow: Update to Nlog 5 - Version 1.3.0.0 2022-11-25 13:07:32 +01:00
Jonathan Jenne
e91af7de7c Windream: Update to Nlog 5 - Version 1.7.0.0 2022-11-25 13:06:23 +01:00
Jonathan Jenne
fb5527036a Windows: Update to Nlog 5 - Version 1.5.0.0 2022-11-25 13:05:44 +01:00
Jonathan Jenne
211c394b2f Patterns: Update to Nlog 5 - Version 1.3.0.0 2022-11-25 13:05:11 +01:00
Jonathan Jenne
5f52434d67 Messaging: Update to Nlog 5 - Version 1.8.0.0 2022-11-25 13:04:38 +01:00
Jonathan Jenne
e2494e5117 Logging: Update to Nlog 5 - Version 2.6.0.0 2022-11-25 13:03:58 +01:00
Jonathan Jenne
dd5a1c0766 License: Update to Nlog 5 - Version 1.1.0.0 2022-11-25 13:03:02 +01:00
Jonathan Jenne
a69fecd75d Language: Update to Nlog 5 - Version 1.7.0.0 2022-11-25 13:01:54 +01:00
Jonathan Jenne
7b249fb9cb Jobs: Update to Nlog 5 - Version 1.11.0.0 2022-11-25 13:01:12 +01:00
Jonathan Jenne
c5973c86c9 Interfaces: Update to Nlog 5 - Version 1.9.0.0 2022-11-25 13:00:27 +01:00
Jonathan Jenne
680b496b90 Filesystem: Update to Nlog 5 - Version 1.4.0.0 2022-11-25 12:59:51 +01:00
Jonathan Jenne
c9ef17e533 Encryption: Update to Nlog 5 - Version 1.2.0.0 2022-11-25 12:59:05 +01:00
Jonathan Jenne
780238625c EDMI.API: Update to Nlog 5 - Version 1.6.0.0 2022-11-25 12:57:18 +01:00
Jonathan Jenne
5794018c5e Database: Update to Nlog 5 - Version 2.3.0.0 2022-11-25 12:56:42 +01:00
Jonathan Jenne
b329492521 Config: Update to Nlog 5 - Version 1.2.0.0 2022-11-25 12:56:24 +01:00
Jonathan Jenne
22b3918a03 Base: Update to Nlog 5 - Version 1.1.0.0 2022-11-25 12:56:10 +01:00
Jonathan Jenne
15d6cac420 Logging: write log when debug flag is changed 2022-11-25 12:09:41 +01:00
Jonathan Jenne
a469ff9a23 1.10.0.4 2022-11-25 11:33:10 +01:00
Jonathan Jenne
55fc875d3a Jobs/GraphQL: Actually insert the status value 2022-11-25 11:28:35 +01:00
Jonathan Jenne
1d04027c5f Jobs: Version 1.10.0.3 2022-11-25 11:05:06 +01:00
Jonathan Jenne
e3c500938b Jobs: fix typo, use truncate instead of delete 2022-11-25 11:04:36 +01:00
Jonathan Jenne
dbbacd2623 Jobs: Version 1.10.0.2 2022-11-25 10:56:30 +01:00
Jonathan Jenne
7d86d583de Jobs: Fix typo 2022-11-25 10:56:07 +01:00
Jonathan Jenne
5c4b302aa7 Jobs: Version 1.10.0.1 2022-11-25 10:29:51 +01:00
Jonathan Jenne
1d8a0faeee Database: Version 2.2.7.6 2022-11-25 10:29:18 +01:00
Jonathan Jenne
ca92abbee5 Jobs: WIP GraphQL Job, fix logic errors, improve logging 2022-11-25 10:28:52 +01:00
Jonathan Jenne
8267ecb72d Database: Fix logging 2022-11-25 10:28:20 +01:00
Jonathan Jenne
86ca1011df Jobs: Version 1.10.0.0 2022-11-24 14:28:39 +01:00
Jonathan Jenne
b1aba0a80d Jobs: Add exception for unsupported zugferd documents 2022-11-24 14:26:42 +01:00
Jonathan Jenne
a8862709d8 Jobs: Update to use Job Runner Table 2022-11-24 14:24:59 +01:00
Jonathan Jenne
36fe39ee66 Merge branch 'master' of http://git.dd:3000/AppStd/Modules 2022-11-24 11:24:37 +01:00
Jonathan Jenne
ddc11b62a5 Database: Small stuff 2022-11-24 11:24:26 +01:00
Jonathan Jenne
7ba516fcd1 Interfaces: Version 1.8.1.0 2022-11-24 11:20:31 +01:00
Jonathan Jenne
05a92c3181 Language: Version 1.6.2.0 2022-11-24 11:20:00 +01:00
Jonathan Jenne
7d63718e96 Interfaces/ActiveDirectory: Improve logging 2022-11-24 11:19:22 +01:00
Jonathan Jenne
8af67ef883 Language: Improve StringEx 2022-11-24 11:14:20 +01:00
6ed636bca0 Merge branch 'master' of http://git.dd:3000/AppStd/Modules 2022-11-17 17:09:16 +01:00
5f8e1a8608 MS windream Mod 2022-11-17 17:09:07 +01:00
Jonathan Jenne
e424402d63 Interfaces: Version 1.8.0.0 2022-11-16 16:34:46 +01:00
Jonathan Jenne
9d6dd695e4 Jobs: 1.9.0.0 2022-11-16 16:34:10 +01:00
Jonathan Jenne
0410e11b59 ZUGFeRD: WIP Allow blocking factur-x and xrechnung invoice files with config flags 2022-11-16 16:33:35 +01:00
Jonathan Jenne
f4adba98eb Interfaces: Version 1.7.5.0 2022-11-14 11:46:08 +01:00
Jonathan Jenne
1dba028deb Interfaces: Add errortype unknownerror 2022-11-14 11:45:20 +01:00
Jonathan Jenne
3a26343083 Merge branch 'Database_SqlConnection' 2022-11-02 16:20:43 +01:00
Jonathan Jenne
1e732a036a Revert all modules to .NET 4.6.1 2022-11-02 14:35:43 +01:00
Jonathan Jenne
41165a470d Language: Version 1.6.1.0 2022-11-02 13:36:52 +01:00
Jonathan Jenne
8128987be4 Language: Add EscapeForSQL string extension method 2022-11-02 13:36:29 +01:00
Jonathan Jenne
6ebd3b82b6 Messaging: Improve logging 2022-11-02 13:36:00 +01:00
Jonathan Jenne
d18ebfe912 Jobs: 1.8.7.0 2022-11-02 13:35:04 +01:00
Jonathan Jenne
b614b3f140 Jobs: escape attachment paths 2022-11-02 13:34:33 +01:00
142 changed files with 2350 additions and 965 deletions

View File

@@ -10,7 +10,7 @@
<AssemblyName>DigitalData.Modules.Base</AssemblyName> <AssemblyName>DigitalData.Modules.Base</AssemblyName>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<MyType>Windows</MyType> <MyType>Windows</MyType>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<Deterministic>true</Deterministic> <Deterministic>true</Deterministic>
<TargetFrameworkProfile /> <TargetFrameworkProfile />
</PropertyGroup> </PropertyGroup>
@@ -46,16 +46,19 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> <Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.7.15\lib\net45\NLog.dll</HintPath> <HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" /> <Reference Include="System.IO.Compression" />
<Reference Include="System.Runtime.Serialization" /> <Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" /> <Reference Include="System.ServiceModel" />
<Reference Include="System.Transactions" /> <Reference Include="System.Transactions" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
@@ -75,10 +78,17 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="BaseClass.vb" /> <Compile Include="BaseClass.vb" />
<Compile Include="BaseUtils.vb" />
<Compile Include="DatabaseEx.vb" />
<Compile Include="ECM\ECM.vb" /> <Compile Include="ECM\ECM.vb" />
<Compile Include="ModuleExtensions.vb" />
<Compile Include="FileEx.vb" />
<Compile Include="ObjectEx.vb" />
<Compile Include="GraphicsEx.vb" />
<Compile Include="IDB\Attributes.vb" /> <Compile Include="IDB\Attributes.vb" />
<Compile Include="IDB\Database.vb" /> <Compile Include="IDB\Database.vb" />
<Compile Include="IDB\FileStore.vb" /> <Compile Include="IDB\FileStore.vb" />
<Compile Include="LanguageEx.vb" />
<Compile Include="My Project\AssemblyInfo.vb" /> <Compile Include="My Project\AssemblyInfo.vb" />
<Compile Include="My Project\Application.Designer.vb"> <Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
@@ -95,7 +105,9 @@
<DependentUpon>Settings.settings</DependentUpon> <DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput> <DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile> </Compile>
<Compile Include="Performance.vb" /> <Compile Include="PerformanceEx.vb" />
<Compile Include="ScreenEx.vb" />
<Compile Include="StringEx.vb" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="My Project\Resources.resx"> <EmbeddedResource Include="My Project\Resources.resx">

7
Base/BaseUtils.vb Normal file
View File

@@ -0,0 +1,7 @@
Friend Class BaseUtils
Friend Shared Function FormatHash(pChecksum)
Return BitConverter.
ToString(pChecksum).
Replace("-", String.Empty)
End Function
End Class

16
Base/DatabaseEx.vb Normal file
View File

@@ -0,0 +1,16 @@
Public Class DatabaseEx
''' <summary>
''' Checks a Row value for three different `null` values,
''' Nothing, Empty String, DBNull
'''
''' Returns the original value if the value is not null, or `defaultValue`
''' </summary>
''' <typeparam name="T">The type of the value</typeparam>
''' <param name="Row">The DataRow that contains the value</param>
''' <param name="Column">The column name</param>
''' <param name="DefaultValue">The default value</param>
''' <returns>The original value or the default value</returns>
Public Shared Function NotNull(Of T)(ByVal Row As DataRow, Column As String, DefaultValue As T) As T
Return ObjectEx.NotNull(Row.Item(Column), DefaultValue)
End Function
End Class

26
Base/FileEx.vb Normal file
View File

@@ -0,0 +1,26 @@
Imports System.IO
Imports System.Security.Cryptography
Public Class FileEx
''' <summary>
''' Reads the file at `FilePath` and computes a SHA256 Hash from its contents
''' </summary>
''' <param name="pFilePath"></param>
''' <returns></returns>
Public Function GetChecksumFromFileContents(pFilePath As String) As String
Try
Using oFileStream = IO.File.OpenRead(pFilePath)
Using oStream As New BufferedStream(oFileStream, 1200000)
Dim oChecksum() As Byte = SHA256.Create.ComputeHash(oStream)
Return BaseUtils.FormatHash(oChecksum)
End Using
End Using
Catch ex As Exception
Return Nothing
End Try
End Function
Public Function GetHashFromFileContents(pFilePath As String) As String
Return GetChecksumFromFileContents(pFilePath)
End Function
End Class

16
Base/GraphicsEx.vb Normal file
View File

@@ -0,0 +1,16 @@
Imports System.Drawing
Public Class GraphicsEx
Public Shared Function GetBrightness(c As Color) As Single
Return (c.R * 0.299F + c.G * 0.587F + c.B * 0.114F) / 256.0F
End Function
Public Shared Function GetContrastedColor(pOtherColor As Color) As Color
If GetBrightness(pOtherColor) < 0.55 Then
Return Color.White
Else
Return Color.Black
End If
End Function
End Class

55
Base/LanguageEx.vb Normal file
View File

@@ -0,0 +1,55 @@
Imports System.Globalization
Imports System.Threading
Imports DigitalData.Modules.Logging
''' <summary>
''' Functions relating to i18n, Cultures, Translations
''' </summary>
Public Class LanguageEx
''' <summary>
''' Sets the Language of the current thread by setting CurrentCulture and CurrentUICulture
''' </summary>
''' <param name="pLogger">A Logger instance</param>
''' <param name="pUserLanguage">A language code in the form of 'de-DE'</param>
''' <param name="pUserDateFormat">A custom date pattern</param>
Public Shared Sub SetApplicationLanguage(pLogger As Logger, pUserLanguage As String, Optional pUserDateFormat As String = Nothing)
Try
pLogger.Debug("Setting application language..")
Dim Culture As New CultureInfo(pUserLanguage)
If String.IsNullOrEmpty(pUserDateFormat) = False Then
Culture.DateTimeFormat.ShortDatePattern = pUserDateFormat
End If
pLogger.Debug("Culture object for language [{0}] created", pUserLanguage)
' The following line provides localization for data formats.
Thread.CurrentThread.CurrentCulture = Culture
' The following line provides localization for the application's user interface.
Thread.CurrentThread.CurrentUICulture = Culture
' Set this culture as the default culture for all threads in this application.
' Note: The following properties are supported in the .NET Framework 4.5+
CultureInfo.DefaultThreadCurrentCulture = Culture
CultureInfo.DefaultThreadCurrentUICulture = Culture
pLogger.Debug("Application language set to [{0}]", Culture.Name)
Catch ex As Exception
pLogger.Warn("Could not set application language!")
pLogger.Error(ex)
End Try
End Sub
''' <summary>
''' Logs the culture settings of the current thread
''' </summary>
''' <param name="pLogger">A Logger instance</param>
Public Shared Sub LogApplicationLanguage(pLogger As Logger)
pLogger.Debug("=== Application Language ===")
pLogger.Debug("Thread.CurrentThread.CurrentCulture: [{0}]", Thread.CurrentThread.CurrentCulture)
pLogger.Debug("Thread.CurrentThread.CurrentUICulture: [{0}]", Thread.CurrentThread.CurrentUICulture)
pLogger.Debug("CultureInfo.DefaultThreadCurrentCulture: [{0}]", CultureInfo.DefaultThreadCurrentCulture)
pLogger.Debug("CultureInfo.DefaultThreadCurrentUICulture: [{0}]", CultureInfo.DefaultThreadCurrentUICulture)
End Sub
End Class

117
Base/ModuleExtensions.vb Normal file
View File

@@ -0,0 +1,117 @@
Imports System.Runtime.CompilerServices
Imports System.Web
Public Module ModuleExtensions
Const UnixEraStartTicks As Long = 621355968000000000
' ======================================================
' === DATETIME
' ======================================================
<Extension()>
Public Function GetUnixTimestamp(pDate As Date) As Long
Dim UnixEraTicks = pDate.Ticks - UnixEraStartTicks
Return UnixEraTicks \ 10000
End Function
<Extension()>
Public Function DateFromUnix(pTimestamp As Long) As Date
Return New Date(UnixEraStartTicks + pTimestamp * 10000)
End Function
' ======================================================
' === STRING
' ======================================================
''' <summary>
''' Truncates a string to the specified length if it exceeds that length.
''' </summary>
''' <param name="pString">The string</param>
''' <param name="pLength">The maximum string length</param>
''' <returns>The truncated string</returns>
<Extension()>
Public Function Truncate(pString As String, pLength As Integer) As String
If String.IsNullOrEmpty(pString) Then Return pString
Return pString.Substring(0, Math.Min(pLength, pString.Length))
End Function
''' <summary>
''' Replaces single quotes in text for SQL Commands.
''' </summary>
''' <param name="pString">The string</param>
''' <returns>The escaped string.</returns>
<Extension()>
Public Function EscapeForSQL(pString As String) As String
Return ObjectEx.NotNull(pString, String.Empty).Replace("'", "''")
End Function
''' <summary>
''' Converts a string to boolean. Accepts true and 1 as truthy values
''' </summary>
''' <param name="pString">The input string</param>
''' <returns>True if input is true or 1, otherwise false.</returns>
<Extension()>
Public Function ToBoolean(pString As String) As Boolean
If String.IsNullOrEmpty(pString) Then Return False
Return (pString.Trim().ToLower() = "true") OrElse (pString.Trim() = "1")
End Function
' ======================================================
' === DICTIONARY
' ======================================================
<Extension()>
Public Function ToURLQueryString(pDictionary As IDictionary(Of String, String)) As String
Dim oQueryString = HttpUtility.ParseQueryString(String.Empty)
For Each oItem As KeyValuePair(Of String, String) In pDictionary
oQueryString.Add(oItem.Key, oItem.Value)
Next
Return oQueryString.ToString()
End Function
' ======================================================
' === DATATABLE
' ======================================================
<Extension()>
Public Function ItemEx(Of T)(pRow As DataRow, pFieldName As String, Optional pDefaultValue As T = Nothing) As T
Try
Return ObjectEx.NotNull(pRow.Item(pFieldName), pDefaultValue)
Catch ex As Exception
Return Nothing
End Try
End Function
<Extension()>
Public Function ItemEx(Of T)(pRow As DataRow, pFieldIndex As Integer, Optional pDefaultValue As T = Nothing) As T
Try
Return ObjectEx.NotNull(pRow.Item(pFieldIndex), pDefaultValue)
Catch ex As Exception
Return Nothing
End Try
End Function
<Extension()>
Public Function FieldOrDefault(Of T)(pRow As DataRow, pFieldName As String, Optional pDefaultValue As T = Nothing) As T
Return ItemEx(pRow, pFieldName, pDefaultValue)
End Function
<Extension()>
Public Function FieldOrDefault(Of T)(pRow As DataRow, pFieldIndex As Integer, Optional pDefaultValue As T = Nothing) As T
Return ItemEx(pRow, pFieldIndex, pDefaultValue)
End Function
<Extension()>
Public Function First(pTable As DataTable) As DataRow
Try
If pTable Is Nothing OrElse pTable.Rows.Count = 0 Then
Return Nothing
End If
Return pTable.Rows.Item(0)
Catch ex As Exception
Return Nothing
End Try
End Function
End Module

View File

@@ -12,8 +12,8 @@ Imports System.Runtime.InteropServices
<Assembly: AssemblyDescription("")> <Assembly: AssemblyDescription("")>
<Assembly: AssemblyCompany("")> <Assembly: AssemblyCompany("")>
<Assembly: AssemblyProduct("Base")> <Assembly: AssemblyProduct("Base")>
<Assembly: AssemblyCopyright("Copyright © 2022")> <Assembly: AssemblyCopyright("Copyright © 2023")>
<Assembly: AssemblyTrademark("")> <Assembly: AssemblyTrademark("1.3.2.0")>
<Assembly: ComVisible(False)> <Assembly: ComVisible(False)>
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
' indem Sie "*" wie unten gezeigt eingeben: ' indem Sie "*" wie unten gezeigt eingeben:
' <Assembly: AssemblyVersion("1.0.*")> ' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.0.0.1")> <Assembly: AssemblyVersion("1.3.2.0")>
<Assembly: AssemblyFileVersion("1.0.0.1")> <Assembly: AssemblyFileVersion("1.3.2.0")>

View File

@@ -22,7 +22,7 @@ Namespace My.Resources
'''<summary> '''<summary>
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. ''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
'''</summary> '''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0"), _ <Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _ Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _ Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _

View File

@@ -15,7 +15,7 @@ Option Explicit On
Namespace My Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ <Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0"), _ Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _ Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase Inherits Global.System.Configuration.ApplicationSettingsBase

46
Base/ObjectEx.vb Normal file
View File

@@ -0,0 +1,46 @@
Public Class ObjectEx
''' <summary>
''' Checks a value for three different `null` values,
''' Nothing, Empty String, DBNull
'''
''' Returns the original value if the value is not null, or `defaultValue`
''' </summary>
''' <typeparam name="T">The type of the value</typeparam>
''' <param name="value">The value</param>
''' <param name="defaultValue">The default Value</param>
''' <returns>The original value or the default value</returns>
Public Shared Function NotNull(Of T)(ByVal value As T, ByVal defaultValue As T) As T
If IsNothing(value) OrElse String.IsNullOrEmpty(value.ToString) OrElse IsDBNull(value) Then
Return defaultValue
Else
Return value
End If
End Function
''' <summary>
''' Converts a String value to the given Enum
''' </summary>
''' <typeparam name="T">The Enum Type</typeparam>
''' <param name="value">The string value to convert</param>
Public Shared Function ToEnum(Of T)(value As String) As T
Return [Enum].Parse(GetType(T), value)
End Function
''' <summary>
''' Converts an Integer value to the given Enum
''' </summary>
''' <typeparam name="T">The Enum Type</typeparam>
''' <param name="value">The integer value to convert</param>
Public Shared Function ToEnum(Of T)(value As Integer) As T
Return [Enum].ToObject(GetType(T), value)
End Function
''' <summary>
''' Converts a Long value to the given Enum
''' </summary>
''' <typeparam name="T">The Enum Type</typeparam>
''' <param name="value">The long value to convert</param>
Public Shared Function ToEnum(Of T)(value As Long) As T
Return [Enum].ToObject(GetType(T), value)
End Function
End Class

View File

@@ -4,7 +4,7 @@ Imports System.Runtime.InteropServices
Imports System.Security.Cryptography Imports System.Security.Cryptography
Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Logging
Public Class Performance Public Class PerformanceEx
Public Sub New(pLogConfig As LogConfig, pAppDataPath As String) Public Sub New(pLogConfig As LogConfig, pAppDataPath As String)
Dim savedHash = String.Empty Dim savedHash = String.Empty
Dim assemblyLocation = Assembly.GetEntryAssembly().Location Dim assemblyLocation = Assembly.GetEntryAssembly().Location

103
Base/ScreenEx.vb Normal file
View File

@@ -0,0 +1,103 @@
Imports System
Imports System.Drawing
Imports System.Windows.Forms
Public Class ScreenEx
Public Const DEFAULT_WINDOW_HEIGHT = 480
Public Const DEFAULT_WINDOW_WIDTH = 640
Public Shared Function GetLocationWithinScreen(pLocation As Point) As Point?
For Each screen As Screen In Screen.AllScreens
If screen.Bounds.Contains(pLocation) Then
Return New Point(pLocation.X - screen.Bounds.Left, pLocation.Y - screen.Bounds.Top)
End If
Next
Return Nothing
End Function
Public Shared Sub RestoreFormPosition(pForm As Form, pPosition As Point)
Dim oLocationWithinScreen As Point? = GetLocationWithinScreen(pPosition)
If oLocationWithinScreen Is Nothing Then
Dim oPrimaryScreen = Screen.PrimaryScreen
pForm.StartPosition = FormStartPosition.CenterScreen
Else
pForm.StartPosition = FormStartPosition.Manual
pForm.Location = pPosition
End If
End Sub
Public Shared Sub RestoreFormState(pForm As Form, pFormState As FormWindowState)
If pFormState = FormWindowState.Maximized Then
pForm.WindowState = FormWindowState.Normal
pForm.WindowState = FormWindowState.Maximized
ElseIf pFormState = FormWindowState.Minimized Then
pForm.WindowState = FormWindowState.Normal
pForm.WindowState = FormWindowState.Minimized
Else
pForm.WindowState = FormWindowState.Normal
End If
End Sub
Public Shared Sub RestoreFormState(pForm As Form, pFormState As String)
Dim oFormState As FormWindowState
If Not [Enum].TryParse(pFormState, oFormState) Then
oFormState = FormWindowState.Normal
End If
RestoreFormState(pForm, oFormState)
End Sub
Public Shared Sub RestoreFormSize(pForm As Form, pFormSize As Size)
Dim oFormSize As Size
If pFormSize.Height < 1 Or pFormSize.Width < 1 Or pFormSize.IsEmpty Then
oFormSize = New Size(DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT)
Else
oFormSize = pFormSize
End If
pForm.Size = oFormSize
End Sub
''' <summary>
''' Checks if a point is Visible on any screen
''' </summary>
Public Shared Function IsVisibleOnAnyScreen(Location As Point) As Boolean
Try
Dim oRect As New Rectangle(Location, New Size(0, 0))
For Each oScreen In Screen.AllScreens
If oScreen.WorkingArea.IntersectsWith(oRect) Then
Return True
End If
Next
Return False
Catch ex As Exception
Return False
End Try
End Function
''' <summary>
''' Checks if Size is not negative
''' </summary>
Public Shared Function SizeIsVisible(Size As Size) As Boolean
If Size.Width >= 0 And Size.Height >= 0 Then
Return True
End If
Return False
End Function
''' <summary>
''' Checks if Location is not negative
''' </summary>
Public Shared Function LocationIsVisible(Location As Point) As Boolean
If Location.X >= 0 And Location.Y >= 0 Then
Return True
End If
Return False
End Function
End Class

116
Base/StringEx.vb Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="NLog" version="4.7.15" targetFramework="net461" /> <package id="NLog" version="5.0.5" targetFramework="net461" />
</packages> </packages>

View File

@@ -10,7 +10,8 @@
<AssemblyName>DigitalData.Modules.Config</AssemblyName> <AssemblyName>DigitalData.Modules.Config</AssemblyName>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<MyType>Windows</MyType> <MyType>Windows</MyType>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkProfile />
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@@ -44,8 +45,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> <Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.7.15\lib\net45\NLog.dll</HintPath> <HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />
@@ -81,6 +82,7 @@
<Compile Include="My Project\Application.Designer.vb"> <Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon> <DependentUpon>Application.myapp</DependentUpon>
<DesignTime>True</DesignTime>
</Compile> </Compile>
<Compile Include="My Project\Resources.Designer.vb"> <Compile Include="My Project\Resources.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>

View File

@@ -123,8 +123,8 @@ Public Class ConfigManager(Of T)
End If End If
If ApplicationStartupPath <> String.Empty Then If ApplicationStartupPath <> String.Empty Then
_Logger.Info($"AppConfig is being used: [{ApplicationStartupPath}]")
_AppConfigPath = Path.Combine(ApplicationStartupPath, APP_CONFIG_NAME) _AppConfigPath = Path.Combine(ApplicationStartupPath, APP_CONFIG_NAME)
End If End If
_WriteAllValuesToUserConfig = ForceUserConfig _WriteAllValuesToUserConfig = ForceUserConfig

View File

@@ -51,7 +51,6 @@ Public Class ConfigUtils
For Each oPath In IO.Directory.EnumerateFiles(SourceDirectory, FilePattern) For Each oPath In IO.Directory.EnumerateFiles(SourceDirectory, FilePattern)
Dim oFileInfo = New IO.FileInfo(oPath) Dim oFileInfo = New IO.FileInfo(oPath)
_Logger.NewBlock($"File {oFileInfo.Name}")
_Logger.Debug("Processing file [{0}]", oFileInfo.Name) _Logger.Debug("Processing file [{0}]", oFileInfo.Name)
_Logger.Debug("Copying [{0}] to TargetDirectory..", oFileInfo.Name) _Logger.Debug("Copying [{0}] to TargetDirectory..", oFileInfo.Name)
@@ -76,7 +75,6 @@ Public Class ConfigUtils
For Each oDirectoryPath In IO.Directory.EnumerateDirectories(SourceDirectory, "*", IO.SearchOption.TopDirectoryOnly) For Each oDirectoryPath In IO.Directory.EnumerateDirectories(SourceDirectory, "*", IO.SearchOption.TopDirectoryOnly)
Dim oDirInfo As New IO.DirectoryInfo(oDirectoryPath) Dim oDirInfo As New IO.DirectoryInfo(oDirectoryPath)
_Logger.NewBlock($"Directory {oDirInfo.Name}")
_Logger.Debug("Processing directory [{0}]", oDirInfo.Name) _Logger.Debug("Processing directory [{0}]", oDirInfo.Name)
' Don't copy TargetDirectory if subpath of SourceDirectory or if MigrationDirectory ' Don't copy TargetDirectory if subpath of SourceDirectory or if MigrationDirectory

View File

@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
' übernehmen, indem Sie "*" eingeben: ' übernehmen, indem Sie "*" eingeben:
' <Assembly: AssemblyVersion("1.0.*")> ' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.1.4.1")> <Assembly: AssemblyVersion("1.2.1.0")>
<Assembly: AssemblyFileVersion("1.1.4.1")> <Assembly: AssemblyFileVersion("1.2.1.0")>

View File

@@ -22,7 +22,7 @@ Namespace My.Resources
'''<summary> '''<summary>
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. ''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
'''</summary> '''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _ <Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _ Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _ Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _

View File

@@ -15,7 +15,7 @@ Option Explicit On
Namespace My Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ <Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0"), _ Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _ Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase Inherits Global.System.Configuration.ApplicationSettingsBase

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="NLog" version="4.7.15" targetFramework="net461" /> <package id="NLog" version="5.0.5" targetFramework="net461" />
</packages> </packages>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MySubMain>true</MySubMain>
<MainForm>Form1</MainForm>
<SingleInstance>false</SingleInstance>
<ShutdownMode>0</ShutdownMode>
<EnableVisualStyles>true</EnableVisualStyles>
<AuthenticationMode>0</AuthenticationMode>
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
</MyApplicationData>

View File

@@ -1,10 +1,7 @@
Imports System.ComponentModel Imports System.ComponentModel
Imports System.Data.Common
Imports System.Data.SqlClient Imports System.Data.SqlClient
Imports DigitalData.Modules.Encryption Imports DigitalData.Modules.Encryption
Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Base
Imports System.Threading
Public Class MSSQLServer Public Class MSSQLServer
Implements IDatabase Implements IDatabase
@@ -103,7 +100,6 @@ Public Class MSSQLServer
End Try End Try
End Function End Function
<DebuggerStepThrough()>
Private Function MaybeGetTransaction(Connection As SqlConnection, Mode As TransactionMode, Transaction As SqlTransaction) As SqlTransaction Private Function MaybeGetTransaction(Connection As SqlConnection, Mode As TransactionMode, Transaction As SqlTransaction) As SqlTransaction
If Connection Is Nothing Then If Connection Is Nothing Then
Throw New ArgumentNullException("Connection") Throw New ArgumentNullException("Connection")
@@ -118,7 +114,6 @@ Public Class MSSQLServer
End If End If
End Function End Function
<DebuggerStepThrough()>
Private Function MaybeCommitTransaction(Transaction As SqlTransaction, TransactionMode As TransactionMode) As Boolean Private Function MaybeCommitTransaction(Transaction As SqlTransaction, TransactionMode As TransactionMode) As Boolean
Select Case TransactionMode Select Case TransactionMode
Case TransactionMode.NoTransaction Case TransactionMode.NoTransaction
@@ -130,6 +125,7 @@ Public Class MSSQLServer
Transaction.Commit() Transaction.Commit()
Return True Return True
Catch ex As Exception Catch ex As Exception
Logger.Warn("Error while committing transaction!")
Logger.Error(ex) Logger.Error(ex)
Return False Return False
End Try End Try
@@ -206,10 +202,13 @@ Public Class MSSQLServer
Dim oDecryptedConnectionString = DecryptConnectionString(pConnectionString) Dim oDecryptedConnectionString = DecryptConnectionString(pConnectionString)
Dim oConnection As New SqlConnection(oDecryptedConnectionString) Dim oConnection As New SqlConnection(oDecryptedConnectionString)
OpenSQLConnection(oConnection) OpenSQLConnection(oConnection)
oConnection.Close() oConnection?.Close()
Return True Return True
Catch ex As Exception Catch ex As Exception
Logger.Error("Error while testing connection!")
Logger.Error(ex) Logger.Error(ex)
Return False Return False
End Try End Try
End Function End Function
@@ -220,11 +219,18 @@ Public Class MSSQLServer
''' <param name="Connection"></param> ''' <param name="Connection"></param>
''' <returns></returns> ''' <returns></returns>
Private Function OpenSQLConnection(Connection As SqlConnection) As SqlConnection Private Function OpenSQLConnection(Connection As SqlConnection) As SqlConnection
Try
If Connection.State = ConnectionState.Closed Then If Connection.State = ConnectionState.Closed Then
Connection.Open() Connection.Open()
End If End If
Return Connection Return Connection
Catch ex As Exception
Logger.Error("Error while opening Connection!")
Logger.Error(ex)
Throw ex
End Try
End Function End Function
<DebuggerStepThrough()> <DebuggerStepThrough()>
@@ -242,6 +248,7 @@ Public Class MSSQLServer
Return oConnection Return oConnection
Catch ex As Exception Catch ex As Exception
Logger.Error("Connection could not be created or opened!")
Logger.Error(ex) Logger.Error(ex)
Return Nothing Return Nothing
@@ -260,7 +267,9 @@ Public Class MSSQLServer
Dim oConnectionString = pConnectionString.Replace(oBuilder.Password, "XXXXX") Dim oConnectionString = pConnectionString.Replace(oBuilder.Password, "XXXXX")
Return oConnectionString Return oConnectionString
Catch ex As Exception Catch ex As Exception
Logger.Error("ConnectionString is invalid and could not be masked!")
Logger.Error(ex) Logger.Error(ex)
Return "Invalid ConnectionString" Return "Invalid ConnectionString"
End Try End Try
End Function End Function
@@ -340,13 +349,13 @@ Public Class MSSQLServer
pSqlCommandObject.CommandTimeout = pTimeout pSqlCommandObject.CommandTimeout = pTimeout
Using oAdapter As New SqlDataAdapter(pSqlCommandObject) Using oAdapter As New SqlDataAdapter(pSqlCommandObject)
Logger.Debug("GetDatatableWithConnectionObject: Running Query [{0}]", pSqlCommandObject.CommandText) Logger.Debug("GetDatatableWithConnectionObject: Running Query [{0}] and Parameters [{1}]", pSqlCommandObject.CommandText, GetParameterListAsString(pSqlCommandObject))
oAdapter.Fill(oTable) oAdapter.Fill(oTable)
End Using End Using
Catch ex As Exception Catch ex As Exception
Logger.Error("GetDatatableWithConnectionObject: Error in GetDatatableWithConnection while executing command: [{0}]", pSqlCommandObject.CommandText)
Logger.Error(ex) Logger.Error(ex)
Logger.Warn("GetDatatableWithConnectionObject: Error in GetDatatableWithConnection while executing command: [{0}]", pSqlCommandObject)
Throw ex Throw ex
Finally Finally
MaybeCommitTransaction(oTransaction, pTransactionMode) MaybeCommitTransaction(oTransaction, pTransactionMode)
@@ -427,7 +436,7 @@ Public Class MSSQLServer
Dim oTransaction As SqlTransaction = MaybeGetTransaction(pSqlConnection, pTransactionMode, pTransaction) Dim oTransaction As SqlTransaction = MaybeGetTransaction(pSqlConnection, pTransactionMode, pTransaction)
Try Try
Logger.Debug("ExecuteNonQueryWithConnectionObject: Running Command [{0}]", pSqlCommandObject.CommandText) Logger.Debug("ExecuteNonQueryWithConnectionObject: Running Command [{0}] and Parameters [{1}]", pSqlCommandObject.CommandText, GetParameterListAsString(pSqlCommandObject))
pSqlCommandObject.Connection = pSqlConnection pSqlCommandObject.Connection = pSqlConnection
pSqlCommandObject.Transaction = oTransaction pSqlCommandObject.Transaction = oTransaction
@@ -436,8 +445,9 @@ Public Class MSSQLServer
Return True Return True
Catch ex As Exception Catch ex As Exception
Logger.Error("ExecuteNonQueryWithConnectionObject: Error in ExecuteNonQueryWithConnectionObject while executing command: [{0}]", pSqlCommandObject.CommandText)
Logger.Error(ex) Logger.Error(ex)
Logger.Warn("ExecuteNonQueryWithConnectionObject: Error in ExecuteNonQueryWithConnectionObject while executing command: [{0}]-[{1}]", SqlCommand, SqlConnection.ConnectionString)
Return False Return False
Finally Finally
MaybeCommitTransaction(oTransaction, pTransactionMode) MaybeCommitTransaction(oTransaction, pTransactionMode)
@@ -517,6 +527,9 @@ Public Class MSSQLServer
Dim oResult As Object = Nothing Dim oResult As Object = Nothing
Try Try
Logger.Debug("GetScalarValueWithConnectionObject: Running Query [{0}] with Parameters [{1}]", pSqlCommandObject.CommandText, GetParameterListAsString(pSqlCommandObject))
pSqlCommandObject.Connection = pSqlConnection pSqlCommandObject.Connection = pSqlConnection
pSqlCommandObject.CommandTimeout = pTimeout pSqlCommandObject.CommandTimeout = pTimeout
pSqlCommandObject.Transaction = oTransaction pSqlCommandObject.Transaction = oTransaction
@@ -524,7 +537,7 @@ Public Class MSSQLServer
Catch ex As Exception Catch ex As Exception
Logger.Error(ex) Logger.Error(ex)
Logger.Warn("GetDatatableWithConnectionObject: Error in GetDatatableWithConnection while executing command: [{0}]", pSqlCommandObject) Logger.Error("GetDatatableWithConnectionObject: Error in GetDatatableWithConnection while executing command: [{0}]", pSqlCommandObject.CommandText)
Finally Finally
MaybeCommitTransaction(oTransaction, pTransactionMode) MaybeCommitTransaction(oTransaction, pTransactionMode)
@@ -559,7 +572,7 @@ Public Class MSSQLServer
End Using End Using
Catch ex As Exception Catch ex As Exception
Logger.Error(ex) Logger.Error(ex)
Logger.Warn($"GetScalarValue failed SQLCommand [{pSqlCommand}]") Logger.Error($"GetScalarValue failed SQLCommand [{pSqlCommand}]")
Return Nothing Return Nothing
End Try End Try
@@ -591,7 +604,7 @@ Public Class MSSQLServer
End Using End Using
Catch ex As Exception Catch ex As Exception
Logger.Error(ex) Logger.Error(ex)
Logger.Warn($"NewExecuteNonQueryAsync failed SQLCommand [{SqlCommand}]") Logger.Error($"NewExecuteNonQueryAsync failed SQLCommand [{SqlCommand}]")
End Try End Try
End Sub End Sub
@@ -601,4 +614,13 @@ Public Class MSSQLServer
Dim res = command.EndExecuteNonQuery(result) Dim res = command.EndExecuteNonQuery(result)
Logger.Info("Finished executing Async database operation: {0}", command.CommandText) Logger.Info("Finished executing Async database operation: {0}", command.CommandText)
End Sub End Sub
Private Function GetParameterListAsString(pSQLCommand As SqlCommand) As String
Dim oList = pSQLCommand.Parameters.
Cast(Of SqlParameter).
Select(Function(p) $"({p.ParameterName}={p.Value})").
ToList()
Return String.Join(",", oList)
End Function
End Class End Class

View File

@@ -127,7 +127,7 @@ Public Class Oracle
End Try End Try
End Function End Function
Public Function GetDatatable(pSQLCommand As String, pTimeout As Integer) As DataTable Implements IDatabase.GetDatatable Public Function GetDatatable(pSQLCommand As String, Optional pTimeout As Integer = Constants.DEFAULT_TIMEOUT) As DataTable Implements IDatabase.GetDatatable
Try Try
Using oConnection = GetConnection(CurrentConnectionString) Using oConnection = GetConnection(CurrentConnectionString)
Dim oSQLCommand As OracleCommand Dim oSQLCommand As OracleCommand
@@ -151,8 +151,8 @@ Public Class Oracle
End Try End Try
End Function End Function
Private Function GetDatatable(pSQLCommand As String) As DataTable Implements IDatabase.GetDatatable Public Function GetDatatable(SqlCommand As SqlClient.SqlCommand, Optional Timeout As Integer = 120) As DataTable Implements IDatabase.GetDatatable
Return GetDatatable(pSQLCommand, _Timeout) Throw New NotImplementedException()
End Function End Function
Public Function ExecuteNonQuery(pSQLCommand As String, pTimeout As Integer) As Boolean Implements IDatabase.ExecuteNonQuery Public Function ExecuteNonQuery(pSQLCommand As String, pTimeout As Integer) As Boolean Implements IDatabase.ExecuteNonQuery
@@ -250,4 +250,6 @@ Public Class Oracle
Return "Invalid ConnectionString" Return "Invalid ConnectionString"
End Try End Try
End Function End Function
End Class End Class

View File

@@ -1,23 +1,23 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<configSections> <configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
</configSections> </configSections>
<entityFramework> <entityFramework>
<defaultConnectionFactory type="EntityFramework.Firebird.FbConnectionFactory, EntityFramework.Firebird" /> <defaultConnectionFactory type="EntityFramework.Firebird.FbConnectionFactory, EntityFramework.Firebird"/>
<providers> <providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/>
<provider invariantName="FirebirdSql.Data.FirebirdClient" type="EntityFramework.Firebird.FbProviderServices, EntityFramework.Firebird" /> <provider invariantName="FirebirdSql.Data.FirebirdClient" type="EntityFramework.Firebird.FbProviderServices, EntityFramework.Firebird"/>
</providers> </providers>
</entityFramework> </entityFramework>
<runtime> <runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="FirebirdSql.Data.FirebirdClient" publicKeyToken="3750abcc3150b00c" culture="neutral" /> <assemblyIdentity name="FirebirdSql.Data.FirebirdClient" publicKeyToken="3750abcc3150b00c" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-7.5.0.0" newVersion="7.5.0.0" /> <bindingRedirect oldVersion="0.0.0.0-7.5.0.0" newVersion="7.5.0.0"/>
</dependentAssembly> </dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>
</configuration> <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/></startup></configuration>

View File

@@ -11,9 +11,10 @@
<AssemblyName>DigitalData.Modules.Database</AssemblyName> <AssemblyName>DigitalData.Modules.Database</AssemblyName>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<MyType>Windows</MyType> <MyType>Windows</MyType>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<NuGetPackageImportStamp> <NuGetPackageImportStamp>
</NuGetPackageImportStamp> </NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@@ -59,8 +60,8 @@
<HintPath>..\packages\FirebirdSql.Data.FirebirdClient.7.5.0\lib\net452\FirebirdSql.Data.FirebirdClient.dll</HintPath> <HintPath>..\packages\FirebirdSql.Data.FirebirdClient.7.5.0\lib\net452\FirebirdSql.Data.FirebirdClient.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> <Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.7.15\lib\net45\NLog.dll</HintPath> <HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath>
</Reference> </Reference>
<Reference Include="Oracle.ManagedDataAccess"> <Reference Include="Oracle.ManagedDataAccess">
<HintPath>P:\Visual Studio Projekte\Bibliotheken\Oracle.ManagedDataAccess.dll</HintPath> <HintPath>P:\Visual Studio Projekte\Bibliotheken\Oracle.ManagedDataAccess.dll</HintPath>
@@ -99,7 +100,6 @@
<Compile Include="Dispatcher.vb" /> <Compile Include="Dispatcher.vb" />
<Compile Include="Exceptions.vb" /> <Compile Include="Exceptions.vb" />
<Compile Include="Adapters\Firebird.vb" /> <Compile Include="Adapters\Firebird.vb" />
<Compile Include="Helpers.vb" />
<Compile Include="IDatabase.vb" /> <Compile Include="IDatabase.vb" />
<Compile Include="Adapters\ODBC.vb" /> <Compile Include="Adapters\ODBC.vb" />
<Compile Include="Adapters\Oracle.vb" /> <Compile Include="Adapters\Oracle.vb" />
@@ -108,6 +108,7 @@
<Compile Include="My Project\Application.Designer.vb"> <Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon> <DependentUpon>Application.myapp</DependentUpon>
<DesignTime>True</DesignTime>
</Compile> </Compile>
<Compile Include="My Project\Resources.Designer.vb"> <Compile Include="My Project\Resources.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
@@ -120,7 +121,6 @@
<DesignTimeSharedInput>True</DesignTimeSharedInput> <DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile> </Compile>
<Compile Include="Queries.vb" /> <Compile Include="Queries.vb" />
<Compile Include="TableCache.vb" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="My Project\Resources.resx"> <EmbeddedResource Include="My Project\Resources.resx">

View File

@@ -1,10 +0,0 @@
Public Class Helpers
Public Shared Function MaybeEscapeSQLCommand(pSQLCommand As String) As String
End Function
End Class

View File

@@ -12,8 +12,8 @@ Imports System.Runtime.InteropServices
<Assembly: AssemblyDescription("")> <Assembly: AssemblyDescription("")>
<Assembly: AssemblyCompany("Digital Data")> <Assembly: AssemblyCompany("Digital Data")>
<Assembly: AssemblyProduct("Modules.Database")> <Assembly: AssemblyProduct("Modules.Database")>
<Assembly: AssemblyCopyright("Copyright © 2022")> <Assembly: AssemblyCopyright("Copyright © 2023")>
<Assembly: AssemblyTrademark("2.2.7.5")> <Assembly: AssemblyTrademark("2.3.3.1")>
<Assembly: ComVisible(False)> <Assembly: ComVisible(False)>
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
' übernehmen, indem Sie "*" eingeben: ' übernehmen, indem Sie "*" eingeben:
' <Assembly: AssemblyVersion("1.0.*")> ' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("2.2.7.5")> <Assembly: AssemblyVersion("2.3.3.1")>
<Assembly: AssemblyFileVersion("2.2.7.5")> <Assembly: AssemblyFileVersion("2.3.3.1")>

View File

@@ -22,7 +22,7 @@ Namespace My.Resources
'''<summary> '''<summary>
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. ''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
'''</summary> '''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _ <Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _ Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _ Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _

View File

@@ -15,7 +15,7 @@ Option Explicit On
Namespace My Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ <Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0"), _ Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _ Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase Inherits Global.System.Configuration.ApplicationSettingsBase

View File

@@ -1,17 +0,0 @@
Public Class TableCache
Private Items As New Dictionary(Of String, DataTable)
Public Function [Get](SQLCommand As String)
Dim oKey As String = SQLCommand.ToUpper
If Items.ContainsKey(oKey) Then
Return Items.Item(oKey)
Else
End If
End Function
Private Function SaveTable()
End Function
End Class

View File

@@ -3,6 +3,6 @@
<package id="EntityFramework" version="6.4.4" targetFramework="net461" /> <package id="EntityFramework" version="6.4.4" targetFramework="net461" />
<package id="EntityFramework.Firebird" version="6.4.0" targetFramework="net461" /> <package id="EntityFramework.Firebird" version="6.4.0" targetFramework="net461" />
<package id="FirebirdSql.Data.FirebirdClient" version="7.5.0" targetFramework="net461" /> <package id="FirebirdSql.Data.FirebirdClient" version="7.5.0" targetFramework="net461" />
<package id="NLog" version="4.7.15" targetFramework="net461" /> <package id="NLog" version="5.0.5" targetFramework="net461" />
<package id="System.Data.Odbc" version="6.0.1" targetFramework="net461" /> <package id="System.Data.Odbc" version="6.0.1" targetFramework="net461" />
</packages> </packages>

View File

@@ -191,25 +191,30 @@ Public Class DatabaseWithFallback
' If there is no client, we assume there is no service (configured) ' If there is no client, we assume there is no service (configured)
If _Client Is Nothing Then If _Client Is Nothing Then
_Logger.Debug("Client is empty, falling back to direct database access.")
Return GetDatatableFromDatabase(pFallbackSQL, pFallbackType, pConnectionId) Return GetDatatableFromDatabase(pFallbackSQL, pFallbackType, pConnectionId)
End If End If
' If ForceFallback flag is set, we go to database immediately ' If ForceFallback flag is set, we go to database immediately
If pForceFallback Or _ClientConfig.ForceDirectDatabaseAccess Then If pForceFallback Or _ClientConfig.ForceDirectDatabaseAccess Then
_Logger.Debug("ForceFallback is True, falling back to direct database access.")
Return GetDatatableFromDatabase(pFallbackSQL, pFallbackType, pConnectionId) Return GetDatatableFromDatabase(pFallbackSQL, pFallbackType, pConnectionId)
End If End If
' If the table is not cached, we try going through the service ' If the table is not cached, we try going through the service
If Not IsTableCached(pDataTableName) Then If Not IsTableCached(pDataTableName) Then
_Logger.Debug("Datatable is not chached, fetching data from service.")
Return GetDatatableFromService(pFallbackSQL, pFallbackType, pConnectionId) Return GetDatatableFromService(pFallbackSQL, pFallbackType, pConnectionId)
End If End If
' If there is a proper ConnectionId, we try going through the service ' If there is a proper ConnectionId, we try going through the service
If pConnectionId > 0 Then If pConnectionId > 0 Then
_Logger.Debug("ConnectionId is set, fetching data from service.")
Return GetDatatableFromService(pFallbackSQL, pFallbackType, pConnectionId) Return GetDatatableFromService(pFallbackSQL, pFallbackType, pConnectionId)
End If End If
Try Try
_Logger.Debug("Datatable is chached, fetching data from cache.")
oTableResult = _Client.GetDatatableByName(pDataTableName, pFilterExpression, pSortByColumn) oTableResult = _Client.GetDatatableByName(pDataTableName, pFilterExpression, pSortByColumn)
Catch ex As Exception Catch ex As Exception
_Logger.Error(ex) _Logger.Error(ex)
@@ -332,26 +337,25 @@ Public Class DatabaseWithFallback
End Function End Function
Private Function GetDatatableFromDatabase(pSQLCommand As String, DatabaseType As Constants.DatabaseType, pConnectionId As Integer) As DataTable Private Function GetDatatableFromDatabase(pSQLCommand As String, pDatabaseType As Constants.DatabaseType, pConnectionId As Integer) As DataTable
Try Try
Dim oResult As ExecuteNonQueryResponse = Nothing _Logger.Debug("Fetching data from database [{0}] with Connection Id [{0}]", pDatabaseType.ToString, pConnectionId)
Select Case DatabaseType
Case Constants.DatabaseType.ECM
Return _DatabaseECM.GetDatatable(pSQLCommand)
Select Case pDatabaseType
Case Constants.DatabaseType.IDB Case Constants.DatabaseType.IDB
Return _DatabaseIDB.GetDatatable(pSQLCommand) Return _DatabaseIDB.GetDatatable(pSQLCommand)
Case Else Case Else
If pConnectionId > 0 Then
_Logger.Debug("Retrieving Connection String from Connection Id [{0}]", pConnectionId)
Dim oConnectionString = _DatabaseECM.Get_ConnectionStringforID(pConnectionId) Dim oConnectionString = _DatabaseECM.Get_ConnectionStringforID(pConnectionId)
If oConnectionString = String.Empty Then
Return _DatabaseECM.GetDatatable(pSQLCommand)
Else
Return _DatabaseECM.GetDatatableWithConnection(pSQLCommand, oConnectionString) Return _DatabaseECM.GetDatatableWithConnection(pSQLCommand, oConnectionString)
Else
Return _DatabaseECM.GetDatatable(pSQLCommand)
End If End If
End Select End Select
Catch ex As Exception Catch ex As Exception
_Logger.Error(ex) _Logger.Error(ex)
Return Nothing Return Nothing
@@ -397,20 +401,19 @@ Public Class DatabaseWithFallback
Private Function GetScalarValueFromDatabase(pSQLCommand As String, DatabaseType As Constants.DatabaseType, pConnectionId As Integer) As Object Private Function GetScalarValueFromDatabase(pSQLCommand As String, DatabaseType As Constants.DatabaseType, pConnectionId As Integer) As Object
Try Try
Select Case DatabaseType Select Case DatabaseType
Case Constants.DatabaseType.ECM
Return _DatabaseECM.GetScalarValue(pSQLCommand)
Case Constants.DatabaseType.IDB Case Constants.DatabaseType.IDB
Return _DatabaseIDB.GetScalarValue(pSQLCommand) Return _DatabaseIDB.GetScalarValue(pSQLCommand)
Case Else Case Else
If pConnectionId > 0 Then
Dim oConnectionString = _DatabaseECM.Get_ConnectionStringforID(pConnectionId) Dim oConnectionString = _DatabaseECM.Get_ConnectionStringforID(pConnectionId)
If oConnectionString = String.Empty Then
Return _DatabaseECM.GetScalarValue(pSQLCommand)
Else
Return _DatabaseECM.GetScalarValueWithConnection(pSQLCommand, oConnectionString) Return _DatabaseECM.GetScalarValueWithConnection(pSQLCommand, oConnectionString)
Else
Return _DatabaseECM.GetScalarValue(pSQLCommand)
End If End If
End Select End Select
Catch ex As Exception Catch ex As Exception
_Logger.Error(ex) _Logger.Error(ex)
Return Nothing Return Nothing
@@ -455,21 +458,19 @@ Public Class DatabaseWithFallback
Private Function ExecuteNonQueryFromDatabase(pSQLCommand As String, DatabaseType As Constants.DatabaseType, pConnectionId As Integer) As Boolean Private Function ExecuteNonQueryFromDatabase(pSQLCommand As String, DatabaseType As Constants.DatabaseType, pConnectionId As Integer) As Boolean
Try Try
Select Case DatabaseType Select Case DatabaseType
Case Constants.DatabaseType.ECM
Return _DatabaseECM.ExecuteNonQuery(pSQLCommand)
Case Constants.DatabaseType.IDB Case Constants.DatabaseType.IDB
Return _DatabaseIDB.ExecuteNonQuery(pSQLCommand) Return _DatabaseIDB.ExecuteNonQuery(pSQLCommand)
Case Else Case Else
If pConnectionId > 0 Then
Dim oConnectionString = _DatabaseECM.Get_ConnectionStringforID(pConnectionId) Dim oConnectionString = _DatabaseECM.Get_ConnectionStringforID(pConnectionId)
If oConnectionString = String.Empty Then
Return _DatabaseECM.ExecuteNonQuery(pSQLCommand)
Else
Return _DatabaseECM.ExecuteNonQueryWithConnection(pSQLCommand, oConnectionString) Return _DatabaseECM.ExecuteNonQueryWithConnection(pSQLCommand, oConnectionString)
Else
Return _DatabaseECM.ExecuteNonQuery(pSQLCommand)
End If End If
End Select End Select
Catch ex As Exception Catch ex As Exception
_Logger.Error(ex) _Logger.Error(ex)
Return False Return False

View File

@@ -10,7 +10,8 @@
<AssemblyName>DigitalData.Modules.EDMI.API</AssemblyName> <AssemblyName>DigitalData.Modules.EDMI.API</AssemblyName>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<MyType>Windows</MyType> <MyType>Windows</MyType>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkProfile />
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@@ -44,8 +45,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> <Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.7.15\lib\net45\NLog.dll</HintPath> <HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />
@@ -101,6 +102,7 @@
<Compile Include="My Project\Application.Designer.vb"> <Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon> <DependentUpon>Application.myapp</DependentUpon>
<DesignTime>True</DesignTime>
</Compile> </Compile>
<Compile Include="My Project\Resources.Designer.vb"> <Compile Include="My Project\Resources.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>

View File

@@ -12,8 +12,8 @@ Imports System.Runtime.InteropServices
<Assembly: AssemblyDescription("")> <Assembly: AssemblyDescription("")>
<Assembly: AssemblyCompany("Digital Data")> <Assembly: AssemblyCompany("Digital Data")>
<Assembly: AssemblyProduct("EDMIAPI")> <Assembly: AssemblyProduct("EDMIAPI")>
<Assembly: AssemblyCopyright("Copyright © 2022")> <Assembly: AssemblyCopyright("Copyright © 2023")>
<Assembly: AssemblyTrademark("1.5.4.0")> <Assembly: AssemblyTrademark("1.6.1.1")>
<Assembly: ComVisible(False)> <Assembly: ComVisible(False)>
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
' übernehmen, indem Sie "*" eingeben: ' übernehmen, indem Sie "*" eingeben:
' <Assembly: AssemblyVersion("1.0.*")> ' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.5.4.0")> <Assembly: AssemblyVersion("1.6.1.1")>
<Assembly: AssemblyFileVersion("1.5.4.0")> <Assembly: AssemblyFileVersion("1.6.1.1")>

View File

@@ -22,7 +22,7 @@ Namespace My.Resources
'''<summary> '''<summary>
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. ''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
'''</summary> '''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _ <Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _ Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _ Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
@@ -39,7 +39,7 @@ Namespace My.Resources
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
Get Get
If Object.ReferenceEquals(resourceMan, Nothing) Then If Object.ReferenceEquals(resourceMan, Nothing) Then
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("DigitalData.Modules.EDMIAPI.Resources", GetType(Resources).Assembly) Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("DigitalData.Modules.EDMI.API.Resources", GetType(Resources).Assembly)
resourceMan = temp resourceMan = temp
End If End If
Return resourceMan Return resourceMan

View File

@@ -15,7 +15,7 @@ Option Explicit On
Namespace My Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ <Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0"), _ Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _ Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase Inherits Global.System.Configuration.ApplicationSettingsBase
@@ -63,7 +63,7 @@ Namespace My
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _ Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
Friend Module MySettingsProperty Friend Module MySettingsProperty
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> <Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
Friend ReadOnly Property Settings() As Global.DigitalData.Modules.EDMI.API.My.MySettings Friend ReadOnly Property Settings() As Global.DigitalData.Modules.EDMI.API.My.MySettings
Get Get
Return Global.DigitalData.Modules.EDMI.API.My.MySettings.Default Return Global.DigitalData.Modules.EDMI.API.My.MySettings.Default

View File

@@ -1,21 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<system.diagnostics> <system.diagnostics>
<sources> <sources>
<!-- Dieser Abschnitt definiert die Protokollierungskonfiguration für My.Application.Log --> <!-- Dieser Abschnitt definiert die Protokollierungskonfiguration für My.Application.Log -->
<source name="DefaultSource" switchName="DefaultSwitch"> <source name="DefaultSource" switchName="DefaultSwitch">
<listeners> <listeners>
<add name="FileLog" /> <add name="FileLog"/>
<!-- Auskommentierung des nachfolgenden Abschnitts aufheben, um in das Anwendungsereignisprotokoll zu schreiben --> <!-- Auskommentierung des nachfolgenden Abschnitts aufheben, um in das Anwendungsereignisprotokoll zu schreiben -->
<!--<add name="EventLog"/>--> <!--<add name="EventLog"/>-->
</listeners> </listeners>
</source> </source>
</sources> </sources>
<switches> <switches>
<add name="DefaultSwitch" value="Information" /> <add name="DefaultSwitch" value="Information"/>
</switches> </switches>
<sharedListeners> <sharedListeners>
<add name="FileLog" type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" initializeData="FileLogWriter" /> <add name="FileLog" type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" initializeData="FileLogWriter"/>
<!-- Auskommentierung des nachfolgenden Abschnitts aufheben und APPLICATION_NAME durch den Namen der Anwendung ersetzen, um in das Anwendungsereignisprotokoll zu schreiben --> <!-- Auskommentierung des nachfolgenden Abschnitts aufheben und APPLICATION_NAME durch den Namen der Anwendung ersetzen, um in das Anwendungsereignisprotokoll zu schreiben -->
<!--<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="APPLICATION_NAME"/> --> <!--<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="APPLICATION_NAME"/> -->
</sharedListeners> </sharedListeners>
@@ -25,7 +25,7 @@
<netTcpBinding> <netTcpBinding>
<binding name="NetTcpBinding_IEDMIService" transferMode="Streamed"> <binding name="NetTcpBinding_IEDMIService" transferMode="Streamed">
<security> <security>
<transport sslProtocols="None" /> <transport sslProtocols="None"/>
</security> </security>
</binding> </binding>
</netTcpBinding> </netTcpBinding>
@@ -33,7 +33,7 @@
<client> <client>
<endpoint address="net.tcp://localhost:9000/DigitalData/Services/Main" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IEDMIService" contract="EDMIServiceReference.IEDMIService" name="NetTcpBinding_IEDMIService"> <endpoint address="net.tcp://localhost:9000/DigitalData/Services/Main" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IEDMIService" contract="EDMIServiceReference.IEDMIService" name="NetTcpBinding_IEDMIService">
<identity> <identity>
<userPrincipalName value="Administrator@dd-san01.dd-gan.local.digitaldata.works" /> <userPrincipalName value="Administrator@dd-san01.dd-gan.local.digitaldata.works"/>
</identity> </identity>
</endpoint> </endpoint>
</client> </client>
@@ -41,9 +41,9 @@
<runtime> <runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="FirebirdSql.Data.FirebirdClient" publicKeyToken="3750abcc3150b00c" culture="neutral" /> <assemblyIdentity name="FirebirdSql.Data.FirebirdClient" publicKeyToken="3750abcc3150b00c" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-7.5.0.0" newVersion="7.5.0.0" /> <bindingRedirect oldVersion="0.0.0.0-7.5.0.0" newVersion="7.5.0.0"/>
</dependentAssembly> </dependentAssembly>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>
</configuration> <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/></startup></configuration>

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="NLog" version="4.7.15" targetFramework="net461" /> <package id="NLog" version="5.0.5" targetFramework="net461" />
</packages> </packages>

View File

@@ -10,8 +10,9 @@
<AssemblyName>DigitalData.Modules.Encryption</AssemblyName> <AssemblyName>DigitalData.Modules.Encryption</AssemblyName>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<MyType>Windows</MyType> <MyType>Windows</MyType>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<Deterministic>true</Deterministic> <Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@@ -45,8 +46,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> <Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.7.15\lib\net45\NLog.dll</HintPath> <HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />

View File

@@ -13,7 +13,7 @@ Imports System.Runtime.InteropServices
<Assembly: AssemblyCompany("")> <Assembly: AssemblyCompany("")>
<Assembly: AssemblyProduct("Encryption")> <Assembly: AssemblyProduct("Encryption")>
<Assembly: AssemblyCopyright("Copyright © 2021")> <Assembly: AssemblyCopyright("Copyright © 2021")>
<Assembly: AssemblyTrademark("")> <Assembly: AssemblyTrademark("1.2.0.0")>
<Assembly: ComVisible(False)> <Assembly: ComVisible(False)>
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
' indem Sie "*" wie unten gezeigt eingeben: ' indem Sie "*" wie unten gezeigt eingeben:
' <Assembly: AssemblyVersion("1.0.*")> ' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.1.0.0")> <Assembly: AssemblyVersion("1.2.0.0")>
<Assembly: AssemblyFileVersion("1.1.0.0")> <Assembly: AssemblyFileVersion("1.2.0.0")>

View File

@@ -22,7 +22,7 @@ Namespace My.Resources
'''<summary> '''<summary>
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. ''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
'''</summary> '''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0"), _ <Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _ Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _ Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _

View File

@@ -15,7 +15,7 @@ Option Explicit On
Namespace My Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ <Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0"), _ Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _ Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase Inherits Global.System.Configuration.ApplicationSettingsBase

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="NLog" version="4.7.15" targetFramework="net461" /> <package id="NLog" version="5.0.5" targetFramework="net461" />
</packages> </packages>

View File

@@ -39,6 +39,9 @@ Public Class File
' Source: https://docs.microsoft.com/de-de/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN#maximum-path-length-limitation ' Source: https://docs.microsoft.com/de-de/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN#maximum-path-length-limitation
Private Const MAX_FILE_PATH_LENGTH = 250 Private Const MAX_FILE_PATH_LENGTH = 250
' This prevents an infinite loop when no file can be created in a location
Private Const MAX_FILE_VERSION = 100
Private Const FILE_NAME_ACCESS_TEST = "accessTest.txt" Private Const FILE_NAME_ACCESS_TEST = "accessTest.txt"
Public Sub New(LogConfig As LogConfig) Public Sub New(LogConfig As LogConfig)
@@ -100,6 +103,14 @@ Public Class File
Return FormatHash(oChecksum) Return FormatHash(oChecksum)
End Function End Function
Public Function GetHash(FilePath As String) As String
Return GetChecksum(FilePath)
End Function
Public Function GetHashFromString(pStringToCheck As String) As String
Return GetChecksumFromString(pStringToCheck)
End Function
Private Function FormatHash(pChecksum) Private Function FormatHash(pChecksum)
Return BitConverter. Return BitConverter.
ToString(pChecksum). ToString(pChecksum).
@@ -109,11 +120,21 @@ Public Class File
''' <summary> ''' <summary>
''' Adds file version string to given filename `Destination` if that file already exists. ''' Adds file version string to given filename `Destination` if that file already exists.
''' </summary> ''' </summary>
''' <param name="Destination"></param> ''' <param name="pFilePath">Filepath to check</param>
''' <returns></returns> ''' <returns>Versioned string</returns>
Public Function GetVersionedFilename(Destination As String) As String Public Function GetVersionedFilename(pFilePath As String) As String
Return GetVersionedFilenameWithFilecheck(pFilePath, Function(pPath As String) IO.File.Exists(pFilePath))
End Function
''' <summary>
''' Adds file version string to given filename `Destination` if that file already exists.
''' </summary>
''' <param name="pFilePath">Filepath to check</param>
''' <param name="pFileExistsAction">Custom action to check for file existence</param>
''' <returns>Versioned string</returns>
Public Function GetVersionedFilenameWithFilecheck(pFilePath As String, pFileExistsAction As Func(Of String, Boolean)) As String
Try Try
Dim oFileName As String = Destination Dim oFileName As String = pFilePath
Dim oFinalFileName = oFileName Dim oFinalFileName = oFileName
Dim oDestinationDir = Path.GetDirectoryName(oFileName) Dim oDestinationDir = Path.GetDirectoryName(oFileName)
@@ -131,31 +152,36 @@ Public Class File
' Shorten the filename (only filename, without extension or version) ' Shorten the filename (only filename, without extension or version)
' by cutting the length in half. This should work no matter how long the path and/or filename are. ' by cutting the length in half. This should work no matter how long the path and/or filename are.
' The initial check operates on the full path to catch all scenarios. ' The initial check operates on the full path to catch all scenarios.
If Destination.Length > MAX_FILE_PATH_LENGTH Then If pFilePath.Length > MAX_FILE_PATH_LENGTH Then
_Logger.Info("Filename is too long. Filename will be cut to prevent further errors.") _Logger.Info("Filename is too long. Filename will be cut to prevent further errors.")
_Logger.Info("Original Filename is: {0}", oFileNameWithoutExtension) _Logger.Info("Original Filename is: {0}", oFileNameWithoutExtension)
Dim oNewLength As Integer = Math.Round(oFileNameWithoutExtension.Length / 2) Dim oNewLength As Integer = CInt(Math.Floor(oFileNameWithoutExtension.Length / 2.0))
Dim oNewFileNameWithoutExtension = oFileNameWithoutExtension.Substring(0, oNewLength) Dim oNewFileNameWithoutExtension = oFileNameWithoutExtension.Substring(0, oNewLength)
_Logger.Info("New Filename will be: {0}", oNewFileNameWithoutExtension) _Logger.Info("New Filename will be: {0}", oNewFileNameWithoutExtension)
oFileNameWithoutExtension = oNewFileNameWithoutExtension oFileNameWithoutExtension = oNewFileNameWithoutExtension
End If End If
' while file exists, increment version ' while file exists, increment version.
' version cannot go above MAX_FILE_VERSION, to prevent infinite loop
Do Do
If oFileVersion >= MAX_FILE_VERSION Then
Throw New OverflowException($"Tried '{MAX_FILE_VERSION}' times to version filename before giving up. Sorry.")
End If
oFinalFileName = Path.Combine(oDestinationDir, GetFilenameWithVersion(oFileNameWithoutExtension, oVersionSeparator, oFileVersion, oExtension)) oFinalFileName = Path.Combine(oDestinationDir, GetFilenameWithVersion(oFileNameWithoutExtension, oVersionSeparator, oFileVersion, oExtension))
_Logger.Debug("Intermediate Filename is {0}", oFinalFileName) _Logger.Debug("Intermediate Filename is {0}", oFinalFileName)
_Logger.Debug("File version: {0}", oFileVersion) _Logger.Debug("File version: {0}", oFileVersion)
oFileVersion += 1 oFileVersion += 1
Loop While (IO.File.Exists(oFinalFileName)) Loop While pFileExistsAction(oFinalFileName) = True
_Logger.Debug("Final Filename is {0}", oFinalFileName) _Logger.Debug("Final Filename is {0}", oFinalFileName)
Return oFinalFileName Return oFinalFileName
Catch ex As Exception Catch ex As Exception
_Logger.Warn("Filename {0} could not be versioned. Original filename will be returned!", Destination) _Logger.Warn("Filename {0} could not be versioned. Original filename will be returned!", pFilePath)
_Logger.Error(ex) _Logger.Error(ex)
Return Destination Return pFilePath
End Try End Try
End Function End Function
@@ -195,6 +221,8 @@ Public Class File
oStringVersion = 1 oStringVersion = 1
End If End If
_Logger.Debug("Versioned: String [{0}], Version [{1}]", pString, oStringVersion)
Return New Tuple(Of String, Integer)(pString, oStringVersion) Return New Tuple(Of String, Integer)(pString, oStringVersion)
End Function End Function
@@ -392,6 +420,34 @@ Public Class File
Return oIsDirectory Return oIsDirectory
End Function End Function
''' <summary>
''' Checks the size of the supplied file.
''' </summary>
''' <param name="pFilePath"></param>
''' <param name="pMaxFileSizeInMegaBytes"></param>
''' <returns></returns>
Public Function TestFileSizeIsLessThanMaxFileSize(pFilePath As String, pMaxFileSizeInMegabytes As Integer) As Boolean
Dim oFileInfo As New FileInfo(pFilePath)
_Logger.Info("Checking Filesize of {0}", oFileInfo.Name)
_Logger.Debug("Filesize threshold is {0} MB.", pMaxFileSizeInMegabytes)
If pMaxFileSizeInMegabytes <= 0 Then
_Logger.Debug("Filesize is not configured. Skipping check.")
Return True
End If
Dim oMaxSize = pMaxFileSizeInMegabytes * 1024 * 1024
If oMaxSize > 0 And oFileInfo.Length > oMaxSize Then
_Logger.Debug("Filesize is bigger than threshold.")
Return False
Else
_Logger.Debug("Filesize is smaller than threshold. All fine.")
Return True
End If
End Function
Public Function GetDateDirectory(pBaseDirectory As String, pDate As Date) As String Public Function GetDateDirectory(pBaseDirectory As String, pDate As Date) As String
Dim oDateDirectory = GetDateString(pDate) Dim oDateDirectory = GetDateString(pDate)
Dim oFinalDirectory As String = IO.Path.Combine(pBaseDirectory, oDateDirectory) Dim oFinalDirectory As String = IO.Path.Combine(pBaseDirectory, oDateDirectory)

View File

@@ -10,7 +10,8 @@
<AssemblyName>DigitalData.Modules.Filesystem</AssemblyName> <AssemblyName>DigitalData.Modules.Filesystem</AssemblyName>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<MyType>Windows</MyType> <MyType>Windows</MyType>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkProfile />
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@@ -44,8 +45,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> <Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.7.15\lib\net45\NLog.dll</HintPath> <HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath>
</Reference> </Reference>
<Reference Include="protobuf-net, Version=2.4.0.0, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL"> <Reference Include="protobuf-net, Version=2.4.0.0, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
<HintPath>..\packages\protobuf-net.2.4.0\lib\net40\protobuf-net.dll</HintPath> <HintPath>..\packages\protobuf-net.2.4.0\lib\net40\protobuf-net.dll</HintPath>
@@ -86,6 +87,7 @@
<Compile Include="My Project\Application.Designer.vb"> <Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon> <DependentUpon>Application.myapp</DependentUpon>
<DesignTime>True</DesignTime>
</Compile> </Compile>
<Compile Include="My Project\Resources.Designer.vb"> <Compile Include="My Project\Resources.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>

View File

@@ -12,8 +12,8 @@ Imports System.Runtime.InteropServices
<Assembly: AssemblyDescription("")> <Assembly: AssemblyDescription("")>
<Assembly: AssemblyCompany("Digital Data")> <Assembly: AssemblyCompany("Digital Data")>
<Assembly: AssemblyProduct("Modules.Filesystem")> <Assembly: AssemblyProduct("Modules.Filesystem")>
<Assembly: AssemblyCopyright("Copyright © 2022")> <Assembly: AssemblyCopyright("Copyright © 2023")>
<Assembly: AssemblyTrademark("1.3.1.1")> <Assembly: AssemblyTrademark("1.5.1.1")>
<Assembly: ComVisible(False)> <Assembly: ComVisible(False)>
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
' übernehmen, indem Sie "*" eingeben: ' übernehmen, indem Sie "*" eingeben:
' <Assembly: AssemblyVersion("1.0.*")> ' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.3.1.1")> <Assembly: AssemblyVersion("1.5.1.1")>
<Assembly: AssemblyFileVersion("1.3.1.1")> <Assembly: AssemblyFileVersion("1.5.1.1")>

View File

@@ -22,7 +22,7 @@ Namespace My.Resources
'''<summary> '''<summary>
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. ''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
'''</summary> '''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _ <Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _ Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _ Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _

View File

@@ -15,7 +15,7 @@ Option Explicit On
Namespace My Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ <Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0"), _ Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _ Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase Inherits Global.System.Configuration.ApplicationSettingsBase

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="NLog" version="4.7.15" targetFramework="net461" /> <package id="NLog" version="5.0.5" targetFramework="net461" />
<package id="protobuf-net" version="2.4.0" targetFramework="net461" /> <package id="protobuf-net" version="2.4.0" targetFramework="net461" />
</packages> </packages>

View File

@@ -193,6 +193,8 @@ Public Class ActiveDirectoryInterface
.FirebirdSyskey = oMap.FirebirdSyskey, .FirebirdSyskey = oMap.FirebirdSyskey,
.MSSQLColumn = oMap.MSSQLColumn .MSSQLColumn = oMap.MSSQLColumn
}) })
Else
_logger.Debug("Attribute [{0}] is empty.", oMap.AttributeName)
End If End If
Next Next
Else Else

View File

@@ -8,6 +8,7 @@ Public Class ADUser
Public Property GivenName As String Public Property GivenName As String
Public Property Middlename As String Public Property Middlename As String
Public Property Email As String Public Property Email As String
Public Property Language As String
Public CustomAttributes As List(Of CustomAttribute) Public CustomAttributes As List(Of CustomAttribute)

View File

@@ -42,7 +42,7 @@ Namespace SyncUsers
End Try End Try
For Each oUser In Users For Each oUser In Users
Dim oUserId As Int64 Dim oUserId As Long
Dim oUserExists As Boolean Dim oUserExists As Boolean
' Check if user already exists ' Check if user already exists
@@ -68,7 +68,7 @@ Namespace SyncUsers
_logger.Debug("Creating new user for [{0}]", oUser) _logger.Debug("Creating new user for [{0}]", oUser)
oUserId = CreateUser(oUser) oUserId = CreateUser(oUser)
_logger.Debug("User created with Id [{0}]", oUserId) _logger.Debug("User created with Id [{0}]", oUserId)
_logger.Info("Added new User [{0}]", oUser.samAccountName) _logger.Info("Added new User [{0}]", oUser)
oCreatedUsers.Add(oUser) oCreatedUsers.Add(oUser)
Else Else
@@ -76,7 +76,7 @@ Namespace SyncUsers
oUserId = UpdateUser(oUser) oUserId = UpdateUser(oUser)
If oUserId <> 0 Then If oUserId <> 0 Then
_logger.Debug("User created with Id [{0}]", oUserId) _logger.Debug("User created with Id [{0}]", oUserId)
_logger.Info("Updated User [{0}]", oUser.samAccountName) _logger.Info("Updated User [{0}]", oUser)
oUpdatedUsers.Add(oUser) oUpdatedUsers.Add(oUser)
End If End If
@@ -84,7 +84,7 @@ Namespace SyncUsers
Catch ex As Exception Catch ex As Exception
_logger.Error(ex) _logger.Error(ex)
_logger.Warn("Could Not create/update user [{0}]. Skipping.", oUser.samAccountName) _logger.Warn("Could Not create/update user [{0}]. Skipping.", oUser)
Continue For Continue For
End Try End Try
@@ -99,7 +99,7 @@ Namespace SyncUsers
' Add the user to group ' Add the user to group
Try Try
If AddUserToGroup(oUserId, oGroupId) Then If AddUserToGroup(oUserId, oGroupId) Then
_logger.Info("User [{0}] added to group [{1}]", oUser.samAccountName, GroupName) _logger.Info("User [{0}] added to group [{1}]", oUser, GroupName)
End If End If
Catch ex As Exception Catch ex As Exception
_logger.Error(ex) _logger.Error(ex)
@@ -175,7 +175,8 @@ Namespace SyncUsers
Dim oSQL As String = $"SELECT GUID FROM TBDD_USER WHERE UPPER(USERNAME) = UPPER('{UserName}')" Dim oSQL As String = $"SELECT GUID FROM TBDD_USER WHERE UPPER(USERNAME) = UPPER('{UserName}')"
Dim oUserId = _mssql.GetScalarValue(oSQL) Dim oUserId = _mssql.GetScalarValue(oSQL)
If IsDBNull(oUserId) OrElse oUserId = 0 Then If IsDBNull(oUserId) OrElse IsNothing(oUserId) OrElse oUserId = 0 Then
_logger.Debug("User [{0}] does not exist", UserName)
Return 0 Return 0
End If End If
@@ -194,9 +195,15 @@ Namespace SyncUsers
End If End If
Dim oUserId As Integer = GetUserId(User.samAccountName) Dim oUserId As Integer = GetUserId(User.samAccountName)
_logger.Debug("UserId of User [{0}] is [{1}]", User, oUserId)
If oUserId = 0 Then If oUserId = 0 Then
Dim oSQL As String = $"INSERT INTO TBDD_USER (PRENAME, NAME, USERNAME, EMAIL, ADDED_WHO) VALUES ('{User?.GivenName}', '{User?.Surname?.Replace("'", "''")}', UPPER('{User?.samAccountName?.Replace("'", "''")}'), '{User?.Email?.Replace("'", "''")}', '{ADDED_WHO}')" Dim oPrename = User.GivenName.EscapeForSQL()
Dim oSurname = User.Surname.EscapeForSQL()
Dim oUsername = User.samAccountName.EscapeForSQL()
Dim oEmail = User.Email.EscapeForSQL()
Dim oSQL As String = $"INSERT INTO TBDD_USER (PRENAME, NAME, USERNAME, EMAIL, ADDED_WHO) VALUES ('{oPrename}', '{oSurname}', UPPER('{oUsername}'), '{oEmail}', '{ADDED_WHO}')"
Dim oResult = _mssql.ExecuteNonQuery(oSQL) Dim oResult = _mssql.ExecuteNonQuery(oSQL)
If oResult = True Then If oResult = True Then
@@ -230,11 +237,11 @@ Namespace SyncUsers
Dim oUserId As Integer = GetUserId(User.samAccountName) Dim oUserId As Integer = GetUserId(User.samAccountName)
If Not IsNothing(oUserId) Then If Not IsNothing(oUserId) Then
If oUserId > 0 Then If oUserId > 0 Then
Dim oGivenName As String = EscapeQuotes(User.GivenName) Dim oPrename = User.GivenName.EscapeForSQL()
Dim oSurname As String = EscapeQuotes(User.Surname) Dim oSurname = User.Surname.EscapeForSQL()
Dim oEmail As String = EscapeQuotes(User.Email) Dim oEmail = User.Email.EscapeForSQL()
Dim oSQL As String = $"UPDATE TBDD_USER SET PRENAME = '{oGivenName}', NAME = '{oSurname}', EMAIL = '{oEmail}', CHANGED_WHO = '{ADDED_WHO}' WHERE GUID = {oUserId}" Dim oSQL As String = $"UPDATE TBDD_USER SET PRENAME = '{oPrename}', NAME = '{oSurname}', EMAIL = '{oEmail}', CHANGED_WHO = '{ADDED_WHO}' WHERE GUID = {oUserId}"
Dim oResult = _mssql.ExecuteNonQuery(oSQL) Dim oResult = _mssql.ExecuteNonQuery(oSQL)
If oResult = True Then If oResult = True Then
@@ -256,11 +263,6 @@ Namespace SyncUsers
End Try End Try
End Function End Function
Private Function EscapeQuotes(pString As String)
Dim oString = Utils.NotNull(pString, String.Empty)
Return oString.Replace("'", "''")
End Function
Public Sub AddCustomAttributesToUser(User As ADUser, UserId As Integer) Implements ISyncUsers.AddCustomAttributesToUser Public Sub AddCustomAttributesToUser(User As ADUser, UserId As Integer) Implements ISyncUsers.AddCustomAttributesToUser
Dim oCustomAttributes = User.CustomAttributes Dim oCustomAttributes = User.CustomAttributes

View File

@@ -51,8 +51,8 @@
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> <Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.7.15\lib\net45\NLog.dll</HintPath> <HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />
@@ -111,6 +111,7 @@
<DependentUpon>Settings.settings</DependentUpon> <DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput> <DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile> </Compile>
<Compile Include="ZUGFeRDInterface\Validator.vb" />
<Compile Include="ZUGFeRDInterface\Version1.0\CrossIndustryDocumentType.vb" /> <Compile Include="ZUGFeRDInterface\Version1.0\CrossIndustryDocumentType.vb" />
<Compile Include="ZUGFeRDInterface.vb" /> <Compile Include="ZUGFeRDInterface.vb" />
<Compile Include="ZUGFeRDInterface\FileGroups.vb" /> <Compile Include="ZUGFeRDInterface\FileGroups.vb" />

View File

@@ -12,8 +12,8 @@ Imports System.Runtime.InteropServices
<Assembly: AssemblyDescription("")> <Assembly: AssemblyDescription("")>
<Assembly: AssemblyCompany("Digital Data")> <Assembly: AssemblyCompany("Digital Data")>
<Assembly: AssemblyProduct("Modules.Interfaces")> <Assembly: AssemblyProduct("Modules.Interfaces")>
<Assembly: AssemblyCopyright("Copyright © 2022")> <Assembly: AssemblyCopyright("Copyright © 2023")>
<Assembly: AssemblyTrademark("1.7.4.0")> <Assembly: AssemblyTrademark("1.12.0.0")>
<Assembly: ComVisible(False)> <Assembly: ComVisible(False)>
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
' übernehmen, indem Sie "*" eingeben: ' übernehmen, indem Sie "*" eingeben:
' <Assembly: AssemblyVersion("1.0.*")> ' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.7.4.0")> <Assembly: AssemblyVersion("1.12.0.0")>
<Assembly: AssemblyFileVersion("1.7.4.0")> <Assembly: AssemblyFileVersion("1.12.0.0")>

View File

@@ -15,7 +15,7 @@ Option Explicit On
Namespace My Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ <Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.3.0.0"), _ Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _ Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase Inherits Global.System.Configuration.ApplicationSettingsBase

View File

@@ -1,56 +1,150 @@
Imports System.IO Imports System.Collections.Generic
Imports System.IO
Imports System.Reflection.Emit
Imports System.Xml Imports System.Xml
Imports System.Xml.Serialization Imports System.Xml.Serialization
Imports System.Xml.XPath Imports System.Xml.XPath
Imports System.Xml.Xsl Imports System.Xml.Xsl
Imports DigitalData.Modules.Interfaces.Exceptions Imports DigitalData.Modules.Interfaces.Exceptions
Imports DigitalData.Modules.Interfaces.ZUGFeRD
Imports DigitalData.Modules.Interfaces.ZUGFeRDInterface
Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Logging
Imports GdPicture14 Imports GdPicture14
Public Class ZUGFeRDInterface Public Class ZUGFeRDInterface
Private _logConfig As LogConfig Private ReadOnly _logConfig As LogConfig
Private _logger As Logger Private ReadOnly _logger As Logger
Private ReadOnly _Options As ZugferdOptions
Private ReadOnly _Validator As Validator
' These constants define the specification markers for the different
' zugferd document schema versions. These markers need to be used to
' define the property map in the database (column SPECIFICATION).
Public Const ZUGFERD_SPEC_DEFAULT = "DEFAULT"
Public Const ZUGFERD_SPEC_10 = "ZUGFERD_10"
Public Const ZUGFERD_SPEC_2x = "ZUGFERD_2x"
Private ReadOnly ValidFilenames As New List(Of String) From {
PDFEmbeds.ZUGFERD_XML_FILENAME.ToUpper,
PDFEmbeds.FACTUR_X_XML_FILENAME_DE.ToUpper,
PDFEmbeds.FACTUR_X_XML_FILENAME_FR.ToUpper
}
Private AllowedFilenames As New List(Of String)
Public Enum ErrorType Public Enum ErrorType
NoValidFile NoValidFile
NoZugferd NoZugferd
NoValidZugferd NoValidZugferd
MissingProperties MissingProperties
UnsupportedFormat
FileTooBig
UnknownError
End Enum End Enum
Public ReadOnly Property FileGroup As FileGroups Public ReadOnly Property FileGroup As FileGroups
Public ReadOnly Property PropertyValues As PropertyValues Public ReadOnly Property PropertyValues As PropertyValues
Public Sub New(LogConfig As LogConfig, GDPictureKey As String) Public Class ZugferdOptions
_logConfig = LogConfig Public Property AllowFacturX_Filename As Boolean = True
Public Property AllowXRechnung_Filename As Boolean = True
Public Property AllowZugferd_1_0_Schema As Boolean = True
Public Property AllowZugferd_2_x_Schema As Boolean = True
End Class
Public Class ZugferdResult
Public Property DataFileName As String
Public Property XElementObject As XElement
Public Property SchemaObject As Object
Public Property Specification As String
Public Property ValidationErrors As New List(Of ZugferdValidationError)
End Class
Public Class ZugferdValidationError
Public ElementName As String
Public ElementValue As String
Public ErrorMessage As String
End Class
''' <summary>
''' Create a new instance of ZUGFeRDInterface
''' </summary>
''' <param name="pLogConfig">A LogConfig object</param>
''' <param name="pGDPictureKey">A valid GDPicture License</param>
''' <param name="pOptions">Optional parameters to control various settings</param>
Public Sub New(pLogConfig As LogConfig, pGDPictureKey As String, Optional pOptions As ZugferdOptions = Nothing)
_logConfig = pLogConfig
_logger = _logConfig.GetLogger() _logger = _logConfig.GetLogger()
_Validator = New Validator(_logConfig)
If pOptions Is Nothing Then
_Options = New ZugferdOptions()
Else
_Options = pOptions
End If
ApplyFilenameOptions(_Options)
FileGroup = New FileGroups(_logConfig) FileGroup = New FileGroups(_logConfig)
PropertyValues = New PropertyValues(_logConfig) PropertyValues = New PropertyValues(_logConfig)
Try Try
Dim oLicenseManager As New LicenseManager Dim oLicenseManager As New LicenseManager
oLicenseManager.RegisterKEY(GDPictureKey) oLicenseManager.RegisterKEY(pGDPictureKey)
Catch ex As Exception Catch ex As Exception
_logger.Warn("GDPicture License could not be registered!") _logger.Warn("GDPicture License could not be registered!")
_logger.Error(ex) _logger.Error(ex)
End Try End Try
End Sub End Sub
Private Sub ApplyFilenameOptions(pOptions As ZugferdOptions)
Dim oAllowedFilenames As List(Of String) = ValidFilenames
If pOptions.AllowFacturX_Filename = False Then
oAllowedFilenames = oAllowedFilenames.
Except(New List(Of String) From {PDFEmbeds.FACTUR_X_XML_FILENAME_FR}).ToList()
End If
If pOptions.AllowXRechnung_Filename = False Then
oAllowedFilenames = oAllowedFilenames.
Except(New List(Of String) From {PDFEmbeds.FACTUR_X_XML_FILENAME_DE}).ToList()
End If
AllowedFilenames = oAllowedFilenames
End Sub
Public Function FilterPropertyMap(pPropertyMap As Dictionary(Of String, XmlItemProperty), pSpecification As String) As Dictionary(Of String, XmlItemProperty)
_logger.Debug("Filtering Property map for Specification [{0}]", pSpecification)
If pSpecification = ZUGFERD_SPEC_10 Then
_logger.Debug("Special Case [{0}], including [{1}]", ZUGFERD_SPEC_10, ZUGFERD_SPEC_DEFAULT)
Return pPropertyMap.
Where(Function(kv) kv.Value.Specification = pSpecification Or kv.Value.Specification = ZUGFERD_SPEC_DEFAULT).
ToDictionary(Function(kv) kv.Key, Function(kv) kv.Value)
Else
_logger.Debug("Using Specification [{0}]", pSpecification)
Return pPropertyMap.
Where(Function(kv) kv.Value.Specification = pSpecification).
ToDictionary(Function(kv) kv.Key, Function(kv) kv.Value)
End If
End Function
''' <summary> ''' <summary>
''' Validates a ZUGFeRD File and extracts the XML Document from it ''' Validates a ZUGFeRD File and extracts the XML Document from it
''' </summary> ''' </summary>
''' <param name="Path"></param> ''' <param name="Path"></param>
''' <exception cref="ZUGFeRDExecption"></exception> ''' <exception cref="ZUGFeRDExecption"></exception>
''' <returns></returns> Public Function ExtractZUGFeRDFileWithGDPicture(Path As String) As ZugferdResult
Public Function ExtractZUGFeRDFileWithGDPicture(Path As String) As Object Dim oResult = ValidateZUGFeRDFileWithGDPicture(Path)
Dim oXmlDocument = ValidateZUGFeRDFileWithGDPicture(Path) oResult = ValidateZUGFeRDDocument(oResult)
If IsNothing(oXmlDocument) Then If oResult.ValidationErrors.Any() Then
Throw New ZUGFeRDExecption(ErrorType.NoZugferd, "Datei ist keine ZUGFeRD Datei.") Throw New ValidationException() With {
.ValidationErrors = oResult.ValidationErrors
}
End If End If
Return SerializeZUGFeRDDocument(oXmlDocument) Return SerializeZUGFeRDDocument(oResult)
End Function End Function
''' <summary> ''' <summary>
@@ -58,29 +152,36 @@ Public Class ZUGFeRDInterface
''' </summary> ''' </summary>
''' <param name="Stream"></param> ''' <param name="Stream"></param>
''' <exception cref="ZUGFeRDExecption"></exception> ''' <exception cref="ZUGFeRDExecption"></exception>
''' <returns></returns> Public Function ExtractZUGFeRDFileWithGDPicture(Stream As Stream) As ZugferdResult
Public Function ExtractZUGFeRDFileWithGDPicture(Stream As Stream) As Object Dim oResult = ValidateZUGFeRDFileWithGDPicture(Stream)
Dim oXmlDocument = ValidateZUGFeRDFileWithGDPicture(Stream) oResult = ValidateZUGFeRDDocument(oResult)
If IsNothing(oXmlDocument) Then If oResult.ValidationErrors.Any() Then
Throw New ZUGFeRDExecption(ErrorType.NoZugferd, "Datei ist keine ZUGFeRD Datei.") _logger.Info("Validation found [{0}] errors", oResult.ValidationErrors.Count)
oResult.ValidationErrors.ForEach(
Sub(e) _logger.Info("Field [{0}] with value [{1}] has error: [{2}]", e.ElementName, e.ElementValue, e.ErrorMessage)
)
Throw New ValidationException() With {
.ValidationErrors = oResult.ValidationErrors
}
End If End If
Return SerializeZUGFeRDDocument(oXmlDocument) Return SerializeZUGFeRDDocument(oResult)
End Function End Function
''' <summary> ''' <summary>
''' Validates a ZUGFeRD File and extracts the XML Document from it ''' Validates a ZUGFeRD File and extracts the XML Document from it
''' </summary> ''' </summary>
''' <param name="Stream"></param> ''' <param name="pStream"></param>
''' <exception cref="ZUGFeRDExecption"></exception> ''' <exception cref="ZUGFeRDExecption"></exception>
''' <returns></returns> ''' <returns>The embedded xml data as an XPath document</returns>
Public Function ValidateZUGFeRDFileWithGDPicture(Stream As Stream) As XPathDocument Public Function ValidateZUGFeRDFileWithGDPicture(pStream As Stream) As ZugferdResult
Dim oEmbedExtractor = New PDFEmbeds(_logConfig) Dim oEmbedExtractor = New PDFEmbeds(_logConfig)
Dim oAllowedExtensions = New List(Of String) From {"xml"}
Try Try
Dim oFiles = oEmbedExtractor.Extract(Stream, oAllowedExtensions) ' Extract XML attachments only!
Dim oFiles = oEmbedExtractor.Extract(pStream, New List(Of String) From {"xml"})
' Attachments are in this case the files that are embedded into a pdf file, ' Attachments are in this case the files that are embedded into a pdf file,
' like for example the zugferd-invoice.xml file ' like for example the zugferd-invoice.xml file
@@ -92,17 +193,24 @@ Public Class ZUGFeRDInterface
Throw ex Throw ex
Catch ex As Exception Catch ex As Exception
_logger.Warn("Error while validating ZUGFeRD file with GDPicture")
_logger.Error(ex) _logger.Error(ex)
Throw ex Throw ex
End Try End Try
End Function End Function
Public Function ValidateZUGFeRDFileWithGDPicture(Path As String) As XPathDocument ''' <summary>
''' Validates a ZUGFeRD File and extracts the XML Document from it
''' </summary>
''' <param name="pPath"></param>
''' <exception cref="ZUGFeRDExecption"></exception>
''' <returns>The embedded xml data as an XPath document</returns>
Public Function ValidateZUGFeRDFileWithGDPicture(pPath As String) As ZugferdResult
Dim oEmbedExtractor = New PDFEmbeds(_logConfig) Dim oEmbedExtractor = New PDFEmbeds(_logConfig)
Dim oAllowedExtensions = New List(Of String) From {"xml"}
Try Try
Dim oFiles = oEmbedExtractor.Extract(Path, oAllowedExtensions) ' Extract XML attachments only!
Dim oFiles = oEmbedExtractor.Extract(pPath, New List(Of String) From {"xml"})
' Attachments are in this case the files that are embedded into a pdf file, ' Attachments are in this case the files that are embedded into a pdf file,
' like for example the zugferd-invoice.xml file ' like for example the zugferd-invoice.xml file
@@ -114,43 +222,48 @@ Public Class ZUGFeRDInterface
Throw ex Throw ex
Catch ex As Exception Catch ex As Exception
_logger.Warn("Error while validating ZUGFeRD file with GDPicture")
_logger.Error(ex) _logger.Error(ex)
Throw ex Throw ex
End Try End Try
End Function End Function
Private Function HandleEmbeddedFiles(Results As List(Of PDFEmbeds.EmbeddedFile)) As XPathDocument Private Function HandleEmbeddedFiles(pResults As List(Of PDFEmbeds.EmbeddedFile)) As ZugferdResult
Dim oXmlDocument As XPathDocument If pResults Is Nothing Then
If Results Is Nothing Then
Throw New ZUGFeRDExecption(ErrorType.NoZugferd, "Datei ist keine ZUGFeRD Datei, weil die Attachments nicht gelesen werden konnten.") Throw New ZUGFeRDExecption(ErrorType.NoZugferd, "Datei ist keine ZUGFeRD Datei, weil die Attachments nicht gelesen werden konnten.")
End If End If
If Results.Count = 0 Then If pResults.Count = 0 Then
Throw New ZUGFeRDExecption(ErrorType.NoZugferd, "Datei ist keine ZUGFeRD Datei, weil sie keine Attachments enthält.") Throw New ZUGFeRDExecption(ErrorType.NoZugferd, "Datei ist keine ZUGFeRD Datei, weil sie keine Attachments enthält.")
End If End If
Dim oValidFilenames As New List(Of String) From {
PDFEmbeds.ZUGFERD_XML_FILENAME.ToUpper,
PDFEmbeds.FACTUR_X_XML_FILENAME_DE.ToUpper,
PDFEmbeds.FACTUR_X_XML_FILENAME_FR.ToUpper
}
' Find the first file which filename matches the valid filenames for embedded invoice files ' Find the first file which filename matches the valid filenames for embedded invoice files
Dim oFoundResult As PDFEmbeds.EmbeddedFile = Results. Dim oValidResult As PDFEmbeds.EmbeddedFile = pResults.
Where(Function(result) oValidFilenames.Contains(result.FileName.ToUpper)). Where(Function(f) ValidFilenames.Contains(f.FileName.ToUpper)).
FirstOrDefault() FirstOrDefault()
If oFoundResult Is Nothing Then If oValidResult Is Nothing Then
Throw New ZUGFeRDExecption(ErrorType.NoZugferd, "Datei ist keine ZUGFeRD Datei, weil die zugferd-invoice.xml nicht gefunden wurde.") Throw New ZUGFeRDExecption(ErrorType.NoZugferd, "Datei ist keine ZUGFeRD Datei, weil keine entsprechende XML-Datei gefunden wurde.")
End If
' Search the embedded files for the ones which are allowed as per the configuration.
' The config might say, allow ZUGFeRD but not Factur-X.
Dim oAllowedResult As PDFEmbeds.EmbeddedFile = pResults.
Where(Function(f) AllowedFilenames.Contains(f.FileName.ToUpper)).
FirstOrDefault()
If oAllowedResult Is Nothing Then
Throw New ZUGFeRDExecption(ErrorType.UnsupportedFormat, "Datei ist eine ZUGFeRD Datei, aber das Format wird nicht unterstützt.", oAllowedResult.FileName)
End If End If
Try Try
Using oStream As New MemoryStream(oFoundResult.FileContents) Using oStream As New MemoryStream(oAllowedResult.FileContents)
oXmlDocument = New XPathDocument(oStream) Return New ZugferdResult With {
.DataFileName = oAllowedResult.FileName,
.XElementObject = XElement.Load(oStream)
}
End Using End Using
Return oXmlDocument
Catch ex As ZUGFeRDExecption Catch ex As ZUGFeRDExecption
' Don't log ZUGFeRD Exceptions here, they should be handled by the calling code. ' Don't log ZUGFeRD Exceptions here, they should be handled by the calling code.
' It also produces misleading error messages when checking if an attachment is a zugferd file. ' It also produces misleading error messages when checking if an attachment is a zugferd file.
@@ -162,44 +275,87 @@ Public Class ZUGFeRDInterface
End Try End Try
End Function End Function
Public Function SerializeZUGFeRDDocument(Document As XPathDocument) As Object Private Class AllowedType
Public SchemaType As Type
Public Specification As String
End Class
Public Function ValidateZUGFeRDDocument(pResult As ZugferdResult) As ZugferdResult
Return _Validator.ValidateZUGFeRDDocument(pResult)
End Function
Public Function SerializeZUGFeRDDocument(pResult As ZugferdResult) As ZugferdResult
Try Try
Dim oNavigator As XPathNavigator = Document.CreateNavigator()
Dim oReader As XmlReader Dim oReader As XmlReader
Dim oResult = Nothing
Dim oTypes As New List(Of Type) From { Dim oObject As Object = Nothing
GetType(ZUGFeRD.Version1_0.CrossIndustryDocumentType), Dim oSpecification As String = Nothing
GetType(ZUGFeRD.Version2_0.CrossIndustryInvoiceType),
GetType(ZUGFeRD.Version2_1_1.CrossIndustryInvoiceType), Dim oAllowedTypes As New List(Of AllowedType)
GetType(ZUGFeRD.Version2_2_FacturX.CrossIndustryInvoiceType)
If _Options.AllowZugferd_1_0_Schema Then
oAllowedTypes.Add(New AllowedType With {
.SchemaType = GetType(Version1_0.CrossIndustryDocumentType),
.Specification = ZUGFERD_SPEC_10
})
End If
If _Options.AllowZugferd_2_x_Schema Then
oAllowedTypes.AddRange(New List(Of AllowedType) From {
New AllowedType With {
.SchemaType = GetType(Version2_0.CrossIndustryInvoiceType),
.Specification = ZUGFERD_SPEC_2x
},
New AllowedType With {
.SchemaType = GetType(Version2_1_1.CrossIndustryInvoiceType),
.Specification = ZUGFERD_SPEC_2x
},
New AllowedType With {
.SchemaType = GetType(Version2_2_FacturX.CrossIndustryInvoiceType),
.Specification = ZUGFERD_SPEC_2x
} }
})
End If
For Each oType In oTypes For Each oType In oAllowedTypes
_logger.Debug("Trying Type [{0}]", oType.FullName) Dim oTypeName As String = oType.SchemaType.FullName
Dim oSerializer As New XmlSerializer(oType) Dim oSerializer As New XmlSerializer(oType.SchemaType)
_logger.Debug("Trying Type [{0}]", oTypeName)
Try Try
oReader = oNavigator.ReadSubtree() oReader = pResult.XElementObject.CreateReader()
oResult = oSerializer.Deserialize(oReader) oObject = oSerializer.Deserialize(oReader)
_logger.Debug("Serializing with type [{0}] succeeded", oType.FullName) oSpecification = oType.Specification
_logger.Debug("Serializing with type [{0}] succeeded", oTypeName)
Exit For Exit For
Catch ex As Exception Catch ex As Exception
_logger.Debug("Serializing with type [{0}] failed", oType.FullName) _logger.Debug("Serializing with type [{0}] failed", oTypeName)
_logger.Debug(ex.Message) _logger.Debug(ex.Message)
_logger.Error(ex.InnerException?.Message) If IsNothing(ex.InnerException) = False Then
_logger.Debug(ex.InnerException.Message)
End If
End Try End Try
Next Next
If oResult Is Nothing Then If oObject Is Nothing Then
Throw New ApplicationException("No Types matched the given document. Document could not be serialized.") 'Throw New ApplicationException("No Types matched the given document. Document could not be serialized.")
Throw New ZUGFeRDExecption(ErrorType.UnsupportedFormat, "Unsupported Format")
End If End If
Return oResult pResult.Specification = oSpecification
pResult.SchemaObject = oObject
Return pResult
Catch ex As ZUGFeRDExecption
_logger.Error(ex)
Throw ex
Catch ex As Exception Catch ex As Exception
_logger.Error(ex) _logger.Error(ex)
Throw New ZUGFeRDExecption(ErrorType.NoValidZugferd, "Datei ist eine ungültige ZUGFeRD Datei.") Dim oMessage = "Datei ist eine ungültige ZUGFeRD Datei oder das Format wird nicht unterstüzt, oder das Format ist deaktiviert."
Throw New ZUGFeRDExecption(ErrorType.NoValidZugferd, oMessage)
End Try End Try
End Function End Function

View File

@@ -1,13 +1,38 @@
Public Class Exceptions Imports DigitalData.Modules.Interfaces.ZUGFeRDInterface
Public Class Exceptions
Public Class ZUGFeRDExecption Public Class ZUGFeRDExecption
Inherits ApplicationException Inherits ApplicationException
Public ReadOnly Property ErrorType() As ZUGFeRDInterface.ErrorType Public ReadOnly Property ErrorType() As ZUGFeRDInterface.ErrorType
''' <summary>
''' Contains the name of the extracted xml file if already extracted.
''' </summary>
''' <returns>A filename like zugferd-invoice.xml</returns>
Public ReadOnly Property XmlFile As String = String.Empty
Public Sub New(ErrorType As ZUGFeRDInterface.ErrorType, Message As String) Public Sub New(ErrorType As ZUGFeRDInterface.ErrorType, Message As String)
MyBase.New(Message) MyBase.New(Message)
_ErrorType = ErrorType _ErrorType = ErrorType
End Sub End Sub
Public Sub New(ErrorType As ZUGFeRDInterface.ErrorType, Message As String, pXmlFileName As String)
MyBase.New(Message)
_ErrorType = ErrorType
_XmlFile = pXmlFileName
End Sub
End Class
Public Class ValidationException
Inherits ApplicationException
Public ValidationErrors As List(Of ZugferdValidationError)
Public Sub New()
MyBase.New("ZUGFeRD document found but validation failed!")
End Sub
End Class End Class
End Class End Class

View File

@@ -28,7 +28,7 @@ Public Class PDFEmbeds
Public Function Extract(FilePath As String, AllowedExtensions As List(Of String)) As List(Of EmbeddedFile) Public Function Extract(FilePath As String, AllowedExtensions As List(Of String)) As List(Of EmbeddedFile)
Dim oFile As New List(Of EmbeddedFile) Dim oFile As New List(Of EmbeddedFile)
Dim oFileInfo As FileInfo Dim oFileInfo As FileInfo
Dim oExtensions = AllowedExtensions.ConvertAll(New Converter(Of String, String)(Function(ext) ext.ToUpper)) Dim oExtensions = AllowedExtensions.Select(Function(ext) ext.ToUpper).ToList()
Logger.Debug("Extracting embedded files from [{0}]", FilePath) Logger.Debug("Extracting embedded files from [{0}]", FilePath)
@@ -69,7 +69,7 @@ Public Class PDFEmbeds
''' <param name="AllowedExtensions">List of allowed extensions to be extracted</param> ''' <param name="AllowedExtensions">List of allowed extensions to be extracted</param>
Public Function Extract(Stream As Stream, AllowedExtensions As List(Of String)) As List(Of EmbeddedFile) Public Function Extract(Stream As Stream, AllowedExtensions As List(Of String)) As List(Of EmbeddedFile)
Dim oResults As New List(Of EmbeddedFile) Dim oResults As New List(Of EmbeddedFile)
Dim oExtensions = AllowedExtensions.ConvertAll(New Converter(Of String, String)(Function(ext) ext.ToUpper)) Dim oExtensions = AllowedExtensions.Select(Function(ext) ext.ToUpper).ToList()
Logger.Debug("Extracting embedded files from stream") Logger.Debug("Extracting embedded files from stream")

View File

@@ -24,7 +24,7 @@ Public Class PropertyValues
Public TableName As String Public TableName As String
Public TableColumn As String Public TableColumn As String
Public ISRequired As Boolean Public IsRequired As Boolean
Public GroupCounter As Integer = -1 Public GroupCounter As Integer = -1
Public Description As String Public Description As String
@@ -99,9 +99,7 @@ Public Class PropertyValues
Dim oIsRequired As Boolean = oColumn.Key.IsRequired Dim oIsRequired As Boolean = oColumn.Key.IsRequired
Dim oPropertyDescription As String = oColumn.Key.Description Dim oPropertyDescription As String = oColumn.Key.Description
Dim oRowCounter = oRowIndex + oGlobalGroupCounter + 1 Dim oRowCounter = oRowIndex + oGlobalGroupCounter + 1
If IsNothing(oRowCounter) Then
End If
' Returns nothing if oColumn.Value contains an empty list ' Returns nothing if oColumn.Value contains an empty list
Dim oPropertyValue = oColumn.Value.ElementAtOrDefault(oRowIndex) Dim oPropertyValue = oColumn.Value.ElementAtOrDefault(oRowIndex)
@@ -127,7 +125,7 @@ Public Class PropertyValues
.GroupCounter = oRowCounter, .GroupCounter = oRowCounter,
.TableName = oTableName, .TableName = oTableName,
.TableColumn = oTableColumn, .TableColumn = oTableColumn,
.ISRequired = oIsRequired .IsRequired = oIsRequired
}) })
Next Next
Next Next
@@ -139,6 +137,7 @@ Public Class PropertyValues
For Each oItem As KeyValuePair(Of String, XmlItemProperty) In oDefaultProperties For Each oItem As KeyValuePair(Of String, XmlItemProperty) In oDefaultProperties
Dim oPropertyValueList As List(Of Object) Dim oPropertyValueList As List(Of Object)
Dim oTableColumn As String = oItem.Value.TableColumn Dim oTableColumn As String = oItem.Value.TableColumn
Dim oPropertyDescription As String = oItem.Value.Description
Dim oPropertyValue As Object = Nothing Dim oPropertyValue As Object = Nothing
Dim oTableName = oItem.Value.TableName Dim oTableName = oItem.Value.TableName
Dim oIsRequired = oItem.Value.IsRequired Dim oIsRequired = oItem.Value.IsRequired
@@ -146,7 +145,7 @@ Public Class PropertyValues
Try Try
oPropertyValueList = GetPropValue(Document, oItem.Key) oPropertyValueList = GetPropValue(Document, oItem.Key)
Catch ex As Exception Catch ex As Exception
_logger.Warn("{2} # Unknown error occurred while fetching specification [{0}] in group [{1}]:", oTableColumn, oItem.Value.GroupScope, MessageId) _logger.Warn("{2} # Unknown error occurred while fetching specification [{0}] in group [{1}]:", oPropertyDescription, oItem.Value.GroupScope, MessageId)
_logger.Error(ex) _logger.Error(ex)
oPropertyValueList = New List(Of Object) oPropertyValueList = New List(Of Object)
End Try End Try
@@ -164,24 +163,24 @@ Public Class PropertyValues
' This should hopefully show config errors ' This should hopefully show config errors
If TypeOf oPropertyValue Is List(Of Object) Then If TypeOf oPropertyValue Is List(Of Object) Then
_logger.Warn("Item with TableColumn [{0}] may be configured incorrectly", oTableColumn) _logger.Warn("Item with specification [{0}] may be configured incorrectly", oPropertyDescription)
oPropertyValue = Nothing oPropertyValue = Nothing
End If End If
End Select End Select
End If End If
Catch ex As Exception Catch ex As Exception
_logger.Warn("Unknown error occurred while processing specification [{0}]:", oTableColumn) _logger.Warn("Unknown error occurred while processing specification [{0}]:", oPropertyDescription)
_logger.Error(ex) _logger.Error(ex)
oPropertyValue = Nothing oPropertyValue = Nothing
End Try End Try
If IsNothing(oPropertyValue) OrElse String.IsNullOrEmpty(oPropertyValue) Then If IsNothing(oPropertyValue) OrElse String.IsNullOrEmpty(oPropertyValue) Then
If oItem.Value.IsRequired Then If oItem.Value.IsRequired Then
_logger.Warn("{0} # Specification [{1}] is empty, but marked as required! Skipping.", MessageId, oTableColumn) _logger.Warn("{0} # Specification [{1}] is empty, but marked as required! Skipping.", MessageId, oPropertyDescription)
oResult.MissingProperties.Add(oTableColumn) oResult.MissingProperties.Add(oPropertyDescription)
Continue For Continue For
Else Else
_logger.Debug("{0} # oPropertyValue for specification [{1}] is empty or not found. Skipping.", MessageId, oTableColumn) _logger.Debug("{0} # oPropertyValue for specification [{1}] is empty or not found. Skipping.", MessageId, oPropertyDescription)
Continue For Continue For
End If End If
@@ -193,7 +192,7 @@ Public Class PropertyValues
.Value = oPropertyValue, .Value = oPropertyValue,
.TableName = oTableName, .TableName = oTableName,
.TableColumn = oTableColumn, .TableColumn = oTableColumn,
.ISRequired = oIsRequired .IsRequired = oIsRequired
}) })
Next Next
@@ -240,6 +239,12 @@ Public Class PropertyValues
Obj = oInfo.GetValue(Obj, Nothing) Obj = oInfo.GetValue(Obj, Nothing)
' TODO: This code should check for array properties by itself
' and should not rely on the user to
'If oInfo.PropertyType.IsArray Then
' Obj = Obj(0)
'End If
If oHasIndex Then If oHasIndex Then
Obj = Obj(0) Obj = Obj(0)
End If End If
@@ -265,6 +270,8 @@ Public Class PropertyValues
Return oResults Return oResults
End If End If
Next Next
Return New List(Of Object) From {Obj} Return New List(Of Object) From {Obj}

View File

@@ -0,0 +1,98 @@
Imports DigitalData.Modules.Interfaces.ZUGFeRDInterface
Imports DigitalData.Modules.Logging
Public Class Validator
Private ReadOnly _logConfig As LogConfig
Private ReadOnly _logger As Logger
Public Sub New(pLogConfig As LogConfig)
_logConfig = pLogConfig
_logger = pLogConfig.GetLogger()
End Sub
Public Function ValidateZUGFeRDDocument(pResult As ZugferdResult) As ZugferdResult
ValidateDecimalNodes(pResult)
ValidateCurrencyNodes(pResult)
Return pResult
End Function
Private Sub ValidateDecimalNodes(ByRef pResult As ZugferdResult)
Try
Dim oDecimalNodes = pResult.XElementObject.Descendants().
Where(Function(n) n.Name.ToString.EndsWith("Amount") Or n.Name.ToString.EndsWith("Percent"))
For Each oNode As XElement In oDecimalNodes
Dim oParsedValue As Decimal = 0.0
If Decimal.TryParse(oNode.Value, oParsedValue) = False Then
pResult.ValidationErrors.Add(New ZugferdValidationError() With {
.ElementName = oNode.Name.LocalName,
.ElementValue = oNode.Value,
.ErrorMessage = "Value could not be parsed as Decimal"
})
End If
Next
Catch ex As Exception
_logger.Error(ex)
End Try
End Sub
Private Sub ValidateCurrencyNodes(ByRef pResult As ZugferdResult)
' CurrencyCode Nodes
Try
Dim oCurrencyCodeNodes = pResult.XElementObject.Descendants().
Where(Function(n) n.Name.ToString.EndsWith("CurrencyCode"))
For Each oNode As XElement In oCurrencyCodeNodes
Dim oValid = ValidateCurrencyCode(oNode.Value)
If oValid = False Then
pResult.ValidationErrors.Add(New ZugferdValidationError() With {
.ElementName = oNode.Name.LocalName,
.ElementValue = oNode.Value,
.ErrorMessage = "Invalid CurrencyCode. Only 3-Character codes are allowed."
})
End If
Next
Catch ex As Exception
_logger.Error(ex)
End Try
' currencyID
Try
Dim oCurrencyIDNodes = pResult.XElementObject.Descendants().
Where(Function(n) n.Attributes.Any(Function(a) a.Name.LocalName = "currencyID"))
For Each oNode As XElement In oCurrencyIDNodes
Dim oCurrencyID As String = oNode.Attribute("currencyID")?.Value
' CurrencyID is optional per spec
If String.IsNullOrWhiteSpace(oCurrencyID) Then
Continue For
End If
Dim oValid = ValidateCurrencyCode(oCurrencyID)
If oValid = False Then
pResult.ValidationErrors.Add(New ZugferdValidationError() With {
.ElementName = oNode.Name.LocalName,
.ElementValue = oCurrencyID,
.ErrorMessage = "Invalid currencyID. Only 3-Character codes or empty values are allowed."
})
End If
Next
Catch ex As Exception
_logger.Error(ex)
End Try
End Sub
Private Function ValidateCurrencyCode(pValue As String) As Boolean
Dim oValueRegex As New Text.RegularExpressions.Regex("[A-Z]{3}")
If oValueRegex.IsMatch(pValue) = False Then
Return False
End If
Return True
End Function
End Class

View File

@@ -330,6 +330,17 @@ Namespace ZUGFeRD.Version2_1_1
Private directDebitMandateIDField As IDType Private directDebitMandateIDField As IDType
Private descriptionField As TextType
Public Property Description As TextType
Get
Return descriptionField
End Get
Set
Me.descriptionField = Value
End Set
End Property
'''<remarks/> '''<remarks/>
Public Property DueDateDateTime() As DateTimeType Public Property DueDateDateTime() As DateTimeType
Get Get
@@ -363,7 +374,7 @@ Namespace ZUGFeRD.Version2_1_1
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlElementAttribute("DateTimeString")> <System.Xml.Serialization.XmlElementAttribute("DateTimeString")>
Public Property Item() As DateTimeTypeDateTimeString Public Property DateTimeString() As DateTimeTypeDateTimeString
Get Get
Return Me.itemField Return Me.itemField
End Get End Get
@@ -481,6 +492,28 @@ Namespace ZUGFeRD.Version2_1_1
System.SerializableAttribute(), System.SerializableAttribute(),
System.Diagnostics.DebuggerStepThroughAttribute(), System.Diagnostics.DebuggerStepThroughAttribute(),
System.ComponentModel.DesignerCategoryAttribute("code"), System.ComponentModel.DesignerCategoryAttribute("code"),
System.Xml.Serialization.XmlTypeAttribute([Namespace]:="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:10" &
"")>
Partial Public Class CreditorFinancialInstitutionType
Private bICIDField As IDType
'''<remarks/>
Public Property BICID() As IDType
Get
Return Me.bICIDField
End Get
Set
Me.bICIDField = Value
End Set
End Property
End Class
'''<remarks/>
<System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0"),
System.SerializableAttribute(),
System.Diagnostics.DebuggerStepThroughAttribute(),
System.ComponentModel.DesignerCategoryAttribute("code"),
System.Xml.Serialization.XmlTypeAttribute([Namespace]:="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:10" & System.Xml.Serialization.XmlTypeAttribute([Namespace]:="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:10" &
"0")> "0")>
Partial Public Class DebtorFinancialAccountType Partial Public Class DebtorFinancialAccountType
@@ -581,10 +614,14 @@ Namespace ZUGFeRD.Version2_1_1
Private typeCodeField As PaymentMeansCodeType Private typeCodeField As PaymentMeansCodeType
Private informationField As TextType
Private payerPartyDebtorFinancialAccountField As DebtorFinancialAccountType Private payerPartyDebtorFinancialAccountField As DebtorFinancialAccountType
Private payeePartyCreditorFinancialAccountField As CreditorFinancialAccountType Private payeePartyCreditorFinancialAccountField As CreditorFinancialAccountType
Private payeeSpecifiedCreditorFinancialInstitutionField As CreditorFinancialInstitutionType
'''<remarks/> '''<remarks/>
Public Property TypeCode() As PaymentMeansCodeType Public Property TypeCode() As PaymentMeansCodeType
Get Get
@@ -595,6 +632,16 @@ Namespace ZUGFeRD.Version2_1_1
End Set End Set
End Property End Property
'''<remarks/>
Public Property Information() As TextType
Get
Return Me.informationField
End Get
Set
Me.informationField = Value
End Set
End Property
'''<remarks/> '''<remarks/>
Public Property PayerPartyDebtorFinancialAccount() As DebtorFinancialAccountType Public Property PayerPartyDebtorFinancialAccount() As DebtorFinancialAccountType
Get Get
@@ -614,6 +661,16 @@ Namespace ZUGFeRD.Version2_1_1
Me.payeePartyCreditorFinancialAccountField = Value Me.payeePartyCreditorFinancialAccountField = Value
End Set End Set
End Property End Property
'''<remarks/>
Public Property PayeeSpecifiedCreditorFinancialInstitution() As CreditorFinancialInstitutionType
Get
Return Me.payeeSpecifiedCreditorFinancialInstitutionField
End Get
Set
Me.payeeSpecifiedCreditorFinancialInstitutionField = Value
End Set
End Property
End Class End Class
'''<remarks/> '''<remarks/>
@@ -1207,7 +1264,7 @@ Namespace ZUGFeRD.Version2_1_1
Private specifiedTradeAllowanceChargeField() As TradeAllowanceChargeType Private specifiedTradeAllowanceChargeField() As TradeAllowanceChargeType
Private specifiedTradePaymentTermsField As TradePaymentTermsType Private specifiedTradePaymentTermsField() As TradePaymentTermsType
Private specifiedTradeSettlementHeaderMonetarySummationField As TradeSettlementHeaderMonetarySummationType Private specifiedTradeSettlementHeaderMonetarySummationField As TradeSettlementHeaderMonetarySummationType
@@ -1299,7 +1356,8 @@ Namespace ZUGFeRD.Version2_1_1
End Property End Property
'''<remarks/> '''<remarks/>
Public Property SpecifiedTradePaymentTerms() As TradePaymentTermsType <System.Xml.Serialization.XmlElementAttribute("SpecifiedTradePaymentTerms")>
Public Property SpecifiedTradePaymentTerms() As TradePaymentTermsType()
Get Get
Return Me.specifiedTradePaymentTermsField Return Me.specifiedTradePaymentTermsField
End Get End Get
@@ -4100,171 +4158,171 @@ Namespace ZUGFeRD.Version2_1_1
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("80")> <System.Xml.Serialization.XmlEnumAttribute("80")>
Item80 Item80 = 80
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("81")> <System.Xml.Serialization.XmlEnumAttribute("81")>
Item81 Item81 = 81
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("82")> <System.Xml.Serialization.XmlEnumAttribute("82")>
Item82 Item82 = 82
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("83")> <System.Xml.Serialization.XmlEnumAttribute("83")>
Item83 Item83 = 83
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("84")> <System.Xml.Serialization.XmlEnumAttribute("84")>
Item84 Item84 = 84
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("130")> <System.Xml.Serialization.XmlEnumAttribute("130")>
Item130 Item130 = 130
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("202")> <System.Xml.Serialization.XmlEnumAttribute("202")>
Item202 Item202 = 202
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("203")> <System.Xml.Serialization.XmlEnumAttribute("203")>
Item203 Item203 = 203
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("204")> <System.Xml.Serialization.XmlEnumAttribute("204")>
Item204 Item204 = 204
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("211")> <System.Xml.Serialization.XmlEnumAttribute("211")>
Item211 Item211 = 211
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("261")> <System.Xml.Serialization.XmlEnumAttribute("261")>
Item261 Item261 = 261
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("262")> <System.Xml.Serialization.XmlEnumAttribute("262")>
Item262 Item262 = 262
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("295")> <System.Xml.Serialization.XmlEnumAttribute("295")>
Item295 Item295 = 295
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("296")> <System.Xml.Serialization.XmlEnumAttribute("296")>
Item296 Item296 = 296
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("308")> <System.Xml.Serialization.XmlEnumAttribute("308")>
Item308 Item308 = 308
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("325")> <System.Xml.Serialization.XmlEnumAttribute("325")>
Item325 Item325 = 325
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("326")> <System.Xml.Serialization.XmlEnumAttribute("326")>
Item326 Item326 = 326
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("380")> <System.Xml.Serialization.XmlEnumAttribute("380")>
Item380 Item380 = 380
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("381")> <System.Xml.Serialization.XmlEnumAttribute("381")>
Item381 Item381 = 381
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("383")> <System.Xml.Serialization.XmlEnumAttribute("383")>
Item383 Item383 = 383
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("384")> <System.Xml.Serialization.XmlEnumAttribute("384")>
Item384 Item384 = 384
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("385")> <System.Xml.Serialization.XmlEnumAttribute("385")>
Item385 Item385 = 385
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("386")> <System.Xml.Serialization.XmlEnumAttribute("386")>
Item386 Item386 = 386
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("387")> <System.Xml.Serialization.XmlEnumAttribute("387")>
Item387 Item387 = 387
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("388")> <System.Xml.Serialization.XmlEnumAttribute("388")>
Item388 Item388 = 388
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("389")> <System.Xml.Serialization.XmlEnumAttribute("389")>
Item389 Item389 = 389
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("390")> <System.Xml.Serialization.XmlEnumAttribute("390")>
Item390 Item390 = 390
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("393")> <System.Xml.Serialization.XmlEnumAttribute("393")>
Item393 Item393 = 393
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("394")> <System.Xml.Serialization.XmlEnumAttribute("394")>
Item394 Item394 = 394
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("395")> <System.Xml.Serialization.XmlEnumAttribute("395")>
Item395 Item395 = 395
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("396")> <System.Xml.Serialization.XmlEnumAttribute("396")>
Item396 Item396 = 396
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("420")> <System.Xml.Serialization.XmlEnumAttribute("420")>
Item420 Item420 = 420
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("456")> <System.Xml.Serialization.XmlEnumAttribute("456")>
Item456 Item456 = 456
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("457")> <System.Xml.Serialization.XmlEnumAttribute("457")>
Item457 Item457 = 457
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("458")> <System.Xml.Serialization.XmlEnumAttribute("458")>
Item458 Item458 = 458
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("527")> <System.Xml.Serialization.XmlEnumAttribute("527")>
Item527 Item527 = 527
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("575")> <System.Xml.Serialization.XmlEnumAttribute("575")>
Item575 Item575 = 575
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("623")> <System.Xml.Serialization.XmlEnumAttribute("623")>
Item623 Item623 = 623
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("633")> <System.Xml.Serialization.XmlEnumAttribute("633")>
Item633 Item633 = 633
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("751")> <System.Xml.Serialization.XmlEnumAttribute("751")>
Item751 Item751 = 751
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("780")> <System.Xml.Serialization.XmlEnumAttribute("780")>
Item780 Item780 = 780
'''<remarks/> '''<remarks/>
<System.Xml.Serialization.XmlEnumAttribute("935")> <System.Xml.Serialization.XmlEnumAttribute("935")>
Item935 Item935 = 935
End Enum End Enum
'''<remarks/> '''<remarks/>

View File

@@ -1,8 +1,14 @@
Public Class XmlItemProperty Public Class XmlItemProperty
Public IsRequired As Boolean
Public IsGrouped As Boolean
Public TableName As String Public TableName As String
Public TableColumn As String Public TableColumn As String
Public Description As String Public Description As String
Public IsRequired As Boolean
Public IsGrouped As Boolean
Public GroupScope As String Public GroupScope As String
''' <summary>
''' Document version, eg. ZUGFeRD Schema version
''' </summary>
Public Specification As String
End Class End Class

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net461" /> <package id="Newtonsoft.Json" version="12.0.3" targetFramework="net461" />
<package id="NLog" version="4.7.15" targetFramework="net461" /> <package id="NLog" version="5.0.5" targetFramework="net461" />
</packages> </packages>

View File

@@ -1,223 +0,0 @@
Option Explicit On
Imports System.IO
Imports DigitalData.Modules.Interfaces
Imports DigitalData.Modules.Jobs
Imports DigitalData.Modules.Config
Imports DigitalData.Modules.Logging
Imports Newtonsoft.Json.Linq
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text.RegularExpressions
Imports DigitalData.Modules.Database
Imports System.Data
Public Class GraphQLJob
Inherits JobBase
Implements IJob(Of GraphQLArgs)
Private _GraphQL As GraphQLInterface = Nothing
Private Const PLACEHOLDER_STATIC = "STATIC:"
Public Sub New(LogConfig As LogConfig, MSSQL As MSSQLServer)
MyBase.New(LogConfig, Nothing, MSSQL)
End Sub
Public Sub Start(Args As GraphQLArgs) Implements IJob(Of GraphQLArgs).Start
Try
Dim oConfigPath As String = Args.QueryConfigPath
Dim oConfigManager As New ConfigManager(Of GraphQLConfig)(_LogConfig, oConfigPath)
With oConfigManager.Config
_GraphQL = New GraphQLInterface(_LogConfig, .BaseUrl, .Email, .Password, .CertificateFingerprint)
End With
' Login to get cookie
_Logger.Debug("Logging in")
Dim oLoginResponse = _GraphQL.Login()
' save cookie for future requests
_GraphQL.SaveCookies(oLoginResponse.Cookies.Item(0))
_Logger.Debug("Loading Queries")
' Load query data from TBCUST_JOBRUNNER_QUERY
Dim oQueryTable As DataTable = _MSSQL.GetDatatable("SELECT * FROM TBCUST_JOBRUNNER_QUERY ORDER BY OPERATION_NAME, CLEAR_BEFORE_FILL ASC")
Dim oQueryList As New List(Of GraphQL.Query)
' Save query data to business objects
For Each oRow As DataRow In oQueryTable.Rows
Dim oQuery As New GraphQL.Query With {
.Id = oRow.Item("GUID"),
.Name = oRow.Item("TITLE"),
.ClearBeforeFill = oRow.Item("CLEAR_BEFORE_FILL"),
.ConnectionId = oRow.Item("CON_ID"), ' TODO: Connection String?
.DestinationTable = oRow.Item("DESTINATION_TABLE"),
.OperationName = oRow.Item("OPERATION_NAME"),
.MappingBasePath = oRow.Item("MAPPING_BASE_PATH"),
.QueryString = oRow.Item("QUERY_STRING"),
.QueryConstraint = oRow.Item("QUERY_CONSTRAINT")
}
oQueryList.Add(oQuery)
Next
_Logger.Debug("Getting the data from GraphQL")
For Each oQuery As GraphQL.Query In oQueryList
Try
_Logger.NewBlock($"Query [{oQuery.Name}]")
Dim oConnectionId As Integer = oQuery.ConnectionId
Dim oConnectionString = _MSSQL.Get_ConnectionStringforID(oConnectionId)
Dim oDatabase As New MSSQLServer(_LogConfig, oConnectionString)
' Reset all records to status = 0
_Logger.Info("Resetting data with constraint [{1}]", oQuery.Name, oQuery.QueryConstraint)
Dim oResetSQL = $"UPDATE {oQuery.DestinationTable} SET STATUS = 0"
If oQuery.QueryConstraint <> String.Empty Then
oResetSQL &= $" WHERE {oQuery.QueryConstraint}"
End If
_MSSQL.ExecuteNonQuery(oResetSQL)
_Logger.Info("Getting data..", oQuery.Name)
' get the data from GraphQL
Dim oDataResponse = _GraphQL.GetData(oQuery.QueryString, oQuery.OperationName)
Dim oResult As String
' write data to string
Using oStream = oDataResponse.GetResponseStream()
Using oReader As New StreamReader(oStream)
oResult = oReader.ReadToEnd()
End Using
End Using
' Fill the query object with field mapping data from TBCUST_JOBRUNNER_QUERY_MAPPING
Dim oSQL As String = "SELECT t2.* FROM TBCUST_JOBRUNNER_QUERY_MAPPING t
JOIN TBCUST_JOBRUNNER_MAPPING t2 ON t.MAPPING_ID = t2.GUID
WHERE t.QUERY_ID = {0}"
Dim oMappingTable As DataTable = _MSSQL.GetDatatable(String.Format(oSQL, oQuery.Id))
For Each oMapping As DataRow In oMappingTable.Rows
oQuery.MappingFields.Add(New GraphQL.FieldMapping With {
.DestinationColumn = oMapping.Item("DestinationColumn"),
.SourcePath = oMapping.Item("SourcePath")
})
Next
' Handle the response from GraphQL and insert Data
Dim oQueryHandleResult = HandleResponse(oResult, oQuery, oDatabase)
If IsNothing(oQueryHandleResult) Then
Continue For
End If
' Finally delete all old records
Dim oDeleteSQL = $"DELETE FROM {oQuery.DestinationTable} WHERE STATUS = 0"
If oQuery.QueryConstraint <> String.Empty Then
oDeleteSQL &= $" AND {oQuery.QueryConstraint}"
End If
_Logger.Info("Success, deleting old records..", oQuery.Name)
_MSSQL.ExecuteNonQuery(oDeleteSQL)
Catch ex As Exception
_Logger.Warn("Error while getting Data for Name/OperationName [{0}]/[{1}]", oQuery.Name, oQuery.OperationName)
_Logger.Error(ex)
_Logger.Info("Failure, deleting new records..", oQuery.Name)
' If a crash happens, delete all records which were inserted in this run,
' thus going back to the previous state
Dim oDeleteSQL = $"DELETE FROM {oQuery.DestinationTable} WHERE STATUS = 1"
If oQuery.QueryConstraint <> String.Empty Then
oDeleteSQL &= $" AND {oQuery.QueryConstraint}"
End If
_MSSQL.ExecuteNonQuery(oDeleteSQL)
Finally
_Logger.EndBlock()
End Try
Next
' logout
_Logger.Debug("Logging out")
Dim oLogoutResponse = _GraphQL.Logout()
Catch ex As Exception
_Logger.Error(ex)
Throw ex
End Try
End Sub
Private Function HandleResponse(JsonString As String, QueryData As GraphQL.Query, DB As Database.MSSQLServer) As GraphQL.Query
Dim oObj As JObject = JObject.Parse(JsonString)
Dim oResultList As JToken
If _GraphQL.ReadJSONPathFragmented(oObj, QueryData.MappingBasePath) = False Then
_Logger.Warn("There is an error in the MappingBasePath [{1}] configuration of query [{0}]", QueryData.Name, QueryData.MappingBasePath)
End If
Try
oResultList = oObj.SelectToken(QueryData.MappingBasePath, errorWhenNoMatch:=True)
Catch ex As Exception
_Logger.Warn("HandleResponse: Could not find BasePath: [{0}] for query [{1}]", QueryData.MappingBasePath, QueryData.Name)
_Logger.Error(ex)
Return Nothing
End Try
If oResultList Is Nothing Then
_Logger.Warn("HandleResponse: Could not find BasePath: [{0}] for query [{1}]", QueryData.MappingBasePath, QueryData.Name)
Return Nothing
End If
_Logger.Info("HandleResponse: Processing Queue [{0}] with [{1}] Items", QueryData.Name, oResultList.Count)
For Each oResultItem As JToken In oResultList
Try
Dim oValues As New List(Of String)
Dim oKeys As New List(Of String)
For Each oMapping In QueryData.MappingFields
Dim oValue As String = String.Empty
If oMapping.SourcePath.StartsWith(PLACEHOLDER_STATIC) Then
oValue = oMapping.SourcePath.Replace(PLACEHOLDER_STATIC, String.Empty)
Else
Dim oToken = oResultItem.SelectToken(oMapping.SourcePath)
If oToken Is Nothing Then
_Logger.Warn("HandleResponse: Could not find value at SourcePath: {0}", oMapping.SourcePath)
oValue = String.Empty
Else
oValue = oToken.ToString
End If
End If
oValues.Add(oValue)
oKeys.Add(oMapping.DestinationColumn)
Next
Dim oColumnValues = oValues.
Select(Function(Value) Regex.Replace(Value, "'", "''")).
Select(Function(Value) $"'{Value}'").
ToList()
Dim oValueString = String.Join(",", oColumnValues)
Dim oColumns = String.Join(",", oKeys.ToArray)
Dim oSQL As String = $"INSERT INTO {QueryData.DestinationTable} ({oColumns}) VALUES ({oValueString})"
DB.ExecuteNonQuery(oSQL)
Catch ex As Exception
_Logger.Error(ex)
End Try
Next
Return QueryData
End Function
Public Function ShouldStart(Arguments As GraphQLArgs) As Boolean Implements IJob(Of GraphQLArgs).ShouldStart
Return Arguments.Enabled
End Function
End Class

View File

@@ -1,4 +1,6 @@
Imports System.IO Imports System.Collections.Generic
Imports System.IO
Imports DigitalData.Modules.Interfaces.ZUGFeRDInterface
Public Class Exceptions Public Class Exceptions
Public Class MissingValueException Public Class MissingValueException
@@ -40,6 +42,17 @@ Public Class Exceptions
End Sub End Sub
End Class End Class
Public Class UnsupportedFerdException
Inherits ApplicationException
Public ReadOnly Property XmlFile As String
Public Sub New(pXmlFile As String)
MyBase.New("ZUGFeRD document found but is not supported!")
_XmlFile = pXmlFile
End Sub
End Class
Public Class NoFerdsException Public Class NoFerdsException
Inherits ApplicationException Inherits ApplicationException

284
Jobs/GraphQL/GraphQLJob.vb Normal file
View File

@@ -0,0 +1,284 @@
Option Explicit On
Imports System.Collections.Generic
Imports System.Data
Imports System.IO
Imports System.Linq
Imports System.Net.NetworkInformation
Imports DigitalData.Modules.Config
Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Interfaces
Imports DigitalData.Modules.Jobs.GraphQL
Imports DigitalData.Modules.Language
Imports DigitalData.Modules.Logging
Imports Newtonsoft.Json.Linq
Public Class GraphQLJob
Inherits JobBase
Implements IJob(Of GraphQLArgs)
Private _GraphQL As GraphQLInterface = Nothing
Private Const PLACEHOLDER_STATIC = "STATIC:"
Private Const JOB_NAME = "GraphQL Job"
Public Sub New(LogConfig As LogConfig, MSSQL As MSSQLServer)
MyBase.New(LogConfig, Nothing, MSSQL)
End Sub
Public Sub Start(Args As GraphQLArgs) Implements IJob(Of GraphQLArgs).Start
Try
Dim oConfigPath As String = Args.QueryConfigPath
Dim oConfigManager As New ConfigManager(Of GraphQLConfig)(_LogConfig, oConfigPath)
With oConfigManager.Config
_GraphQL = New GraphQLInterface(_LogConfig, .BaseUrl, .Email, .Password, .CertificateFingerprint)
End With
' Login to get cookie
_Logger.Debug("Logging in")
Dim oLoginResponse = _GraphQL.Login()
' save cookie for future requests
_GraphQL.SaveCookies(oLoginResponse.Cookies.Item(0))
_Logger.Debug("Loading Queries")
' Load query data from TBCUST_JOBRUNNER_QUERY
Dim oQueryTable As DataTable = _MSSQL.GetDatatable("SELECT * FROM TBCUST_JOBRUNNER_QUERY ORDER BY SEQUENCE")
Dim oQueryList As New List(Of Query)
' Save query data to business objects
For Each oRow As DataRow In oQueryTable.Rows
Dim oQuery As New Query With {
.Id = oRow.Item("GUID"),
.Name = oRow.Item("TITLE"),
.ClearBeforeFill = oRow.ItemEx("CLEAR_BEFORE_FILL", False),
.ConnectionId = oRow.ItemEx("CON_ID", 1), ' TODO: Connection String?
.DestinationTable = oRow.ItemEx("DESTINATION_TABLE", String.Empty),
.OperationName = oRow.ItemEx("OPERATION_NAME", String.Empty),
.MappingBasePath = oRow.ItemEx("MAPPING_BASE_PATH", String.Empty),
.QueryString = oRow.ItemEx("QUERY_STRING", String.Empty)
}
If oQuery.DestinationTable = String.Empty Then
_Logger.Warn("Value [DestinationTable] could not be read. Configuration incomplete.")
End If
If oQuery.OperationName = String.Empty Then
_Logger.Warn("Value [OperationName] could not be read. Configuration incomplete.")
End If
If oQuery.MappingBasePath = String.Empty Then
_Logger.Warn("Value [MappingBasePath] could not be read. Configuration incomplete.")
End If
If oQuery.QueryString = String.Empty Then
_Logger.Warn("Value [QueryString] could not be read. Configuration incomplete.")
End If
oQueryList.Add(oQuery)
Next
_Logger.Debug("Running [{0}] queries.", oQueryList.Count)
' run
For Each oQuery As Query In oQueryList
_Logger.Debug("Running Query [{0}].", oQuery.Name)
Dim oQueryResult = RunQuery(oQuery)
_Logger.Info("Query [{0}] finished with Result [{1}]", oQuery.Name, oQueryResult)
Next
' logout
_Logger.Debug("Logging out")
Dim oLogoutResponse = _GraphQL.Logout()
_Logger.Info("Finished GraphQL Job")
Catch ex As Exception
_Logger.Warn("Finished GraphQL Job with errors")
_Logger.Error(ex)
Throw ex
End Try
End Sub
Private Function RunQuery(pQuery As Query)
Try
_Logger.Info("Executing Query [{0}]", pQuery.Name)
Dim oConnectionId As Integer = pQuery.ConnectionId
Dim oConnectionString = _MSSQL.Get_ConnectionStringforID(oConnectionId)
If oConnectionString = String.Empty Then
_Logger.Warn("Could not get Connection String for ConnectionId [{0}]", oConnectionId)
End If
Dim oDatabase As New MSSQLServer(_LogConfig, oConnectionString)
'TODO: ONly set status when clear before fill is false
'TODO: ADDED_WHO which contains the query id which inserted the rows
' Clear Table before inserting
If pQuery.ClearBeforeFill = True Then
If DeleteWithQueryName(pQuery) = False Then
Throw New ApplicationException($"Error while clearing table before fill for Query [{pQuery.Name}]")
End If
End If
' Reset all records to status = 0
If pQuery.ClearBeforeFill = False Then
_Logger.Info("Resetting data for Query [{0}]", pQuery.Name)
If UpdateWithStatus(pQuery, 0) = False Then
Throw New ApplicationException($"Error while resetting status of current Records for Query [{pQuery.Name}]")
End If
End If
' get the data from GraphQL
_Logger.Info("Getting data..", pQuery.Name)
Dim oDataResponse = _GraphQL.GetData(pQuery.QueryString, pQuery.OperationName)
Dim oResult As String
' write data to string
Using oStream = oDataResponse.GetResponseStream()
Using oReader As New StreamReader(oStream)
oResult = oReader.ReadToEnd()
End Using
End Using
' Fill the query object with field mapping data from TBCUST_JOBRUNNER_QUERY_MAPPING
Dim oSQL As String = "SELECT t2.* FROM TBCUST_JOBRUNNER_QUERY_MAPPING t
JOIN TBCUST_JOBRUNNER_MAPPING t2 ON t.MAPPING_ID = t2.GUID
WHERE t.QUERY_ID = {0}"
Dim oMappingTable As DataTable = _MSSQL.GetDatatable(String.Format(oSQL, pQuery.Id))
For Each oMapping As DataRow In oMappingTable.Rows
pQuery.MappingFields.Add(New GraphQL.FieldMapping With {
.DestinationColumn = oMapping.Item("DestinationColumn"),
.SourcePath = oMapping.Item("SourcePath")
})
Next
' Handle the response from GraphQL and insert Data
Dim oWriteDataResult As GraphQL.Query = WriteNewQueryData(oResult, pQuery, oDatabase)
If IsNothing(oWriteDataResult) Then
Throw New ApplicationException($"Error while handling Result of Query [{pQuery.Name}]")
End If
_Logger.Info("New Data successfully inserted for Query [{0}]", pQuery.Name)
' Finally delete all old records
If pQuery.ClearBeforeFill = False Then
_Logger.Info("Deleting old records for Query [{0}].", pQuery.Name)
If DeleteWithStatus(pQuery, 0) = False Then
Throw New ApplicationException($"Error while deleting current Records for Query [{pQuery.Name}]")
End If
End If
Return True
Catch ex As Exception
_Logger.Warn("Error while getting Data for Name/OperationName [{0}]/[{1}]", pQuery.Name, pQuery.OperationName)
_Logger.Error(ex)
' If a crash happens, delete all records which were inserted in this run,
' thus going back to the previous state
_Logger.Info("Failure, deleting new records..", pQuery.Name)
If pQuery.ClearBeforeFill = False Then
If DeleteWithStatus(pQuery, 1) = False Then
Throw New ApplicationException($"Error while deleting new Records for Query [{pQuery.Name}]")
End If
End If
Return False
Finally
_Logger.Debug("Finished running Query [{0}].", pQuery.Name)
End Try
End Function
Private Function DeleteWithQueryName(pQuery)
Dim oDeleteSQL = $"TRUNCATE TABLE {pQuery.DestinationTable}"
Return _MSSQL.ExecuteNonQuery(oDeleteSQL)
End Function
Private Function DeleteWithStatus(pQuery As Query, pStatus As Integer)
Dim oDeleteSQL = $"DELETE FROM {pQuery.DestinationTable} WHERE STATUS = {pStatus} AND ADDED_QUERY_ID = '{pQuery.Id}'"
Return _MSSQL.ExecuteNonQuery(oDeleteSQL)
End Function
Private Function UpdateWithStatus(pQuery As Query, pStatus As Integer)
Dim oResetSQL = $"UPDATE {pQuery.DestinationTable} SET STATUS = {pStatus} WHERE ADDED_QUERY_ID = '{pQuery.Id}'"
Return _MSSQL.ExecuteNonQuery(oResetSQL)
End Function
Private Function WriteNewQueryData(JsonString As String, QueryData As GraphQL.Query, DB As Database.MSSQLServer) As GraphQL.Query
Dim oObj As JObject = JObject.Parse(JsonString)
Dim oResultList As JToken
If _GraphQL.ReadJSONPathFragmented(oObj, QueryData.MappingBasePath) = False Then
_Logger.Warn("There is an error in the MappingBasePath [{1}] configuration of query [{0}]", QueryData.Name, QueryData.MappingBasePath)
End If
Try
oResultList = oObj.SelectToken(QueryData.MappingBasePath, errorWhenNoMatch:=True)
Catch ex As Exception
_Logger.Warn("WriteNewQueryData: Could not find BasePath: [{0}] for query [{1}]", QueryData.MappingBasePath, QueryData.Name)
_Logger.Error(ex)
Return Nothing
End Try
If oResultList Is Nothing Then
_Logger.Warn("WriteNewQueryData: Could not find BasePath: [{0}] for query [{1}]", QueryData.MappingBasePath, QueryData.Name)
Return Nothing
End If
_Logger.Info("WriteNewQueryData: Processing Queue [{0}] with [{1}] Items", QueryData.Name, oResultList.Count)
For Each oResultItem As JToken In oResultList
Try
' ADDED_WHO, ADDED_QUERY_ID are system fields which are used to correctly fill
' and delete rows in the destination table without touching rows from other queries
Dim oKeys As New List(Of String) From {"ADDED_WHO", "ADDED_QUERY_ID", "STATUS"}
Dim oValues As New List(Of String) From {JOB_NAME, QueryData.Id, "1"}
For Each oMapping In QueryData.MappingFields
Dim oValue As String = String.Empty
If oMapping.SourcePath.StartsWith(PLACEHOLDER_STATIC) Then
oValue = oMapping.SourcePath.Replace(PLACEHOLDER_STATIC, String.Empty)
Else
Dim oToken = oResultItem.SelectToken(oMapping.SourcePath)
If oToken Is Nothing Then
_Logger.Warn("WriteNewQueryData: Could not find value at SourcePath: {0}", oMapping.SourcePath)
oValue = String.Empty
Else
oValue = oToken.ToString
End If
End If
oValues.Add(oValue)
oKeys.Add(oMapping.DestinationColumn)
Next
Dim oColumnString = String.Join(",", oKeys.ToArray)
Dim oValueList = oValues.Select(Function(Value) $"'{Value.EscapeForSQL}'").ToList()
Dim oValueString = String.Join(",", oValueList)
Dim oSQL As String = $"INSERT INTO {QueryData.DestinationTable} ({oColumnString}) VALUES ({oValueString})"
DB.ExecuteNonQuery(oSQL)
Catch ex As Exception
_Logger.Error(ex)
End Try
Next
Return QueryData
End Function
Public Function ShouldStart(Arguments As GraphQLArgs) As Boolean Implements IJob(Of GraphQLArgs).ShouldStart
Return Arguments.Enabled
End Function
End Class

View File

@@ -6,9 +6,7 @@ Namespace GraphQL
Public Property Name As String Public Property Name As String
Public Property ConnectionId As String = "" Public Property ConnectionId As String = ""
Public Property ClearBeforeFill As Boolean = False Public Property ClearBeforeFill As Boolean = False
Public Property ClearCommand As String = ""
Public Property QueryString As String = "" Public Property QueryString As String = ""
Public Property QueryConstraint As String = ""
Public Property OperationName As String = "" Public Property OperationName As String = ""
Public Property DestinationTable As String = "" Public Property DestinationTable As String = ""

View File

@@ -1,8 +1,19 @@
Imports System.Collections.Generic Imports System.Collections.Generic
Public Class JobConfig Public Class JobConfig
Public Enabled As Boolean Public Property Name As JobType
Public StartImmediately As Boolean Public Property Enabled As Boolean = False
Public CronExpression As String Public Property StartWithoutDelay As Boolean = False
Public Arguments As Dictionary(Of String, String) Public Property CronSchedule As String = ""
Public Property ArgsString As String = ""
<Xml.Serialization.XmlIgnore>
Public Property Args As New Dictionary(Of String, String)
Public Enum JobType
ADSync
GraphQL
Test
End Enum
End Class End Class

View File

@@ -13,46 +13,17 @@ Public Class JobConfigParser
''' </summary> ''' </summary>
''' <param name="ConfigString"></param> ''' <param name="ConfigString"></param>
''' <returns>A populated JobConfig object</returns> ''' <returns>A populated JobConfig object</returns>
Public Shared Function ParseConfig(ConfigString As String) As JobConfig Public Shared Function ParseConfig(pJobConfig As JobConfig) As JobConfig
If JobOptionsRegex.IsMatch(ConfigString) Then
Dim oMatches = JobOptionsRegex.Matches(ConfigString)
Dim oOptions As New JobConfig
Dim oSplitOptions As String() = ConfigString.Split(ARGS_LIST_DELIMITER) ' 24.11.2022: This only parses the optional Job arguments,
' everything is comparmentalized in the Service config
pJobConfig.Args = ParseOptionalArguments(pJobConfig.ArgsString)
Return pJobConfig
If oSplitOptions.Length = 3 Then
oOptions = ParseEnabled(oSplitOptions(0), oOptions)
oOptions.CronExpression = oSplitOptions(1)
oOptions.Arguments = ParseOptionalArguments(oSplitOptions(2))
ElseIf oSplitOptions.Length = 2 Then
oOptions = ParseEnabled(oSplitOptions(0), oOptions)
oOptions.CronExpression = oSplitOptions(1)
oOptions.Arguments = New Dictionary(Of String, String)
Else
Throw New ArgumentException("Config Malformed")
End If
Return oOptions
Else
Throw New ArgumentException("Config Malformed")
End If
End Function End Function
Public Shared Function ParseEnabled(EnabledValue As String, Options As JobConfig) As JobConfig
Select Case EnabledValue
Case "True"
Options.Enabled = True
Options.StartImmediately = False
Case "Debug"
Options.Enabled = True
Options.StartImmediately = True
Case Else
Options.Enabled = False
Options.StartImmediately = False
End Select
Return Options
End Function
Private Shared Function ParseOptionalArguments(ArgsString As String) As Dictionary(Of String, String) Private Shared Function ParseOptionalArguments(ArgsString As String) As Dictionary(Of String, String)
Dim oArgsDictionary As New Dictionary(Of String, String) Dim oArgsDictionary As New Dictionary(Of String, String)

View File

@@ -91,17 +91,17 @@
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="EDMI\ADSync\ADSyncArgs.vb" /> <Compile Include="ADSync\ADSyncArgs.vb" />
<Compile Include="EDMI\ADSync\ADSyncJob.vb" /> <Compile Include="ADSync\ADSyncJob.vb" />
<Compile Include="EDMI\GraphQL\GraphQLArgs.vb" /> <Compile Include="GraphQL\GraphQLArgs.vb" />
<Compile Include="EDMI\GraphQL\GraphQLConfig.vb" /> <Compile Include="GraphQL\GraphQLConfig.vb" />
<Compile Include="EDMI\GraphQL\GraphQLJob.vb" /> <Compile Include="GraphQL\GraphQLJob.vb" />
<Compile Include="EDMI\GraphQL\GraphQLQuery.vb" /> <Compile Include="GraphQL\GraphQLQuery.vb" />
<Compile Include="EDMI\ZUGFeRD\EmailData.vb" /> <Compile Include="ZUGFeRD\EmailData.vb" />
<Compile Include="EDMI\ZUGFeRD\EmailFunctions.vb" /> <Compile Include="ZUGFeRD\EmailFunctions.vb" />
<Compile Include="EDMI\ZUGFeRD\EmailStrings.vb" /> <Compile Include="ZUGFeRD\EmailStrings.vb" />
<Compile Include="EDMI\ZUGFeRD\ImportZUGFeRDFiles.vb" /> <Compile Include="ZUGFeRD\ImportZUGFeRDFiles.vb" />
<Compile Include="EDMI\ZUGFeRD\WorkerArgs.vb" /> <Compile Include="ZUGFeRD\WorkerArgs.vb" />
<Compile Include="Exceptions.vb" /> <Compile Include="Exceptions.vb" />
<Compile Include="JobInterface.vb" /> <Compile Include="JobInterface.vb" />
<Compile Include="JobBase.vb" /> <Compile Include="JobBase.vb" />
@@ -116,6 +116,10 @@
</Compile> </Compile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Reference Include="DigitalData.Modules.Language, Version=1.7.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Language\bin\Debug\DigitalData.Modules.Language.dll</HintPath>
</Reference>
<Reference Include="FirebirdSql.Data.FirebirdClient, Version=7.5.0.0, Culture=neutral, PublicKeyToken=3750abcc3150b00c, processorArchitecture=MSIL"> <Reference Include="FirebirdSql.Data.FirebirdClient, Version=7.5.0.0, Culture=neutral, PublicKeyToken=3750abcc3150b00c, processorArchitecture=MSIL">
<HintPath>..\packages\FirebirdSql.Data.FirebirdClient.7.5.0\lib\net452\FirebirdSql.Data.FirebirdClient.dll</HintPath> <HintPath>..\packages\FirebirdSql.Data.FirebirdClient.7.5.0\lib\net452\FirebirdSql.Data.FirebirdClient.dll</HintPath>
</Reference> </Reference>
@@ -123,8 +127,8 @@
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference> </Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> <Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.7.15\lib\net45\NLog.dll</HintPath> <HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />

View File

@@ -12,8 +12,8 @@ Imports System.Runtime.InteropServices
<Assembly: AssemblyDescription("")> <Assembly: AssemblyDescription("")>
<Assembly: AssemblyCompany("Digital Data")> <Assembly: AssemblyCompany("Digital Data")>
<Assembly: AssemblyProduct("Modules.Jobs")> <Assembly: AssemblyProduct("Modules.Jobs")>
<Assembly: AssemblyCopyright("Copyright © 2021")> <Assembly: AssemblyCopyright("Copyright © 2023")>
<Assembly: AssemblyTrademark("")> <Assembly: AssemblyTrademark("1.15.1.0")>
<Assembly: ComVisible(False)> <Assembly: ComVisible(False)>
@@ -30,5 +30,5 @@ Imports System.Runtime.InteropServices
' Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern ' Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
' übernehmen, indem Sie "*" eingeben: ' übernehmen, indem Sie "*" eingeben:
<Assembly: AssemblyVersion("1.8.6.0")> <Assembly: AssemblyVersion("1.15.1.0")>
<Assembly: AssemblyFileVersion("1.8.6.0")> <Assembly: AssemblyFileVersion("1.15.1.0")>

View File

@@ -12,11 +12,12 @@ Option Strict On
Option Explicit On Option Explicit On
Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ <Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.3.0.0"), _ Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _ Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class Settings Partial Friend NotInheritable Class Settings
Inherits Global.System.Configuration.ApplicationSettingsBase Inherits Global.System.Configuration.ApplicationSettingsBase
Private Shared defaultInstance As Settings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New Settings()),Settings) Private Shared defaultInstance As Settings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New Settings()),Settings)
@@ -52,7 +53,8 @@ Partial Friend NotInheritable Class Settings
Return defaultInstance Return defaultInstance
End Get End Get
End Property End Property
End Class End Class
End Namespace
Namespace My Namespace My
@@ -62,9 +64,9 @@ Namespace My
Friend Module MySettingsProperty Friend Module MySettingsProperty
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _ <Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
Friend ReadOnly Property Settings() As Global.DigitalData.Modules.Jobs.Settings Friend ReadOnly Property Settings() As Global.DigitalData.Modules.Jobs.My.Settings
Get Get
Return Global.DigitalData.Modules.Jobs.Settings.Default Return Global.DigitalData.Modules.Jobs.My.Settings.Default
End Get End Get
End Property End Property
End Module End Module

View File

@@ -1,5 +1,6 @@
Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Database Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Language
Imports System.Data Imports System.Data
Imports System.IO Imports System.IO
Imports System.Data.SqlClient Imports System.Data.SqlClient
@@ -83,13 +84,14 @@ Public Class EmailFunctions
Dim oFinalBodyText = String.Format(EmailStrings.EMAIL_WRAPPING_TEXT.Replace(EmailStrings.constNAME_ZUGFERD_PORTAL, NamePortal), oCompleteBodyText) Dim oFinalBodyText = String.Format(EmailStrings.EMAIL_WRAPPING_TEXT.Replace(EmailStrings.constNAME_ZUGFERD_PORTAL, NamePortal), oCompleteBodyText)
Dim oEmailAddress = pEmailData.From Dim oEmailAddress = pEmailData.From
Dim oAttachment = pEmailData.Attachment Dim oAttachmentPath = pEmailData.Attachment
If oAttachment <> String.Empty Then If oAttachmentPath <> String.Empty Then
_logger.Debug($"Attachment_String [{oAttachment}]!") _logger.Debug($"Attachment_String [{oAttachmentPath}]!")
If IO.File.Exists(oAttachment) = False Then If IO.File.Exists(oAttachmentPath) = False Then
_logger.Info($"Attachment.File [{oAttachment}] is not existing!!!") _logger.Info($"Attachment.File [{oAttachmentPath}] is not existing!!!")
End If End If
End If End If
Dim oAttachmentPathEscaped = oAttachmentPath.Replace("'", "''")
If IsNothing(oEmailAddress) OrElse String.IsNullOrWhiteSpace(oEmailAddress) Then If IsNothing(oEmailAddress) OrElse String.IsNullOrWhiteSpace(oEmailAddress) Then
_logger.Warn("Could not find email-address for MessageId {0}", MessageId) _logger.Warn("Could not find email-address for MessageId {0}", MessageId)
@@ -133,7 +135,7 @@ Public Class EmailFunctions
,'{oFinalBodyText}' ,'{oFinalBodyText}'
,'{SourceProcedure}' ,'{SourceProcedure}'
,'{oCreatedWho}' ,'{oCreatedWho}'
,'{oAttachment}')" ,'{oAttachmentPathEscaped}')"
_mssql.ExecuteNonQuery(oInsert) _mssql.ExecuteNonQuery(oInsert)
Else Else
'If oDTResult.Rows.Count = 0 Then 'If oDTResult.Rows.Count = 0 Then
@@ -163,10 +165,19 @@ Public Class EmailFunctions
_logger.Debug("Got Email Data for FileId {0}", MessageId) _logger.Debug("Got Email Data for FileId {0}", MessageId)
oRow = oDatatable.Rows.Item(oDatatable.Rows.Count - 1) oRow = oDatatable.Rows.Item(oDatatable.Rows.Count - 1)
Dim oFromDefault = String.Format("No Sender found for ({0})", MessageId)
Dim oFrom = oRow.ItemEx("EMAIL_FROM", oFromDefault)
Dim oAttachmentDefault = String.Format("No Attachment found for ({0})", MessageId)
Dim oAttachment = oRow.ItemEx("EMAIL_ATTMT1", oAttachmentDefault)
Dim oSubjectDefault = String.Format("No Subject found for ({0})", MessageId)
Dim oSubject = oRow.ItemEx("EMAIL_SUBJECT", oSubjectDefault)
Return New EmailData() With { Return New EmailData() With {
.From = oRow.Item("EMAIL_FROM"), .From = oFrom,
.Attachment = oRow.Item("EMAIL_ATTMT1"), .Attachment = oAttachment,
.Subject = oRow.Item("EMAIL_SUBJECT") .Subject = oSubject
} }
Catch ex As Exception Catch ex As Exception
_logger.Warn("Could not fetch Email Data for FileId {0}", MessageId) _logger.Warn("Could not fetch Email Data for FileId {0}", MessageId)

View File

@@ -20,9 +20,13 @@
Public Const EMAIL_MD5_ERROR = "<p>Die von Ihnen gesendete Rechnung wurde bereits von unserem System verarbeitet.</p>" Public Const EMAIL_MD5_ERROR = "<p>Die von Ihnen gesendete Rechnung wurde bereits von unserem System verarbeitet.</p>"
Public Const EMAIL_TOO_MUCH_FERDS = "<p>Ihre Email enthielt mehr als ein ZUGFeRD-Dokument.</p>" Public Const EMAIL_VALIDATION_ERROR = "
<p>Die von Ihnen gesendete Rechnung hat die ZUGFeRD Validierung nicht bestanden.</p>
<p>Die folgenden Felder sind nicht korrekt:<ul>{0}</ul></p>"
Public Const EMAIL_NO_FERDS = "<p>Ihre Email enthielt keine ZUGFeRD-Dokumente.</p>" Public Const EMAIL_TOO_MUCH_FERDS = "<p>In Ihrer Email ({0}) sind mehr als ein ZUGFeRD Dokument enthalten. Bitte prüfen Sie Rechnung an Anhänge. Nur eine Rechnung darf das ZUGFeRD-Format enthalten</p>"
Public Const EMAIL_NO_FERDS = "<p>Ihre Email ({0}) enthielt keine ZUGFeRD-Dokumente.</p>"
Public Const EMAIL_FILE_SIZE_REACHED = " Public Const EMAIL_FILE_SIZE_REACHED = "
<p>Die von Ihnen gesendete Rechnung oder einer der Rechnungs-Anhänge überschreitet die erlaubte Größe von <strong>{0} MB</strong>.</p> <p>Die von Ihnen gesendete Rechnung oder einer der Rechnungs-Anhänge überschreitet die erlaubte Größe von <strong>{0} MB</strong>.</p>
@@ -32,9 +36,13 @@
" "
Public Const EMAIL_INVALID_DOCUMENT = " Public Const EMAIL_INVALID_DOCUMENT = "
<p>Ihre Email enthielt ein ZUGFeRD Dokument, welches aber inkorrekt formatiert wurde.</p> <p>Ihre Email ({0}) enthielt ein ZUGFeRD Dokument, welches aber inkorrekt formatiert wurde.</p>
<p>Mögliche Gründe für ein inkorrektes Format:<ul> <p>Mögliche Gründe für ein inkorrektes Format:<ul>
<li>Betrags-Werte weisen ungültiges Format auf (25,01 anstatt 25.01)</li> <li>Betrags-Werte weisen ungültiges Format auf (z.B. 25,01 anstatt 25.01)</li>
</ul></p> </ul></p>
" "
Public Const EMAIL_UNSUPPORTED_DOCUMENT = "
<p>Ihre Email ({0}) enthielt ein ZUGFeRD Format ({1}), welches zur Zeit noch nicht freigeschaltet ist.</p>
"
End Class End Class

View File

@@ -26,35 +26,40 @@ Public Class ImportZUGFeRDFiles
Private Const DIRECTORY_DONT_MOVE = "DIRECTORY_DONT_MOVE" Private Const DIRECTORY_DONT_MOVE = "DIRECTORY_DONT_MOVE"
' List of allowed extensions for PDF/A Attachments ' List of allowed extensions for PDF/A Attachments
' This list should not contain xml so the zugferd xml file will be filtered out ' This list should not contain xml so the zugferd xml file will be filtered out
Private ReadOnly AllowedExtensions As List(Of String) = New List(Of String) From {"docx", "doc", "pdf", "xls", "xlsx", "ppt", "pptx", "txt"} Private ReadOnly AllowedExtensions As New List(Of String) From {"docx", "doc", "pdf", "xls", "xlsx", "ppt", "pptx", "txt"}
Private ReadOnly _logger As Logger Private ReadOnly _logger As Logger
Private ReadOnly _logConfig As LogConfig Private ReadOnly _logConfig As LogConfig
Private ReadOnly _zugferd As ZUGFeRDInterface
Private ReadOnly _firebird As Firebird Private ReadOnly _firebird As Firebird
Private ReadOnly _filesystem As Filesystem.File Private ReadOnly _filesystem As Filesystem.File
Private ReadOnly _EmailOutAccountId As Integer
Private ReadOnly _mssql As MSSQLServer Private ReadOnly _mssql As MSSQLServer
Private ReadOnly _email As EmailFunctions Private ReadOnly _email As EmailFunctions
Private ReadOnly _gdpictureLicenseKey As String
Private _zugferd As ZUGFeRDInterface
Private _EmailOutAccountId As Integer
Public Sub New(LogConfig As LogConfig, Firebird As Firebird, pEmailOutAccount As Integer, pPortalName As String, Optional MSSQL As MSSQLServer = Nothing) Private Class DatabaseConnections
Public Property SQLServerConnection As SqlConnection
Public Property SQLServerTransaction As SqlTransaction
Public Property FirebirdConnection As FbConnection
Public Property FirebirdTransaction As FbTransaction
End Class
Public Sub New(LogConfig As LogConfig, Firebird As Firebird, Optional MSSQL As MSSQLServer = Nothing)
_logConfig = LogConfig _logConfig = LogConfig
_logger = LogConfig.GetLogger() _logger = LogConfig.GetLogger()
_firebird = Firebird _firebird = Firebird
_filesystem = New Filesystem.File(_logConfig) _filesystem = New Filesystem.File(_logConfig)
_mssql = MSSQL _mssql = MSSQL
_EmailOutAccountId = pEmailOutAccount
_email = New EmailFunctions(LogConfig, _mssql, _firebird) _email = New EmailFunctions(LogConfig, _mssql, _firebird)
_logger.Debug("Registering GDPicture License") _logger.Debug("Registering GDPicture License")
If _mssql IsNot Nothing Then If _mssql IsNot Nothing Then
Dim oSQL = "SELECT LICENSE FROM TBDD_3RD_PARTY_MODULES WHERE NAME = 'GDPICTURE'" Dim oSQL = "SELECT LICENSE FROM TBDD_3RD_PARTY_MODULES WHERE NAME = 'GDPICTURE'"
Dim oLicenseKey As String = _mssql.GetScalarValue(oSQL) _gdpictureLicenseKey = _mssql.GetScalarValue(oSQL)
_zugferd = New ZUGFeRDInterface(_logConfig, oLicenseKey)
Else Else
_logger.Warn("GDPicture License could not be registered! MSSQL is not enabled!") _logger.Warn("GDPicture License could not be registered! MSSQL is not enabled!")
Throw New ArgumentNullException("MSSQL") Throw New ArgumentNullException("MSSQL")
@@ -125,6 +130,14 @@ Public Class ImportZUGFeRDFiles
Dim oPropertyExtractor = New PropertyValues(_logConfig) Dim oPropertyExtractor = New PropertyValues(_logConfig)
Dim oAttachmentExtractor = New PDFEmbeds(_logConfig) Dim oAttachmentExtractor = New PDFEmbeds(_logConfig)
_EmailOutAccountId = oArgs.EmailOutProfileId
Dim oOptions As New ZUGFeRDInterface.ZugferdOptions() With {
.AllowFacturX_Filename = oArgs.AllowFacturX,
.AllowXRechnung_Filename = oArgs.AllowXRechnung
}
_zugferd = New ZUGFeRDInterface(_logConfig, _gdpictureLicenseKey, oOptions)
_logger.Debug("Starting Job {0}", [GetType].Name) _logger.Debug("Starting Job {0}", [GetType].Name)
Try Try
@@ -164,6 +177,13 @@ Public Class ImportZUGFeRDFiles
Dim oSQLConnection As SqlConnection = _mssql.GetConnection() Dim oSQLConnection As SqlConnection = _mssql.GetConnection()
Dim oSQLTransaction As SqlTransaction = oSQLConnection?.BeginTransaction() Dim oSQLTransaction As SqlTransaction = oSQLConnection?.BeginTransaction()
Dim oConnections As New DatabaseConnections() With {
.SQLServerConnection = oSQLConnection,
.SQLServerTransaction = oSQLTransaction,
.FirebirdConnection = oFBConnection,
.FirebirdTransaction = oFBTransaction
}
If oSQLConnection Is Nothing Then If oSQLConnection Is Nothing Then
_logger.Warn("SQL Connection was not set. No INSERTs for MSSQL Server will be performed!") _logger.Warn("SQL Connection was not set. No INSERTs for MSSQL Server will be performed!")
oArgs.InsertIntoSQLServer = False oArgs.InsertIntoSQLServer = False
@@ -192,14 +212,17 @@ Public Class ImportZUGFeRDFiles
Dim oMissingProperties As New List(Of String) Dim oMissingProperties As New List(Of String)
Dim oMD5CheckSum As String = String.Empty Dim oMD5CheckSum As String = String.Empty
_logger.NewBlock($"Message Id {oMessageId}")
_logger.Info("Start processing file group {0}", oMessageId) _logger.Info("Start processing file group {0}", oMessageId)
Try Try
For Each oFile In oFileGroupFiles For Each oFile In oFileGroupFiles
' 09.12.2021: oDocument is now an Object, because have different classes corresponding to the ' 09.12.2021: oDocument is now an Object, because have different classes corresponding to the
' different versions of ZUGFeRD and the type is unknown at compile-time. ' different versions of ZUGFeRD and the type is unknown at compile-time.
Dim oDocument As Object ' 17.11.2022: oDocument is now a Tuple of (String, Object), to be able to return the filename
' of the extracted xml file.
' 21.12.2022: oDocument is now an object of type ZugferdResult to be able to save
' the new meta data, ie. the type of schema (zugferd version)
Dim oDocument As ZUGFeRDInterface.ZugferdResult
' Start a global group counter for each file ' Start a global group counter for each file
Dim oGlobalGroupCounter = 0 Dim oGlobalGroupCounter = 0
@@ -213,7 +236,7 @@ Public Class ImportZUGFeRDFiles
oEmailAttachmentFiles.Add(oFile) oEmailAttachmentFiles.Add(oFile)
' Checking filesize for attachment files ' Checking filesize for attachment files
If Check_FileSize(oFile, oArgs.MaxAttachmentSizeInMegaBytes) = False Then If _filesystem.TestFileSizeIsLessThanMaxFileSize(oFile.FullName, oArgs.MaxAttachmentSizeInMegaBytes) = False Then
_logger.Warn("Filesize for File [{0}] exceeded limit of {1} MB", oFile.Name, oArgs.MaxAttachmentSizeInMegaBytes) _logger.Warn("Filesize for File [{0}] exceeded limit of {1} MB", oFile.Name, oArgs.MaxAttachmentSizeInMegaBytes)
Throw New FileSizeLimitReachedException(oFile.Name, oArgs.MaxAttachmentSizeInMegaBytes) Throw New FileSizeLimitReachedException(oFile.Name, oArgs.MaxAttachmentSizeInMegaBytes)
End If End If
@@ -224,13 +247,17 @@ Public Class ImportZUGFeRDFiles
_logger.Info("Start processing file {0}", oFile.Name) _logger.Info("Start processing file {0}", oFile.Name)
' Checking filesize for pdf files ' Checking filesize for pdf files
If Check_FileSize(oFile, oArgs.MaxAttachmentSizeInMegaBytes) = False Then If _filesystem.TestFileSizeIsLessThanMaxFileSize(oFile.FullName, oArgs.MaxAttachmentSizeInMegaBytes) = False Then
_logger.Warn("Filesize for File [{0}] exceeded limit of {1} MB", oFile.Name, oArgs.MaxAttachmentSizeInMegaBytes) _logger.Warn("Filesize for File [{0}] exceeded limit of {1} MB", oFile.Name, oArgs.MaxAttachmentSizeInMegaBytes)
Throw New FileSizeLimitReachedException(oFile.Name, oArgs.MaxAttachmentSizeInMegaBytes) Throw New FileSizeLimitReachedException(oFile.Name, oArgs.MaxAttachmentSizeInMegaBytes)
End If End If
Try Try
oDocument = _zugferd.ExtractZUGFeRDFileWithGDPicture(oFile.FullName) oDocument = _zugferd.ExtractZUGFeRDFileWithGDPicture(oFile.FullName)
Catch ex As ValidationException
Throw ex
Catch ex As ZUGFeRDExecption Catch ex As ZUGFeRDExecption
Select Case ex.ErrorType Select Case ex.ErrorType
Case ZUGFeRDInterface.ErrorType.NoZugferd Case ZUGFeRDInterface.ErrorType.NoZugferd
@@ -238,8 +265,12 @@ Public Class ImportZUGFeRDFiles
oEmailAttachmentFiles.Add(oFile) oEmailAttachmentFiles.Add(oFile)
Continue For Continue For
Case ZUGFeRDInterface.ErrorType.UnsupportedFormat
_logger.Info("File [{0}/{1}] is an unsupported ZUFeRD document format!", oFile.Name, ex.XmlFile)
Throw New UnsupportedFerdException(ex.XmlFile)
Case ZUGFeRDInterface.ErrorType.NoValidZugferd Case ZUGFeRDInterface.ErrorType.NoValidZugferd
_logger.Warn("File [{0}] is an Incorrectly formatted ZUGFeRD document!", oFile.Name) _logger.Info("File [{0}] is an Incorrectly formatted ZUGFeRD document!", oFile.Name)
Throw New InvalidFerdException() Throw New InvalidFerdException()
Case Else Case Else
@@ -248,6 +279,14 @@ Public Class ImportZUGFeRDFiles
End Select End Select
End Try End Try
' Check if there are more than one ZUGFeRD files
If oZUGFeRDCount = 1 Then
Throw New TooMuchFerdsException()
End If
' Since extraction went well, increase the amount of ZUGFeRD files
oZUGFeRDCount += 1
' Extract all attachments with the extensions specified in `AllowedExtensions`. ' Extract all attachments with the extensions specified in `AllowedExtensions`.
' If you need to extract and use embedded xml files, you need to filter out the zugferd-invoice.xml yourself. ' If you need to extract and use embedded xml files, you need to filter out the zugferd-invoice.xml yourself.
' Right now the zugferd-invoice.xml is filtered out because `AllowedExtensions` does not contain `xml`. ' Right now the zugferd-invoice.xml is filtered out because `AllowedExtensions` does not contain `xml`.
@@ -261,18 +300,12 @@ Public Class ImportZUGFeRDFiles
' Check the Checksum and rejection status ' Check the Checksum and rejection status
oMD5CheckSum = GenerateAndCheck_MD5Sum(oFile.FullName, oArgs.IgnoreRejectionStatus) oMD5CheckSum = GenerateAndCheck_MD5Sum(oFile.FullName, oArgs.IgnoreRejectionStatus)
' Check if there are more than one ZUGFeRD files
If oZUGFeRDCount = 1 Then
Throw New TooMuchFerdsException()
End If
' Since extraction went well, increase the amount of ZUGFeRD files
oZUGFeRDCount += 1
' Check the document against the configured property map and return: ' Check the document against the configured property map and return:
' - a List of valid properties ' - a List of valid properties
' - a List of missing properties ' - a List of missing properties
Dim oCheckResult = _zugferd.PropertyValues.CheckPropertyValues(oDocument, oArgs.PropertyMap, oMessageId)
Dim oPropertyMap = _zugferd.FilterPropertyMap(oArgs.PropertyMap, oDocument.Specification)
Dim oCheckResult = _zugferd.PropertyValues.CheckPropertyValues(oDocument.SchemaObject, oPropertyMap, oMessageId)
_logger.Info("Properties checked: [{0}] missing properties / [{1}] valid properties found.", oCheckResult.MissingProperties.Count, oCheckResult.ValidProperties.Count) _logger.Info("Properties checked: [{0}] missing properties / [{1}] valid properties found.", oCheckResult.MissingProperties.Count, oCheckResult.ValidProperties.Count)
@@ -280,51 +313,28 @@ Public Class ImportZUGFeRDFiles
_logger.Warn("[{0}] missing properties found. Exiting.", oCheckResult.MissingProperties.Count) _logger.Warn("[{0}] missing properties found. Exiting.", oCheckResult.MissingProperties.Count)
oMissingProperties = oCheckResult.MissingProperties oMissingProperties = oCheckResult.MissingProperties
Throw New MissingValueException(oFile) Throw New MissingValueException(oFile)
End If Else
_logger.Debug("No missing properties found. Continuing.") _logger.Debug("No missing properties found. Continuing.")
Dim oDelSQL = $"DELETE FROM TBEDMI_ITEM_VALUE where REFERENCE_GUID = '{oMessageId}'" End If
Dim oStep As String
oStep = "Firebird TBEDMI_ITEM_VALUE Delete messageID Items" DeleteExistingPropertyValues(oMessageId, oArgs, oConnections)
Try
_firebird.ExecuteNonQueryWithConnection(oDelSQL, oFBConnection, Firebird.TransactionMode.ExternalTransaction, oFBTransaction)
Catch ex As Exception
_logger.Error(ex)
_logger.Warn("Step [{0}] with SQL [{1}] was not successful.", oStep, oDelSQL)
End Try
If oArgs.InsertIntoSQLServer = True Then Dim oFirstProperty = oCheckResult.ValidProperties.FirstOrDefault()
oStep = "MSSQL TBEDMI_ITEM_VALUE Delete messageID Items" If oFirstProperty IsNot Nothing Then
Try InsertPropertyValue(oMessageId, oArgs, oConnections, New PropertyValues.ValidProperty() With {
_mssql.ExecuteNonQueryWithConnectionObject(oDelSQL, oSQLConnection, MSSQLServer.TransactionMode.ExternalTransaction, oSQLTransaction) .MessageId = oMessageId,
Catch ex As Exception .Description = "ZUGFeRDSpezifikation",
_logger.Warn("Step [{0}] with SQL [{1}] was not successful.", oStep, oDelSQL) .GroupCounter = 0,
End Try .IsRequired = False,
.Value = oDocument.Specification,
.TableName = oFirstProperty.TableName,
.TableColumn = "ZUGFERD_SPECIFICATION"
})
End If End If
For Each oProperty In oCheckResult.ValidProperties For Each oProperty In oCheckResult.ValidProperties
Dim oGroupCounterValue = oProperty.GroupCounter InsertPropertyValue(oMessageId, oArgs, oConnections, oProperty)
' If GroupCounter is -1, it means this is a default property that can only occur once.
' Set the actual inserted value to 0
If oGroupCounterValue = -1 Then
oGroupCounterValue = 0
End If
Dim oCommand = $"INSERT INTO {oProperty.TableName} (REFERENCE_GUID, ITEM_DESCRIPTION, ITEM_VALUE, GROUP_COUNTER,SPEC_NAME,IS_REQUIRED) VALUES
('{oMessageId}', '{oProperty.Description}', '{oProperty.Value.Replace("'", "''")}', {oGroupCounterValue},'{oProperty.TableColumn}','{oProperty.ISRequired}')"
_logger.Debug("Mapping Property [{0}] with value [{1}], Will be inserted into table [{2}]", oProperty.TableColumn, oProperty.Value.Replace("'", "''"), oProperty.TableName)
' Insert into SQL Server
If oArgs.InsertIntoSQLServer = True Then
Dim oResult = _mssql.ExecuteNonQueryWithConnectionObject(oCommand, oSQLConnection, MSSQLServer.TransactionMode.ExternalTransaction, oSQLTransaction)
If oResult = False Then
_logger.Warn($"SQL Command [{oCommand}] was not successful. Check the log.")
End If
End If
' Insert into Firebird
_firebird.ExecuteNonQueryWithConnection(oCommand, oFBConnection, Firebird.TransactionMode.ExternalTransaction, oFBTransaction)
Next Next
Next Next
@@ -369,6 +379,24 @@ Public Class ImportZUGFeRDFiles
oIsSuccess = True oIsSuccess = True
oMoveDirectory = oArgs.SuccessDirectory oMoveDirectory = oArgs.SuccessDirectory
Catch ex As ValidationException
_logger.Error(ex)
Dim oErrors = ex.ValidationErrors
Dim oMessage = "REJECTED - ZUGFeRD yes but formal validation failed!"
Update_HistoryEntry(oMessageId, oMD5CheckSum, oMessage, oFBTransaction)
Dim oErrorList As String = ""
For Each oError In oErrors
oErrorList += $"<li>Element '{oError.ElementName}' mit Wert '{oError.ElementValue}': {oError.ErrorMessage}</li>"
Next
Dim oBody = String.Format(EmailStrings.EMAIL_VALIDATION_ERROR, oErrorList)
Dim oEmailData = MoveAndRenameEmailToRejected(oArgs, oMessageId)
_email.AddToEmailQueueMSSQL(oMessageId, oBody, oEmailData, "ValidationException", _EmailOutAccountId, oArgs.NamePortal)
AddRejectedState(oMessageId, "ValidationException", "Die Rechnungsvalidierung ist fehlgeschlagen!", "", oSQLTransaction)
Catch ex As MD5HashException Catch ex As MD5HashException
_logger.Error(ex) _logger.Error(ex)
@@ -380,6 +408,19 @@ Public Class ImportZUGFeRDFiles
_email.AddToEmailQueueMSSQL(oMessageId, oBody, oEmailData, "MD5HashException", _EmailOutAccountId, oArgs.NamePortal) _email.AddToEmailQueueMSSQL(oMessageId, oBody, oEmailData, "MD5HashException", _EmailOutAccountId, oArgs.NamePortal)
AddRejectedState(oMessageId, "MD5HashException", "Die gesendete Rechnung wurde bereits verarbeitet!", "", oSQLTransaction) AddRejectedState(oMessageId, "MD5HashException", "Die gesendete Rechnung wurde bereits verarbeitet!", "", oSQLTransaction)
Catch ex As UnsupportedFerdException
_logger.Error(ex)
' When UnsupportedFerdException is thrown, we don't have a MD5Hash yet.
' That 's why we set it to String.Empty here.
Create_HistoryEntry(oMessageId, String.Empty, "REJECTED - ZUGFeRD yes but unsupported format", oFBTransaction)
Dim oEmailData = MoveAndRenameEmailToRejected(oArgs, oMessageId)
Dim oBody As String = String.Format(EmailStrings.EMAIL_UNSUPPORTED_DOCUMENT, oEmailData.Subject, ex.XmlFile)
_email.AddToEmailQueueMSSQL(oMessageId, oBody, oEmailData, "UnsupportedFerdException", _EmailOutAccountId, oArgs.NamePortal)
AddRejectedState(oMessageId, "UnsupportedFerdException", "Nicht unterstütztes Datenformat", "", oSQLTransaction)
Catch ex As InvalidFerdException Catch ex As InvalidFerdException
_logger.Error(ex) _logger.Error(ex)
@@ -387,8 +428,9 @@ Public Class ImportZUGFeRDFiles
' That 's why we set it to String.Empty here. ' That 's why we set it to String.Empty here.
Create_HistoryEntry(oMessageId, String.Empty, "REJECTED - ZUGFeRD yes but incorrect format", oFBTransaction) Create_HistoryEntry(oMessageId, String.Empty, "REJECTED - ZUGFeRD yes but incorrect format", oFBTransaction)
Dim oBody = EmailStrings.EMAIL_INVALID_DOCUMENT
Dim oEmailData = MoveAndRenameEmailToRejected(oArgs, oMessageId) Dim oEmailData = MoveAndRenameEmailToRejected(oArgs, oMessageId)
Dim oBody = String.Format(EmailStrings.EMAIL_INVALID_DOCUMENT, oEmailData.Subject)
_email.AddToEmailQueueMSSQL(oMessageId, oBody, oEmailData, "InvalidFerdException", _EmailOutAccountId, oArgs.NamePortal) _email.AddToEmailQueueMSSQL(oMessageId, oBody, oEmailData, "InvalidFerdException", _EmailOutAccountId, oArgs.NamePortal)
AddRejectedState(oMessageId, "InvalidFerdException", "Inkorrekte Formate", "", oSQLTransaction) AddRejectedState(oMessageId, "InvalidFerdException", "Inkorrekte Formate", "", oSQLTransaction)
@@ -397,8 +439,9 @@ Public Class ImportZUGFeRDFiles
Create_HistoryEntry(oMessageId, oMD5CheckSum, "REJECTED - More than one ZUGFeRD-document in email", oFBTransaction) Create_HistoryEntry(oMessageId, oMD5CheckSum, "REJECTED - More than one ZUGFeRD-document in email", oFBTransaction)
Dim oBody = EmailStrings.EMAIL_TOO_MUCH_FERDS
Dim oEmailData = MoveAndRenameEmailToRejected(oArgs, oMessageId) Dim oEmailData = MoveAndRenameEmailToRejected(oArgs, oMessageId)
Dim oBody = String.Format(EmailStrings.EMAIL_TOO_MUCH_FERDS, oEmailData.Subject)
_email.AddToEmailQueueMSSQL(oMessageId, oBody, oEmailData, "TooMuchFerdsException", _EmailOutAccountId, oArgs.NamePortal) _email.AddToEmailQueueMSSQL(oMessageId, oBody, oEmailData, "TooMuchFerdsException", _EmailOutAccountId, oArgs.NamePortal)
AddRejectedState(oMessageId, "TooMuchFerdsException", "Email enthielt mehr als ein ZUGFeRD-Dokument", "", oSQLTransaction) AddRejectedState(oMessageId, "TooMuchFerdsException", "Email enthielt mehr als ein ZUGFeRD-Dokument", "", oSQLTransaction)
@@ -407,8 +450,9 @@ Public Class ImportZUGFeRDFiles
Create_HistoryEntry(oMessageId, oMD5CheckSum, "REJECTED - no ZUGFeRD-Document in email", oFBTransaction) Create_HistoryEntry(oMessageId, oMD5CheckSum, "REJECTED - no ZUGFeRD-Document in email", oFBTransaction)
Dim oBody = EmailStrings.EMAIL_NO_FERDS
Dim oEmailData = MoveAndRenameEmailToRejected(oArgs, oMessageId) Dim oEmailData = MoveAndRenameEmailToRejected(oArgs, oMessageId)
Dim oBody = String.Format(EmailStrings.EMAIL_NO_FERDS, oEmailData.Subject)
_email.AddToEmailQueueMSSQL(oMessageId, oBody, oEmailData, "NoFerdsException", _EmailOutAccountId, oArgs.NamePortal) _email.AddToEmailQueueMSSQL(oMessageId, oBody, oEmailData, "NoFerdsException", _EmailOutAccountId, oArgs.NamePortal)
AddRejectedState(oMessageId, "NoFerdsException", " Email enthielt keine ZUGFeRD-Dokumente", "", oSQLTransaction) AddRejectedState(oMessageId, "NoFerdsException", " Email enthielt keine ZUGFeRD-Dokumente", "", oSQLTransaction)
@@ -516,8 +560,6 @@ Public Class ImportZUGFeRDFiles
_logger.Warn("Could not move files!") _logger.Warn("Could not move files!")
_logger.Error(ex) _logger.Error(ex)
Throw ex Throw ex
Finally
_logger.EndBlock()
End Try End Try
Try Try
@@ -555,6 +597,57 @@ Public Class ImportZUGFeRDFiles
End Try End Try
End Sub End Sub
Private Sub DeleteExistingPropertyValues(pMessageId As String, pArgs As WorkerArgs, pConnections As DatabaseConnections)
Dim oDelSQL = $"DELETE FROM TBEDMI_ITEM_VALUE where REFERENCE_GUID = '{pMessageId}'"
Dim oStep As String
oStep = "Firebird TBEDMI_ITEM_VALUE Delete messageID Items"
Try
_firebird.ExecuteNonQueryWithConnection(oDelSQL, pConnections.FirebirdConnection, Firebird.TransactionMode.ExternalTransaction, pConnections.FirebirdTransaction)
Catch ex As Exception
_logger.Error(ex)
_logger.Warn("Step [{0}] with SQL [{1}] was not successful.", oStep, oDelSQL)
End Try
If pArgs.InsertIntoSQLServer = True Then
oStep = "MSSQL TBEDMI_ITEM_VALUE Delete messageID Items"
Try
_mssql.ExecuteNonQueryWithConnectionObject(oDelSQL, pConnections.SQLServerConnection, MSSQLServer.TransactionMode.ExternalTransaction, pConnections.SQLServerTransaction)
Catch ex As Exception
_logger.Warn("Step [{0}] with SQL [{1}] was not successful.", oStep, oDelSQL)
End Try
End If
End Sub
Private Sub InsertPropertyValue(pMessageId As String, pArgs As WorkerArgs, pConnections As DatabaseConnections, pProperty As PropertyValues.ValidProperty)
Dim oGroupCounterValue = pProperty.GroupCounter
' If GroupCounter is -1, it means this is a default property that can only occur once.
' Set the actual inserted value to 0
If oGroupCounterValue = -1 Then
oGroupCounterValue = 0
End If
Dim oCommand = $"INSERT INTO {pProperty.TableName} (REFERENCE_GUID, ITEM_DESCRIPTION, ITEM_VALUE, GROUP_COUNTER, SPEC_NAME, IS_REQUIRED) VALUES
('{pMessageId}', '{pProperty.Description}', '{pProperty.Value.Replace("'", "''")}', {oGroupCounterValue},'{pProperty.TableColumn}','{pProperty.IsRequired}')"
_logger.Debug("Mapping Property [{0}] with value [{1}], Will be inserted into table [{2}]", pProperty.TableColumn, pProperty.Value.Replace("'", "''"), pProperty.TableName)
' Insert into SQL Server
If pArgs.InsertIntoSQLServer = True Then
Dim oResult = _mssql.ExecuteNonQueryWithConnectionObject(oCommand, pConnections.SQLServerConnection, MSSQLServer.TransactionMode.ExternalTransaction, pConnections.SQLServerTransaction)
If oResult = False Then
_logger.Warn($"SQL Command [{oCommand}] was not successful. Check the log.")
End If
End If
' Insert into Firebird
_firebird.ExecuteNonQueryWithConnection(oCommand, pConnections.FirebirdConnection, Firebird.TransactionMode.ExternalTransaction, pConnections.FirebirdTransaction)
End Sub
Private Function DoGetPropertyMapFor(pWorkerArgs As WorkerArgs, pSpecification As String) As Dictionary(Of String, XmlItemProperty)
Return pWorkerArgs.PropertyMap.
Where(Function(kv) kv.Value.Specification = pSpecification).
ToDictionary(Function(kv) kv.Key, Function(kv) kv.Value)
End Function
Private Sub MoveFiles( Private Sub MoveFiles(
Args As WorkerArgs, Args As WorkerArgs,
MessageId As String, MessageId As String,
@@ -796,30 +889,4 @@ Public Class ImportZUGFeRDFiles
Return oMD5CheckSum Return oMD5CheckSum
End Function End Function
''' <summary>
''' Checks the size of the supplied file.
''' </summary>
''' <param name="pFileInfo"></param>
''' <param name="pMaxFileSizeInMegaBytes"></param>
''' <returns></returns>
Private Function Check_FileSize(pFileInfo As FileInfo, pMaxFileSizeInMegaBytes As Integer) As Boolean
_logger.Info("Checking Filesize of {0}", pFileInfo.Name)
_logger.Debug("Filesize threshold is {0} MB.", pMaxFileSizeInMegaBytes)
If pMaxFileSizeInMegaBytes <= 0 Then
_logger.Debug("Filesize is not configured. Skipping check.")
Return True
End If
Dim oMaxSize = pMaxFileSizeInMegaBytes * 1024 * 1024
If oMaxSize > 0 And pFileInfo.Length > oMaxSize Then
_logger.Debug("Filesize is bigger than threshold. Rejecting.")
Return False
Else
_logger.Debug("Filesize is smaller than threshold. All fine.")
Return True
End If
End Function
End Class End Class

View File

@@ -14,10 +14,18 @@ Public Class WorkerArgs
' Property Parameter ' Property Parameter
Public PropertyMap As New Dictionary(Of String, XmlItemProperty) Public PropertyMap As New Dictionary(Of String, XmlItemProperty)
' Email Parameter
Public EmailOutProfileId As Integer = 0
' Misc Flag Parameters ' Misc Flag Parameters
Public InsertIntoSQLServer As Boolean = False Public InsertIntoSQLServer As Boolean = False
Public ExceptionEmailAddress As String = Nothing Public ExceptionEmailAddress As String = Nothing
Public IgnoreRejectionStatus As Boolean = False Public IgnoreRejectionStatus As Boolean = False
Public MaxAttachmentSizeInMegaBytes As Integer = -1 Public MaxAttachmentSizeInMegaBytes As Integer = -1
Public NamePortal As String = "NO PORTAL_NAME IN CONFIG" Public NamePortal As String = "NO PORTAL_NAME IN CONFIG"
Public AllowFacturX As Boolean = True
Public AllowXRechnung As Boolean = True
Public AllowZugferd10 As Boolean = True
Public AllowZugferd2x As Boolean = True
End Class End Class

View File

@@ -2,5 +2,5 @@
<packages> <packages>
<package id="FirebirdSql.Data.FirebirdClient" version="7.5.0" targetFramework="net461" /> <package id="FirebirdSql.Data.FirebirdClient" version="7.5.0" targetFramework="net461" />
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net461" /> <package id="Newtonsoft.Json" version="12.0.3" targetFramework="net461" />
<package id="NLog" version="4.7.15" targetFramework="net461" /> <package id="NLog" version="5.0.5" targetFramework="net461" />
</packages> </packages>

View File

@@ -19,6 +19,16 @@ Public Module DataTableEx
End Try End Try
End Function End Function
<Extension()>
Public Function FieldOrDefault(Of T)(pRow As DataRow, pFieldName As String, Optional pDefaultValue As T = Nothing) As T
Return ItemEx(pRow, pFieldName, pDefaultValue)
End Function
<Extension()>
Public Function FieldOrDefault(Of T)(pRow As DataRow, pFieldIndex As Integer, Optional pDefaultValue As T = Nothing) As T
Return ItemEx(pRow, pFieldIndex, pDefaultValue)
End Function
<Extension()> <Extension()>
Public Function First(pTable As DataTable) As DataRow Public Function First(pTable As DataTable) As DataRow
Try Try

View File

@@ -10,7 +10,8 @@
<AssemblyName>DigitalData.Modules.Language</AssemblyName> <AssemblyName>DigitalData.Modules.Language</AssemblyName>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<MyType>Windows</MyType> <MyType>Windows</MyType>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkProfile />
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@@ -44,8 +45,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> <Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.7.15\lib\net45\NLog.dll</HintPath> <HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />
@@ -83,6 +84,7 @@
<Compile Include="My Project\Application.Designer.vb"> <Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon> <DependentUpon>Application.myapp</DependentUpon>
<DesignTime>True</DesignTime>
</Compile> </Compile>
<Compile Include="My Project\Resources.Designer.vb"> <Compile Include="My Project\Resources.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>

View File

@@ -12,8 +12,8 @@ Imports System.Runtime.InteropServices
<Assembly: AssemblyDescription("")> <Assembly: AssemblyDescription("")>
<Assembly: AssemblyCompany("")> <Assembly: AssemblyCompany("")>
<Assembly: AssemblyProduct("Language")> <Assembly: AssemblyProduct("Language")>
<Assembly: AssemblyCopyright("Copyright © 2022")> <Assembly: AssemblyCopyright("Copyright © 2023")>
<Assembly: AssemblyTrademark("")> <Assembly: AssemblyTrademark("1.7.1.0")>
<Assembly: ComVisible(False)> <Assembly: ComVisible(False)>
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
' übernehmen, indem Sie "*" eingeben: ' übernehmen, indem Sie "*" eingeben:
' <Assembly: AssemblyVersion("1.0.*")> ' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.6.0.0")> <Assembly: AssemblyVersion("1.7.1.0")>
<Assembly: AssemblyFileVersion("1.6.0.0")> <Assembly: AssemblyFileVersion("1.7.1.0")>

View File

@@ -22,7 +22,7 @@ Namespace My.Resources
'''<summary> '''<summary>
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. ''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
'''</summary> '''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _ <Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _ Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _ Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _

View File

@@ -15,7 +15,7 @@ Option Explicit On
Namespace My Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ <Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0"), _ Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _ Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase Inherits Global.System.Configuration.ApplicationSettingsBase

View File

@@ -12,4 +12,14 @@ Public Module StringEx
If String.IsNullOrEmpty(pString) Then Return pString If String.IsNullOrEmpty(pString) Then Return pString
Return pString.Substring(0, Math.Min(pLength, pString.Length)) Return pString.Substring(0, Math.Min(pLength, pString.Length))
End Function End Function
''' <summary>
''' Replaces single quotes in text for SQL Commands.
''' </summary>
''' <param name="pString">The string</param>
''' <returns>The escaped string.</returns>
<Extension()>
Public Function EscapeForSQL(pString As String) As String
Return Utils.NotNull(pString, String.Empty).Replace("'", "''")
End Function
End Module End Module

View File

@@ -42,6 +42,11 @@ Public Class Utils
Return [Enum].ToObject(GetType(T), value) Return [Enum].ToObject(GetType(T), value)
End Function End Function
''' <summary>
''' Converts a string to boolean. Accepts true and 1 as truthy values
''' </summary>
''' <param name="input">The input string</param>
''' <returns>True if input is true or 1, otherwise false.</returns>
Public Shared Function ToBoolean(input As String) As Boolean Public Shared Function ToBoolean(input As String) As Boolean
If String.IsNullOrEmpty(input) Then Return False If String.IsNullOrEmpty(input) Then Return False
Return (input.Trim().ToLower() = "true") OrElse (input.Trim() = "1") Return (input.Trim().ToLower() = "true") OrElse (input.Trim() = "1")
@@ -151,6 +156,11 @@ Public Class Utils
End Try End Try
End Function End Function
''' <summary>
''' Checks if string contains invalid characters
''' </summary>
''' <param name="pString"></param>
''' <returns></returns>
Public Shared Function TestContainsInvalidCharacters(pString As String) As Boolean Public Shared Function TestContainsInvalidCharacters(pString As String) As Boolean
Return Not pString.Equals(RemoveInvalidCharacters(pString)) Return Not pString.Equals(RemoveInvalidCharacters(pString))
End Function End Function

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="NLog" version="4.7.15" targetFramework="net461" /> <package id="NLog" version="5.0.5" targetFramework="net461" />
</packages> </packages>

View File

@@ -10,7 +10,8 @@
<AssemblyName>DigitalData.Modules.License</AssemblyName> <AssemblyName>DigitalData.Modules.License</AssemblyName>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<MyType>Windows</MyType> <MyType>Windows</MyType>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<TargetFrameworkProfile />
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@@ -44,8 +45,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> <Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.7.15\lib\net45\NLog.dll</HintPath> <HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />
@@ -84,6 +85,7 @@
<Compile Include="My Project\Application.Designer.vb"> <Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon> <DependentUpon>Application.myapp</DependentUpon>
<DesignTime>True</DesignTime>
</Compile> </Compile>
<Compile Include="My Project\Resources.Designer.vb"> <Compile Include="My Project\Resources.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>

View File

@@ -12,8 +12,8 @@ Imports System.Runtime.InteropServices
<Assembly: AssemblyDescription("")> <Assembly: AssemblyDescription("")>
<Assembly: AssemblyCompany("")> <Assembly: AssemblyCompany("")>
<Assembly: AssemblyProduct("Modules.License")> <Assembly: AssemblyProduct("Modules.License")>
<Assembly: AssemblyCopyright("Copyright © 2019")> <Assembly: AssemblyCopyright("Copyright © 2022")>
<Assembly: AssemblyTrademark("")> <Assembly: AssemblyTrademark("1.1.0.0")>
<Assembly: ComVisible(False)> <Assembly: ComVisible(False)>
@@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices
' übernehmen, indem Sie "*" eingeben: ' übernehmen, indem Sie "*" eingeben:
' <Assembly: AssemblyVersion("1.0.*")> ' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("1.0.0.0")> <Assembly: AssemblyVersion("1.1.0.0")>
<Assembly: AssemblyFileVersion("1.0.0.0")> <Assembly: AssemblyFileVersion("1.1.0.0")>

View File

@@ -22,7 +22,7 @@ Namespace My.Resources
'''<summary> '''<summary>
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. ''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
'''</summary> '''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _ <Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _ Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _ Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _

View File

@@ -15,7 +15,7 @@ Option Explicit On
Namespace My Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ <Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0"), _ Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _ Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase Inherits Global.System.Configuration.ApplicationSettingsBase

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="NLog" version="4.7.15" targetFramework="net461" /> <package id="NLog" version="5.0.5" targetFramework="net461" />
</packages> </packages>

View File

@@ -10,7 +10,7 @@
<AssemblyName>DigitalData.Modules.Logging.Test</AssemblyName> <AssemblyName>DigitalData.Modules.Logging.Test</AssemblyName>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<MyType>Windows</MyType> <MyType>Windows</MyType>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{F184B08F-C81C-45F6-A57F-5ABD9991F28F}</ProjectTypeGuids> <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{F184B08F-C81C-45F6-A57F-5ABD9991F28F}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
@@ -19,6 +19,7 @@
<TestProjectType>UnitTest</TestProjectType> <TestProjectType>UnitTest</TestProjectType>
<NuGetPackageImportStamp> <NuGetPackageImportStamp>
</NuGetPackageImportStamp> </NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@@ -82,6 +83,7 @@
<Compile Include="My Project\Application.Designer.vb"> <Compile Include="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon> <DependentUpon>Application.myapp</DependentUpon>
<DesignTime>True</DesignTime>
</Compile> </Compile>
<Compile Include="My Project\Resources.Designer.vb"> <Compile Include="My Project\Resources.Designer.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>

View File

@@ -22,7 +22,7 @@ Namespace My.Resources
'''<summary> '''<summary>
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. ''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
'''</summary> '''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _ <Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _ Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _ Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _

View File

@@ -15,7 +15,7 @@ Option Explicit On
Namespace My Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _ <Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0"), _ Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _ Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase Inherits Global.System.Configuration.ApplicationSettingsBase

Some files were not shown because too many files have changed in this diff Show More