Class SalesDiscountProvider
- Namespace
- Dynamicweb.Ecommerce.Orders.SalesDiscounts
- Assembly
- Dynamicweb.Ecommerce.dll
The SalesDiscountProvider allows you to invent your own discount types from scratch and apply them to an order,
or to extend the built-in discount types in the Sales Discount module.
All SalesDiscountAddIns need to override a function called ProcessOrder, which is the function that is called when
Dynamicweb eCommerce goes through all the SalesDiscountAddIns searching for discounts.
This allows the whole procedure to be more flexible, allowing you to decide how your SalesDiscountAddIn should work.
[Obsolete("Sales discount provider is obsolete. Use DiscountExtender and related interfaces instead.")]
public class SalesDiscountProvider : ConfigurableAddIn
- Inheritance
-
SalesDiscountProvider
- Inherited Members
Examples
This code sample shows how to make a SalesDiscountProvider that triggers discount if the total sum of purchased products (“Order total amount”) exceeds the specified amount.using System;
using Dynamicweb.Core;
using Dynamicweb.Ecommerce.Extensibility.Controls;
using Dynamicweb.Ecommerce.Orders;
#if !DW10
using Dynamicweb.Ecommerce.Orders.SalesDiscounts;
#endif
using Dynamicweb.Ecommerce.Prices;
using Dynamicweb.Extensibility.AddIns;
using Dynamicweb.Extensibility.Editors;
namespace Dynamicweb.Ecommerce.Examples.Orders.SalesDiscount
{
#if !DW10
[AddInName("Total price discount")]
[AddInDescription("If the total sum of the products purchased on an order is equal or bigger that the specified amount a discount will be triggered.")]
public class SalesDiscountSample : SalesDiscountProvider
{
#region Fields
private DiscountValueHandler _discountValue = new DiscountValueHandler();
#endregion
#region Properties
[AddInParameter("Condition"), AddInParameterEditor(typeof(MoreLessParameterEditor), "")]
public string MoreLess { get; set; } = "";
[AddInParameter("Order buylimit"), AddInParameterEditor(typeof(TextParameterEditor), "")]
public double BuyLimit { get; set; } = 1000.0;
#endregion
#region Methods
public override void ProcessOrder(Order order)
{
bool amountValid = false;
if (MoreLess == "<" && order.PriceBeforeFees.Price < BuyLimit)
amountValid = true;
else if (MoreLess == "<=" && order.PriceBeforeFees.Price <= BuyLimit)
amountValid = true;
else if (MoreLess == "==" && order.PriceBeforeFees.Price == BuyLimit)
amountValid = true;
else if (MoreLess == ">" && order.PriceBeforeFees.Price > BuyLimit)
amountValid = true;
else if (MoreLess == ">=" && order.PriceBeforeFees.Price >= BuyLimit)
amountValid = true;
if (amountValid)
{
if (_discountValue.Type == DiscountType.Products)
{
foreach (Dynamicweb.Ecommerce.Products.Product product in _discountValue.ProductCollection)
{
OrderLine line = new OrderLine(order);
line.ProductId = product.Id;
line.ProductVariantId = product.VariantId;
line.Quantity = 1;
line.Modified = DateTime.Now;
line.ProductName = product.Name;
line.ProductNumber = product.Number;
line.Reference = "Default.aspx?ID=" + order.CheckoutPageId + "&ProductID=" + product.Id + "&VariantID=" + product.VariantId;
line.OrderLineType = OrderLineType.Discount;
line.PageId = order.CheckoutPageId;
line.Product = product;
order.OrderLines.Add(line, false);
}
}
else
{
// Calculate discount
double discountPrice = 0;
// How are we going to calculate this?
if (_discountValue.Type == DiscountType.Percent)
{
discountPrice -= (order.PriceBeforeFees.Price / 100) * _discountValue.Amount;
}
else if (_discountValue.Type == DiscountType.FixedAmount)
{
discountPrice -= _discountValue.Amount;
}
// Add a new order line
OrderLine line = new OrderLine(order);
line.OrderLineType = OrderLineType.Discount;
line.Quantity = 1;
line.ProductName = DiscountName;
Services.OrderLines.SetUnitPrice(line, discountPrice, false);
// Insert orderline
order.OrderLines.Add(line, false);
}
}
}
#endregion
}
#endif
}
using System;
using System.Linq;
using System.Collections;
using Dynamicweb.Ecommerce.Prices;
using Dynamicweb.Ecommerce.Orders;
using Dynamicweb.Ecommerce.Products;
using Dynamicweb.Extensibility.Editors;
#if !DW10
using Dynamicweb.Ecommerce.Orders.SalesDiscounts;
#endif
using Dynamicweb.Ecommerce.Extensibility.Controls;
using Dynamicweb.Extensibility.AddIns;
using Dynamicweb.Configuration;
namespace ProductQuantityDiscount
{
#if !DW10
[AddInName("Quantity discount"),
AddInDescription("A 'Buy 3 pay for 2' or 'Buy 4, get 50% of the cheapest' discount."),
AddInActive(true),
AddInIsAdditional(false),
AddInOrder(2)]
public class ProductQuantityDiscount : SalesDiscountProvider, IDropDownOptions
{
public enum ApplyTypes
{
Cheapest,
MostExpensive
}
#region "Fields"
private ProductsAndGroupsHandler _ProductsAndGroups = new ProductsAndGroupsHandler();
private int _ProductQuantity = 1;
#endregion
private ApplyTypes _ApplyType;
#region "Properties"
[AddInParameter("Products"), AddInParameterEditor(typeof(Dynamicweb.Ecommerce.Extensibility.Editors.ProductsAndGroupsEditor), "width=300px;height=100px")]
public string ProductsAndGroups
{
get
{
if (_ProductsAndGroups == null)
{
_ProductsAndGroups = new ProductsAndGroupsHandler();
}
return _ProductsAndGroups.ToString();
}
set
{
if (_ProductsAndGroups == null)
{
_ProductsAndGroups = new ProductsAndGroupsHandler();
}
_ProductsAndGroups.ParseData(value);
}
}
[AddInParameter("Product quantity"), AddInParameterEditor(typeof(Dynamicweb.Extensibility.Editors.TextParameterEditor), "")]
public int ProductQuantity
{
get { return _ProductQuantity; }
set { _ProductQuantity = value; }
}
[AddInParameter("Applies to"), AddInParameterEditor(typeof(Dynamicweb.Extensibility.Editors.RadioParameterEditor), "")]
public string ApplyType
{
get { return Dynamicweb.Core.Converter.ToString(_ApplyType); }
set { _ApplyType = (ApplyTypes)System.Enum.Parse(typeof(ApplyTypes), value); }
}
#endregion
#region "Methods"
public override void ProcessOrder(Order _order)
{
OrderLineCollection includedProducts = new OrderLineCollection(_order);
double productQuantity = 0;
foreach (OrderLine line in _order.ProductOrderLines)
{
if (_ProductsAndGroups.IsProductIncluded(line.Product))
{
includedProducts.Add(line);
productQuantity += line.Quantity;
}
}
if (productQuantity >= this.ProductQuantity)
{
switch (DiscountValue.Type)
{
case Dynamicweb.Ecommerce.Extensibility.Controls.DiscountType.FixedAmount:
OrderLine fixedOrderLine = default(OrderLine);
fixedOrderLine = this.CreateAmountOrderline(_order, DiscountValue.Amount, false);
fixedOrderLine.Quantity = Math.Floor(productQuantity / this.ProductQuantity);
_order.OrderLines.Add(fixedOrderLine, false);
break;
case Dynamicweb.Ecommerce.Extensibility.Controls.DiscountType.Percent:
var applicableOrderline = includedProducts.OrderByDescending(productLine => _ApplyType == ApplyTypes.Cheapest ? 1 / (productLine.UnitPrice.Price + 1) : productLine.UnitPrice.Price).FirstOrDefault();
double discount = CalculateDiscountPrice(applicableOrderline, DiscountValue.Amount);
OrderLine newLine = CreateOrderLine(_order, discount);
newLine.Quantity = Math.Floor(productQuantity / this.ProductQuantity);
_order.OrderLines.Add(newLine, false);
break;
case Dynamicweb.Ecommerce.Extensibility.Controls.DiscountType.Products:
foreach (Dynamicweb.Ecommerce.Products.Product product in DiscountValue.ProductCollection)
{
_order.OrderLines.Add(this.CreateProductOrderline(_order, product), false);
}
break;
case Dynamicweb.Ecommerce.Extensibility.Controls.DiscountType.Unknown:
break;
}
}
}
public System.Collections.Hashtable GetOptions(string Name)
{
// Get Hashtable
Hashtable htOptions = new Hashtable();
switch (Name)
{
case "Applies to":
htOptions.Add(Dynamicweb.Core.Converter.ToString(ApplyTypes.Cheapest), "Cheapest product");
htOptions.Add(Dynamicweb.Core.Converter.ToString(ApplyTypes.MostExpensive), "The most expensive product");
break;
}
// Return the hashtable
return htOptions;
}
private double CalculateDiscountPrice(OrderLine _orderLine, double _discountPercent)
{
string originalPriceInDBSetting = SystemConfiguration.Instance.GetValue("/Globalsettings/Ecom/Price/PricesInDbIncludesVAT");
bool isPricesWithVat = Dynamicweb.Core.Converter.ToBoolean(originalPriceInDBSetting);
double discountPrice = 0;
if (isPricesWithVat)
{
discountPrice += _orderLine.UnitPrice.PriceWithVAT / 100 * _discountPercent;
}
else
{
discountPrice += _orderLine.UnitPrice.PriceWithoutVAT / 100 * _discountPercent;
}
if (isPricesWithVat)
{
//Add system VAT
double systemVat = 0;
if (double.TryParse(SystemConfiguration.Instance.GetValue("/Globalsettings/Ecom/Price/PricesInDbVAT"), out systemVat))
{
discountPrice *= 1 + (systemVat / 100.0);
}
//Remove country VAT
discountPrice /= 1 + (PriceCalculated.FindVatPercent(_orderLine.Order.VatCountry) / 100.0);
}
return discountPrice * -1;
}
private OrderLine CreateOrderLine(Order _order, double discountPrice)
{
OrderLine line = new OrderLine(_order);
line.Quantity = 1;
line.ProductName = DiscountName;
line.SetUnitPrice(discountPrice);
line.DiscountId = DiscountId;
line.OrderLineType = OrderLineType.ProductDiscount;
return line;
}
private new OrderLine CreateProductOrderline(Order _order, Product product)
{
double quantity = 1;
OrderLine parentOrderLine = null;
if (IsProductDiscount)
{
foreach (OrderLine ol in _order.ProductOrderLines)
{
if (ol.Product.Id == ProductDiscountProduct.Id && ol.Product.VariantId == ProductDiscountProduct.VariantId && ol.Product.LanguageId == ProductDiscountProduct.LanguageId)
{
quantity = ol.Quantity;
parentOrderLine = ol;
break; // TODO: might not be correct. Was : Exit For
}
}
}
OrderLine line = new OrderLine(_order);
line.ProductId = product.Id;
line.ProductVariantId = product.VariantId;
line.Quantity = quantity;
line.Modified = DateTime.Now;
line.ProductName = product.Name;
line.ProductNumber = product.Number;
line.Reference = "Default.aspx?ID=" + _order.CheckoutPageId + "&ProductID=" + product.Id + "&VariantID=" + product.VariantId;
line.OrderLineType = OrderLineType.ProductDiscount;
//Always set to ProductDiscount to avoid this discount to be removed when applying highest/lowest discount only
line.PageId = _order.CheckoutPageId;
line.Product = product;
line.DiscountId = DiscountId;
if (parentOrderLine != null)
{
line.ParentLineId = parentOrderLine.Id;
}
return line;
}
private new OrderLine CreateAmountOrderline(Order _order, double Amount, bool IsPercent)
{
double discountPrice = 0;
_order.IsCart = true;
string originalPriceInDBSetting = SystemConfiguration.Instance.GetValue("/Globalsettings/Ecom/Price/PricesInDbIncludesVAT");
bool isPricesWithVat = Dynamicweb.Core.Converter.ToBoolean(originalPriceInDBSetting);
double quantity = 1;
string parentLineID = null;
//Order discount
if (IsPercent)
{
foreach (OrderLine ol in _order.ProductOrderLines)
{
if (ol.OrderLineType != OrderLineType.Discount)
{
if (isPricesWithVat)
{
discountPrice += ol.UnitPrice.PriceWithVAT / 100 * Amount * ol.Quantity;
}
else
{
discountPrice += ol.UnitPrice.PriceWithoutVAT / 100 * Amount * ol.Quantity;
}
}
}
}
else
{
discountPrice = Amount;
}
if (isPricesWithVat)
{
//Add system VAT
double systemVat = 0;
if (double.TryParse(SystemConfiguration.Instance.GetValue("/Globalsettings/Ecom/Price/PricesInDbVAT"), out systemVat))
{
discountPrice *= 1 + (systemVat / 100.0);
}
//Remove country VAT
discountPrice /= 1 + (PriceCalculated.FindVatPercent(_order.VatCountry) / 100.0);
}
//Negate
discountPrice *= -1;
// Add a new order line
OrderLine line = new OrderLine(_order);
line.Quantity = quantity;
line.ProductName = this.DiscountName;
line.SetUnitPrice(discountPrice);
line.ParentLineId = parentLineID;
line.DiscountId = DiscountId;
if (IsProductDiscount)
{
line.OrderLineType = OrderLineType.ProductDiscount;
}
else
{
line.OrderLineType = OrderLineType.Discount;
}
return line;
}
#endregion
}
#endif
}
Fields
DefaultVoucherCodeFieldCaption
protected readonly string DefaultVoucherCodeFieldCaption
Field Value
DefaultVoucherCodeFieldName
protected const string DefaultVoucherCodeFieldName = "OrderVoucherCode"
Field Value
Properties
DiscountId
Gets or sets the discount ID.
public virtual string DiscountId { get; set; }
Property Value
- string
- The discount ID.
DiscountName
Gets or sets the name of the discount.
public virtual string DiscountName { get; set; }
Property Value
- string
- The name of the discount.
Discounts
Gets or sets the currently added discounts applied to the order.
public OrderLineCollection Discounts { get; }
Property Value
- OrderLineCollection
- List of order lines that contains the discounts applied to the order at the time of the execution of this provider instance.
DiscountValue
Gets or sets the discount value.
public DiscountValueHandler DiscountValue { get; set; }
Property Value
- DiscountValueHandler
- The discount value.
HideDiscountValueGroupBox
Gets or sets a value indicating whether to hide discount value group box in the UI.
public virtual bool HideDiscountValueGroupBox { get; set; }
Property Value
- bool
true
if it is needed to hide discount value group box; otherwise,false
.
IsProductDiscount
Gets or sets a value indicating whether this instance is product discount.
public virtual bool IsProductDiscount { get; set; }
Property Value
- bool
true
if this instance is product discount; otherwise,false
.
ProductDiscountProduct
Gets or sets the discount product.
public virtual Product ProductDiscountProduct { get; set; }
Property Value
- Product
- The product discount product.
Methods
CreateAmountOrderline(Order, double, bool)
public OrderLine CreateAmountOrderline(Order order, double amount, bool isPercent)
Parameters
Returns
CreateAmountOrderline(Order, double, bool, OrderLine)
public OrderLine CreateAmountOrderline(Order order, double amount, bool isPercent, OrderLine productDiscountOrderLine)
Parameters
Returns
CreateProductOrderline(Order, Product)
protected OrderLine CreateProductOrderline(Order order, Product product)
Parameters
Returns
CreateProductOrderline(Order, string)
protected OrderLine CreateProductOrderline(Order order, string productId)
Parameters
Returns
CreateProductOrderline(Order, string, string)
protected OrderLine CreateProductOrderline(Order order, string productId, string variantId)
Parameters
Returns
GetOrderDiscounts(Order)
protected Dictionary<OrderLine, bool> GetOrderDiscounts(Order order)
Parameters
order
Order
Returns
ProcessOrder(Order)
Processes the order.
public virtual void ProcessOrder(Order order)
Parameters
order
Order- The order.
Examples
Look on example forSalesDiscountProvider
class