diff --git a/CompControl.SapFrameworkConnector/App.config b/CompControl.SapFrameworkConnector/App.config
new file mode 100644
index 0000000..e7094ce
--- /dev/null
+++ b/CompControl.SapFrameworkConnector/App.config
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CompControl.SapFrameworkConnector/CompControl.SapFrameworkConnector.csproj b/CompControl.SapFrameworkConnector/CompControl.SapFrameworkConnector.csproj
new file mode 100644
index 0000000..1a78ebc
--- /dev/null
+++ b/CompControl.SapFrameworkConnector/CompControl.SapFrameworkConnector.csproj
@@ -0,0 +1,145 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {236F375E-DEA1-461E-A05D-5358DCD25D09}
+ WinExe
+ CompControl.SapFrameworkConnector
+ CompControl.SapFrameworkConnector
+ v4.8
+ 512
+ true
+ true
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ExternalDLLs\CompControl.dll
+
+
+ ExternalDLLs\CompControl.ErpConnector.Service.dll
+
+
+ packages\log4net.3.2.0\lib\net462\log4net.dll
+
+
+ packages\Microsoft.Owin.4.2.3\lib\net45\Microsoft.Owin.dll
+
+
+ packages\Microsoft.Owin.Host.HttpListener.4.2.3\lib\net45\Microsoft.Owin.Host.HttpListener.dll
+
+
+ packages\Microsoft.Owin.Hosting.4.2.3\lib\net45\Microsoft.Owin.Hosting.dll
+
+
+ packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll
+
+
+ packages\Newtonsoft.Json.Bson.1.0.2\lib\net45\Newtonsoft.Json.Bson.dll
+
+
+ packages\Owin.1.0\lib\net40\Owin.dll
+
+
+ ExternalDLLs\sapnco.dll
+
+
+ ExternalDLLs\sapnco_utils.dll
+
+
+
+ packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll
+
+
+
+
+
+
+ packages\System.Memory.4.5.5\lib\net461\System.Memory.dll
+
+
+ packages\Microsoft.AspNet.WebApi.Client.6.0.0\lib\net45\System.Net.Http.Formatting.dll
+
+
+
+ packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll
+
+
+ packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll
+
+
+ packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll
+
+
+
+ packages\Microsoft.AspNet.WebApi.Core.5.3.0\lib\net45\System.Web.Http.dll
+
+
+ packages\Microsoft.AspNet.WebApi.Owin.5.3.0\lib\net45\System.Web.Http.Owin.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Component
+
+
+ ProjectInstaller.cs
+
+
+
+
+ Component
+
+
+ Service.cs
+
+
+
+
+
+
+
+
+
+
+
+
+ ProjectInstaller.cs
+
+
+ Service.cs
+
+
+
+
+
\ No newline at end of file
diff --git a/CompControl.SapFrameworkConnector/CompControl.SapFrameworkConnector.sln b/CompControl.SapFrameworkConnector/CompControl.SapFrameworkConnector.sln
new file mode 100644
index 0000000..e007a68
--- /dev/null
+++ b/CompControl.SapFrameworkConnector/CompControl.SapFrameworkConnector.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.12.35728.132 d17.12
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CompControl.SapFrameworkConnector", "CompControl.SapFrameworkConnector.csproj", "{236F375E-DEA1-461E-A05D-5358DCD25D09}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {236F375E-DEA1-461E-A05D-5358DCD25D09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {236F375E-DEA1-461E-A05D-5358DCD25D09}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {236F375E-DEA1-461E-A05D-5358DCD25D09}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {236F375E-DEA1-461E-A05D-5358DCD25D09}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/CompControl.SapFrameworkConnector/ConfigHelper.cs b/CompControl.SapFrameworkConnector/ConfigHelper.cs
new file mode 100644
index 0000000..5765cd1
--- /dev/null
+++ b/CompControl.SapFrameworkConnector/ConfigHelper.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Configuration;
+
+namespace CompControl.SapFrameworkConnector
+{
+ public class ConfigHelper
+ {
+ public static readonly string ThisWebApiServiceEndpoint = ConfigurationManager.AppSettings["ThisWebApiServiceEndpoint"];
+ public static readonly string ActiveSapDestinationName = ConfigurationManager.AppSettings["ActiveSapDestinationName"];
+ public static readonly string SapDefaultUSER = ConfigurationManager.AppSettings["SapDefaultUSER"];
+ public static readonly string SapDefaultPASSWD = ConfigurationManager.AppSettings["SapDefaultPASSWD"];
+ public static readonly string SapCLIENT = ConfigurationManager.AppSettings["SapCLIENT"];
+ public static readonly string SapLanguage = ConfigurationManager.AppSettings["SapLanguage"];
+ public static readonly string SapASHOST = ConfigurationManager.AppSettings["SapASHOST"];
+ public static readonly string SapSYSNR = ConfigurationManager.AppSettings["SapSYSNR"];
+ public static readonly string SapMaxPoolSize = ConfigurationManager.AppSettings["SapMaxPoolSize"];
+ public static readonly string SapIdleTimeout = ConfigurationManager.AppSettings["SapIdleTimeout"];
+ }
+}
diff --git a/CompControl.SapFrameworkConnector/ExternalDLLs/CompControl.ErpConnector.Service.dll b/CompControl.SapFrameworkConnector/ExternalDLLs/CompControl.ErpConnector.Service.dll
new file mode 100644
index 0000000..8cd7a93
Binary files /dev/null and b/CompControl.SapFrameworkConnector/ExternalDLLs/CompControl.ErpConnector.Service.dll differ
diff --git a/CompControl.SapFrameworkConnector/ExternalDLLs/CompControl.dll b/CompControl.SapFrameworkConnector/ExternalDLLs/CompControl.dll
new file mode 100644
index 0000000..b7f9a47
Binary files /dev/null and b/CompControl.SapFrameworkConnector/ExternalDLLs/CompControl.dll differ
diff --git a/CompControl.SapFrameworkConnector/ExternalDLLs/sapnco.dll b/CompControl.SapFrameworkConnector/ExternalDLLs/sapnco.dll
new file mode 100644
index 0000000..61bb9a3
Binary files /dev/null and b/CompControl.SapFrameworkConnector/ExternalDLLs/sapnco.dll differ
diff --git a/CompControl.SapFrameworkConnector/ExternalDLLs/sapnco_utils.dll b/CompControl.SapFrameworkConnector/ExternalDLLs/sapnco_utils.dll
new file mode 100644
index 0000000..9c65d6c
Binary files /dev/null and b/CompControl.SapFrameworkConnector/ExternalDLLs/sapnco_utils.dll differ
diff --git a/CompControl.SapFrameworkConnector/GBS/GBSApiController.cs b/CompControl.SapFrameworkConnector/GBS/GBSApiController.cs
new file mode 100644
index 0000000..21b1a1a
--- /dev/null
+++ b/CompControl.SapFrameworkConnector/GBS/GBSApiController.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web.Http;
+
+namespace CompControl.SapFrameworkConnector
+{
+ [RoutePrefix("api/gbs")]
+ public class GBSApiController
+ {
+ private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ }
+}
diff --git a/CompControl.SapFrameworkConnector/Program.cs b/CompControl.SapFrameworkConnector/Program.cs
new file mode 100644
index 0000000..63cc98d
--- /dev/null
+++ b/CompControl.SapFrameworkConnector/Program.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.ServiceProcess;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CompControl.SapFrameworkConnector
+{
+ internal static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ static void Main()
+ {
+ ServiceBase[] ServicesToRun;
+ ServicesToRun = new ServiceBase[]
+ {
+ new Service()
+ };
+ ServiceBase.Run(ServicesToRun);
+ }
+ }
+}
diff --git a/CompControl.SapFrameworkConnector/ProjectInstaller.Designer.cs b/CompControl.SapFrameworkConnector/ProjectInstaller.Designer.cs
new file mode 100644
index 0000000..6944bfa
--- /dev/null
+++ b/CompControl.SapFrameworkConnector/ProjectInstaller.Designer.cs
@@ -0,0 +1,66 @@
+using System.Configuration.Install;
+
+namespace CompControl.SapFrameworkConnector
+{
+ partial class ProjectInstaller
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
+ this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
+
+ // serviceProcessInstaller1
+ this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
+ this.serviceProcessInstaller1.Password = null;
+ this.serviceProcessInstaller1.Username = null;
+
+ // serviceInstaller1
+ this.serviceInstaller1.DelayedAutoStart = true;
+ this.serviceInstaller1.Description = "CompControl SapFrameworkConnector";
+ this.serviceInstaller1.ServiceName = "CompControl.SapFrameworkConnector";
+ this.serviceInstaller1.DisplayName = this.serviceInstaller1.ServiceName;
+ this.serviceInstaller1.ServicesDependedOn = new string[] { "" };
+ this.serviceInstaller1.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.serviceInstaller1_AfterInstall);
+
+ // ProjectInstaller
+ this.Installers.AddRange(new System.Configuration.Install.Installer[] {
+ this.serviceProcessInstaller1,
+ this.serviceInstaller1});
+
+ }
+
+ #endregion
+
+ private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
+ private System.ServiceProcess.ServiceInstaller serviceInstaller1;
+
+ private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e)
+ {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/CompControl.SapFrameworkConnector/ProjectInstaller.cs b/CompControl.SapFrameworkConnector/ProjectInstaller.cs
new file mode 100644
index 0000000..85112c1
--- /dev/null
+++ b/CompControl.SapFrameworkConnector/ProjectInstaller.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Configuration.Install;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace CompControl.SapFrameworkConnector
+{
+ [RunInstaller(true)]
+ public partial class ProjectInstaller : System.Configuration.Install.Installer
+ {
+ public ProjectInstaller()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/CompControl.SapFrameworkConnector/ProjectInstaller.resx b/CompControl.SapFrameworkConnector/ProjectInstaller.resx
new file mode 100644
index 0000000..efe3a56
--- /dev/null
+++ b/CompControl.SapFrameworkConnector/ProjectInstaller.resx
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
+ 227, 17
+
+
+ False
+
+
\ No newline at end of file
diff --git a/CompControl.SapFrameworkConnector/Properties/AssemblyInfo.cs b/CompControl.SapFrameworkConnector/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..9192e21
--- /dev/null
+++ b/CompControl.SapFrameworkConnector/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("CompControl.SapFrameworkConnector")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("CompControl.SapFrameworkConnector")]
+[assembly: AssemblyCopyright("Copyright © 2025")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("236f375e-dea1-461e-a05d-5358dcd25d09")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/CompControl.SapFrameworkConnector/Service.Designer.cs b/CompControl.SapFrameworkConnector/Service.Designer.cs
new file mode 100644
index 0000000..71823b5
--- /dev/null
+++ b/CompControl.SapFrameworkConnector/Service.Designer.cs
@@ -0,0 +1,36 @@
+namespace CompControl.SapFrameworkConnector
+{
+ partial class Service
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.ServiceName = "CompControl.SapFrameworkConnector";
+ }
+
+ #endregion
+ }
+}
diff --git a/CompControl.SapFrameworkConnector/Service.cs b/CompControl.SapFrameworkConnector/Service.cs
new file mode 100644
index 0000000..0672792
--- /dev/null
+++ b/CompControl.SapFrameworkConnector/Service.cs
@@ -0,0 +1,65 @@
+using CompControl.SapFrameworkConnector;
+using Microsoft.Owin;
+using Microsoft.Owin.Hosting;
+using SAP.Middleware.Connector;
+using System;
+using System.Configuration;
+using System.ServiceProcess;
+using System.Xml;
+
+namespace CompControl.SapFrameworkConnector
+{
+ public partial class Service : ServiceBase
+ {
+ private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+ private IDisposable _server = null;
+
+
+ public Service()
+ {
+ InitializeComponent();
+ }
+
+ protected override void OnStart(string[] args)
+ {
+ RfcTrace.DefaultTraceLevel = 3;
+ RfcTrace.TraceDirectory = @"C:\Temp\CC\NCoLogs"; // Log-Dateien in diesem Ordner speichern
+ _log.Debug("SAP NCo Logging aktiviert: " + RfcTrace.TraceDirectory);
+
+ var config = new ConfigFileDestination();
+ if (!RfcDestinationManager.IsDestinationConfigurationRegistered()) { RfcDestinationManager.RegisterDestinationConfiguration(config); }
+ var dest = RfcDestinationManager.GetDestination(ConfigHelper.ActiveSapDestinationName); // Jetzt kannst du die Destination abrufen
+ _log.Info("SAP Destination loaded: " + dest.Name);
+
+ _server = WebApp.Start(url: ConfigHelper.ThisWebApiServiceEndpoint);
+ _log.Info($"Service started successfully at: {ConfigHelper.ThisWebApiServiceEndpoint}");
+ }
+
+ protected override void OnStop()
+ {
+ _log.Debug($"Service was stopped!");
+ }
+
+ }
+}
+
+public class ConfigFileDestination : IDestinationConfiguration
+{
+ private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ public RfcConfigParameters GetParameters(string destinationName)
+ {
+ RfcConfigParameters parms = new RfcConfigParameters();
+ parms.Add(RfcConfigParameters.AppServerHost, ConfigHelper.SapASHOST);
+ parms.Add(RfcConfigParameters.SystemNumber, ConfigHelper.SapSYSNR);
+ parms.Add(RfcConfigParameters.Client, ConfigHelper.SapCLIENT);
+ parms.Add(RfcConfigParameters.User, ConfigHelper.SapDefaultUSER);
+ parms.Add(RfcConfigParameters.Password, ConfigHelper.SapDefaultPASSWD);
+ parms.Add(RfcConfigParameters.Language, ConfigHelper.SapLanguage);
+ _log.Debug($"Destination registered => ASHOST={ConfigHelper.SapASHOST} | SYSNR={ConfigHelper.SapSYSNR} | CLIENT={ConfigHelper.SapCLIENT} | USER={ConfigHelper.SapDefaultUSER} | LANG={ConfigHelper.SapLanguage}");
+ return parms;
+ }
+
+ public bool ChangeEventsSupported() => false;
+ public event RfcDestinationManager.ConfigurationChangeHandler ConfigurationChanged;
+}
\ No newline at end of file
diff --git a/CompControl.SapFrameworkConnector/Service.resx b/CompControl.SapFrameworkConnector/Service.resx
new file mode 100644
index 0000000..e5858cc
--- /dev/null
+++ b/CompControl.SapFrameworkConnector/Service.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ False
+
+
\ No newline at end of file
diff --git a/CompControl.SapFrameworkConnector/ServiceController.cs b/CompControl.SapFrameworkConnector/ServiceController.cs
new file mode 100644
index 0000000..0fd8a59
--- /dev/null
+++ b/CompControl.SapFrameworkConnector/ServiceController.cs
@@ -0,0 +1,22 @@
+using System.Net;
+using System.Net.Http;
+using System.Web.Http;
+
+namespace CompControl.SapFrameworkConnector
+{
+ [RoutePrefix("api/service")]
+ public class ServiceController : ApiController
+ {
+ private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ #region Ping
+ // GET api/service/ping
+ [Route("ping")]
+ [HttpGet]
+ public HttpResponseMessage Ping()
+ {
+ return Request.CreateResponse(HttpStatusCode.OK, true);
+ }
+ #endregion
+ }
+}
diff --git a/CompControl.SapFrameworkConnector/Standard/SapStandardFunctions.cs b/CompControl.SapFrameworkConnector/Standard/SapStandardFunctions.cs
new file mode 100644
index 0000000..7e54996
--- /dev/null
+++ b/CompControl.SapFrameworkConnector/Standard/SapStandardFunctions.cs
@@ -0,0 +1,261 @@
+using log4net;
+using SAP.Middleware.Connector;
+using System;
+using System.Collections.Generic;
+using static CompControl.ErpConnector.Service.Models.Cicor_SapModels;
+using static CompControl.ErpConnector.Service.Models.SapDataTypes;
+
+namespace CompControl.SapFrameworkConnector
+{
+ public class SapStandardFunctions
+ {
+ private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); //Logger
+
+
+ //-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+ public static DateTime ConvertSapDateToDateTime(string sapDate, bool delimitersUsed = true)
+ {
+ if (delimitersUsed) //Style: 2022-02-18, mostly gotten from SAP with GetString on DATS
+ {
+ int year = Convert.ToInt32(sapDate.Substring(0, 4));
+ int month = Convert.ToInt32(sapDate.Substring(5, 2));
+ int day = Convert.ToInt32(sapDate.Substring(8, 2));
+ return new DateTime(year, month, day);
+ }
+ else //Style: 20220218 (Like stored in SAP, needed for input)
+ {
+ int year = Convert.ToInt32(sapDate.Substring(0, 4));
+ int month = Convert.ToInt32(sapDate.Substring(4, 2));
+ int day = Convert.ToInt32(sapDate.Substring(6, 2));
+ return new DateTime(year, month, day);
+ }
+ }
+ public static string ConvertDateTimeToSapTime(DateTime date)
+ {
+ if (date == null) { return "00000000"; }
+ return date.ToString("yyyyMMdd");
+ }
+ public static string ConvertMslToSAPString(string matfeuchte)
+ {
+ if (matfeuchte == null || matfeuchte.Equals("")) { return "01"; }
+ switch (matfeuchte)
+ {
+ case "0":
+ return "01";
+ case "1":
+ return "01";
+ case "2":
+ return "02";
+ case "3":
+ return "03";
+ case "4":
+ return "04";
+ case "5":
+ return "05";
+ case "6":
+ return "06";
+ case "2a":
+ return "07";
+ case "5a":
+ return "08";
+ default:
+ return "01";
+ }
+ }
+
+ //-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+ public static GetMATNRfromBMATN_EXPORT GetMATNRfromBMATN(GetMATNRfromBMATN_IMPORT import)
+ {
+ string errorMsg = "";
+ GetMATNRfromBMATN_EXPORT export = new GetMATNRfromBMATN_EXPORT();
+
+ try
+ {
+ RfcDestination dest = RfcDestinationManager.GetDestination(ConfigHelper.ActiveSapDestinationName);
+ IRfcFunction func = dest.Repository.CreateFunction("RFC_READ_TABLE"); //Create Function
+ IRfcTable t2 = func.GetTable("DATA");
+ t2.Clear();
+ IRfcTable options2 = func.GetTable("OPTIONS");
+ options2.Clear();
+ options2.Append();
+ options2.SetValue("TEXT", "BMATN = '" + import.BMATN?.Trim().PadLeft(18, '0') + "'");
+ IRfcTable fields2 = func.GetTable("FIELDS");
+ fields2.Append(1);
+ fields2.CurrentIndex = 0; fields2.SetValue(0, "EMATN");
+ func.SetValue("QUERY_TABLE", "AMPL"); //Set Value to function
+ func.SetValue("DELIMITER", ";"); //Set Value to function
+ func.SetValue("USE_ET_DATA_4_RETURN", "0");
+ func.Invoke(dest); //Invoke function at Sap destination
+
+ IRfcTable rfcTable2 = func.GetTable("DATA"); //Process return values
+ _log.Debug("Number rows DATA of MATNR found: " + rfcTable2.Count);
+ int rowCount2 = rfcTable2.Count;
+
+ foreach (IRfcStructure structure in rfcTable2)
+ {
+ export.MATNR = structure.GetString(0);
+ _log.Debug("MATNR received: " + export.MATNR);
+ }
+ }
+ catch (Exception ex) { errorMsg += "CI: SAP Other Exception: " + ex; }
+
+ if (!errorMsg.Equals("")) { _log.Error(errorMsg); }
+
+ return export;
+ }
+ public static GetMAKTXfromMATNR_EXPORT GetMAKTXfromMATNR(GetMAKTXfromMATNR_IMPORT import)
+ {
+ string errorMsg = "";
+ GetMAKTXfromMATNR_EXPORT export = new GetMAKTXfromMATNR_EXPORT();
+
+ try
+ {
+ RfcDestination dest = RfcDestinationManager.GetDestination(ConfigHelper.ActiveSapDestinationName);
+ IRfcFunction func3 = dest.Repository.CreateFunction("RFC_READ_TABLE"); //Create Function
+ IRfcTable t3 = func3.GetTable("DATA");
+ t3.Clear();
+ IRfcTable options3 = func3.GetTable("OPTIONS");
+ options3.Clear();
+ options3.Append();
+ options3.SetValue("TEXT", "MATNR = '" + import.MATNR?.Trim().PadLeft(18, '0') + "'");
+ options3.Append();
+ IRfcTable fields3 = func3.GetTable("FIELDS");
+ fields3.Append(1);
+ fields3.CurrentIndex = 0; fields3.SetValue(0, "MAKTX");
+ func3.SetValue("QUERY_TABLE", "MAKT");
+ func3.SetValue("DELIMITER", ";");
+ func3.SetValue("USE_ET_DATA_4_RETURN", "0");
+ func3.Invoke(dest); //Invoke function at Sap destination
+
+ IRfcTable rfcTable3 = func3.GetTable("DATA"); //Process return values
+ _log.Debug("Number rows DATA of MAKTX found: " + rfcTable3.Count);
+ int rowCount3 = rfcTable3.Count;
+
+ foreach (IRfcStructure structure in rfcTable3)
+ {
+ export.MAKTX = structure.GetString(0);
+ _log.Info("MAKTX received: " + export.MAKTX);
+ }
+ }
+ catch (Exception ex) { errorMsg += "CI: SAP Other Exception: " + ex; }
+
+ if (!errorMsg.Equals("")) { _log.Error(errorMsg); }
+
+ _log.Debug($"GetMAKTXforMATNR: Found MAKTX for MATNR {import.MATNR}: {export.MAKTX}");
+
+ return export;
+ }
+
+ public static BAPI_PO_GETDETAIL_EXPORT BAPI_PO_GETDETAILS(BAPI_PO_GETDETAIL_IMPORT import)
+ {
+ string errorMsg = "";
+ BAPI_PO_GETDETAIL_EXPORT export = new BAPI_PO_GETDETAIL_EXPORT();
+ List poItemBuffer = new List();
+
+
+ if (import != null)
+ {
+ try
+ {
+ RfcDestination dest = RfcDestinationManager.GetDestination(ConfigHelper.ActiveSapDestinationName);
+ IRfcFunction func = dest.Repository.CreateFunction("BAPI_PO_GETDETAIL"); //Create Function
+ func.SetValue("PURCHASEORDER", import.PURCHASEORDER?.Trim().PadLeft(10, '0')); //Set Value to function
+ func.SetValue("ITEMS", import.ITEMS); //Set Value to function
+ func.SetValue("HISTORY", "X");
+ func.SetValue("SCHEDULES", "X");
+ func.SetValue("ACCOUNT_ASSIGNMENT", "X");
+ func.SetValue("ITEM_TEXTS", "X");
+ func.SetValue("HEADER_TEXTS", "X");
+ func.SetValue("SERVICES", "X");
+ func.SetValue("CONFIRMATIONS", "X");
+ func.SetValue("SERVICE_TEXTS", "X");
+ func.SetValue("EXTENSIONS", "X");
+ func.Invoke(dest); //Invoke function at Sap destination
+
+ IRfcStructure po_header_struct = func.GetStructure("PO_HEADER");
+ export.PO_HEADER.PO_NUMBER = po_header_struct.GetString("PO_NUMBER");
+ export.PO_HEADER.CREATED_ON = po_header_struct.GetString("CREATED_ON");
+ export.PO_HEADER.CREATED_BY = po_header_struct.GetString("CREATED_BY");
+ export.PO_HEADER.DOC_TYPE = po_header_struct.GetString("DOC_TYPE");
+ export.PO_HEADER.VENDOR = po_header_struct.GetString("VENDOR");
+ export.PO_HEADER.VEND_NAME = po_header_struct.GetString("VEND_NAME");
+ if (!(export.PO_HEADER.DOC_TYPE.Equals("MP") || export.PO_HEADER.DOC_TYPE.Equals("MP") || export.PO_HEADER.DOC_TYPE.Equals("MP") || export.PO_HEADER.DOC_TYPE.Equals("ZBRO"))) { }
+
+ IRfcTable po_items_table = func.GetTable("PO_ITEMS");
+ foreach (IRfcStructure row in po_items_table)
+ {
+ BAPIEKPO temp = new BAPIEKPO();
+ temp.PO_NUMBER = row.GetString("PO_NUMBER").TrimStart('0') ?? "";
+ temp.PO_ITEM = row.GetString("PO_ITEM").TrimStart('0') ?? "";
+ temp.STATUS = row.GetString("STATUS") ?? "";
+ temp.CHANGED_ON = row.GetString("CHANGED_ON") ?? "";
+ temp.SHORT_TEXT = row.GetString("SHORT_TEXT") ?? "";
+ temp.MATERIAL = row.GetString("MATERIAL").TrimStart('0') ?? "";
+ temp.PUR_MAT = row.GetString("PUR_MAT").TrimStart('0') ?? "";
+ temp.QUANTITY = row.GetDecimal("QUANTITY");
+ temp.UNIT = row.GetString("UNIT") ?? "";
+ temp.PLANT = row.GetString("PLANT") ?? "";
+ temp.MAT_GRP = row.GetString("MAT_GRP") ?? "";
+ temp.ACCTASSCAT = row.GetString("ACCTASSCAT") ?? "";
+ temp.QUAL_INSP = row.GetString("QUAL_INSP") ?? "";
+ temp.MANU_MAT = row.GetString("MANU_MAT") ?? "";
+ temp.MFR_NO = row.GetString("MFR_NO") ?? "";
+ temp.VEND_MAT = row.GetString("VEND_MAT") ?? "";
+ temp.STOR_LOC = row.GetString("STORE_LOC") ?? "";
+ temp.DELETE_IND = row.GetString("DELETE_IND") ?? "";
+ poItemBuffer.Add(temp);
+ }
+
+ IRfcTable po_item_hist_total = func.GetTable("PO_ITEM_HISTORY_TOTALS");
+ foreach (IRfcStructure row in po_item_hist_total)
+ {
+ BAPIEKBES temp = new BAPIEKBES();
+ temp.BLOCKED_QY = row.GetDecimal("BLOCKED_QY");
+ temp.BL_QTY = row.GetDecimal("BL_QTY");
+ temp.BL_QTY_TOTAL = row.GetDecimal("BL_QTY_TOTAL");
+ temp.DELIV_QTY = row.GetDecimal("DELIV_QTY");
+ temp.DL_QTY_TOTAL = row.GetDecimal("DL_QTY_TOTAL");
+ temp.DL_QTY_TRSP = row.GetDecimal("DL_QTY_TRSP");
+ temp.IV_QTY = row.GetDecimal("IV_QTY");
+ temp.IV_QTY_TOTAL = row.GetDecimal("IV_QTY_TOTAL");
+ temp.PO_ITEM = row.GetString("PO_ITEM").TrimStart('0') ?? "";
+ temp.PO_PR_QNT = row.GetDecimal("PO_PR_QNT");
+ temp.SERIAL_NO = row.GetString("SERIAL_NO").TrimStart('0') ?? "";
+ temp.WITHDR_QTY = row.GetDecimal("WITHDR_QTY");
+ export.PO_ITEM_HISTORY_TOTAL.Add(temp);
+ }
+
+ IRfcTable po_item_hist = func.GetTable("PO_ITEM_HISTORY");
+ foreach (IRfcStructure row in po_item_hist)
+ {
+ BAPIEKBE temp = new BAPIEKBE();
+ temp.BATCH = row.GetString("BATCH") ?? "";
+ temp.DOC_YEAR = row.GetString("DOC_YEAR") ?? "";
+ temp.MATDOC_ITM = row.GetString("MATDOC_ITM") ?? "";
+ temp.MATERIAL = row.GetString("MATERIAL") ?? "";
+ temp.MAT_DOC = row.GetString("MAT_DOC") ?? "";
+ temp.MOVE_TYPE = row.GetString("MOVE_TYPE") ?? "";
+ temp.PO_ITEM = row.GetString("PO_ITEM") ?? "";
+ temp.PROCESS_ID = row.GetString("PROCESS_ID") ?? "";
+ temp.PSTNG_DATE = row.GetString("PSTNG_DATE") ?? "";
+ temp.PUR_MAT = row.GetString("PUR_MAT") ?? "";
+ temp.QUANTITY = row.GetDecimal("QUANTITY");
+ temp.REF_DOC_NO = row.GetString("REF_DOC_NO") ?? "";
+ temp.SERIAL_NO = row.GetString("SERIAL_NO") ?? "";
+ temp.DELIV_QTY = row.GetDecimal("DELIV_QTY");
+ temp.DELIV_UNIT = row.GetString("DELIV_UNIT") ?? "";
+ export.PO_ITEM_HISTORY.Add(temp);
+ }
+ }
+ catch (Exception ex) { errorMsg += "CI: SAP Other Exception: " + ex; }
+ }
+ else { _log.Debug("Error, IMPORT for BAPI_PO_GETDETAILS was NULL! "); }
+
+ if (!errorMsg.Equals("")) { _log.Debug(errorMsg); }
+
+ return export;
+ }
+ }
+}
diff --git a/CompControl.SapFrameworkConnector/Standard/StandardApiController.cs b/CompControl.SapFrameworkConnector/Standard/StandardApiController.cs
new file mode 100644
index 0000000..0944928
--- /dev/null
+++ b/CompControl.SapFrameworkConnector/Standard/StandardApiController.cs
@@ -0,0 +1,141 @@
+using System;
+using System.Net.Http;
+using System.Net;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Web.Http;
+using CompControl.ErpConnector.Service.Models;
+using static CompControl.ErpConnector.Service.Models.Cicor_SapModels;
+using static CompControl.ErpConnector.Service.Models.SapDataTypes;
+
+
+namespace CompControl.SapFrameworkConnector
+{
+ [RoutePrefix("api/we")]
+ public class StandardApiController: ApiController
+ {
+ private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ [Route("getbestellungen")]
+ [HttpPut]
+ public async Task GetBestellungen([FromBody] FilterBestellungen filterBestellungen, CancellationToken cancellationToken)
+ {
+ ApiResultBestellungen result = new ApiResultBestellungen(); //New ApiResult to return via Web
+
+ try
+ {
+ _log.Debug("GetBestellungen received for Filter: " + filterBestellungen.ToString());
+
+ BAPI_PO_GETDETAIL_IMPORT import = new BAPI_PO_GETDETAIL_IMPORT() { PURCHASEORDER = filterBestellungen.OrderNo };
+ BAPI_PO_GETDETAIL_EXPORT details = SapStandardFunctions.BAPI_PO_GETDETAILS(import);
+ int cnt = 0;
+
+ foreach (BAPIEKPO det in details.PO_ITEMS)
+ {
+ cnt++;
+ string inspect = "";
+ string inspectInfo = "";
+ string prioText = "";
+ string prioChar = "";
+ string ItemText1 = "";
+ bool posIsClosed = false;
+ DateTime expDeliverDate = DateTime.MaxValue;
+
+ if (det.QUAL_INSP.Equals("X"))
+ {
+ inspect = "Q";
+ if (ConfigHelper.SapLanguage.Equals("DE")) { inspectInfo = "Qualitaetspruefung erforderlich!"; }
+ else { inspectInfo = "Quality check mandatory!"; }
+ }
+
+ expDeliverDate = SapStandardFunctions.ConvertSapDateToDateTime(det.ExpectedDeliveryDate, false);
+ if (det.QUANTITY <= det.QUANTITYPROCESSED) { posIsClosed = true; }
+
+ GetMAKTXfromMATNR_IMPORT getMak = new GetMAKTXfromMATNR_IMPORT();
+ getMak.MATNR = det.MATERIAL.Trim();
+ GetMAKTXfromMATNR_EXPORT outMak = SapStandardFunctions.GetMAKTXfromMATNR(getMak);
+ ItemText1 = outMak.MAKTX;
+
+ GrDataItem gr = new GrDataItem();
+ gr.AcceptedManufacturesLink = cnt.ToString();
+ gr.Created = SapStandardFunctions.ConvertSapDateToDateTime(details.PO_HEADER.CREATED_ON);
+ gr.LastUpdate = SapStandardFunctions.ConvertSapDateToDateTime(det.CHANGED_ON);
+ gr.PosIsClosed = posIsClosed;
+ gr.OrderNo = det.PO_NUMBER;
+ gr.OrderPos = det.PO_ITEM;
+ gr.OrderQuantity = det.QUANTITY;
+ gr.ItemNo = det.MATERIAL.Trim();
+ gr.ItemText1 = ItemText1;
+ gr.ItemNoRef = gr.CustomValue05 = det.PUR_MAT;
+ gr.OrderPosInfoText = det.ACCTASSCAT;
+ gr.QuantityProcessed = det.QUANTITYPROCESSED;
+ gr.QuantityUnit = det.UNIT;
+ gr.Plant = det.PLANT;
+ gr.Inspection = inspect;
+ gr.InspectionInfo = inspectInfo;
+ gr.Priority = prioChar;
+ gr.PriorityInfoText = prioText;
+ gr.CustomValue01 = det.QUAL_INSP;
+ gr.ExpectedDeliveryDate = expDeliverDate;
+ gr.MPN = det.MANU_MAT.Trim();
+ gr.SupplierNo = details.PO_HEADER.VENDOR;
+ gr.SupplierName = details.PO_HEADER.VEND_NAME;
+ gr.SupplierItemNo = det.VEND_MAT;
+ gr.StorageLocation = det.STOR_LOC;
+ gr.Schedule = det.SCHEDULE.TrimStart('0');
+ gr.CustomValue08 = details.PO_HEADER.DOC_TYPE;
+ if (!det.DELETE_IND.Equals("L")) { result.GrDataItems.Add(gr); }
+ }
+
+ _log.Debug($"Result of GetBestellungen now consists of {result.GrDataItems.Count} GrDataItems and {result.ManufacturerDataItems.Count} ManufactuerDataItems...");
+
+ if (result.IsSuccessful) { _log.Debug(result); } //Action was successful => log for debug
+ else { _log.Error(result); } //An error occurred
+ }
+ catch (Exception ex)
+ {
+ string sm = $"GetBestellungen: An unexpected error occured: " + ex;
+ _log.Error(sm);
+ result = new ApiResultBestellungen //ApiResult on Exception
+ {
+ ErrorNumber = 101,
+ MessageShort = sm,
+ MessageLong = sm,
+ MessageTechnical = $"{sm} [{filterBestellungen}] - {ex}"
+ };
+ }
+
+ return Request.CreateResponse(HttpStatusCode.OK, result);
+ }
+
+
+ [Route("getherstellerdaten")]
+ public async Task GetHerstellerdaten([FromUri] string itemNo, CancellationToken cancellationToken)
+ {
+ ApiResultHerstellerdaten result = new ApiResultHerstellerdaten(); //New ApiResult to return via Web
+ _log.Debug("GetHerstellerdaten received for itemNo: " + itemNo);
+
+ try
+ {
+
+
+ if (result.IsSuccessful) { _log.Debug(result); } //Action was successful => log for debug
+ else { _log.Error(result); } //An error occurred
+ }
+ catch (Exception ex)
+ {
+ string sm = $"GetHerstellerDaten: An unexpected error occured for '{itemNo}' " + ex;
+ _log.Error(sm);
+ result = new ApiResultHerstellerdaten //Default ApiResult on error
+ {
+ ErrorNumber = 101,
+ MessageShort = sm,
+ MessageLong = sm,
+ MessageTechnical = $"{sm} [{itemNo}] - {ex}"
+ };
+ }
+
+ return Request.CreateResponse(HttpStatusCode.OK, result);
+ }
+ }
+}
diff --git a/CompControl.SapFrameworkConnector/Startup.cs b/CompControl.SapFrameworkConnector/Startup.cs
new file mode 100644
index 0000000..1e6aa4d
--- /dev/null
+++ b/CompControl.SapFrameworkConnector/Startup.cs
@@ -0,0 +1,95 @@
+using Owin;
+using System.Web.Http.ExceptionHandling;
+using System.Web.Http;
+using Microsoft.Owin;
+using System.Net.Http;
+using System.Net;
+using System.Threading.Tasks;
+using System.Threading;
+using System;
+
+[assembly: OwinStartup(typeof(CompControl.SapFrameworkConnector.Startup))]
+[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config", Watch = true)]
+
+namespace CompControl.SapFrameworkConnector
+{
+ public class Startup
+ {
+ public void Configuration(IAppBuilder app)
+ {
+ HttpConfiguration config = new HttpConfiguration();
+ config.Services.Replace(typeof(IExceptionLogger), new UnhandledExceptionLogger());
+ config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler());
+ config.MapHttpAttributeRoutes();
+ config.Routes.MapHttpRoute(name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional });
+ app.UseWebApi(config);
+ }
+ }
+
+ class UnhandledExceptionLogger : ExceptionLogger
+ {
+ private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+ public override void Log(ExceptionLoggerContext context) { _log.Error("Web API - Unhandled Exception", context.Exception); }
+ }
+
+ class GlobalExceptionHandler : ExceptionHandler
+ {
+ public override void Handle(ExceptionHandlerContext context)
+ {
+ if (context.Exception is ArgumentNullException)
+ {
+ var result = new HttpResponseMessage(HttpStatusCode.BadRequest)
+ {
+ Content = new StringContent(context.Exception.Message),
+ ReasonPhrase = "ArgumentNullException"
+ };
+
+ context.Result = new ArgumentNullResult(context.Request, result);
+ }
+ else
+ {
+ // Handle other exceptions
+ context.Result = new TextPlainErrorResult
+ {
+ Request = context.ExceptionContext.Request,
+ Content = context.Exception.Message,
+ ReasonPhrase = "Unhandled Web API Exception"
+ };
+ }
+ }
+
+ private class TextPlainErrorResult : IHttpActionResult
+ {
+ public HttpRequestMessage Request { get; set; }
+ public string Content { get; set; }
+ public string ReasonPhrase { get; set; }
+
+ public Task ExecuteAsync(CancellationToken cancellationToken)
+ {
+ HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.InternalServerError);
+ response.Content = new StringContent(Content);
+ response.RequestMessage = Request;
+ response.ReasonPhrase = ReasonPhrase;
+ return Task.FromResult(response);
+ }
+ }
+
+ private class ArgumentNullResult : IHttpActionResult
+ {
+ private HttpRequestMessage _request;
+ private HttpResponseMessage _httpResponseMessage;
+
+
+ public ArgumentNullResult(HttpRequestMessage request, HttpResponseMessage httpResponseMessage)
+ {
+ _request = request;
+ _httpResponseMessage = httpResponseMessage;
+ }
+
+ public Task ExecuteAsync(CancellationToken cancellationToken)
+ {
+ return Task.FromResult(_httpResponseMessage);
+ }
+ }
+ }
+}
diff --git a/CompControl.SapFrameworkConnector/packages.config b/CompControl.SapFrameworkConnector/packages.config
new file mode 100644
index 0000000..09a5b87
--- /dev/null
+++ b/CompControl.SapFrameworkConnector/packages.config
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file