From 43653fb7a1f3fe283f8d68c5d06b760c8047ff4e Mon Sep 17 00:00:00 2001 From: Dmitriy Benyuk Date: Thu, 16 Oct 2025 19:44:27 +0300 Subject: [PATCH 1/4] Live integration UI updates --- ...Ecommerce.DynamicwebLiveIntegration.csproj | 2 +- .../LiveIntegrationAddIn.cs | 106 +++++++++++++----- 2 files changed, 79 insertions(+), 29 deletions(-) diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Dynamicweb.Ecommerce.DynamicwebLiveIntegration.csproj b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Dynamicweb.Ecommerce.DynamicwebLiveIntegration.csproj index d2c7dde..b4b15fe 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.31 + 10.4.32 1.0.0.0 Live Integration Live Integration diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveIntegrationAddIn.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveIntegrationAddIn.cs index 398d97f..74e600e 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveIntegrationAddIn.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveIntegrationAddIn.cs @@ -1,4 +1,5 @@ using Dynamicweb.Content; +using Dynamicweb.Core; using Dynamicweb.DataIntegration.EndpointManagement; using Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Configuration; using Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Connectors; @@ -11,7 +12,6 @@ using Dynamicweb.Rendering; using Dynamicweb.Security.UserManagement; using System; -using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -29,7 +29,7 @@ namespace Dynamicweb.Ecommerce.DynamicwebLiveIntegration [AddInIgnore(false)] [AddInUseParameterGrouping(true)] [AddInUseParameterOrdering(true)] - public class LiveIntegrationAddIn : BaseLiveIntegrationAddIn, IDropDownOptions, ISettings + public class LiveIntegrationAddIn : BaseLiveIntegrationAddIn, IParameterOptions, ISettings, IParameterVisibility { /// /// Initializes a new instance of the class. @@ -77,12 +77,19 @@ public LiveIntegrationAddIn() [AddInParameterOrder(6)] public string InstanceLabel { get; set; } + [AddInParameterGroup("General")] + [AddInParameter("ConnectionToType")] + [AddInLabel("Connect to")] + [AddInParameterEditor(typeof(RadioParameterEditor), "")] + [AddInParameterOrder(9)] + public string ConnectionToType { get; set; } = nameof(ConnectionType.Endpoint); + /// /// The web service Uri /// /// The web service URI. [AddInParameter("Web service URL")] - [AddInParameterEditor(typeof(TextParameterEditor), "TextArea=True")] + [AddInParameterEditor(typeof(TextParameterEditor), "TextArea=True;")] [AddInParameterGroup("General")] [AddInParameterOrder(10)] public override string WebServiceURI { get; set; } @@ -92,7 +99,7 @@ public LiveIntegrationAddIn() /// /// The security key. [AddInParameter("Security key")] - [AddInParameterEditor(typeof(TextParameterEditor), "password=true")] + [AddInParameterEditor(typeof(TextParameterEditor), "password=true;")] [AddInParameterGroup("General")] [AddInParameterOrder(20)] public override string SecurityKey { get; set; } @@ -494,7 +501,7 @@ public LiveIntegrationAddIn() /// /// The notification email. [AddInParameter("Notification recipient groups")] - [AddInParameterEditor(typeof(UserGroupParameterEditor), "Multiple=true;")] + [AddInParameterEditor(typeof(UserGroupParameterEditor), "Multiple=true;")] [AddInParameterGroup("Notifications")] [AddInParameterOrder(235)] public string RecipientGroups { get; set; } @@ -621,58 +628,58 @@ public LiveIntegrationAddIn() /// /// Name of the dropdown. /// Hashtable. - public Hashtable GetOptions(string dropdownName) + IEnumerable IParameterOptions.GetParameterOptions(string dropdownName) { - var options = new Hashtable(); + var options = new List(); switch (dropdownName) { case "Notification sending frequency": foreach (NotificationFrequency frequencyLevel in Enum.GetValues(typeof(NotificationFrequency))) { - options.Add(((int)frequencyLevel).ToString(), GetNotificationFrequencyText(frequencyLevel)); + options.Add(new(GetNotificationFrequencyText(frequencyLevel), ((int)frequencyLevel).ToString())); } break; case "Order state after export succeeded": case "Order state after export failed": - options.Add(string.Empty, "Leave unchanged"); + options.Add(new("Leave unchanged", string.Empty)); foreach (var state in Services.OrderStates.GetStatesByOrderType(OrderType.Order)) { if (state.IsDeleted) continue; - options.Add(state.Id, state.GetName(Services.Languages.GetDefaultLanguageId())); + options.Add(new(state.GetName(Services.Languages.GetDefaultLanguageId()), state.Id)); } break; case "Shop": - options.Add(string.Empty, "Any"); + options.Add(new("Any", string.Empty)); var shops = Services.Shops.GetShops(); foreach (var shop in shops) { - options.Add(shop.Id, shop.Name); + options.Add(new(shop.Name, shop.Id)); } break; case "Website": foreach (var area in new AreaService().GetAreas()) { - options.Add(area.ID, area.Name); + options.Add(new(area.Name, area.ID)); } break; case "Cart communication type": - options.Add(Constants.CartCommunicationType.None, Constants.CartCommunicationType.None); - options.Add(Constants.CartCommunicationType.Full, Constants.CartCommunicationType.Full); - options.Add(Constants.CartCommunicationType.OnlyOnOrderComplete, Constants.CartCommunicationType.OnlyOnOrderComplete); - options.Add(Constants.CartCommunicationType.CartOnly, Constants.CartCommunicationType.CartOnly); + options.Add(new(Constants.CartCommunicationType.None, Constants.CartCommunicationType.None)); + options.Add(new(Constants.CartCommunicationType.Full, Constants.CartCommunicationType.Full)); + options.Add(new(Constants.CartCommunicationType.OnlyOnOrderComplete, Constants.CartCommunicationType.OnlyOnOrderComplete)); + options.Add(new(Constants.CartCommunicationType.CartOnly, Constants.CartCommunicationType.CartOnly)); break; case "Number format culture": foreach (CultureInfo culture in CultureInfo.GetCultures(CultureTypes.AllCultures)) { - if (!string.IsNullOrEmpty(culture.Name) && !culture.IsNeutralCulture && !options.ContainsKey(culture.Name)) + if (!string.IsNullOrEmpty(culture.Name) && !culture.IsNeutralCulture && !options.Any(o => string.Equals(o.Value.ToString(), culture.Name, StringComparison.OrdinalIgnoreCase))) { - options.Add(culture.Name, $"{culture.Name} - {culture.EnglishName}"); + options.Add(new($"{culture.Name} - {culture.EnglishName}", culture.Name)); } } break; @@ -680,7 +687,7 @@ public Hashtable GetOptions(string dropdownName) case "Product information cache level": foreach (var cacheLevel in Enum.GetNames(typeof(Cache.ResponseCacheLevel))) { - options.Add(cacheLevel, cacheLevel); + options.Add(new(cacheLevel, cacheLevel)); } break; case "Endpoint": @@ -708,20 +715,24 @@ public Hashtable GetOptions(string dropdownName) if (endpointFilters.ContainsKey(endpoint.Id)) { string str = endpointFilters[endpoint.Id]; - options.Add(str, endpoint.Name + str.Substring(str.IndexOf(";"))); + options.Add(new(endpoint.Name + str.Substring(str.IndexOf(";")), str)); } else { - options.Add(endpoint.Id.ToString(), endpoint.Name); + options.Add(new(endpoint.Name, endpoint.Id.ToString())); } } break; case "ERP shipping item type": - options.Add(Constants.OrderConfiguration.DefaultShippingItemType, "Item Charge"); - options.Add("Account", "G/L Account"); - options.Add("Item", "Item"); - options.Add("FixedAsset", "Fixed Asset"); - options.Add("Resource", "Resource"); + options.Add(new("Item Charge", Constants.OrderConfiguration.DefaultShippingItemType)); + options.Add(new("G/L Account", "Account")); + options.Add(new("Item", "Item")); + options.Add(new("Fixed Asset", "FixedAsset")); + options.Add(new("Resource", "Resource")); + break; + case "ConnectionToType": + options.Add(new(nameof(ConnectionType.Endpoint), ConnectionType.Endpoint)); + options.Add(new("Dynamicweb connector web service", ConnectionType.WebService)); break; default: throw new ArgumentException($"Unsupported dropdown: {dropdownName}", nameof(dropdownName)); @@ -730,6 +741,27 @@ public Hashtable GetOptions(string dropdownName) return options; } + IEnumerable IParameterVisibility.GetHiddenParameterNames(string parameterName, object? parameterValue) + { + var result = new List(); + var parameterValueStr = Converter.ToString(parameterValue); + switch (parameterName) + { + case nameof(ConnectionToType): + if (nameof(ConnectionType.Endpoint).Equals(parameterValueStr, StringComparison.OrdinalIgnoreCase)) + { + result.Add("Web service URL"); + result.Add("Security key"); + } + else + { + result.Add("Endpoint"); + } + break; + } + return result; + } + private Settings GetCurrentSettings() { Settings settings = null; @@ -781,6 +813,11 @@ public override string LoadSettings() Settings settings = GetCurrentSettings(); Settings.UpdateFrom(settings, this); + if (string.IsNullOrEmpty(Endpoint) && !string.IsNullOrEmpty(WebServiceURI)) + { + ConnectionToType = nameof(ConnectionType.WebService); + } + var xml = GetParametersToXml(false); return xml; @@ -792,6 +829,13 @@ public override string LoadSettings() public override void SaveSettings() { Settings settings = GetCurrentSettings(); + // Do not allow Endpoint and WebService to be selected at the same time + if (!string.IsNullOrEmpty(Endpoint) && !string.IsNullOrEmpty(WebServiceURI) + && Enum.TryParse(ConnectionToType, out var connectionType) && connectionType == ConnectionType.WebService) + { + Endpoint = ""; + } + Settings.UpdateFrom(this, settings); if (string.IsNullOrEmpty(settings.InstanceId)) { @@ -807,7 +851,7 @@ public override void SaveSettings() { AutoPingInterval = Constants.MinPingInterval; } - if(ConnectionTimeout < Constants.DefaultConnectionTimeout) + if (ConnectionTimeout < Constants.DefaultConnectionTimeout) { ConnectionTimeout = Constants.DefaultConnectionTimeout; } @@ -930,5 +974,11 @@ private static void SaveTranslations(Settings settings) Helpers.SaveTranslation(Constants.OrderConfiguration.OrderDiscountText, settings.OrderDiscountText); Helpers.SaveTranslation(Constants.OrderConfiguration.ProductDiscountText, settings.ProductDiscountText); } + + private enum ConnectionType + { + Endpoint, + WebService, + } } } \ No newline at end of file From 60fbb83518127f61c419bd11a464291dbec39346 Mon Sep 17 00:00:00 2001 From: Dmitriy Benyuk Date: Mon, 20 Oct 2025 11:39:22 +0300 Subject: [PATCH 2/4] Use Multi Dual for Endpoint --- .../LiveIntegrationAddIn.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveIntegrationAddIn.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveIntegrationAddIn.cs index 74e600e..e2260ff 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveIntegrationAddIn.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveIntegrationAddIn.cs @@ -109,7 +109,7 @@ public LiveIntegrationAddIn() /// /// The Endpoint id. [AddInParameter("Endpoint")] - [AddInParameterEditor(typeof(DropDownParameterEditor), "multiple=true;none=true;InfoBar=true;Tooltip=Only works with a web service exposed by a plug-in unit from Dynamicweb. This option takes precedence")] + [AddInParameterEditor(typeof(SelectionBoxParameterEditor), "multiple=true;none=true;InfoBar=true;explanation=Select one or more endpoints exposing a plug-in unit from Dynamicweb")] [AddInParameterGroup("General")] [AddInParameterOrder(20)] public string Endpoint { get; set; } From 1a0b05c0f4a25535f75540e3fbb500d6e273a014 Mon Sep 17 00:00:00 2001 From: Dmitriy Benyuk Date: Mon, 20 Oct 2025 11:55:11 +0300 Subject: [PATCH 3/4] fix exception --- .../Connectors/ConnectorBase.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/ConnectorBase.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/ConnectorBase.cs index fb71f3d..120b361 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/ConnectorBase.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/ConnectorBase.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net.Http; using static Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Notifications.Communication; namespace Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Connectors { @@ -117,7 +118,7 @@ internal bool IsConnectionAvailableFromBackend(string multipleUrlsText) } if (!result && urls?.Count() > 1 && errorsList.Count > 0) { - throw new Exception(string.Join(System.Environment.NewLine, errorsList)); + throw new HttpRequestException(string.Join(System.Environment.NewLine, errorsList)); } return result; } From 8035c430b074e317a1266c7a0be3fa20b07ea067 Mon Sep 17 00:00:00 2001 From: Dmitriy Benyuk Date: Tue, 21 Oct 2025 16:57:51 +0300 Subject: [PATCH 4/4] update ctrls --- .../LiveIntegrationAddIn.cs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveIntegrationAddIn.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveIntegrationAddIn.cs index e2260ff..d777a1c 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveIntegrationAddIn.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/LiveIntegrationAddIn.cs @@ -109,7 +109,7 @@ public LiveIntegrationAddIn() /// /// The Endpoint id. [AddInParameter("Endpoint")] - [AddInParameterEditor(typeof(SelectionBoxParameterEditor), "multiple=true;none=true;InfoBar=true;explanation=Select one or more endpoints exposing a plug-in unit from Dynamicweb")] + [AddInParameterEditor(typeof(DropDownParameterEditor), "none=true;InfoBar=true;explanation=Select endpoint exposing a plug-in unit from Dynamicweb")] [AddInParameterGroup("General")] [AddInParameterOrder(20)] public string Endpoint { get; set; } @@ -184,7 +184,7 @@ public LiveIntegrationAddIn() /// /// true if [enable live prices]; otherwise, false. [AddInParameter("Enable live prices")] - [AddInParameterEditor(typeof(YesNoParameterEditor), "")] + [AddInParameterEditor(typeof(YesNoParameterEditor), "reloadonchange=true;")] [AddInParameterGroup("Products")] [AddInParameterOrder(63)] public bool EnableLivePrices { get; set; } = true; @@ -741,7 +741,7 @@ IEnumerable IParameterOptions.GetParameterOptions(string dropdo return options; } - IEnumerable IParameterVisibility.GetHiddenParameterNames(string parameterName, object? parameterValue) + IEnumerable IParameterVisibility.GetHiddenParameterNames(string parameterName, object parameterValue) { var result = new List(); var parameterValueStr = Converter.ToString(parameterValue); @@ -758,6 +758,19 @@ IEnumerable IParameterVisibility.GetHiddenParameterNames(string paramete result.Add("Endpoint"); } break; + case "Enable live prices": + if (Converter.ToBoolean(parameterValue) is false) + { + result.Add("Lazy load product info (&getproductinfo=true)"); + result.Add("Include product custom fields in request"); + result.Add("Product information cache level"); + result.Add("Use product number in price calculation"); + result.Add("Use unit prices"); + result.Add("Retry request for the product information"); + result.Add("Include variants in the product information request"); + result.Add("Max products per request"); + } + break; } return result; }