From ae4b660c8f02092784b697300df6ab9d62f95d0b Mon Sep 17 00:00:00 2001 From: nunomaia Date: Sat, 21 Sep 2019 21:57:47 +0100 Subject: [PATCH] closes #6 Refactor RfcType --- .gitignore | 1 + NwRfcNet.sln | 17 +- README.md | 1 + .../BapiCompanyList/BapiCompanyList.csproj | 2 +- .../BapiCustomerDetail.csproj | 5 +- .../BapiCustomerList/BapiCustomerList.csproj | 6 +- samples/BapiCustomerList/BapiParameters.cs | 18 +- .../BapiGetGlAccountBalance.csproj | 15 ++ .../BapiGetGlAccountBalance/BapiParameters.cs | 43 +++++ samples/BapiGetGlAccountBalance/Program.cs | 171 ++++++++++++++++++ src/NwRfcNet/Bapi/BapiMessageType.cs | 21 +++ src/NwRfcNet/Bapi/BapiReturn.cs | 50 +++++ src/NwRfcNet/Bapi/MappperExtentions.cs | 66 +++++++ .../Interop/RfcInterop.DataContainer.cs | 14 +- src/NwRfcNet/NwRfcNet.csproj | 6 +- src/NwRfcNet/RfcParameterInput.cs | 13 +- src/NwRfcNet/RfcParameterOutput.cs | 11 +- src/NwRfcNet/RfcTypes/IRfcType.cs | 9 + src/NwRfcNet/RfcTypes/RfcBcd.cs | 50 +++++ src/NwRfcNet/RfcTypes/RfcDate.cs | 16 +- src/NwRfcNet/RfcTypes/RfcInt8.cs | 59 ++++++ src/NwRfcNet/RfcTypes/RfcString.cs | 52 ++++++ src/NwRfcNet/RfcTypes/RfcTime.cs | 16 +- tests/NwRfcNet.Tests/NwRfcNet.Tests.csproj | 2 +- tests/NwRfcNet.Tests/RfcTypesTest.cs | 28 ++- 25 files changed, 638 insertions(+), 54 deletions(-) create mode 100644 samples/BapiGetGlAccountBalance/BapiGetGlAccountBalance.csproj create mode 100644 samples/BapiGetGlAccountBalance/BapiParameters.cs create mode 100644 samples/BapiGetGlAccountBalance/Program.cs create mode 100644 src/NwRfcNet/Bapi/BapiMessageType.cs create mode 100644 src/NwRfcNet/Bapi/BapiReturn.cs create mode 100644 src/NwRfcNet/Bapi/MappperExtentions.cs create mode 100644 src/NwRfcNet/RfcTypes/IRfcType.cs create mode 100644 src/NwRfcNet/RfcTypes/RfcBcd.cs create mode 100644 src/NwRfcNet/RfcTypes/RfcInt8.cs create mode 100644 src/NwRfcNet/RfcTypes/RfcString.cs diff --git a/.gitignore b/.gitignore index 5cb1795..06589ed 100644 --- a/.gitignore +++ b/.gitignore @@ -342,3 +342,4 @@ healthchecksdb /samples/BapiCompanyList/Properties/launchSettings.json /samples/BapiCustomerDetail/Properties/launchSettings.json /samples/BapiCustomerList/Properties/launchSettings.json +/samples/BapiGetGlAccountBalance/Properties/launchSettings.json diff --git a/NwRfcNet.sln b/NwRfcNet.sln index d4d6b55..efdb924 100644 --- a/NwRfcNet.sln +++ b/NwRfcNet.sln @@ -17,7 +17,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BapiCompanyList", "samples\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BapiCustomerList", "samples\BapiCustomerList\BapiCustomerList.csproj", "{973E85D8-8F8B-45F1-B062-B110595371C7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BapiCustomerDetail", "samples\BapiCustomerDetail\BapiCustomerDetail.csproj", "{D506F2A9-D77B-490B-872B-680729E5529E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BapiCustomerDetail", "samples\BapiCustomerDetail\BapiCustomerDetail.csproj", "{D506F2A9-D77B-490B-872B-680729E5529E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BapiGetGlAccountBalance", "samples\BapiGetGlAccountBalance\BapiGetGlAccountBalance.csproj", "{F4C2ADD5-BA4C-45C2-AEF6-3340A5CDF0C2}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -89,6 +91,18 @@ Global {D506F2A9-D77B-490B-872B-680729E5529E}.Release|x64.Build.0 = Release|Any CPU {D506F2A9-D77B-490B-872B-680729E5529E}.Release|x86.ActiveCfg = Release|Any CPU {D506F2A9-D77B-490B-872B-680729E5529E}.Release|x86.Build.0 = Release|Any CPU + {F4C2ADD5-BA4C-45C2-AEF6-3340A5CDF0C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F4C2ADD5-BA4C-45C2-AEF6-3340A5CDF0C2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F4C2ADD5-BA4C-45C2-AEF6-3340A5CDF0C2}.Debug|x64.ActiveCfg = Debug|Any CPU + {F4C2ADD5-BA4C-45C2-AEF6-3340A5CDF0C2}.Debug|x64.Build.0 = Debug|Any CPU + {F4C2ADD5-BA4C-45C2-AEF6-3340A5CDF0C2}.Debug|x86.ActiveCfg = Debug|Any CPU + {F4C2ADD5-BA4C-45C2-AEF6-3340A5CDF0C2}.Debug|x86.Build.0 = Debug|Any CPU + {F4C2ADD5-BA4C-45C2-AEF6-3340A5CDF0C2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F4C2ADD5-BA4C-45C2-AEF6-3340A5CDF0C2}.Release|Any CPU.Build.0 = Release|Any CPU + {F4C2ADD5-BA4C-45C2-AEF6-3340A5CDF0C2}.Release|x64.ActiveCfg = Release|Any CPU + {F4C2ADD5-BA4C-45C2-AEF6-3340A5CDF0C2}.Release|x64.Build.0 = Release|Any CPU + {F4C2ADD5-BA4C-45C2-AEF6-3340A5CDF0C2}.Release|x86.ActiveCfg = Release|Any CPU + {F4C2ADD5-BA4C-45C2-AEF6-3340A5CDF0C2}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -99,6 +113,7 @@ Global {914BE78B-9205-4DD1-89A9-3059F2CA5469} = {813ACAE4-6905-4DE0-BD6B-AADF0535B2B5} {973E85D8-8F8B-45F1-B062-B110595371C7} = {813ACAE4-6905-4DE0-BD6B-AADF0535B2B5} {D506F2A9-D77B-490B-872B-680729E5529E} = {813ACAE4-6905-4DE0-BD6B-AADF0535B2B5} + {F4C2ADD5-BA4C-45C2-AEF6-3340A5CDF0C2} = {813ACAE4-6905-4DE0-BD6B-AADF0535B2B5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3BA7E01A-BE1C-404B-838B-0766A1657F8B} diff --git a/README.md b/README.md index a5066c8..5aee1c2 100644 --- a/README.md +++ b/README.md @@ -97,3 +97,4 @@ Included samples in project * List FI Comapnies * List FI Customers * Get Details of a FI Customer +* FI General Ledger Account diff --git a/samples/BapiCompanyList/BapiCompanyList.csproj b/samples/BapiCompanyList/BapiCompanyList.csproj index f07a442..364dec5 100644 --- a/samples/BapiCompanyList/BapiCompanyList.csproj +++ b/samples/BapiCompanyList/BapiCompanyList.csproj @@ -10,7 +10,7 @@ - + diff --git a/samples/BapiCustomerDetail/BapiCustomerDetail.csproj b/samples/BapiCustomerDetail/BapiCustomerDetail.csproj index 05a0719..641b0ed 100644 --- a/samples/BapiCustomerDetail/BapiCustomerDetail.csproj +++ b/samples/BapiCustomerDetail/BapiCustomerDetail.csproj @@ -9,10 +9,7 @@ - - - - + diff --git a/samples/BapiCustomerList/BapiCustomerList.csproj b/samples/BapiCustomerList/BapiCustomerList.csproj index d936440..317d427 100644 --- a/samples/BapiCustomerList/BapiCustomerList.csproj +++ b/samples/BapiCustomerList/BapiCustomerList.csproj @@ -10,7 +10,11 @@ - + + + + + diff --git a/samples/BapiCustomerList/BapiParameters.cs b/samples/BapiCustomerList/BapiParameters.cs index 0bd3ff8..7cf8974 100644 --- a/samples/BapiCustomerList/BapiParameters.cs +++ b/samples/BapiCustomerList/BapiParameters.cs @@ -1,4 +1,6 @@ -namespace Sample.BapiCustomerList +using NwRfcNet.Bapi; + +namespace Sample.BapiCustomerList { public class ListCustomersInputParameters { @@ -21,20 +23,6 @@ public class CustomerAddress public string Name { get; set; } } - public class BapiReturn - { - public string Type { get; set; } - public string Id { get; set; } - public string Number { get; set; } - public string Message { get; set; } - public string LogNumber { get; set; } - public string LogMsgNumber { get; set; } - public string Message1 { get; set; } - public string Message2 { get; set; } - public string Message3 { get; set; } - public string Message4 { get; set; } - } - public class ListCustomersOutputParameters { diff --git a/samples/BapiGetGlAccountBalance/BapiGetGlAccountBalance.csproj b/samples/BapiGetGlAccountBalance/BapiGetGlAccountBalance.csproj new file mode 100644 index 0000000..f959097 --- /dev/null +++ b/samples/BapiGetGlAccountBalance/BapiGetGlAccountBalance.csproj @@ -0,0 +1,15 @@ + + + + Exe + netcoreapp2.2 + Sample.BapiGetGlAccountBalance + Sample.BapiGetGlAccountBalance + + + + + + + + diff --git a/samples/BapiGetGlAccountBalance/BapiParameters.cs b/samples/BapiGetGlAccountBalance/BapiParameters.cs new file mode 100644 index 0000000..d16a3e0 --- /dev/null +++ b/samples/BapiGetGlAccountBalance/BapiParameters.cs @@ -0,0 +1,43 @@ +using NwRfcNet.Bapi; + +namespace Sample.BapiGetGlAccountBalance +{ + public class BapiParametersInput + { + public string CompanyCode { get; set; } + + public string GlAccount { get; set; } + + public int FiscalYear { get; set; } + + public string CurrencyType { get; set; } + } + + public class BapiParametersOutput + { + public GlBalanceDetail[] Detail { get; set; } + + public BapiReturn BapiReturn { get; set; } + } + + public class GlBalanceDetail + { + public string CompanyCode { get; set; } + + public string GlAccount { get; set; } + + public int FiscalYear { get; set; } + + public int FiscalPeriod { get; set; } + + public decimal TotalDebit { get; set; } + + public decimal TotalCredit { get; set; } + + public decimal MontlySales { get; set; } + + public decimal AccountBalance { get; set; } + + public string Currency { get; set; } + } +} diff --git a/samples/BapiGetGlAccountBalance/Program.cs b/samples/BapiGetGlAccountBalance/Program.cs new file mode 100644 index 0000000..5d21185 --- /dev/null +++ b/samples/BapiGetGlAccountBalance/Program.cs @@ -0,0 +1,171 @@ +using CommandLine; +using NwRfcNet; +using NwRfcNet.Bapi; +using NwRfcNet.TypeMapper; +using System; + +namespace Sample.BapiGetGlAccountBalance +{ + + class Options + { + [Option('u', "username", Required = true, HelpText = "RFC User Name")] + public string UserName { get; set; } + + [Option('p', "password", Required = true, HelpText = "RFC User Password")] + public string Password { get; set; } + + [Option('h', "hostname", Required = true, HelpText = "RFC Server Hostname")] + public string Hostname { get; set; } + + [Option('c', "client", Required = true, HelpText = "RFC Server Client Id")] + public string Client { get; set; } + + [Option('a', "account", Required = true, HelpText = "G/L Account")] + public string GlAccount { get; set; } + + [Option('k', "company", Required = true, HelpText = "FI Company Code")] + public string Company { get; set; } + + [Option('f', "fiscalyear", Required = true, HelpText = "FI Fiscal Year")] + public int FiscalYear { get; set; } + } + + class Program + { + static void ParameterMapping() + { + var mapper = RfcMapper.DefaultMapper; + + mapper.Parameter() + .Property(x => x.CompanyCode) + .HasParameterName("COMPANYCODE") + .HasParameterType(RfcFieldType.Char) + .MaxLength(4); + + mapper.Parameter() + .Property(x => x.GlAccount) + .HasParameterName("GLACCT") + .HasParameterType(RfcFieldType.Char) + .MaxLength(10); + + mapper.Parameter() + .Property(x => x.FiscalYear) + .HasParameterName("FISCALYEAR") + .HasParameterType(RfcFieldType.Int); + + mapper.Parameter() + .Property(x => x.CurrencyType) + .HasParameterName("CURRENCYTYPE") + .HasParameterType(RfcFieldType.Char) + .MaxLength(2); + + mapper.Parameter() + .Property(x => x.Detail) + .HasParameterName("ACCOUNT_BALANCES") + .HasParameterType(RfcFieldType.Table); + + mapper.MapBapiReturn(); + + mapper.Parameter() + .Property(x => x.BapiReturn) + .HasParameterName("RETURN") + .HasParameterType(RfcFieldType.Structure); + + mapper.Parameter() + .Property(x => x.CompanyCode) + .HasParameterName("COMP_CODE") + .MaxLength(4) + .HasParameterType(RfcFieldType.Char); + + mapper.Parameter() + .Property(x => x.GlAccount) + .HasParameterName("GL_ACCOUNT") + .MaxLength(10) + .HasParameterType(RfcFieldType.Char); + + mapper.Parameter() + .Property(x => x.FiscalYear) + .HasParameterName("FISC_YEAR") + .HasParameterType(RfcFieldType.Int); + + mapper.Parameter() + .Property(x => x.FiscalPeriod) + .HasParameterName("FIS_PERIOD") + .HasParameterType(RfcFieldType.Int); + + mapper.Parameter() + .Property(x => x.TotalDebit) + .HasParameterName("DEBITS_PER") + .HasParameterType(RfcFieldType.Bcd); + + mapper.Parameter() + .Property(x => x.TotalCredit) + .HasParameterName("CREDIT_PER") + .HasParameterType(RfcFieldType.Bcd); + + mapper.Parameter() + .Property(x => x.MontlySales) + .HasParameterName("PER_SALES") + .HasParameterType(RfcFieldType.Bcd); + + mapper.Parameter() + .Property(x => x.Currency) + .HasParameterName("CURRENCY") + .MaxLength(10) + .HasParameterType(RfcFieldType.Char); + + } + + static void Main(string[] args) + { + Parser.Default.ParseArguments(args) + .WithParsed(o => + { + try + { + ParameterMapping(); + + var version = RfcConnection.GetLibVersion(); + Console.WriteLine($"currently loaded sapnwrfc library version : Major {version.MajorVersion}, Minor {version.MinorVersion}, patchLevel {version.PatchLevel}"); + + using (var conn = new RfcConnection(userName: o.UserName, password: o.Password, hostname: o.Hostname, client: o.Client)) + { + conn.Open(); + using (var func = conn.CallRfcFunction("BAPI_GL_GETGLACCPERIODBALANCES")) + { + var inParams = new BapiParametersInput + { + CompanyCode = o.Company, + CurrencyType = "10", // document Currency + FiscalYear = o.FiscalYear, + GlAccount = o.GlAccount + }; + func.Invoke(inParams); + + var result = func.GetOutputParameters(); + + Console.WriteLine(String.Format("|{0,-6}|{1,-6}|{2,-10}|{3,-10}", "Company", "Period", "Debit", "Credit")); + foreach (var row in result.Detail) + { + Console.WriteLine(String.Format("|{0,-6}|{1,-6}|{2,-10}|{3,-10}", + row.CompanyCode, + row.FiscalPeriod, + row.TotalCredit.ToString(), + row.TotalDebit.ToString() + )); ; + } + + } + } + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + throw ex; + } + }); + + } + } +} diff --git a/src/NwRfcNet/Bapi/BapiMessageType.cs b/src/NwRfcNet/Bapi/BapiMessageType.cs new file mode 100644 index 0000000..683a5b1 --- /dev/null +++ b/src/NwRfcNet/Bapi/BapiMessageType.cs @@ -0,0 +1,21 @@ +namespace NwRfcNet.Bapi +{ + public static class BapiMessageType + { + public static readonly string Success = "S"; + + public static readonly string Error = "S"; + + public static readonly string Warning = "W"; + + public static readonly string Information = "I"; + + public static readonly string Abort = "A"; + } + + public static class BapiMessageTypeExtentions + { + public static bool IsError(this BapiReturn bapiReturn) + => bapiReturn.MessageType == BapiMessageType.Error || bapiReturn.MessageType == BapiMessageType.Abort; + } +} diff --git a/src/NwRfcNet/Bapi/BapiReturn.cs b/src/NwRfcNet/Bapi/BapiReturn.cs new file mode 100644 index 0000000..5db78a1 --- /dev/null +++ b/src/NwRfcNet/Bapi/BapiReturn.cs @@ -0,0 +1,50 @@ +namespace NwRfcNet.Bapi +{ + public class BapiReturn + { + /// + /// Message Code + /// + public string Code { get; set; } + + /// + /// Message Type + /// + public string MessageType { get; set; } + + /// + /// Message Text + /// + public string Message { get; set; } + + /// + /// Application log: log number + /// + public string LogNo { get; set; } + + /// + /// Internal message serial number + /// + public string LogMessageNumber { get; set; } + + /// + /// Message Variable 1 + /// + public string MessageV1 { get; set; } + + /// + /// Message Variable 2 + /// + public string MessageV2 { get; set; } + + /// + /// Message Variable 3 + /// + public string MessageV3 { get; set; } + + /// + /// Message Variable 4 + /// + public string MessageV4 { get; set; } + } +} diff --git a/src/NwRfcNet/Bapi/MappperExtentions.cs b/src/NwRfcNet/Bapi/MappperExtentions.cs new file mode 100644 index 0000000..7bccf98 --- /dev/null +++ b/src/NwRfcNet/Bapi/MappperExtentions.cs @@ -0,0 +1,66 @@ +using NwRfcNet.TypeMapper; + +namespace NwRfcNet.Bapi +{ + public static class Mappper + { + public static RfcMapper MapBapiReturn(this RfcMapper mapper) + { + mapper.Parameter() + .Property(x => x.MessageType) + .HasParameterName("TYPE") + .HasParameterType(RfcFieldType.Char) + .MaxLength(1); + + mapper.Parameter() + .Property(x => x.Code) + .HasParameterName("CODE") + .HasParameterType(RfcFieldType.Char) + .MaxLength(5); + + mapper.Parameter() + .Property(x => x.Message) + .HasParameterName("MESSAGE") + .HasParameterType(RfcFieldType.Char) + .MaxLength(220); + + mapper.Parameter() + .Property(x => x.LogNo) + .HasParameterName("LOG_NO") + .HasParameterType(RfcFieldType.Char) + .MaxLength(20); + + mapper.Parameter() + .Property(x => x.LogMessageNumber) + .HasParameterName("LOG_MSG_NO") + .HasParameterType(RfcFieldType.Char) + .MaxLength(6); + + mapper.Parameter() + .Property(x => x.MessageV1) + .HasParameterName("MESSAGE_V1") + .HasParameterType(RfcFieldType.Char) + .MaxLength(50); + + mapper.Parameter() + .Property(x => x.MessageV2) + .HasParameterName("MESSAGE_V2") + .HasParameterType(RfcFieldType.Char) + .MaxLength(50); + + mapper.Parameter() + .Property(x => x.MessageV3) + .HasParameterName("MESSAGE_V3") + .HasParameterType(RfcFieldType.Char) + .MaxLength(50); + + mapper.Parameter() + .Property(x => x.MessageV4) + .HasParameterName("MESSAGE_V4") + .HasParameterType(RfcFieldType.Char) + .MaxLength(50); + + return mapper; + } + } +} diff --git a/src/NwRfcNet/Interop/RfcInterop.DataContainer.cs b/src/NwRfcNet/Interop/RfcInterop.DataContainer.cs index 5c39b81..a08348a 100644 --- a/src/NwRfcNet/Interop/RfcInterop.DataContainer.cs +++ b/src/NwRfcNet/Interop/RfcInterop.DataContainer.cs @@ -43,7 +43,7 @@ internal static partial class RfcInterop public static extern IntPtr RfcGetCurrentRow(IntPtr tableHandle, out RFC_ERROR_INFO errorInfo); [DllImport(NwRfcLib, CharSet = CharSet.Unicode)] - public static extern RFC_RC RfcGetString(IntPtr dataHandle, string name, StringBuilder stringBuffer, uint bufferLength, uint stringLength, out RFC_ERROR_INFO errorInfo); + public static extern RFC_RC RfcGetString(IntPtr dataHandle, string name, char[] stringBuffer, uint bufferLength, out uint stringLength, out RFC_ERROR_INFO errorInfo); [DllImport(NwRfcLib, CharSet = CharSet.Unicode)] public static extern IntPtr RfcCreateTable(IntPtr typeDescHandle, out RFC_ERROR_INFO errorInfo); @@ -66,5 +66,17 @@ internal static partial class RfcInterop [DllImport(NwRfcLib, CharSet = CharSet.Unicode)] public static extern RFC_RC RfcGetTime(IntPtr dataHandle, string name, char[] emptyTime, out RFC_ERROR_INFO errorInfo); + [DllImport(NwRfcLib, CharSet = CharSet.Unicode)] + public static extern RFC_RC RfcGetInt8(IntPtr dataHandle, string name, ref long value, out RFC_ERROR_INFO errorInfo); + + [DllImport(NwRfcLib, CharSet = CharSet.Unicode)] + public static extern RFC_RC RfcSetInt8(IntPtr dataHandle, string name, long value, out RFC_ERROR_INFO errorInfo); + + [DllImport(NwRfcLib, CharSet = CharSet.Unicode)] + public static extern RFC_RC RfcSetString(IntPtr dataHandle, string name, string value, uint valueLength, out RFC_ERROR_INFO errorInfo); + + [DllImport(NwRfcLib, CharSet = CharSet.Unicode)] + public static extern RFC_RC RfcGetString(IntPtr dataHandle, string name, ref char[] stringBuffer, uint valueLength, out uint stringLength, out RFC_ERROR_INFO errorInfo); + } } \ No newline at end of file diff --git a/src/NwRfcNet/NwRfcNet.csproj b/src/NwRfcNet/NwRfcNet.csproj index 9acf682..7134622 100644 --- a/src/NwRfcNet/NwRfcNet.csproj +++ b/src/NwRfcNet/NwRfcNet.csproj @@ -4,7 +4,7 @@ netstandard2.0 NwRfcNet NwRfcNet - 0.0.2 + 0.0.3 Nuno Maia An easy way of making SAP RFC calls from .NET Core (Windows, Linux and macOS ) sap rfc bapi @@ -13,8 +13,8 @@ false Apache-2.0 https://github.com/nunomaia/NwRfcNet/ - 0.0.2.0 - 0.0.2.0 + 0.0.3.0 + 0.0.3.0 diff --git a/src/NwRfcNet/RfcParameterInput.cs b/src/NwRfcNet/RfcParameterInput.cs index b9a53af..c09b579 100644 --- a/src/NwRfcNet/RfcParameterInput.cs +++ b/src/NwRfcNet/RfcParameterInput.cs @@ -50,14 +50,23 @@ internal void SetParameters(IntPtr handler, object inputValue) case RfcFieldType.Date: var date = new RfcDate((DateTime)((object)propMap.Value)); - date.SetDate(handler, propMap.Value.RfcParameterName); + date.SetFieldValue(handler, propMap.Value.RfcParameterName); break; case RfcFieldType.Time: var time = new RfcTime((TimeSpan)((object)propMap.Value)); - time.SetTime(handler, propMap.Value.RfcParameterName); + time.SetFieldValue(handler, propMap.Value.RfcParameterName); break; + case RfcFieldType.Int8: + var int8 = new RfcInt8((long)((object)propMap.Value)); + int8.SetFieldValue(handler, propMap.Value.RfcParameterName); + break; + + case RfcFieldType.Bcd: + var bcd = new RfcBcd((decimal)((object)propMap.Value)); + bcd.SetFieldValue(handler, propMap.Value.RfcParameterName); + break; default: throw new RfcException("Rfc Type not handled"); diff --git a/src/NwRfcNet/RfcParameterOutput.cs b/src/NwRfcNet/RfcParameterOutput.cs index fa0cf16..c5a7998 100644 --- a/src/NwRfcNet/RfcParameterOutput.cs +++ b/src/NwRfcNet/RfcParameterOutput.cs @@ -56,13 +56,20 @@ internal object GetReturnParameters(IntPtr handler, Type type) break; case RfcFieldType.Date: - objectValue = RfcDate.GetDate(handler, map.RfcParameterName)?.Date; + objectValue = RfcDate.GetFieldValue(handler, map.RfcParameterName)?.RfcValue; break; case RfcFieldType.Time: - objectValue = RfcTime.GetTime(handler, map.RfcParameterName)?.Time; + objectValue = RfcTime.GetFieldValue(handler, map.RfcParameterName)?.RfcValue; break; + case RfcFieldType.Int8: + objectValue = RfcInt8.GetFieldValue(handler, map.RfcParameterName).RfcValue; + break; + + case RfcFieldType.Bcd: + objectValue = RfcBcd.GetFieldValue(handler, map.RfcParameterName).RfcValue; + break; default: throw new RfcException("Rfc Type not handled"); diff --git a/src/NwRfcNet/RfcTypes/IRfcType.cs b/src/NwRfcNet/RfcTypes/IRfcType.cs new file mode 100644 index 0000000..1db71b5 --- /dev/null +++ b/src/NwRfcNet/RfcTypes/IRfcType.cs @@ -0,0 +1,9 @@ +using System; + +namespace NwRfcNet.RfcTypes +{ + internal interface IRfcType + { + T RfcValue { get; } + } +} diff --git a/src/NwRfcNet/RfcTypes/RfcBcd.cs b/src/NwRfcNet/RfcTypes/RfcBcd.cs new file mode 100644 index 0000000..d1ff96c --- /dev/null +++ b/src/NwRfcNet/RfcTypes/RfcBcd.cs @@ -0,0 +1,50 @@ +using System; +using System.Globalization; + +namespace NwRfcNet.RfcTypes +{ + public class RfcBcd : IRfcType + { + #region Constructors + + public RfcBcd(decimal value) => RfcValue = value; + + public RfcBcd(string value) => RfcValue = decimal.Parse(value, CultureInfo.InvariantCulture); + + #endregion + + #region Properties + + public decimal RfcValue { get; } + + #endregion + + public override string ToString() => RfcValue.ToString(CultureInfo.InvariantCulture); + + #region Interop + + /// + /// sets the value of a RFC INT8 field + /// + /// handle to container + /// field name + internal void SetFieldValue(IntPtr dataHandle, string name) + { + var str = new RfcString(RfcValue.ToString()); + str.SetFieldValue(dataHandle, name); + } + + /// + /// Gets the value of a RFC INT8 field + /// + /// handle to container + /// field name + /// + internal static RfcBcd GetFieldValue(IntPtr dataHandle, string name) + { + var str = RfcString.GetFieldValue(dataHandle, name); + return new RfcBcd(str.RfcValue); + } + #endregion + } +} diff --git a/src/NwRfcNet/RfcTypes/RfcDate.cs b/src/NwRfcNet/RfcTypes/RfcDate.cs index 877206c..2c0602e 100644 --- a/src/NwRfcNet/RfcTypes/RfcDate.cs +++ b/src/NwRfcNet/RfcTypes/RfcDate.cs @@ -33,7 +33,7 @@ public RfcDate(string date) { if (string.IsNullOrEmpty(date) || date == NullRfcDateString || date == ZerolRfcDateString) { - Date = null; + RfcValue = null; return; } @@ -44,14 +44,14 @@ public RfcDate(string date) int month = Int32.Parse(date.Substring(YearFormat.Length, MonthFormat.Length)); int day = Int32.Parse(date.Substring(YearFormat.Length + MonthFormat.Length, DayFormat.Length)); - Date = new DateTime(year, month, day); + RfcValue = new DateTime(year, month, day); } /// /// Creates a new RfcDate with format YYYMMDD /// /// YYYYMMDD RFC Date - public RfcDate(DateTime? date) => Date = date?.Date; + public RfcDate(DateTime? date) => RfcValue = date?.Date; #endregion @@ -60,7 +60,7 @@ public RfcDate(string date) /// /// Date /// - public DateTime? Date { get; } + public DateTime? RfcValue { get; } #endregion @@ -69,7 +69,7 @@ public RfcDate(string date) /// /// public override string ToString() - => Date?.ToString("yyyyMMdd") ?? ZerolRfcDateString; + => RfcValue?.ToString("yyyyMMdd") ?? ZerolRfcDateString; public char[] ToBuffer() => ToString().ToCharArray(); @@ -81,9 +81,9 @@ public override string ToString() /// /// handle to container /// field name - internal void SetDate(IntPtr dataHandle, string name) + internal void SetFieldValue(IntPtr dataHandle, string name) { - if (Date != null) + if (RfcValue != null) { var rc = RfcInterop.RfcSetDate(dataHandle, name, ToBuffer(), out var errorInfo); rc.OnErrorThrowException(errorInfo); @@ -96,7 +96,7 @@ internal void SetDate(IntPtr dataHandle, string name) /// handle to container /// field name /// - internal static RfcDate GetDate(IntPtr dataHandle, string name) + internal static RfcDate GetFieldValue(IntPtr dataHandle, string name) { var buffer = new char[RfcDateTemplate.Length]; // = new StringBuilder(YearFormat.Length + MonthFormat.Length + DayFormat.Length); buffer.FillAll(' '); diff --git a/src/NwRfcNet/RfcTypes/RfcInt8.cs b/src/NwRfcNet/RfcTypes/RfcInt8.cs new file mode 100644 index 0000000..1f8155f --- /dev/null +++ b/src/NwRfcNet/RfcTypes/RfcInt8.cs @@ -0,0 +1,59 @@ +using NwRfcNet.Interop; +using NwRfcNet.Util; +using System; + +namespace NwRfcNet.RfcTypes +{ + /// + /// Represents an RFC INT8. + /// + public class RfcInt8 + { + #region Constructors + + /// + /// Creates a new RfcInt8 + /// + /// + public RfcInt8(Int64 value) => RfcValue = value; + + #endregion + + #region Properties + + /// + /// Date + /// + public Int64 RfcValue { get; } + + #endregion + + #region Interop + + /// + /// sets the value of a RFC INT8 field + /// + /// handle to container + /// field name + internal void SetFieldValue(IntPtr dataHandle, string name) + { + var rc = RfcInterop.RfcSetInt8(dataHandle, name, RfcValue, out var errorInfo); + rc.OnErrorThrowException(errorInfo); + } + + /// + /// Gets the value of a RFC INT8 field + /// + /// handle to container + /// field name + /// + internal static RfcInt8 GetFieldValue(IntPtr dataHandle, string name) + { + long value = 0; + var rc = RfcInterop.RfcGetInt8(dataHandle, name, ref value, out var errorInfo); + rc.OnErrorThrowException(errorInfo); + return new RfcInt8(value); + } + #endregion + } +} diff --git a/src/NwRfcNet/RfcTypes/RfcString.cs b/src/NwRfcNet/RfcTypes/RfcString.cs new file mode 100644 index 0000000..103c077 --- /dev/null +++ b/src/NwRfcNet/RfcTypes/RfcString.cs @@ -0,0 +1,52 @@ +using NwRfcNet.Interop; +using System; + +namespace NwRfcNet.RfcTypes +{ + public class RfcString : IRfcType + { + public RfcString(string value) => RfcValue = value; + + public RfcString(char[] value) => RfcValue = new string(value); + + public RfcString(char[] value, int startIndex, int length) => RfcValue = new string(value, startIndex, length); + + public String RfcValue { get; } + + #region Interop + + /// + /// sets the value of a RFC STRING field + /// + /// handle to container + /// field name + internal void SetFieldValue(IntPtr dataHandle, string name) + { + var rc = RfcInterop.RfcSetString(dataHandle, name, RfcValue, (uint) RfcValue.Length, out var errorInfo); + rc.OnErrorThrowException(errorInfo); + } + + /// + /// Gets the value of a RFC STRING field + /// + /// handle to container + /// field name + /// + internal static RfcString GetFieldValue(IntPtr dataHandle, string name) + { + char[] buffer = new char[1024]; + var rc = RfcInterop.RfcGetString(dataHandle, name, buffer, (uint)buffer.Length, out var bufferLength, out var errorInfo); + + if (rc == RfcInterop.RFC_RC.RFC_AUTHORIZATION_FAILURE) + { + buffer = new char[bufferLength]; + rc = RfcInterop.RfcGetString(dataHandle, name, buffer, (uint)buffer.Length, out bufferLength, out errorInfo); + } + + rc.OnErrorThrowException(errorInfo); + return new RfcString(buffer, 0, (int) bufferLength); + + } + #endregion + } +} diff --git a/src/NwRfcNet/RfcTypes/RfcTime.cs b/src/NwRfcNet/RfcTypes/RfcTime.cs index ff45404..8cdce75 100644 --- a/src/NwRfcNet/RfcTypes/RfcTime.cs +++ b/src/NwRfcNet/RfcTypes/RfcTime.cs @@ -30,7 +30,7 @@ public RfcTime(string time) { if (string.IsNullOrEmpty(time) || time == NullRfcTimeString || time == ZeroRfcTimeString) { - Time = null; + RfcValue = null; return; } @@ -41,21 +41,21 @@ public RfcTime(string time) int minutes = Int32.Parse(time.Substring(HoursFormat.Length, MinutesFormat.Length)); int seconds = Int32.Parse(time.Substring(HoursFormat.Length + MinutesFormat.Length, SecondsFormat.Length)); - Time = new TimeSpan(hours, minutes, seconds); + RfcValue = new TimeSpan(hours, minutes, seconds); } /// /// Creates a new RfcDate with format YYYMMDD /// /// YYYYMMDD RFC Date - public RfcTime(TimeSpan? time) => Time = time; + public RfcTime(TimeSpan? time) => RfcValue = time; #region Properties /// /// Time /// - public TimeSpan? Time { get; } + public TimeSpan? RfcValue { get; } #endregion @@ -64,7 +64,7 @@ public RfcTime(string time) /// /// public override string ToString() - => Time?.ToString("hhmmss") ?? ZeroRfcTimeString; + => RfcValue?.ToString("hhmmss") ?? ZeroRfcTimeString; public char[] ToBuffer() => ToString().ToCharArray(); @@ -75,9 +75,9 @@ public override string ToString() /// /// handle to container /// field name - internal void SetTime(IntPtr dataHandle, string name) + internal void SetFieldValue(IntPtr dataHandle, string name) { - if (Time != null) + if (RfcValue != null) { var rc = RfcInterop.RfcSetTime(dataHandle, name, ToBuffer(), out var errorInfo); rc.OnErrorThrowException(errorInfo); @@ -90,7 +90,7 @@ internal void SetTime(IntPtr dataHandle, string name) /// handle to container /// field name /// - internal static RfcTime GetTime(IntPtr dataHandle, string name) + internal static RfcTime GetFieldValue(IntPtr dataHandle, string name) { var buffer = new char[RfcTimeTemplate.Length]; // = new StringBuilder(YearFormat.Length + MonthFormat.Length + DayFormat.Length); buffer.FillAll(' '); diff --git a/tests/NwRfcNet.Tests/NwRfcNet.Tests.csproj b/tests/NwRfcNet.Tests/NwRfcNet.Tests.csproj index 5cea292..65d98f0 100644 --- a/tests/NwRfcNet.Tests/NwRfcNet.Tests.csproj +++ b/tests/NwRfcNet.Tests/NwRfcNet.Tests.csproj @@ -8,7 +8,7 @@ - + all diff --git a/tests/NwRfcNet.Tests/RfcTypesTest.cs b/tests/NwRfcNet.Tests/RfcTypesTest.cs index 7022359..32c0d5a 100644 --- a/tests/NwRfcNet.Tests/RfcTypesTest.cs +++ b/tests/NwRfcNet.Tests/RfcTypesTest.cs @@ -11,9 +11,9 @@ public class RfcTypesTest public void RfcDateTest_1() { RfcDate date = new RfcDate("20190921"); - Assert.Equal(2019, date.Date?.Year); - Assert.Equal(9, date.Date?.Month); - Assert.Equal(21, date.Date?.Day); + Assert.Equal(2019, date.RfcValue?.Year); + Assert.Equal(9, date.RfcValue?.Month); + Assert.Equal(21, date.RfcValue?.Day); } [Fact] @@ -31,16 +31,30 @@ public void RfcDateTest_3() public void RfcDateTest_4() { RfcDate date = new RfcDate("00000000"); - Assert.Null(date.Date); + Assert.Null(date.RfcValue); } [Fact] public void RfcTimeTest_1() { var t = new RfcTime("140423"); - Assert.Equal(14, t.Time?.Hours); - Assert.Equal(4, t.Time?.Minutes); - Assert.Equal(23, t.Time?.Seconds); + Assert.Equal(14, t.RfcValue?.Hours); + Assert.Equal(4, t.RfcValue?.Minutes); + Assert.Equal(23, t.RfcValue?.Seconds); + } + + [Fact] + public void RfcBcd_1() + { + var bcd = new RfcBcd("140423.2101"); + Assert.Equal(140423.2101M, bcd.RfcValue); + } + + [Fact] + public void RfcBcd_2() + { + var bcd = new RfcBcd(140423.2101M); + Assert.Equal("140423.2101", bcd.ToString()); } } }