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..d1fbd41 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,8 +355,27 @@ private static void HandleException(ConnectorBase connector, Settings settings,
}
}
- internal static string RetrievePDF(Settings settings, string requestString, SubmitType submitType)
+ ///
+ /// 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)
{
+ if (settings is null)
+ {
+ throw new ArgumentNullException(nameof(settings));
+ }
+
+ if (string.IsNullOrEmpty(requestString))
+ {
+ throw new ArgumentException("RequestString value cannot be null or empty.", nameof(requestString));
+ }
+
Diagnostics.ExecutionTable.Current.Add("DynamicwebLiveIntegration.Connector.RetrievePDF START");
string base64EncodedPDF;
var logger = new Logger(settings);
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/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/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..8245bf6 100644
--- a/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs
+++ b/src/Dynamicweb.Ecommerce.DynamicwebLiveIntegration/Products/ProductProviderBase.cs
@@ -19,6 +19,8 @@ namespace Dynamicweb.Ecommerce.DynamicwebLiveIntegration.Products
///
public class ProductProviderBase
{
+ 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.
/// Override to build up your own unique identifier.
@@ -93,22 +95,46 @@ public virtual Product GetProductWithUnit(Product product, string unitId)
///
/// Gets the price.
///
- /// The product.
+ /// The product info.
/// The quantity.
/// PriceInfo
- /// product
+ /// productInfo
///
///
///
- public virtual PriceInfo GetPriceInfo(LiveContext context, ProductInfo product, double quantity)
+ [Obsolete("Use GetPriceInfo(LiveContext context, ProductInfo productInfo, double quantity, Product product) instead")]
+ public virtual PriceInfo GetPriceInfo(LiveContext context, ProductInfo productInfo, double quantity) =>
+ GetPriceInfoCore(context, productInfo, quantity, null);
+
+ ///
+ /// Gets the price.
+ ///
+ /// The product info.
+ /// The quantity.
+ /// The product.
+ /// PriceInfo
+ /// productInfo
+ ///
+ ///
+ ///
+ public virtual PriceInfo GetPriceInfo(LiveContext context, ProductInfo productInfo, double quantity, Product product)
{
- if (product == null)
+ if (HasLegacyGetPriceInfoOverride)
{
- throw new ArgumentNullException(nameof(product));
+#pragma warning disable CS0618
+ return GetPriceInfo(context, productInfo, quantity);
+#pragma warning restore CS0618
}
- double? priceWithoutVat = (double?)product["TotalPrice"];
- double? priceWithVat = (double?)product["TotalPriceWithVat"];
+ 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"];
if (!priceWithoutVat.HasValue)
{
@@ -117,7 +143,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,8 +152,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);
- return result;
+ return GetPriceInfo(context.PriceContext ?? new PriceContext(context.Currency, context.Country), priceWithoutVat, priceWithVat, product);
}
///
@@ -138,7 +163,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 +299,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 +319,9 @@ internal static PriceInfo GetPriceInfo(PriceContext priceContext, double? priceW
Price = result.PriceWithoutVAT,
Currency = priceContext.Currency
};
- var calculated = PriceCalculated.Create(priceContext, price);
+ var calculated = product == null
+ ? PriceCalculated.Create(priceContext, price)
+ : PriceCalculated.Create(priceContext, price, product);
if (calculated != null)
{
calculated.Calculate();