From 6a52b45692abfffc933bd86968b7ebf58b5809d8 Mon Sep 17 00:00:00 2001 From: Dmitriy Benyuk Date: Tue, 12 May 2026 11:38:46 +0300 Subject: [PATCH 1/8] Fix VAT Group prices and Expose Connector --- .../CustomProductProvider.cs | 11 +++--- .../Connectors/Connector.cs | 12 +++--- ...Ecommerce.DynamicwebLiveIntegration.csproj | 2 +- .../Products/ProductPriceProvider.cs | 4 +- .../Products/ProductProviderBase.cs | 37 +++++++++++++------ 5 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Examples/CustomProductProvider.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Examples/CustomProductProvider.cs index 20bf509..42d56ed 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Examples/CustomProductProvider.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Examples/CustomProductProvider.cs @@ -27,15 +27,16 @@ public override string GetProductIdentifier(Settings settings, Product product, /// /// Gets the price. /// - /// The product. + /// The product info. /// The quantity. + /// The product. /// PriceInfo. - public override PriceInfo GetPriceInfo(LiveContext context, ProductInfo product, double quantity) + public override PriceInfo GetPriceInfo(LiveContext context, ProductInfo productInfo, double quantity, Product product) { // Example: if we have a price per kilogram - we need to multiply it by quantity - if (double.TryParse(product["TotalPrice"].ToString(), out double unitPriceWithoutVat)) + if (double.TryParse(productInfo["TotalPrice"].ToString(), out double unitPriceWithoutVat)) { - double? unitPriceWithVat = (double?)product["TotalPriceWithVat"]; + double? unitPriceWithVat = (double?)productInfo["TotalPriceWithVat"]; var currency = Common.Context.Currency; if (currency is null) @@ -47,7 +48,7 @@ public override PriceInfo GetPriceInfo(LiveContext context, ProductInfo product, } else { - return base.GetPriceInfo(context, product, quantity); + return base.GetPriceInfo(context, productInfo, quantity, product); } } } diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs index ccd1143..fb3da60 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs @@ -9,8 +9,6 @@ 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; @@ -19,7 +17,7 @@ namespace Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Connectors /// /// Main class to interact with a remote ERP. /// - internal static class Connector + public static class Connector { /// /// The maximum retry count @@ -40,7 +38,7 @@ public static bool EnableThrowExceptions { return Core.Converter.ToBoolean(Context.Current?.Items?["DynamicwebLiveIntegrationAddInThrowExceptions"]); } - set + internal set { if (Context.Current?.Items != null) { @@ -68,7 +66,7 @@ private static ConnectorBase GetConnector(Settings settings, Logger logger, Subm { return new EndpointConnector(settings, logger, submitType, order); } - } + } /// /// Calculates the order. @@ -278,7 +276,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}'."); - HandleException(connector, settings, endpoint, ex, out httpStatusCode, ref retry); + HandleException(connector, settings, endpoint, ex, out httpStatusCode, ref retry); NotificationManager.Notify(OnAfterErpException, new OnAfterErpExceptionArgs(request, erpXmlResponse, referenceName, ex, settings, logger)); } @@ -357,7 +355,7 @@ private static void HandleException(ConnectorBase connector, Settings settings, } } - internal static string RetrievePDF(Settings settings, string requestString, SubmitType submitType) + public static string RetrievePDF(Settings settings, string requestString, SubmitType submitType) { Diagnostics.ExecutionTable.Current.Add("DynamicwebLiveIntegration.Connector.RetrievePDF START"); string base64EncodedPDF; diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Dynamicweb.Ecommerce.DynamicwebLiveIntegration.csproj b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Dynamicweb.Ecommerce.DynamicwebLiveIntegration.csproj index 8365b8a..0e6cccb 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.35 + 10.4.36 1.0.0.0 Live Integration Live Integration diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductPriceProvider.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductPriceProvider.cs index 313bd85..6cf42d3 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductPriceProvider.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductPriceProvider.cs @@ -132,7 +132,7 @@ public PriceInfo FindPriceInfo(PriceContext context, PriceProductSelection selec ? productInfo : null; - return productInfo != null ? productProvider.GetPriceInfo(liveContext, productInfo, selection.Quantity) : null; + return productInfo != null ? productProvider.GetPriceInfo(liveContext, productInfo, selection.Quantity, selection.Product) : null; } catch (Exception e) { @@ -161,7 +161,7 @@ IEnumerable> IPriceInfoProvider.FindQ Quantity = unitPrice.Quantity ?? 0, UnitId = unitPrice.UnitId, }, - ProductProviderBase.GetPriceInfo(context, unitPrice.Amount, unitPrice.AmountWithVat) + ProductProviderBase.GetPriceInfo(context, unitPrice.Amount, unitPrice.AmountWithVat, product) )); } return result; diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs index dbf7be5..c5a4303 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs @@ -93,22 +93,37 @@ public virtual Product GetProductWithUnit(Product product, string unitId) /// /// Gets the price. /// - /// The product. + /// The product. + /// The quantity. + /// PriceInfo + /// product + /// + /// + /// + [Obsolete("Use GetPriceInfo(LiveContext context, ProductInfo productInfo, double quantity, Product product) instead")] + public virtual PriceInfo GetPriceInfo(LiveContext context, ProductInfo productInfo, double quantity) => + GetPriceInfo(context, productInfo, quantity, null); + + /// + /// Gets the price. + /// + /// The product info. /// The quantity. + /// The product. /// PriceInfo /// product /// /// /// - public virtual PriceInfo GetPriceInfo(LiveContext context, ProductInfo product, double quantity) + public virtual PriceInfo GetPriceInfo(LiveContext context, ProductInfo productInfo, double quantity, Product product) { - if (product == null) + if (productInfo == null) { - throw new ArgumentNullException(nameof(product)); + throw new ArgumentNullException(nameof(productInfo)); } - double? priceWithoutVat = (double?)product["TotalPrice"]; - double? priceWithVat = (double?)product["TotalPriceWithVat"]; + double? priceWithoutVat = (double?)productInfo["TotalPrice"]; + double? priceWithVat = (double?)productInfo["TotalPriceWithVat"]; if (!priceWithoutVat.HasValue) { @@ -117,7 +132,7 @@ public virtual PriceInfo GetPriceInfo(LiveContext context, ProductInfo product, quantity = 1; } - var erpPriceResponse = ((IList)product["Prices"] ?? Enumerable.Empty()) + var erpPriceResponse = ((IList)productInfo["Prices"] ?? Enumerable.Empty()) .Where(p => quantity >= p.Quantity.GetValueOrDefault(1)) .OrderByDescending(p => p.Quantity.GetValueOrDefault(1)) .FirstOrDefault(); @@ -126,7 +141,7 @@ public virtual PriceInfo GetPriceInfo(LiveContext context, ProductInfo product, priceWithVat = erpPriceResponse?.AmountWithVat; } - PriceInfo result = GetPriceInfo(context.PriceContext != null ? context.PriceContext : new PriceContext(context.Currency, context.Country), priceWithoutVat, priceWithVat); + PriceInfo result = GetPriceInfo(context.PriceContext != null ? context.PriceContext : new PriceContext(context.Currency, context.Country), priceWithoutVat, priceWithVat, product); return result; } @@ -138,7 +153,7 @@ public virtual PriceInfo GetPriceInfo(LiveContext context, ProductInfo product, /// The quantity. public virtual void FillProductValues(ProductInfo productInfo, Product product, Settings settings, double quantity, LiveContext context) { - var price = GetPriceInfo(context, productInfo, quantity); + var price = GetPriceInfo(context, productInfo, quantity, product); PriceInfo productPrice = PriceManager.GetPrice(context.PriceContext ?? new PriceContext(context.Currency, context.Country), product); productPrice.PriceWithoutVAT = price.PriceWithoutVAT; productPrice.PriceWithVAT = price.PriceWithVAT; @@ -274,7 +289,7 @@ public virtual void FillProductFieldValues(Product product, ProductInfo productI } } - internal static PriceInfo GetPriceInfo(PriceContext priceContext, double? priceWithoutVat, double? priceWithVat) + internal static PriceInfo GetPriceInfo(PriceContext priceContext, double? priceWithoutVat, double? priceWithVat, Product product) { PriceInfo result = new PriceInfo(priceContext.Currency); result.PriceWithoutVAT = priceWithoutVat != null ? priceWithoutVat.Value : 0; @@ -294,7 +309,7 @@ internal static PriceInfo GetPriceInfo(PriceContext priceContext, double? priceW Price = result.PriceWithoutVAT, Currency = priceContext.Currency }; - var calculated = PriceCalculated.Create(priceContext, price); + var calculated = PriceCalculated.Create(priceContext, price, product); if (calculated != null) { calculated.Calculate(); From 2326836e62a80f2904e695efe3d4d4278d620916 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 12 May 2026 14:11:42 +0000 Subject: [PATCH 2/8] Fix XML doc inconsistencies in GetPriceInfo: update param and exception references from 'product' to 'productInfo' Agent-Logs-Url: https://github.com/dynamicweb/DataIntegration.LiveIntegration/sessions/109a717e-4ead-4d8d-98c7-26b0c32530f2 Co-authored-by: MatthiasSort <123721955+MatthiasSort@users.noreply.github.com> --- .../Products/ProductProviderBase.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs index c5a4303..4847126 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs @@ -93,10 +93,10 @@ public virtual Product GetProductWithUnit(Product product, string unitId) /// /// Gets the price. /// - /// The product. + /// The product info. /// The quantity. /// PriceInfo - /// product + /// productInfo /// /// /// @@ -111,7 +111,7 @@ public virtual PriceInfo GetPriceInfo(LiveContext context, ProductInfo productIn /// The quantity. /// The product. /// PriceInfo - /// product + /// productInfo /// /// /// From ff929e0aa95c406b4990988d74cae5cd2862d7f4 Mon Sep 17 00:00:00 2001 From: DWDBE <123462359+DWDBE@users.noreply.github.com> Date: Tue, 12 May 2026 17:39:09 +0300 Subject: [PATCH 3/8] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../Products/ProductProviderBase.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs index 4847126..b6dc750 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs @@ -309,7 +309,9 @@ internal static PriceInfo GetPriceInfo(PriceContext priceContext, double? priceW Price = result.PriceWithoutVAT, Currency = priceContext.Currency }; - var calculated = PriceCalculated.Create(priceContext, price, product); + var calculated = product == null + ? PriceCalculated.Create(priceContext, price) + : PriceCalculated.Create(priceContext, price, product); if (calculated != null) { calculated.Calculate(); From 209aafe2ce945054270bf4b2bddb824ab8b184a1 Mon Sep 17 00:00:00 2001 From: Dmitriy Benyuk Date: Tue, 12 May 2026 17:58:13 +0300 Subject: [PATCH 4/8] fix breaking change --- .../Products/ProductProviderBase.cs | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs index b6dc750..5302552 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs @@ -102,7 +102,7 @@ public virtual Product GetProductWithUnit(Product product, string unitId) /// [Obsolete("Use GetPriceInfo(LiveContext context, ProductInfo productInfo, double quantity, Product product) instead")] public virtual PriceInfo GetPriceInfo(LiveContext context, ProductInfo productInfo, double quantity) => - GetPriceInfo(context, productInfo, quantity, null); + GetPriceInfoCore(context, productInfo, quantity, null); /// /// Gets the price. @@ -117,11 +117,26 @@ public virtual PriceInfo GetPriceInfo(LiveContext context, ProductInfo productIn /// public virtual PriceInfo GetPriceInfo(LiveContext context, ProductInfo productInfo, double quantity, Product product) { - if (productInfo == null) + // If a subclass has overridden the legacy 3-parameter overload, honor that override + // so existing customizations are not silently bypassed when internal callers use the new overload. + if (GetType() != typeof(ProductProviderBase)) { - throw new ArgumentNullException(nameof(productInfo)); + var legacyOverride = GetType().GetMethod(nameof(GetPriceInfo), [typeof(LiveContext), typeof(ProductInfo), typeof(double)]); + if (legacyOverride?.DeclaringType != typeof(ProductProviderBase)) + { +#pragma warning disable CS0618 + return GetPriceInfo(context, productInfo, quantity); +#pragma warning restore CS0618 + } } + return GetPriceInfoCore(context, productInfo, quantity, product); + } + + private static PriceInfo GetPriceInfoCore(LiveContext context, ProductInfo productInfo, double quantity, Product product) + { + ArgumentNullException.ThrowIfNull(productInfo); + double? priceWithoutVat = (double?)productInfo["TotalPrice"]; double? priceWithVat = (double?)productInfo["TotalPriceWithVat"]; @@ -141,8 +156,7 @@ public virtual PriceInfo GetPriceInfo(LiveContext context, ProductInfo productIn priceWithVat = erpPriceResponse?.AmountWithVat; } - PriceInfo result = GetPriceInfo(context.PriceContext != null ? context.PriceContext : new PriceContext(context.Currency, context.Country), priceWithoutVat, priceWithVat, product); - return result; + return GetPriceInfo(context.PriceContext ?? new PriceContext(context.Currency, context.Country), priceWithoutVat, priceWithVat, product); } /// From 00feac16cd4e1aa80289ea484f80c2e04b90b46b Mon Sep 17 00:00:00 2001 From: Dmitriy Benyuk Date: Tue, 12 May 2026 17:59:28 +0300 Subject: [PATCH 5/8] add comment --- .../Connectors/Connector.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs index fb3da60..d3999ce 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs @@ -355,6 +355,15 @@ private static void HandleException(ConnectorBase connector, Settings settings, } } + /// + /// Retrieves a PDF document as a Base64-encoded string based on the specified request and submission type. + /// + /// The returned string can be decoded to obtain the original PDF file. Ensure that the + /// provided settings and request string are valid to avoid exceptions during execution. + /// The settings used to configure the connector and logging behavior. Cannot be null. + /// The request data to be sent to the connector for PDF retrieval. Cannot be null or empty. + /// The type of submission to use when executing the request. + /// A Base64-encoded string representing the retrieved PDF document. public static string RetrievePDF(Settings settings, string requestString, SubmitType submitType) { Diagnostics.ExecutionTable.Current.Add("DynamicwebLiveIntegration.Connector.RetrievePDF START"); From 28531a794ee8a0ddc741d13c439de9b9eca34f4d Mon Sep 17 00:00:00 2001 From: DWDBE <123462359+DWDBE@users.noreply.github.com> Date: Tue, 12 May 2026 21:39:25 +0300 Subject: [PATCH 6/8] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../Connectors/Connector.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs index d3999ce..60011cc 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs @@ -366,6 +366,16 @@ private static void HandleException(ConnectorBase connector, Settings settings, /// A Base64-encoded string representing the retrieved PDF document. public static string RetrievePDF(Settings settings, string requestString, SubmitType submitType) { + if (settings is null) + { + throw new ArgumentNullException(nameof(settings)); + } + + if (string.IsNullOrEmpty(requestString)) + { + throw new ArgumentException("Value cannot be null or empty.", nameof(requestString)); + } + Diagnostics.ExecutionTable.Current.Add("DynamicwebLiveIntegration.Connector.RetrievePDF START"); string base64EncodedPDF; var logger = new Logger(settings); From dfd104746e5ac5de7e74a9f6157557490f6b7667 Mon Sep 17 00:00:00 2001 From: Dmitriy Benyuk Date: Tue, 12 May 2026 21:40:20 +0300 Subject: [PATCH 7/8] code review --- .../Connectors/Connector.cs | 2 +- .../Products/ProductProviderBase.cs | 21 ++++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs index 60011cc..d1fbd41 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Connectors/Connector.cs @@ -373,7 +373,7 @@ public static string RetrievePDF(Settings settings, string requestString, Submit if (string.IsNullOrEmpty(requestString)) { - throw new ArgumentException("Value cannot be null or empty.", nameof(requestString)); + throw new ArgumentException("RequestString value cannot be null or empty.", nameof(requestString)); } Diagnostics.ExecutionTable.Current.Add("DynamicwebLiveIntegration.Connector.RetrievePDF START"); diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs index 5302552..8028dd8 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs @@ -4,6 +4,7 @@ using Dynamicweb.Ecommerce.Prices; using Dynamicweb.Ecommerce.Products; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Xml; @@ -19,6 +20,8 @@ namespace Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Products /// public class ProductProviderBase { + private static readonly ConcurrentDictionary _legacyGetPriceInfoOverrideCache = new(); + /// /// Creates a unique product identifier by concatenating the product ID or number (depends on the CalculatePriceUsingProductNumber setting), the variant ID and the language ID. /// Override to build up your own unique identifier. @@ -117,17 +120,19 @@ public virtual PriceInfo GetPriceInfo(LiveContext context, ProductInfo productIn /// public virtual PriceInfo GetPriceInfo(LiveContext context, ProductInfo productInfo, double quantity, Product product) { - // If a subclass has overridden the legacy 3-parameter overload, honor that override - // so existing customizations are not silently bypassed when internal callers use the new overload. - if (GetType() != typeof(ProductProviderBase)) + // Honor legacy 3-parameter overrides in subclasses so existing customizations are not silently + // bypassed when internal callers use this new overload. Result is cached per provider type. + bool hasLegacyOverride = _legacyGetPriceInfoOverrideCache.GetOrAdd(GetType(), static t => + { + var method = t.GetMethod(nameof(GetPriceInfo), [typeof(LiveContext), typeof(ProductInfo), typeof(double)]); + return method?.DeclaringType != typeof(ProductProviderBase); + }); + + if (hasLegacyOverride) { - var legacyOverride = GetType().GetMethod(nameof(GetPriceInfo), [typeof(LiveContext), typeof(ProductInfo), typeof(double)]); - if (legacyOverride?.DeclaringType != typeof(ProductProviderBase)) - { #pragma warning disable CS0618 - return GetPriceInfo(context, productInfo, quantity); + return GetPriceInfo(context, productInfo, quantity); #pragma warning restore CS0618 - } } return GetPriceInfoCore(context, productInfo, quantity, product); From 25265b4ed35c4cab80625e668c7676bec0728e18 Mon Sep 17 00:00:00 2001 From: Dmitriy Benyuk Date: Tue, 12 May 2026 22:42:51 +0300 Subject: [PATCH 8/8] cleanup code --- .../Products/ProductManager.cs | 4 ++++ .../Products/ProductProviderBase.cs | 13 ++----------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductManager.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductManager.cs index 4a06c61..fc6b4f8 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductManager.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductManager.cs @@ -50,6 +50,10 @@ internal static ProductProviderBase ProductProvider if (!ReferenceEquals(addIn, typeof(ProductProviderBase))) { provider = (ProductProviderBase)AddInManager.GetInstance(addIn); + // Honor legacy 3-parameter overrides in subclasses so existing customizations are not silently + // bypassed when internal callers use the new overload with 4-parameters. + var method = addIn.GetMethod(nameof(ProductProviderBase.GetPriceInfo), [typeof(LiveContext), typeof(ProductInfo), typeof(double)]); + provider.HasLegacyGetPriceInfoOverride = method is not null; break; } } diff --git a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs index 8028dd8..8245bf6 100644 --- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs +++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs @@ -4,7 +4,6 @@ using Dynamicweb.Ecommerce.Prices; using Dynamicweb.Ecommerce.Products; using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Xml; @@ -20,7 +19,7 @@ namespace Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Products /// public class ProductProviderBase { - private static readonly ConcurrentDictionary _legacyGetPriceInfoOverrideCache = new(); + internal bool HasLegacyGetPriceInfoOverride { get; set; } /// /// Creates a unique product identifier by concatenating the product ID or number (depends on the CalculatePriceUsingProductNumber setting), the variant ID and the language ID. @@ -120,15 +119,7 @@ public virtual PriceInfo GetPriceInfo(LiveContext context, ProductInfo productIn /// public virtual PriceInfo GetPriceInfo(LiveContext context, ProductInfo productInfo, double quantity, Product product) { - // Honor legacy 3-parameter overrides in subclasses so existing customizations are not silently - // bypassed when internal callers use this new overload. Result is cached per provider type. - bool hasLegacyOverride = _legacyGetPriceInfoOverrideCache.GetOrAdd(GetType(), static t => - { - var method = t.GetMethod(nameof(GetPriceInfo), [typeof(LiveContext), typeof(ProductInfo), typeof(double)]); - return method?.DeclaringType != typeof(ProductProviderBase); - }); - - if (hasLegacyOverride) + if (HasLegacyGetPriceInfoOverride) { #pragma warning disable CS0618 return GetPriceInfo(context, productInfo, quantity);