From be12fe90a14c562c664f36d1fe8295d343b13753 Mon Sep 17 00:00:00 2001 From: Dmitriy Benyuk Date: Mon, 3 Mar 2025 09:59:10 +0200 Subject: [PATCH 1/2] Fix getting correct Backend context for connection restoring| Fix exception handling for HttpRequestException | Fix warnings --- .../Configuration/Global.cs | 25 ++-- .../Connectors/Connector.cs | 134 ++++++++++-------- .../Connectors/ConnectorBase.cs | 24 +--- .../Connectors/EndpointConnector.cs | 16 +-- .../Connectors/WebServiceConnector.cs | 14 +- ...Ecommerce.DynamicwebLiveIntegration.csproj | 2 +- .../EndpointMonitoringService.cs | 20 +-- .../Helpers.cs | 20 ++- .../IntegrationCustomerCenterHandler.cs | 26 ++-- .../LiveContext.cs | 13 +- .../LiveIntegrationAddIn.cs | 8 +- .../CartCheckoutDoneOrderIsComplete.cs | 5 +- .../NotificationSubscriberBase.cs | 15 +- .../NotificationSubscribers/OrderAfterSave.cs | 8 +- .../NotificationSubscribers/PageLoaded.cs | 7 +- .../PageOnGlobalTags.cs | 4 +- .../VariantListBeforeRender.cs | 8 +- .../OrderHandler.cs | 74 +++++----- .../Orders/LiveCartCalculationProvider.cs | 5 +- .../Products/ProductManager.cs | 31 ++-- .../Products/ProductPriceProvider.cs | 8 +- .../Products/StockProvider.cs | 2 +- .../CaptureOrdersScheduledTask.cs | 6 +- .../QueuedOrdersSyncScheduledTask.cs | 2 +- .../UpdateOrdersScheduledTask.cs | 4 +- .../SubmitType.cs | 12 +- .../ProductTemplateExtender.cs | 6 +- .../TemplatesHelper.cs | 6 +- .../UrlHandler.cs | 69 +++++---- 29 files changed, 299 insertions(+), 275 deletions(-) diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Configuration/Global.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Configuration/Global.cs index 792f023..111a0c2 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Configuration/Global.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Configuration/Global.cs @@ -44,23 +44,14 @@ public static bool EnableCartCommunication(Settings settings, bool orderComplete { string enableCartCommunication = settings.CartCommunicationType; - switch (enableCartCommunication) + return enableCartCommunication switch { - case Constants.CartCommunicationType.None: - return false; - - case Constants.CartCommunicationType.Full: - return true; - - case Constants.CartCommunicationType.OnlyOnOrderComplete: - return orderComplete; - - case Constants.CartCommunicationType.CartOnly: - return !orderComplete; - - default: - return false; - } + Constants.CartCommunicationType.None => false, + Constants.CartCommunicationType.Full => true, + Constants.CartCommunicationType.OnlyOnOrderComplete => orderComplete, + Constants.CartCommunicationType.CartOnly => !orderComplete, + _ => false, + }; } /// @@ -112,7 +103,7 @@ public static string GetShopId(PageView pageView) public static bool IsLazyLoadingForProductInfoEnabled(Settings settings) { - return Global.IsIntegrationActive(settings) && settings.EnableLivePrices && Connector.IsWebServiceConnectionAvailable(settings) + return Global.IsIntegrationActive(settings) && settings.EnableLivePrices && Connector.IsWebServiceConnectionAvailable(settings, SubmitType.Live) && (settings.LiveProductInfoForAnonymousUsers || Helpers.GetCurrentExtranetUser() != null) && (Helpers.GetCurrentExtranetUser() == null || !Helpers.GetCurrentExtranetUser().IsLivePricesDisabled) && settings.LazyLoadProductInfo; diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs index ec2df03..8192c7b 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs @@ -8,6 +8,9 @@ using System; using System.Collections.Concurrent; using System.Net; +using System.Net.Http; +using System.Net.Mail; +using System.Runtime.ExceptionServices; using System.Xml; using static Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Notifications.Communication; @@ -28,7 +31,7 @@ internal static class Connector /// private static readonly int RetryInterval = 500; - private static ConcurrentDictionary InstanceIdTooManyRequestsCollection = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary InstanceIdTooManyRequestsCollection = new ConcurrentDictionary(); private static int TooManyRequestsTimeoutSeconds = 60; public static bool EnableThrowExceptions @@ -55,31 +58,17 @@ static Connector() } } - private static ConnectorBase GetConnector(Settings settings, Logger logger, Order order = null) + private static ConnectorBase GetConnector(Settings settings, Logger logger, SubmitType submitType, Order order = null) { if (settings == null || string.IsNullOrEmpty(settings.Endpoint)) { - return new WebServiceConnector(settings, logger, order); + return new WebServiceConnector(settings, logger, submitType, order); } else { - return new EndpointConnector(settings, logger, order); + return new EndpointConnector(settings, logger, submitType, order); } - } - - /// - /// Calculates the order. - /// - /// The order XML. - /// The order identifier. - /// if set to true [create order]. - /// The error. - /// XmlDocument. - [Obsolete("Use CalculateOrder(Settings settings, string orderXml, Order order, bool createOrder, out Exception error, Logger logger) instead")] - public static XmlDocument CalculateOrder(Settings settings, string orderXml, string orderId, bool createOrder, out Exception error, Logger logger) - { - return CalculateOrder(settings, orderXml, Services.Orders.GetById(orderId), createOrder, out error, logger); - } + } /// /// Calculates the order. @@ -89,7 +78,7 @@ public static XmlDocument CalculateOrder(Settings settings, string orderXml, str /// if set to true [create order]. /// The error. /// XmlDocument. - public static XmlDocument CalculateOrder(Settings settings, string orderXml, Order order, bool createOrder, out Exception error, Logger logger) + public static XmlDocument CalculateOrder(Settings settings, string orderXml, Order order, bool createOrder, out Exception error, Logger logger, SubmitType submitType) { error = null; XmlDocument document = null; @@ -98,7 +87,7 @@ public static XmlDocument CalculateOrder(Settings settings, string orderXml, Ord { Diagnostics.ExecutionTable.Current.Add("DynamicwebLiveIntegration.Connector.CalculateOrder START"); // only retry if is not create order, for create order schedule task will send later - document = Communicate(settings, orderXml, $"CalculateOrder (ID: {order.Id}, CreateOrder: {createOrder})", logger, !createOrder, true, order); + document = Communicate(settings, orderXml, $"CalculateOrder (ID: {order.Id}, CreateOrder: {createOrder})", logger, submitType, !createOrder, true, order); Diagnostics.ExecutionTable.Current.Add("DynamicwebLiveIntegration.Connector.CalculateOrder END"); } catch (Exception ex) @@ -133,7 +122,7 @@ public static void ClearCache() public static XmlDocument GetProductsInfo(Settings settings, string productsXml, Logger logger, out HttpStatusCode httpStatusCode, bool retry = false) { Diagnostics.ExecutionTable.Current.Add("DynamicwebLiveIntegration.Connector.GetProductsInfo START"); - var result = Communicate(settings, productsXml, "GetProductsInfo", logger, out httpStatusCode, retry); ; + var result = Communicate(settings, productsXml, "GetProductsInfo", logger, SubmitType.Live, out httpStatusCode, retry); Diagnostics.ExecutionTable.Current.Add("DynamicwebLiveIntegration.Connector.GetProductsInfo END"); return result; } @@ -141,15 +130,15 @@ public static XmlDocument GetProductsInfo(Settings settings, string productsXml, /// /// Determines whether the web service connection is available. /// - public static bool IsWebServiceConnectionAvailable(Settings settings) + public static bool IsWebServiceConnectionAvailable(Settings settings, SubmitType submitType) { - return IsWebServiceConnectionAvailable(settings, new Logger(settings)); + return IsWebServiceConnectionAvailable(settings, new Logger(settings), submitType); } /// /// Determines whether the web service connection is available. /// - public static bool IsWebServiceConnectionAvailable(Settings settings, Logger logger) + public static bool IsWebServiceConnectionAvailable(Settings settings, Logger logger, SubmitType submitType) { if (settings is null) { @@ -157,7 +146,7 @@ public static bool IsWebServiceConnectionAvailable(Settings settings, Logger log } else { - var connector = GetConnector(settings, logger); + var connector = GetConnector(settings, logger, submitType); return connector.IsWebServiceConnectionAvailable(); } } @@ -167,10 +156,10 @@ public static bool IsWebServiceConnectionAvailable(Settings settings, Logger log /// /// The request. /// XmlDocument. - public static XmlDocument RetrieveDataFromRequestString(Settings settings, string request, Logger logger) + public static XmlDocument RetrieveDataFromRequestString(Settings settings, string request, Logger logger, SubmitType submitType) { Diagnostics.ExecutionTable.Current.Add("DynamicwebLiveIntegration.Connector.RetrieveDataFromRequestString START"); - var result = Communicate(settings, request, "RetrieveDataFromRequestString", logger); + var result = Communicate(settings, request, "RetrieveDataFromRequestString", logger, submitType); Diagnostics.ExecutionTable.Current.Add("DynamicwebLiveIntegration.Connector.RetrieveDataFromRequestString END"); return result; } @@ -183,9 +172,9 @@ public static XmlDocument RetrieveDataFromRequestString(Settings settings, strin /// if set to true [retry]. /// if set to true [throw exception]. /// XmlDocument. - private static XmlDocument Communicate(Settings settings, string request, string referenceName, Logger logger, bool retry = true, bool throwException = false, Order order = null) + private static XmlDocument Communicate(Settings settings, string request, string referenceName, Logger logger, SubmitType submitType, bool retry = true, bool throwException = false, Order order = null) { - return Communicate(settings, request, referenceName, logger, out _, retry, throwException, order); + return Communicate(settings, request, referenceName, logger, submitType, out _, retry, throwException, order); } /// @@ -196,12 +185,12 @@ private static XmlDocument Communicate(Settings settings, string request, string /// if set to true [retry]. /// if set to true [throw exception]. /// XmlDocument. - private static XmlDocument Communicate(Settings settings, string request, string referenceName, Logger logger, out HttpStatusCode httpStatusCode, bool retry = true, bool throwException = false, Order order = null) + private static XmlDocument Communicate(Settings settings, string request, string referenceName, Logger logger, SubmitType submitType, out HttpStatusCode httpStatusCode, bool retry = true, bool throwException = false, Order order = null) { XmlDocument result = null; int retryCount = 0; httpStatusCode = HttpStatusCode.OK; - var connector = GetConnector(settings, logger, order); + var connector = GetConnector(settings, logger, submitType, order); if (InstanceIdTooManyRequestsCollection.TryGetValue(settings.InstanceId, out DateTime lastErrorTime) && DateTime.Now.Subtract(lastErrorTime).TotalSeconds < TooManyRequestsTimeoutSeconds) @@ -277,31 +266,7 @@ private static XmlDocument Communicate(Settings settings, string request, string logger.Log(ErrorLevel.ConnectionError, $"An error occurred while calling {referenceName} from Web Service: '{ex.Message}'."); Diagnostics.ExecutionTable.Current.Add($"DynamicwebLiveIntegration: An error occurred while calling {referenceName} from Web Service: '{ex.Message}'."); - bool skipError = false; - //Do not ping Endpoints with Internal Server Error 500 (that means that the request was received but generating response failed) - if (ex?.InnerException != null && ex.InnerException is WebException webException) - { - if (webException != null && webException.Response != null && webException.Response is HttpWebResponse httpWebResponse) - { - httpStatusCode = httpWebResponse.StatusCode; - if (httpWebResponse != null && httpWebResponse.StatusCode == HttpStatusCode.InternalServerError) - { - skipError = true; - retry = false; - } - } - } - //ConnectionError: An error occurred while calling GetProductsInfo from Web Service: 'The remote server returned an error: (429).' - if (!skipError && !string.IsNullOrEmpty(ex.Message) && ex.Message.Contains("(429)")) - { - skipError = true; - retry = false; - InstanceIdTooManyRequestsCollection.TryAdd(settings.InstanceId, DateTime.Now); - } - if (!skipError) - { - connector.Error(endpoint); - } + HandleException(connector, settings, endpoint, ex, out httpStatusCode, ref retry); NotificationManager.Notify(OnAfterErpException, new OnAfterErpExceptionArgs(request, erpXmlResponse, referenceName, ex, settings, logger)); } @@ -329,7 +294,58 @@ private static XmlDocument Communicate(Settings settings, string request, string return result; } - internal static string RetrievePDF(Settings settings, string requestString) + private static void HandleException(ConnectorBase connector, Settings settings, EndpointInfo endpoint, Exception ex, out HttpStatusCode httpStatusCode, ref bool retry) + { + httpStatusCode = HttpStatusCode.OK; + bool skipError = false; + //Do not ping Endpoints with Internal Server Error 500 (that means that the request was received but generating response failed) + if (ex?.InnerException is not null) + { + if (ex.InnerException is WebException webException) + { + if (webException is not null && webException.Response is not null && webException.Response is HttpWebResponse httpWebResponse) + { + httpStatusCode = httpWebResponse.StatusCode; + if (httpWebResponse is not null && httpWebResponse.StatusCode == HttpStatusCode.InternalServerError) + { + skipError = true; + retry = false; + } + } + } + else if (ex.InnerException is HttpRequestException httpReqException && httpReqException?.StatusCode is not null) + { + httpStatusCode = (HttpStatusCode)httpReqException.StatusCode; + if (httpReqException.StatusCode == HttpStatusCode.InternalServerError) + { + skipError = true; + retry = false; + } + } + } + if (!skipError && ex is not null && ex is HttpRequestException httpRequestException && httpRequestException?.StatusCode is not null) + { + httpStatusCode = (HttpStatusCode)httpRequestException.StatusCode; + if (httpRequestException.StatusCode == HttpStatusCode.InternalServerError) + { + skipError = true; + retry = false; + } + } + //ConnectionError: An error occurred while calling GetProductsInfo from Web Service: 'The remote server returned an error: (429).' + if (!skipError && !string.IsNullOrEmpty(ex.Message) && ex.Message.Contains("(429)")) + { + skipError = true; + retry = false; + InstanceIdTooManyRequestsCollection.TryAdd(settings.InstanceId, DateTime.Now); + } + if (!skipError) + { + connector.Error(endpoint); + } + } + + internal static string RetrievePDF(Settings settings, string requestString, SubmitType submitType) { Diagnostics.ExecutionTable.Current.Add("DynamicwebLiveIntegration.Connector.RetrievePDF START"); string base64EncodedPDF; @@ -337,7 +353,7 @@ internal static string RetrievePDF(Settings settings, string requestString) try { logger.Log(ErrorLevel.DebugInfo, string.Format("Request RetrievePDF sent: '{0}'.", requestString)); - base64EncodedPDF = GetConnector(settings, logger).Execute(requestString); + base64EncodedPDF = GetConnector(settings, logger, submitType).Execute(requestString); logger.Log(ErrorLevel.DebugInfo, string.Format("Response RetrievePDF received: '{0}'.", base64EncodedPDF)); } catch (Exception ex) diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/ConnectorBase.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/ConnectorBase.cs index 55ef297..fb71f3d 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/ConnectorBase.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/ConnectorBase.cs @@ -13,23 +13,13 @@ namespace Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Connectors /// /// Abstract base connector /// - internal abstract class ConnectorBase + internal abstract class ConnectorBase(Settings settings, Logger logger, Order order, SubmitType submitType) { - protected Settings Settings { get; } - protected Logger Logger { get; } - protected Order Order { get; } + protected Settings Settings { get; } = settings; + protected Logger Logger { get; } = logger; + protected Order Order { get; } = order; - [Obsolete("Use ConnectorBase(Settings settings, Logger logger, Order order) instead")] - public ConnectorBase(Settings settings, Logger logger) : this(settings, logger, null) - { - } - - public ConnectorBase(Settings settings, Logger logger, Order order) - { - Settings = settings; - Logger = logger; - Order = order; - } + protected SubmitType SubmitType { get; } = submitType; internal abstract EndpointInfo GetEndpoint(); internal abstract string Execute(string request); @@ -46,7 +36,7 @@ public ConnectorBase(Settings settings, Logger logger, Order order) internal void Error(EndpointInfo endpoint) { - EndpointMonitoringService.Error(Settings, endpoint); + EndpointMonitoringService.Error(Settings, endpoint, SubmitType); } internal string Execute(EndpointInfo endpoint, string request) @@ -81,7 +71,7 @@ protected bool ExecuteConnectionAvailableRequest(EndpointInfo endpoint, out Exce error = ex; Logger?.Log(ErrorLevel.ConnectionError, $"Error checking Web Service connection: '{ex.Message}'. Request: '{request}'."); - EndpointMonitoringService.Error(Settings, endpoint); + EndpointMonitoringService.Error(Settings, endpoint, SubmitType); NotificationManager.Notify(OnErpCommunicationLost, new OnErpCommunicationLostArgs(request, ex, Settings, Logger)); diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/EndpointConnector.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/EndpointConnector.cs index e06abfd..23717fe 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/EndpointConnector.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/EndpointConnector.cs @@ -12,12 +12,8 @@ namespace Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Connectors /// /// Endpoint Connector /// - internal class EndpointConnector : ConnectorBase + internal class EndpointConnector(Settings settings, Logger logger, SubmitType submitType, Order order = null) : ConnectorBase(settings, logger, order, submitType) { - public EndpointConnector(Settings settings, Logger logger, Order order = null) : base(settings, logger, order) - { - } - internal override EndpointInfo GetEndpoint() { return new EndpointInfo(GetEndpoint(Settings.Endpoint, Logger)); @@ -27,7 +23,7 @@ internal Endpoint GetEndpoint(string multipleUrlsText, Logger logger) { if (!string.IsNullOrEmpty(multipleUrlsText)) { - var endpoint = UrlHandler.Instance.GetEndpoint(multipleUrlsText, false, logger, Order); + var endpoint = UrlHandler.Instance.GetEndpoint(multipleUrlsText, false, logger, Order, SubmitType); return endpoint ?? throw new ArgumentException("Cannot find appropriate endpoint. Check Endpoint settings."); } else @@ -36,7 +32,7 @@ internal Endpoint GetEndpoint(string multipleUrlsText, Logger logger) } } - internal EndpointInfo GetEndpointInfo(Endpoint endpoint) + internal static EndpointInfo GetEndpointInfo(Endpoint endpoint) { return new EndpointInfo(endpoint); } @@ -72,18 +68,18 @@ internal override string Execute(EndpointInfo endpoint, string request, TimeSpan internal override string Execute(string request) { - return Execute(GetEndpointInfo(UrlHandler.Instance.GetEndpoint(Settings, Logger, Order)), request); + return Execute(GetEndpointInfo(UrlHandler.Instance.GetEndpoint(Settings, Logger, Order, SubmitType)), request); } internal override IEnumerable GetUrls(string multipleUrlsText) { - return UrlHandler.Instance.GetEndpointUrls(multipleUrlsText); + return UrlHandler.GetEndpointUrls(multipleUrlsText); } internal override bool IsConnectionAvailableFromBackend(string endpointId, out string error) { error = null; - var endpoint = UrlHandler.Instance.GetEndpoint(endpointId, false, Logger, Order); + var endpoint = UrlHandler.Instance.GetEndpoint(endpointId, false, Logger, Order, SubmitType); if (endpoint != null) { var key = $"IsConnectionAvailableFromBackend{endpointId}"; diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/WebServiceConnector.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/WebServiceConnector.cs index dcbd879..22d7875 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/WebServiceConnector.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/WebServiceConnector.cs @@ -14,14 +14,10 @@ namespace Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Connectors /// /// Web service connector /// - internal class WebServiceConnector : ConnectorBase + internal class WebServiceConnector(Settings settings, Logger logger, SubmitType submitType, Order order = null) : ConnectorBase(settings, logger, order, submitType) { private static readonly ILogger LegacyLogger = LogManager.System.GetLogger(LogCategory.DataIntegration, "ERPIntegration"); - public WebServiceConnector(Settings settings, Logger logger, Order order = null) : base(settings, logger, order) - { - } - /// /// Gets the URL. /// @@ -35,7 +31,7 @@ private string WebServiceUrl { get { - string url = UrlHandler.Instance.GetWebServiceUrl(Settings, Order); + string url = UrlHandler.Instance.GetWebServiceUrl(Settings, Order, SubmitType); if (!string.IsNullOrEmpty(url)) { return url; @@ -57,7 +53,7 @@ internal override EndpointInfo GetEndpoint() return new EndpointInfo(WebServiceUrl); } - internal EndpointInfo GetEndpointInfo(string url) + internal static EndpointInfo GetEndpointInfo(string url) { return new EndpointInfo(url); } @@ -76,7 +72,7 @@ internal override bool IsWebServiceConnectionAvailable() internal override string Execute(string request) { - return Execute(GetEndpointInfo(UrlHandler.Instance.GetWebServiceUrl(Settings, Order)), request); + return Execute(GetEndpointInfo(UrlHandler.Instance.GetWebServiceUrl(Settings, Order, SubmitType)), request); } internal override string Execute(EndpointInfo endpoint, string request, TimeSpan responseTimeout) @@ -88,7 +84,7 @@ internal override string Execute(EndpointInfo endpoint, string request, TimeSpan internal override IEnumerable GetUrls(string multipleUrlsText) { - return UrlHandler.Instance.GetWebServiceUrls(multipleUrlsText).Select(u => UrlHandler.Instance.GetUrl(u)).Distinct(); + return UrlHandler.GetWebServiceUrls(multipleUrlsText).Select(u => UrlHandler.GetUrl(u)).Distinct(); } internal override bool IsConnectionAvailableFromBackend(string url, out string error) diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Dynamicweb.Ecommerce.DynamicwebLiveIntegration.csproj b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Dynamicweb.Ecommerce.DynamicwebLiveIntegration.csproj index ceb2adb..a55b5c9 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Dynamicweb.Ecommerce.DynamicwebLiveIntegration.csproj +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Dynamicweb.Ecommerce.DynamicwebLiveIntegration.csproj @@ -1,6 +1,6 @@  - 10.4.18 + 10.5.0 1.0.0.0 Live Integration Live Integration diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/EndpointMonitoring/EndpointMonitoringService.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/EndpointMonitoring/EndpointMonitoringService.cs index 92d9377..f686d1c 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/EndpointMonitoring/EndpointMonitoringService.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/EndpointMonitoring/EndpointMonitoringService.cs @@ -1,6 +1,7 @@ using Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Configuration; using Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Connectors; using Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Logging; +using System; using System.Collections.Concurrent; using System.Threading; @@ -79,7 +80,7 @@ public static void Success(EndpointInfo endpoint) /// Sets endpoint communication failed. /// /// The endpoint - public static void Error(Settings settings, EndpointInfo endpoint) + public static void Error(Settings settings, EndpointInfo endpoint, SubmitType submitType) { string url = endpoint.GetUrl(); if (!EndpointCollection.TryGetValue(url, out EndpointStatus status)) @@ -87,9 +88,9 @@ public static void Error(Settings settings, EndpointInfo endpoint) status = new EndpointStatus(); EndpointCollection.TryAdd(url, status); } - if (!EndpointsInPing.ContainsKey(endpoint.Id) && !Environment.ExecutingContext.IsBackEnd()) + if (!EndpointsInPing.ContainsKey(endpoint.Id) && !LiveContext.IsBackEnd(submitType)) { - PingEndpoint(settings, endpoint); + PingEndpoint(settings, endpoint, submitType); } status.SetError(); } @@ -126,7 +127,7 @@ public static void ClearEndpoint(EndpointInfo endpoint) /// /// /// - private static void PingEndpoint(Settings settings, EndpointInfo endpoint) + private static void PingEndpoint(Settings settings, EndpointInfo endpoint, SubmitType submitType) { var autoPingInterval = settings?.AutoPingInterval; if (autoPingInterval <= 0) @@ -137,25 +138,28 @@ private static void PingEndpoint(Settings settings, EndpointInfo endpoint) { EndpointsInPing.TryAdd(endpoint.Id, null); var statusChecker = new EndpointMonitoringService(); - var timer = new Timer(statusChecker.Ping, settings, 0, autoPingInterval.Value * 1000); + var timer = new Timer(statusChecker.Ping, new Tuple(settings, submitType), 0, autoPingInterval.Value * 1000); PingTimers.TryAdd(endpoint.Id, timer); } } private void Ping(object stateInfo) { - Settings settings = (Settings)stateInfo; + Tuple state = (Tuple)stateInfo; + Settings settings = state.Item1; + SubmitType submitType = state.Item2; + var logger = new Logger(settings); ConnectorBase currentConnector = null; EndpointInfo endpoint = null; if (!string.IsNullOrEmpty(settings.Endpoint)) { - currentConnector = new EndpointConnector(settings, logger); + currentConnector = new EndpointConnector(settings, logger, submitType); endpoint = new EndpointInfo(((EndpointConnector)currentConnector).GetEndpoint(settings.Endpoint, logger)); } else if (!string.IsNullOrEmpty(settings.WebServiceURI)) { - currentConnector = new WebServiceConnector(settings, logger); + currentConnector = new WebServiceConnector(settings, logger, submitType); endpoint = new EndpointInfo(settings.WebServiceURI); } EndpointsInPing.TryRemove(endpoint.Id, out _); diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Helpers.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Helpers.cs index 70cc74b..5e2aa28 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Helpers.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Helpers.cs @@ -305,7 +305,7 @@ internal static bool CanCheckPrice(Settings settings, Product product, User user || Global.IsProductLazyLoad(settings) || (user == null && !settings.LiveProductInfoForAnonymousUsers) || (user != null && user.IsLivePricesDisabled) - || !Connector.IsWebServiceConnectionAvailable(settings) + || !Connector.IsWebServiceConnectionAvailable(settings, SubmitType.Live) || product == null || string.IsNullOrEmpty(product.Id) || string.IsNullOrEmpty(product.Number)) @@ -334,18 +334,16 @@ internal static Currency GetCurrentCurrency() /// System.String. internal static string CalculateHash(string request) { - using (var hashEngine = new System.Security.Cryptography.HMACMD5(new byte[] { 14, 4, 78 })) - { - byte[] hash = hashEngine.ComputeHash(Encoding.UTF8.GetBytes(request)); - string hashString = string.Empty; - - foreach (byte x in hash) - { - hashString += $"{x:x2}"; - } + using var hashEngine = new System.Security.Cryptography.HMACMD5(new byte[] { 14, 4, 78 }); + byte[] hash = hashEngine.ComputeHash(Encoding.UTF8.GetBytes(request)); + string hashString = string.Empty; - return hashString; + foreach (byte x in hash) + { + hashString += $"{x:x2}"; } + + return hashString; } #endregion Session Hash helper methods diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/IntegrationCustomerCenterHandler.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/IntegrationCustomerCenterHandler.cs index 0986e9e..02cf2a6 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/IntegrationCustomerCenterHandler.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/IntegrationCustomerCenterHandler.cs @@ -67,7 +67,7 @@ internal static Template RetrieveItemDetailsFromRemoteSystem(Template template, }; string request = new ItemDetailsXmlGenerator().GenerateItemDetailsXml(settings); logger.Log(ErrorLevel.DebugInfo, string.Format("Request RetrieveItemDetailsFromRemoteSystem sent: '{0}'.", request)); - XmlDocument response = Connector.RetrieveDataFromRequestString(currentSettings, request, logger); + XmlDocument response = Connector.RetrieveDataFromRequestString(currentSettings, request, logger, SubmitType.Live); if (response != null && !string.IsNullOrEmpty(response.InnerXml)) { logger.Log(ErrorLevel.DebugInfo, string.Format("Response RetrieveItemDetailsFromRemoteSystem received: '{0}'.", response.InnerXml)); @@ -121,7 +121,7 @@ internal static Template RetrieveItemsListFromRemoteSystem(Template template, st string request = new ItemListXmlGenerator().GenerateItemListXml(settings); var logger = new Logger(currentSettings); logger.Log(ErrorLevel.DebugInfo, string.Format("Request RetrieveItemsListFromRemoteSystem sent: '{0}'.", request)); - XmlDocument response = Connector.RetrieveDataFromRequestString(currentSettings, request, logger); + XmlDocument response = Connector.RetrieveDataFromRequestString(currentSettings, request, logger, SubmitType.Live); if (response != null && !string.IsNullOrEmpty(response.InnerXml)) { logger.Log(ErrorLevel.DebugInfo, string.Format("Response RetrieveItemsListFromRemoteSystem received: '{0}'.", response.InnerXml)); @@ -202,7 +202,7 @@ private static void ProcessItemsListResponse(XmlDocument response, Template temp bool isTotalCountAttributePresent = itemsNode != null && itemsNode.Attributes["totalCount"] != null; if (isTotalCountAttributePresent) { - Int32.TryParse(itemsNode.Attributes["totalCount"].Value, out totalItemsCount); + int.TryParse(itemsNode.Attributes["totalCount"].Value, out totalItemsCount); } if (totalItemsCount <= 0) { @@ -365,7 +365,7 @@ internal static string RetrievePDF(IRequest request) ItemId = id }; string requestString = new RetrievePdfXmlGenerator().GenerateXml(settings); - string base64EncodedPDF = Connector.RetrievePDF(currentSettings, requestString); + string base64EncodedPDF = Connector.RetrievePDF(currentSettings, requestString, SubmitType.Live); return base64EncodedPDF; } return null; @@ -378,18 +378,14 @@ internal static string RetrievePDF(IRequest request) /// The output. private static void DecodeStream(Stream inStream, Stream output) { - using (System.Security.Cryptography.ICryptoTransform transform = new System.Security.Cryptography.FromBase64Transform()) + using System.Security.Cryptography.ICryptoTransform transform = new System.Security.Cryptography.FromBase64Transform(); + using var cryptStream = new System.Security.Cryptography.CryptoStream(inStream, transform, System.Security.Cryptography.CryptoStreamMode.Read); + byte[] buffer = new byte[4096]; + int bytesRead = cryptStream.Read(buffer, 0, buffer.Length); + while (bytesRead > 0) { - using (var cryptStream = new System.Security.Cryptography.CryptoStream(inStream, transform, System.Security.Cryptography.CryptoStreamMode.Read)) - { - byte[] buffer = new byte[4096]; - int bytesRead = cryptStream.Read(buffer, 0, buffer.Length); - while (bytesRead > 0) - { - output.Write(buffer, 0, bytesRead); - bytesRead = cryptStream.Read(buffer, 0, buffer.Length); - } - } + output.Write(buffer, 0, bytesRead); + bytesRead = cryptStream.Read(buffer, 0, buffer.Length); } } } diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveContext.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveContext.cs index 14674e7..44a3567 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveContext.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveContext.cs @@ -15,7 +15,7 @@ public class LiveContext public Shop Shop { get; } - public PriceContext PriceContext { get; set; } + public PriceContext PriceContext { get; set; } public LiveContext(Currency currency, User user, Shop shop) { @@ -34,7 +34,7 @@ public LiveContext(PriceContext priceContext) Country = priceContext.Country; } - private Country GetCountry(User user) + private static Country GetCountry(User user) { Country country = null; if (user != null && !string.IsNullOrEmpty(user.CountryCode)) @@ -59,5 +59,14 @@ private Country GetCountry(User user) } return country; } + + public static bool IsBackEnd(SubmitType submitType) + { + return submitType switch + { + SubmitType.Live or SubmitType.LiveOrderOrCart or SubmitType.FromTemplates => false, + _ => true, + }; + } } } diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveIntegrationAddIn.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveIntegrationAddIn.cs index de64a7a..6269f08 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveIntegrationAddIn.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveIntegrationAddIn.cs @@ -692,7 +692,7 @@ public Hashtable GetOptions(string dropdownName) { if (str.Contains(";")) { - int id = Core.Converter.ToInt32(UrlHandler.Instance.GetUrl(str)); + int id = Core.Converter.ToInt32(UrlHandler.GetUrl(str)); if (id > 0) { if (!endpointFilters.ContainsKey(id)) @@ -761,12 +761,12 @@ public override bool IsWebServiceConnectionAvailable() string multipleUrlsText = settings?.Endpoint; if (!string.IsNullOrEmpty(multipleUrlsText)) { - EndpointConnector endpointConnector = new EndpointConnector(settings, logger); + EndpointConnector endpointConnector = new EndpointConnector(settings, logger, SubmitType.Backend); return endpointConnector.IsConnectionAvailableFromBackend(multipleUrlsText); } else { - WebServiceConnector webServiceConnector = new WebServiceConnector(settings, logger); + WebServiceConnector webServiceConnector = new WebServiceConnector(settings, logger, SubmitType.Backend); return webServiceConnector.IsConnectionAvailableFromBackend(settings.WebServiceURI); } } @@ -924,7 +924,7 @@ private static string GetNotificationFrequencyText(NotificationFrequency frequen return result; } - private void SaveTranslations(Settings settings) + private static void SaveTranslations(Settings settings) { Helpers.SaveTranslation(Constants.OrderConfiguration.OrderDiscountText, settings.OrderDiscountText); Helpers.SaveTranslation(Constants.OrderConfiguration.ProductDiscountText, settings.ProductDiscountText); diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/CartCheckoutDoneOrderIsComplete.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/CartCheckoutDoneOrderIsComplete.cs index 42a16da..546be5d 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/CartCheckoutDoneOrderIsComplete.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/CartCheckoutDoneOrderIsComplete.cs @@ -26,8 +26,9 @@ public override void OnNotify(string notification, NotificationArgs args) } Settings settings = SettingsManager.GetSettingsByShop(myArgs.Order.ShopId); + var submitType = SubmitType.LiveOrderOrCart; - if (!EnabledAndActive(settings)) + if (!EnabledAndActive(settings, submitType)) { return; } @@ -47,7 +48,7 @@ public override void OnNotify(string notification, NotificationArgs args) return; } - bool? result = OrderHandler.UpdateOrder(settings, myArgs.Order, SubmitType.LiveOrderOrCart); + bool? result = OrderHandler.UpdateOrder(settings, myArgs.Order, submitType); // clear cached prices to update stock if order is completed with success if (result.HasValue && result.Value) diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/NotificationSubscriberBase.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/NotificationSubscriberBase.cs index 6a2375b..91f2bce 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/NotificationSubscriberBase.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/NotificationSubscriberBase.cs @@ -7,6 +7,7 @@ using Dynamicweb.Ecommerce.Orders; using Dynamicweb.Ecommerce.Prices; using Dynamicweb.Extensibility.Notifications; +using System; using System.Collections.Generic; using System.Linq; @@ -22,7 +23,13 @@ public abstract class NotificationSubscriberBase : NotificationSubscriber /// Gets a value that determines whether live integration is enabled for the current shop, active and a connection to the ERP is available. /// /// true if the live integration is enabled and active, false otherwise. - protected static bool EnabledAndActive(Settings settings) + [Obsolete("Use EnabledAndActive(Settings settings, SubmitType submitType) instead")] + protected static bool EnabledAndActive(Settings settings) => EnabledAndActive(settings, SubmitType.Live); + /// + /// Gets a value that determines whether live integration is enabled for the current shop, active and a connection to the ERP is available. + /// + /// true if the live integration is enabled and active, false otherwise. + protected static bool EnabledAndActive(Settings settings, SubmitType submitType) { var cacheValue = Context.Current?.Items?["DynamicwebLiveIntegrationEnabledAndActive"]; if (cacheValue != null) @@ -32,7 +39,7 @@ protected static bool EnabledAndActive(Settings settings) else { bool result = Global.IsIntegrationActive(settings) - && Connector.IsWebServiceConnectionAvailable(settings); + && Connector.IsWebServiceConnectionAvailable(settings, submitType); if (Context.Current?.Items != null) { Context.Current.Items["DynamicwebLiveIntegrationEnabledAndActive"] = result; @@ -60,10 +67,10 @@ protected internal static void SetProductInformation(Settings settings, Order or if (productsToUpdate != null && productsToUpdate.Any()) { var logger = new Logger(settings); - logger.Log(ErrorLevel.DebugInfo, $"Reload prices. products #{productsToUpdate.Count()}"); + logger.Log(ErrorLevel.DebugInfo, $"Reload prices. products #{productsToUpdate.Count}"); var context = new LiveContext(order.GetPriceContext()); - if (!ProductManager.FetchProductInfos(productsToUpdate, context, settings, logger, false)) + if (!ProductManager.FetchProductInfos(productsToUpdate, context, settings, logger, false, SubmitType.Live)) { return; } diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/OrderAfterSave.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/OrderAfterSave.cs index eefd6d6..4c8faad 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/OrderAfterSave.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/OrderAfterSave.cs @@ -4,6 +4,9 @@ namespace Dynamicweb.Ecommerce.DynamicwebLiveIntegration.NotificationSubscribers { + /// + /// LiveIntegration in WebApi handle CreateOrder request implemented for #10951 + /// [Subscribe(Ecommerce.Notifications.Ecommerce.Order.AfterSave)] public class OrderAfterSave : NotificationSubscriberBase { @@ -21,8 +24,9 @@ public override void OnNotify(string notification, NotificationArgs args) } Settings settings = SettingsManager.GetSettingsByShop(myArgs.Order.ShopId); + var submitType = SubmitType.WebApi; - if (!EnabledAndActive(settings)) + if (!EnabledAndActive(settings, submitType)) { return; } @@ -30,7 +34,7 @@ public override void OnNotify(string notification, NotificationArgs args) if (settings != null && Global.EnableCartCommunication(settings, myArgs.Order.Complete) && IsCreateOrderAllowed(myArgs.Order)) { - OrderHandler.UpdateOrder(settings, myArgs.Order, SubmitType.LiveOrderOrCart); + OrderHandler.UpdateOrder(settings, myArgs.Order, submitType); } } } diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/PageLoaded.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/PageLoaded.cs index e5c2bfb..fd5cfd4 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/PageLoaded.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/PageLoaded.cs @@ -25,13 +25,12 @@ public override void OnNotify(string notification, NotificationArgs args) bool isWebServiceConnectionAvailable = false; bool isLazyLoadingForProductInfoEnabled = false; - Dynamicweb.Notifications.Standard.Page.LoadedArgs loadedArgs = args as Dynamicweb.Notifications.Standard.Page.LoadedArgs; - if (loadedArgs != null) - { + if (args is Dynamicweb.Notifications.Standard.Page.LoadedArgs loadedArgs) + { var settings = SettingsManager.GetSettingsByShop(Global.GetShopId(loadedArgs.PageViewInstance)); if (settings != null && Global.IsIntegrationActive(settings)) { - isWebServiceConnectionAvailable = Connector.IsWebServiceConnectionAvailable(settings); + isWebServiceConnectionAvailable = Connector.IsWebServiceConnectionAvailable(settings, SubmitType.Live); isLazyLoadingForProductInfoEnabled = Global.IsLazyLoadingForProductInfoEnabled(settings); if (Context.Current.Session != null && Convert.ToBoolean(Context.Current.Session["DynamicwebLiveIntegration.OrderExportFailed"])) diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/PageOnGlobalTags.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/PageOnGlobalTags.cs index 0f65358..f95295f 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/PageOnGlobalTags.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/PageOnGlobalTags.cs @@ -22,14 +22,14 @@ public override void OnNotify(string notification, NotificationArgs args) if (pageviewNotificationArgs != null) { var settings = SettingsManager.GetSettingsByShop(Global.GetShopId(pageviewNotificationArgs.Pageview)); - if (settings != null && EnabledAndActive(settings)) + if (settings != null && EnabledAndActive(settings, SubmitType.Live)) { string globalTagName = settings.WebServiceConnectionStatusGlobalTagName; if (!string.IsNullOrEmpty(globalTagName)) { if (pageviewNotificationArgs.Template.TagExists(globalTagName)) { - pageviewNotificationArgs.Template.SetTag(globalTagName, Connector.IsWebServiceConnectionAvailable(settings).ToString().ToLower()); + pageviewNotificationArgs.Template.SetTag(globalTagName, Connector.IsWebServiceConnectionAvailable(settings, SubmitType.Live).ToString().ToLower()); pageviewNotificationArgs.Template.SetTag("Global:LiveIntegration.IsLazyLoadingForProductInfoEnabled", Global.IsLazyLoadingForProductInfoEnabled(settings).ToString().ToLower()); } } diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/VariantListBeforeRender.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/VariantListBeforeRender.cs index 5c0373e..d1ba415 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/VariantListBeforeRender.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/NotificationSubscribers/VariantListBeforeRender.cs @@ -11,9 +11,9 @@ public class VariantListBeforeRender : NotificationSubscriberBase { public override void OnNotify(string notification, NotificationArgs args) { - if (args is Ecommerce.Notifications.Ecommerce.VariantList.BeforeRenderArgs) + if (args is Ecommerce.Notifications.Ecommerce.VariantList.BeforeRenderArgs beforeRenderArgs) { - var variantCombinationProducts = ((Ecommerce.Notifications.Ecommerce.VariantList.BeforeRenderArgs)args).VariantCombinationsProducts; + var variantCombinationProducts = beforeRenderArgs.VariantCombinationsProducts; if (variantCombinationProducts != null) { var settings = SettingsManager.GetSettingsByShop(Global.CurrentShopId); if (settings != null && @@ -46,9 +46,9 @@ public override void OnNotify(string notification, NotificationArgs args) } } - private bool CanCheckPrice(Settings settings) + private static bool CanCheckPrice(Settings settings) { - return EnabledAndActive(settings) && settings.EnableLivePrices && + return EnabledAndActive(settings, SubmitType.Live) && settings.EnableLivePrices && (settings.LiveProductInfoForAnonymousUsers || Helpers.GetCurrentExtranetUser() != null) && (Helpers.GetCurrentExtranetUser() == null || !Helpers.GetCurrentExtranetUser().IsLivePricesDisabled) && !Global.IsProductLazyLoad(settings); diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/OrderHandler.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/OrderHandler.cs index 1e21be2..656f513 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/OrderHandler.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/OrderHandler.cs @@ -8,7 +8,6 @@ using Dynamicweb.Ecommerce.DynamicwebLiveIntegration.XmlGenerators; using Dynamicweb.Ecommerce.Orders; using Dynamicweb.Ecommerce.Prices; -using Dynamicweb.Environment; using Dynamicweb.Extensibility.Notifications; using Dynamicweb.Security.UserManagement; using System; @@ -63,7 +62,7 @@ private static ResponseCacheLevel GetOrderCacheLevel(Settings settings) } var orderId = order.Id ?? "ID is null"; - bool executingContextIsBackEnd = ExecutingContext.IsBackEnd(); + bool executingContextIsBackEnd = LiveContext.IsBackEnd(liveIntegrationSubmitType); var logger = new Logger(settings); logger.Log(ErrorLevel.DebugInfo, $"Updating order with ID: {orderId}. Complete: {order.Complete}. Order submitted from the backend: {executingContextIsBackEnd}"); @@ -109,7 +108,7 @@ private static ResponseCacheLevel GetOrderCacheLevel(Settings settings) xmlGeneratorSettings.GenerateXmlForHash = true; var requestXmlForHash = new OrderXmlGenerator().GenerateOrderXml(settings, order, xmlGeneratorSettings, logger); - if (createOrder && settings.SaveCopyOfOrderXml && liveIntegrationSubmitType == SubmitType.LiveOrderOrCart) + if (createOrder && settings.SaveCopyOfOrderXml && (liveIntegrationSubmitType == SubmitType.LiveOrderOrCart || liveIntegrationSubmitType == SubmitType.WebApi)) { SaveCopyOfXml(order.Id, requestXml, logger); } @@ -120,7 +119,7 @@ private static ResponseCacheLevel GetOrderCacheLevel(Settings settings) // get last hash string lastHash = GetLastOrderHash(settings); - if (liveIntegrationSubmitType != SubmitType.ScheduledTask && liveIntegrationSubmitType != SubmitType.CaptureTask && + if (liveIntegrationSubmitType != SubmitType.ScheduledTask && liveIntegrationSubmitType != SubmitType.CaptureTask && !string.IsNullOrEmpty(lastHash) && lastHash == currentHash) { // no changes to order @@ -131,7 +130,7 @@ private static ResponseCacheLevel GetOrderCacheLevel(Settings settings) // save this hash for next calls SaveOrderHash(settings, currentHash); - XmlDocument response = GetResponse(settings, requestXml, order, createOrder, logger, out bool? requestCancelled); + XmlDocument response = GetResponse(settings, requestXml, order, createOrder, logger, out bool? requestCancelled, liveIntegrationSubmitType); if (response != null && !string.IsNullOrWhiteSpace(response.InnerXml)) { bool processResponseResult = ProcessResponse(settings, response, order, createOrder, successOrderStateId, failedOrderStateId, logger); @@ -230,10 +229,7 @@ private static void AssignIntegrationOrderId(Order order, XmlNode orderNode) /// OrderLine. private static OrderLine CreateOrderLine(Order order, string productNumber, Logger logger) { - if (order == null) - { - throw new ArgumentNullException(nameof(order)); - } + ArgumentNullException.ThrowIfNull(order); if (string.IsNullOrEmpty(productNumber)) { @@ -268,7 +264,7 @@ private static OrderLine CreateOrderLine(Order order, string productNumber, Logg /// The order. /// if set to true [create order]. /// XmlDocument. - private static XmlDocument GetResponse(Settings settings, string requestXml, Order order, bool createOrder, Logger logger, out bool? requestCancelled) + private static XmlDocument GetResponse(Settings settings, string requestXml, Order order, bool createOrder, Logger logger, out bool? requestCancelled, SubmitType submitType) { XmlDocument response = null; requestCancelled = null; @@ -277,46 +273,40 @@ private static XmlDocument GetResponse(Settings settings, string requestXml, Ord Dictionary responsesCache = ResponseCache.GetWebOrdersConnectorResponses(GetOrderCacheLevel(settings)); - if (!createOrder && responsesCache is object && responsesCache.ContainsKey(orderIdentifier)) + if (!createOrder && responsesCache is not null && responsesCache.TryGetValue(orderIdentifier, out response)) { - response = responsesCache[orderIdentifier]; + return response; } - else + + Notifications.Order.OnBeforeSendingOrderToErpArgs onBeforeSendingOrderToErpArgs = new Notifications.Order.OnBeforeSendingOrderToErpArgs(order, createOrder, settings, logger); + NotificationManager.Notify(Notifications.Order.OnBeforeSendingOrderToErp, onBeforeSendingOrderToErpArgs); + requestCancelled = onBeforeSendingOrderToErpArgs.Cancel; + + if (!onBeforeSendingOrderToErpArgs.Cancel) { - Notifications.Order.OnBeforeSendingOrderToErpArgs onBeforeSendingOrderToErpArgs = new Notifications.Order.OnBeforeSendingOrderToErpArgs(order, createOrder, settings, logger); - NotificationManager.Notify(Notifications.Order.OnBeforeSendingOrderToErp, onBeforeSendingOrderToErpArgs); - requestCancelled = onBeforeSendingOrderToErpArgs.Cancel; + response = Connector.CalculateOrder(settings, requestXml, order, createOrder, out Exception error, logger, submitType); - if (!onBeforeSendingOrderToErpArgs.Cancel) + if (createOrder && error != null) { - response = Connector.CalculateOrder(settings, requestXml, order, createOrder, out Exception error, logger); + Services.OrderDebuggingInfos.Save(order, $"ERP communication failed with error: {error}", OrderErpCallFailed, DebuggingInfoType.Undefined); + } - if (createOrder && error != null) - { - Services.OrderDebuggingInfos.Save(order, $"ERP communication failed with error: {error}", OrderErpCallFailed, DebuggingInfoType.Undefined); - } + NotificationManager.Notify(Notifications.Order.OnAfterSendingOrderToErp, new Notifications.Order.OnAfterSendingOrderToErpArgs(order, createOrder, response, error, settings, logger)); - NotificationManager.Notify(Notifications.Order.OnAfterSendingOrderToErp, new Notifications.Order.OnAfterSendingOrderToErpArgs(order, createOrder, response, error, settings, logger)); + if (responsesCache is not null) + { + responsesCache.Remove(orderIdentifier); - if (responsesCache is object) + if (response != null && !string.IsNullOrWhiteSpace(response.InnerXml)) { - if (responsesCache.ContainsKey(orderIdentifier)) - { - responsesCache.Remove(orderIdentifier); - } - - if (response != null && !string.IsNullOrWhiteSpace(response.InnerXml)) - { - responsesCache.Add(orderIdentifier, response); - } + responsesCache.Add(orderIdentifier, response); } } - else - { - Services.OrderDebuggingInfos.Save(order, "Order not sent to ERP because a subscriber cancelled sending it", OrderErpCallCancelled, DebuggingInfoType.Undefined); - } } - + else + { + Services.OrderDebuggingInfos.Save(order, "Order not sent to ERP because a subscriber cancelled sending it", OrderErpCallCancelled, DebuggingInfoType.Undefined); + } return response; } @@ -383,7 +373,7 @@ private static bool IsOrderUpdateAllowed(Settings settings, Order order, SubmitT if (order == null || !order.OrderLines.Any() || (order.IsLedgerEntry && settings.SkipLedgerOrder) - || (liveIntegrationSubmitType == SubmitType.LiveOrderOrCart && !string.IsNullOrEmpty(order.IntegrationOrderId))) + || (!string.IsNullOrEmpty(order.IntegrationOrderId) && (liveIntegrationSubmitType == SubmitType.LiveOrderOrCart || liveIntegrationSubmitType == SubmitType.WebApi))) { return false; } @@ -505,7 +495,7 @@ private static void ProcessDiscountOrderLine(Settings settings, Order order, Ord unitId = orderLineNode.SelectSingleNode("column [@columnName='OrderLineUnitId']")?.InnerText; } foreach (var productOrderLine in order.OrderLines) - { + { string id = settings.CalculateOrderUsingProductNumber ? productOrderLine.ProductNumber : productOrderLine.ProductId; if (string.Compare(id, parentProductId, StringComparison.OrdinalIgnoreCase) == 0) { @@ -1243,7 +1233,7 @@ private static void MergeOrderLines(Settings settings, Order order) return; } var newLines = order.OrderLines.Where(l => string.IsNullOrEmpty(l.Id)).ToList(); - if (!newLines.Any()) + if (newLines.Count == 0) { return; } @@ -1267,7 +1257,7 @@ private static void MergeOrderLines(Settings settings, Order order) } } } - if (mergedLines.Any()) + if (mergedLines.Count != 0) { foreach (var mergedLine in mergedLines) { diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Orders/LiveCartCalculationProvider.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Orders/LiveCartCalculationProvider.cs index 21fc42d..b5c3eca 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Orders/LiveCartCalculationProvider.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Orders/LiveCartCalculationProvider.cs @@ -15,9 +15,10 @@ public override bool CalculateCart(Order cart) !(cart.Complete && cart.IsExported)) { var settings = SettingsManager.GetSettingsByShop(cart.ShopId); + SubmitType submitType = SubmitType.LiveOrderOrCart; if (Global.IsIntegrationActive(settings) && - Connector.IsWebServiceConnectionAvailable(settings)) + Connector.IsWebServiceConnectionAvailable(settings, submitType)) { if (Global.EnableCartCommunication(settings, cart.Complete)) { @@ -26,7 +27,7 @@ public override bool CalculateCart(Order cart) { Services.Orders.ForcePriceRecalculation(cart); } - bool? result = OrderHandler.UpdateOrder(settings, cart, SubmitType.LiveOrderOrCart); + bool? result = OrderHandler.UpdateOrder(settings, cart, submitType); return result.HasValue ? result.Value : false; } } diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductManager.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductManager.cs index 7f80979..7ce4ca8 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductManager.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductManager.cs @@ -118,7 +118,7 @@ public static List GetPrices(ProductInfo productInfo) /// The user. /// Update cache with products information retrieved. /// true if product information was fetched, false otherwise. - internal static bool FetchProductInfos(List products, LiveContext context, Settings settings, Logger logger, bool doCurrencyCheck, bool updateCache = true) + internal static bool FetchProductInfos(List products, LiveContext context, Settings settings, Logger logger, bool doCurrencyCheck, SubmitType submitType, bool updateCache = true) { if (products == null || products.Count == 0) { @@ -137,7 +137,7 @@ internal static bool FetchProductInfos(List products, Liv return false; } - if (!Connector.IsWebServiceConnectionAvailable(settings, logger)) + if (!Connector.IsWebServiceConnectionAvailable(settings, logger, submitType)) { logger.Log(ErrorLevel.DebugInfo, "Live Prices are unavailable"); return false; @@ -222,10 +222,7 @@ private static bool FetchProductInfosInternal(List produc // Cache prices foreach (string productKey in prices.Keys) { - if (cachedProductInfos.ContainsKey(productKey)) - { - cachedProductInfos.Remove(productKey); - } + cachedProductInfos.Remove(productKey); cachedProductInfos.Add(productKey, prices[productKey]); } } @@ -320,10 +317,25 @@ private static List GetProductsForRequest(Settings settin } } } + else + { + if (!string.IsNullOrEmpty(product.VariantId) && !string.IsNullOrEmpty(product.DefaultVariantComboId) && !string.Equals(product.VariantId, product.DefaultVariantComboId) + && GetFilteredVariants(new List() { product }).Count != 0) + { + productIdentifier = ProductProvider.GetProductIdentifier(settings, product, productWithQuantity.UnitId); + if (!ResponseCache.IsProductInCache(productCacheLevel, productIdentifier, context.User, doCurrencyCheck ? context.Currency : null)) + { + if (ProductProvider.IsLivePriceEnabledForProduct(product) && product.HasIdentifier(settings)) + { + productsForRequest.Add(product.GetPriceProductSelection(productWithQuantity.Quantity, productWithQuantity.UnitId)); + } + } + } + } product = ProductProvider.GetProductFromVariantComboId(product, logger); - if (string.IsNullOrEmpty(product.VariantId) || GetFilteredVariants(new List() { product }).Any()) + if (string.IsNullOrEmpty(product.VariantId) || GetFilteredVariants(new List() { product }).Count != 0) { productIdentifier = ProductProvider.GetProductIdentifier(settings, product, productWithQuantity.UnitId); isProductCached = ResponseCache.IsProductInCache(productCacheLevel, productIdentifier, context.User, @@ -442,10 +454,7 @@ private static Dictionary ProcessResponse(Settings settings } // avoid exception to duplicate products in XML - if (!infos.ContainsKey(productIdentifier)) - { - infos.Add(productIdentifier, productInfo); - } + infos.TryAdd(productIdentifier, productInfo); } } diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductPriceProvider.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductPriceProvider.cs index 2698d5a..32eb255 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductPriceProvider.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductPriceProvider.cs @@ -17,7 +17,7 @@ namespace Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Products /// public class ProductPriceProvider : PriceProvider, IPriceInfoProvider { - private bool? FetchProductInfo(Settings settings, PriceProductSelection product, + private static bool? FetchProductInfo(Settings settings, PriceProductSelection product, string productIdentifier, ResponseCacheLevel productCacheLevel, LiveContext context, Logger logger) { // If Product is not in the cache, then get it from Erp @@ -35,7 +35,7 @@ public class ProductPriceProvider : PriceProvider, IPriceInfoProvider // After GetProductFromVariantComboId the variantId is empty or other product is returned so new identifier must be generated productIdentifier = ProductManager.ProductProvider.GetProductIdentifier(settings, changedProduct, product.UnitId); - bool fetchedProductInfo = ProductManager.FetchProductInfos(products, context, settings, logger, true); + bool fetchedProductInfo = ProductManager.FetchProductInfos(products, context, settings, logger, true, SubmitType.Live); if (fetchedProductInfo && // Check if requested product was not received from response !ResponseCache.IsProductInCache(productCacheLevel, productIdentifier, context.User, context.Currency) @@ -67,7 +67,7 @@ public override void PreparePrices(PriceContext context, IEnumerable _paymentHandlers = new Dictionary(); private string _processError; private OrderInvoiceType _orderInvoiceTypeValue; - private static string _leaveUnchangedValue = "Leave unchanged"; + private static readonly string _leaveUnchangedValue = "Leave unchanged"; private enum OrderInvoiceType { @@ -181,9 +181,9 @@ public override bool Run() //get the relevant data from the DB var ordersToSync = ReadOrders(); - if (ordersToSync != null && ordersToSync.Count() > 0) + if (ordersToSync != null && ordersToSync.Count > 0) { - if (CommunicateBackToErp && !Connector.IsWebServiceConnectionAvailable(settings)) + if (CommunicateBackToErp && !Connector.IsWebServiceConnectionAvailable(settings, SubmitType.CaptureTask)) { var msg = "The ERP connection is currently unavailable, but 'Update order to ERP after capture' is enabled. Wait to retry when the ERP is back online."; Logger.Log(msg); diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/ScheduledTasks/QueuedOrdersSyncScheduledTask.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/ScheduledTasks/QueuedOrdersSyncScheduledTask.cs index e290cb7..3325f7e 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/ScheduledTasks/QueuedOrdersSyncScheduledTask.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/ScheduledTasks/QueuedOrdersSyncScheduledTask.cs @@ -136,7 +136,7 @@ public override bool Run() } var ordersToSync = Services.Orders.GetOrdersBySearch(filter); - + if (ordersToSync != null && ordersToSync.GetResultOrders() != null && ordersToSync.GetResultOrders().Any()) { Settings shopSettings = SettingsManager.GetSettingsByShop(ShopId); diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/ScheduledTasks/UpdateOrdersScheduledTask.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/ScheduledTasks/UpdateOrdersScheduledTask.cs index 32849c9..ff22a35 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/ScheduledTasks/UpdateOrdersScheduledTask.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/ScheduledTasks/UpdateOrdersScheduledTask.cs @@ -205,7 +205,7 @@ public override bool Run() // get the relevant data from the DB var ordersToSync = ReadOrders(); - if (ordersToSync != null && ordersToSync.Count() > 0) + if (ordersToSync != null && ordersToSync.Count > 0) { ProcessOrders(ordersToSync); } @@ -337,7 +337,7 @@ private bool SendToErp(Order order) { var settings = GetSettings(order.ShopId); // save capture changes and try to update ERP - if (settings != null && settings.IsLiveIntegrationEnabled && Connector.IsWebServiceConnectionAvailable(settings)) + if (settings != null && settings.IsLiveIntegrationEnabled && Connector.IsWebServiceConnectionAvailable(settings, SubmitType.ScheduledTask)) { var result = OrderHandler.UpdateOrder(settings, order, SubmitType.ScheduledTask); if (result == null || !result.Value) diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/SubmitType.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/SubmitType.cs index 1ed0e9c..40e1938 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/SubmitType.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/SubmitType.cs @@ -38,6 +38,16 @@ public enum SubmitType /// /// The XML is sent by a Capture order scheduled task that sends orders that were previously not captured. /// - CaptureTask + CaptureTask, + + /// + /// Request is coming from Backend + /// + Backend, + + /// + /// Request is coming from the WebApi + /// + WebApi } } \ No newline at end of file diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/TemplateExtenders/ProductTemplateExtender.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/TemplateExtenders/ProductTemplateExtender.cs index ad63118..446eec1 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/TemplateExtenders/ProductTemplateExtender.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/TemplateExtenders/ProductTemplateExtender.cs @@ -149,7 +149,7 @@ private ProductInfo FetchProductInfo(Settings settings, Product product, User us Diagnostics.ExecutionTable.Current.Add($"ProductTemplateExtender FetchProductInfos product[id='{product?.Id}' variantId='{product.VariantId}'] START"); var products = new List() { productSelection }; var context = new LiveContext(Helpers.GetCurrentCurrency(), user, Services.Shops.GetShop(Global.CurrentShopId)); - if (ProductManager.FetchProductInfos(products, context, settings, new Logger(settings), false)) + if (ProductManager.FetchProductInfos(products, context, settings, new Logger(settings), false, SubmitType.Live)) { productInfo = ProductManager.GetProductInfo(product, settings, user, context, productSelection.UnitId); } @@ -158,7 +158,7 @@ private ProductInfo FetchProductInfo(Settings settings, Product product, User us return productInfo; } - private Price GetBaseUOMPrice(Settings settings, ProductInfo productInfo, List prices) + private static Price GetBaseUOMPrice(Settings settings, ProductInfo productInfo, List prices) { Price price = null; if (settings.UseUnitPrices && prices != null && productInfo["ProductDefaultUnitId"] != null) @@ -172,7 +172,7 @@ private Price GetBaseUOMPrice(Settings settings, ProductInfo productInfo, List

@@ -104,7 +104,7 @@ public static bool UpdateProduct(Product product, double quantity, string curren return Products.ProductManager.FetchProductInfos( new List(){ productSelection }, context, - settings, new Logging.Logger(settings), false, updateCache); + settings, new Logging.Logger(settings), false, SubmitType.Live, updateCache); } ///

@@ -116,7 +116,7 @@ public static bool IsLazyLoadingForProductInfoEnabled get { var settings = SettingsManager.GetSettingsByShop(Global.CurrentShopId); - return Global.IsIntegrationActive(settings) && settings.EnableLivePrices && Connector.IsWebServiceConnectionAvailable(settings) + return Global.IsIntegrationActive(settings) && settings.EnableLivePrices && Connector.IsWebServiceConnectionAvailable(settings, SubmitType.Live) && (settings.LiveProductInfoForAnonymousUsers || Helpers.GetCurrentExtranetUser() != null) && (Helpers.GetCurrentExtranetUser() == null || !Helpers.GetCurrentExtranetUser().IsLivePricesDisabled) && settings.LazyLoadProductInfo; diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/UrlHandler.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/UrlHandler.cs index 81f7afd..960d65c 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/UrlHandler.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/UrlHandler.cs @@ -59,7 +59,7 @@ public static UrlHandler Instance /// Gets the URL cache key. /// /// The URL cache key. - private string UrlCacheKey + private static string UrlCacheKey { get { @@ -83,12 +83,12 @@ public void ClearCachedUrl() /// /// The URL. /// System.String. - internal string GetUrl(string url) + internal static string GetUrl(string url) { - return (!string.IsNullOrEmpty(url) && url.Contains(";")) ? url.Substring(0, url.IndexOf(";", StringComparison.Ordinal)) : url; + return (!string.IsNullOrEmpty(url) && url.Contains(';')) ? url[..url.IndexOf(';', StringComparison.Ordinal)] : url; } - internal int GetEndpointId(string multipleUrlsText, Order order) + internal int GetEndpointId(string multipleUrlsText, Order order, SubmitType submitType) { int id = 0; if (!string.IsNullOrEmpty(multipleUrlsText)) @@ -96,13 +96,13 @@ internal int GetEndpointId(string multipleUrlsText, Order order) string[] urls = GetEndpointUrls(multipleUrlsText); if (urls.Length > 0) { - if (urls.Any(u => u.Contains(";"))) + if (urls.Any(u => u.Contains(';'))) { string url; bool isFrontEnd = ExecutingContext.IsFrontEnd(); if (isFrontEnd || order != null) { - url = GetMatchedUrl(urls, order); + url = GetMatchedUrl(urls, order, submitType); if(!isFrontEnd && string.IsNullOrEmpty(url)) { @@ -127,11 +127,11 @@ internal int GetEndpointId(string multipleUrlsText, Order order) return id; } - internal Endpoint GetEndpoint(string multipleUrlsText, bool logIfNotFound, Logger logger, Order order) + internal Endpoint GetEndpoint(string multipleUrlsText, bool logIfNotFound, Logger logger, Order order, SubmitType submitType) { if (!string.IsNullOrEmpty(multipleUrlsText)) { - int id = GetEndpointId(multipleUrlsText, order); + int id = GetEndpointId(multipleUrlsText, order, submitType); EndpointService endpointService = new EndpointService(); var endpoint = endpointService.GetEndpointById(id); @@ -144,7 +144,7 @@ internal Endpoint GetEndpoint(string multipleUrlsText, bool logIfNotFound, Logge return null; } - internal Endpoint GetEndpoint(Settings settings, Logger logger, Order order) + internal Endpoint GetEndpoint(Settings settings, Logger logger, Order order, SubmitType submitType) { Endpoint ret = null; string multiLineUrlText = settings.Endpoint; @@ -156,7 +156,7 @@ internal Endpoint GetEndpoint(Settings settings, Logger logger, Order order) } else { - ret = GetEndpoint(multiLineUrlText, false, logger, order); + ret = GetEndpoint(multiLineUrlText, false, logger, order, submitType); if (Context.Current?.Items != null) { Context.Current.Items[UrlCacheKey] = ret; @@ -171,14 +171,21 @@ internal Endpoint GetEndpoint(Settings settings, Logger logger, Order order) /// /// System.String. [Obsolete("Use GetWebServiceUrl(Settings settings, Order order) instead")] - public string GetWebServiceUrl(Settings settings) => GetWebServiceUrl(settings, null); + public string GetWebServiceUrl(Settings settings) => GetWebServiceUrl(settings, null, SubmitType.Live); + + /// + /// Gets the web service URL for the current context. + /// + /// System.String. + [Obsolete("Use GetWebServiceUrl(Settings settings, Order order, SubmitType submitType) instead")] + public string GetWebServiceUrl(Settings settings, Order order) => GetWebServiceUrl(settings, order, SubmitType.Live); /// /// Gets the web service URL for the current context. /// /// System.String. - public string GetWebServiceUrl(Settings settings, Order order) + public string GetWebServiceUrl(Settings settings, Order order, SubmitType submitType) { string ret = string.Empty; if (Context.Current?.Items[UrlCacheKey] != null && ExecutingContext.IsFrontEnd()) @@ -191,9 +198,9 @@ public string GetWebServiceUrl(Settings settings, Order order) string[] urls = GetWebServiceUrls(multiLineUrlText); if (urls.Length > 0) { - if (multiLineUrlText.Contains(";")) + if (multiLineUrlText.Contains(';')) { - ret = GetMatchedUrl(urls, order); + ret = GetMatchedUrl(urls, order, submitType); } else { @@ -209,7 +216,7 @@ public string GetWebServiceUrl(Settings settings, Order order) return ret; } - private string GetMatchedUrl(string[] urls, Order order) + private string GetMatchedUrl(string[] urls, Order order, SubmitType submitType) { string ret = null; foreach (string url in urls) @@ -224,24 +231,24 @@ private string GetMatchedUrl(string[] urls, Order order) { if (fieldName.StartsWith("User.")) { - if (TreatUserFields(fieldName, fieldValue, order)) + if (TreatUserFields(fieldName, fieldValue, order, submitType)) { ret = GetUrl(url); break; } } - else if (fieldName.StartsWith("Order.") && GetCurrentOrder(order) != null) + else if (fieldName.StartsWith("Order.") && GetCurrentOrder(order, submitType) != null) { - foreach (OrderFieldValue ofv in GetCurrentOrder(order).OrderFieldValues) + foreach (OrderFieldValue ofv in GetCurrentOrder(order, submitType).OrderFieldValues) { - if (ofv != null && ofv.OrderField != null && ofv.OrderField.SystemName == fieldName.Substring(6) && (string)ofv.Value == fieldValue) + if (ofv != null && ofv.OrderField != null && ofv.OrderField.SystemName == fieldName[6..] && (string)ofv.Value == fieldValue) { ret = GetUrl(url); break; } } } - else if (fieldName == "Session.Shop" && fieldValue == GetCurrentShopId(order)) + else if (fieldName == "Session.Shop" && fieldValue == GetCurrentShopId(order, submitType)) { ret = GetUrl(url); break; @@ -256,9 +263,9 @@ private string GetMatchedUrl(string[] urls, Order order) /// Gets the current order. /// /// Order. - private Order GetCurrentOrder(Order order) + private static Order GetCurrentOrder(Order order, SubmitType submitType) { - if(ExecutingContext.IsBackEnd() && order != null) + if(LiveContext.IsBackEnd(submitType) && order != null) { return order; } @@ -277,9 +284,9 @@ private Order GetCurrentOrder(Order order) /// Gets the current shop identifier. /// /// System.String. - private string GetCurrentShopId(Order order) + private static string GetCurrentShopId(Order order, SubmitType submitType) { - if (ExecutingContext.IsBackEnd() && order != null) + if (LiveContext.IsBackEnd(submitType) && order != null) { return order.ShopId; } @@ -311,7 +318,7 @@ public int GetWebServiceUrlsCount(Settings settings) string multilineUrlText = settings.WebServiceURI; if (!string.IsNullOrEmpty(multilineUrlText)) { - if (multilineUrlText.Contains("\r\n") || multilineUrlText.Contains("\n")) + if (multilineUrlText.Contains("\r\n") || multilineUrlText.Contains('\n')) { return multilineUrlText.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries).Length; } @@ -326,14 +333,14 @@ public int GetWebServiceUrlsCount(Settings settings) /// /// The multiline URL text. /// System.String[]. - internal string[] GetWebServiceUrls(string multilineUrlText) + internal static string[] GetWebServiceUrls(string multilineUrlText) { string[] ret; if (!string.IsNullOrEmpty(multilineUrlText)) { ret = new string[] { multilineUrlText }; - if (multilineUrlText.Contains("\r\n") || multilineUrlText.Contains("\n")) + if (multilineUrlText.Contains("\r\n") || multilineUrlText.Contains('\n')) { ret = multilineUrlText.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); } @@ -351,14 +358,14 @@ internal string[] GetWebServiceUrls(string multilineUrlText) /// /// The multiple Urls text. /// System.String[]. - internal string[] GetEndpointUrls(string multipleUrlsText) + internal static string[] GetEndpointUrls(string multipleUrlsText) { string[] ret; if (!string.IsNullOrEmpty(multipleUrlsText)) { ret = new string[] { multipleUrlsText }; - if (multipleUrlsText.Contains(",")) + if (multipleUrlsText.Contains(',')) { ret = multipleUrlsText.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); } @@ -377,9 +384,9 @@ internal string[] GetEndpointUrls(string multipleUrlsText) /// Name of the field. /// The field value. /// true if the user field matched the passed fieldName, false otherwise. - private bool TreatUserFields(string fieldName, string fieldValue, Order order) + private static bool TreatUserFields(string fieldName, string fieldValue, Order order, SubmitType submitType) { - User user = (ExecutingContext.IsBackEnd() && order != null) ? UserManagementServices.Users.GetUserById(order.CustomerAccessUserId) : + User user = (LiveContext.IsBackEnd(submitType) && order != null) ? UserManagementServices.Users.GetUserById(order.CustomerAccessUserId) : Helpers.GetCurrentExtranetUser(); if (user == null) From 6a56359070c584ddc1a774ad60061b6a9ebe8846 Mon Sep 17 00:00:00 2001 From: Dmitriy Benyuk Date: Fri, 7 Mar 2025 12:38:05 +0200 Subject: [PATCH 2/2] code review --- ...micweb.Ecommerce.DynamicwebLiveIntegration.csproj | 2 +- .../EndpointMonitoring/EndpointMonitoringService.cs | 12 +++++++++--- .../IntegrationCustomerCenterHandler.cs | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Dynamicweb.Ecommerce.DynamicwebLiveIntegration.csproj b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Dynamicweb.Ecommerce.DynamicwebLiveIntegration.csproj index a55b5c9..150544e 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Dynamicweb.Ecommerce.DynamicwebLiveIntegration.csproj +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Dynamicweb.Ecommerce.DynamicwebLiveIntegration.csproj @@ -1,6 +1,6 @@  - 10.5.0 + 10.4.19 1.0.0.0 Live Integration Live Integration diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/EndpointMonitoring/EndpointMonitoringService.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/EndpointMonitoring/EndpointMonitoringService.cs index f686d1c..75bb6a6 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/EndpointMonitoring/EndpointMonitoringService.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/EndpointMonitoring/EndpointMonitoringService.cs @@ -143,11 +143,17 @@ private static void PingEndpoint(Settings settings, EndpointInfo endpoint, Submi } } + private static (Settings Settings, SubmitType SubmitType) GetStateInfo(object stateInfo) + { + var state = (Tuple)stateInfo; + return (state.Item1, state.Item2); + } + private void Ping(object stateInfo) { - Tuple state = (Tuple)stateInfo; - Settings settings = state.Item1; - SubmitType submitType = state.Item2; + var state = GetStateInfo(stateInfo); + Settings settings = state.Settings; + SubmitType submitType = state.SubmitType; var logger = new Logger(settings); ConnectorBase currentConnector = null; diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/IntegrationCustomerCenterHandler.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/IntegrationCustomerCenterHandler.cs index 02cf2a6..0ff244f 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/IntegrationCustomerCenterHandler.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/IntegrationCustomerCenterHandler.cs @@ -202,7 +202,7 @@ private static void ProcessItemsListResponse(XmlDocument response, Template temp bool isTotalCountAttributePresent = itemsNode != null && itemsNode.Attributes["totalCount"] != null; if (isTotalCountAttributePresent) { - int.TryParse(itemsNode.Attributes["totalCount"].Value, out totalItemsCount); + totalItemsCount = Converter.ToInt32(itemsNode.Attributes["totalCount"].Value); } if (totalItemsCount <= 0) {