Skip to content

Commit

Permalink
#26 Added possibility to set product attribute price adjustments as …
Browse files Browse the repository at this point in the history
…percentages
  • Loading branch information
skoshelev committed Jan 29, 2018
1 parent 923fe94 commit ff9ddf0
Show file tree
Hide file tree
Showing 22 changed files with 195 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ public partial class PredefinedProductAttributeValue : BaseEntity, ILocalizedEnt
/// </summary>
public decimal PriceAdjustment { get; set; }

/// <summary>
/// Gets or sets a value indicating whether "price adjustment" is specified as percentage
/// </summary>
public bool PriceAdjustmentUsePercentage { get; set; }

/// <summary>
/// Gets or sets the weight adjustment
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ public partial class ProductAttributeValue : BaseEntity, ILocalizedEntity
/// </summary>
public decimal PriceAdjustment { get; set; }

/// <summary>
/// Gets or sets a value indicating whether "price adjustment" is specified as percentage (used only with AttributeValueType.Simple)
/// </summary>
public bool PriceAdjustmentUsePercentage { get; set; }

/// <summary>
/// Gets or sets the weight adjustment (used only with AttributeValueType.Simple)
/// </summary>
Expand Down
1 change: 1 addition & 0 deletions src/Libraries/Nop.Services/Catalog/CopyProductService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ protected virtual void CopyAttributesMapping(Product product, Product productCop
Name = productAttributeValue.Name,
ColorSquaresRgb = productAttributeValue.ColorSquaresRgb,
PriceAdjustment = productAttributeValue.PriceAdjustment,
PriceAdjustmentUsePercentage = productAttributeValue.PriceAdjustmentUsePercentage,
WeightAdjustment = productAttributeValue.WeightAdjustment,
Cost = productAttributeValue.Cost,
CustomerEntersQty = productAttributeValue.CustomerEntersQty,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,14 @@ public partial interface IPriceCalculationService
/// <param name="attributesXml">Shopping cart item attributes in XML</param>
/// <returns>Product cost (one item)</returns>
decimal GetProductCost(Product product, string attributesXml);

/// <summary>
/// Get a price adjustment of a product attribute value
/// </summary>
/// <param name="value">Product attribute value</param>
/// <param name="customer">Customer</param>
/// <param name="productPrice">Product price (null for using the base product price)</param>
/// <returns>Price adjustment</returns>
decimal GetProductAttributeValuePriceAdjustment(ProductAttributeValue value);
decimal GetProductAttributeValuePriceAdjustment(ProductAttributeValue value, Customer customer, decimal? productPrice = null);
}
}
22 changes: 14 additions & 8 deletions src/Libraries/Nop.Services/Catalog/PriceCalculationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ protected virtual IList<DiscountForCaching> GetAllowedDiscounts(Product product,
{
foreach (var attributeValue in attributeValues)
{
attributesTotalPrice += GetProductAttributeValuePriceAdjustment(attributeValue);
attributesTotalPrice += GetProductAttributeValuePriceAdjustment(attributeValue, customer, product.CustomerEntersPrice ? (decimal?)customerEnteredPrice : null);
}
}

Expand Down Expand Up @@ -734,23 +734,29 @@ public virtual decimal GetProductCost(Product product, string attributesXml)
return cost;
}

/// <summary>
/// Get a price adjustment of a product attribute value
/// </summary>
/// <param name="value">Product attribute value</param>
/// <returns>Price adjustment</returns>
public virtual decimal GetProductAttributeValuePriceAdjustment(ProductAttributeValue value)
public virtual decimal GetProductAttributeValuePriceAdjustment(ProductAttributeValue value, Customer customer, decimal? productPrice = null)
{
if (value == null)
throw new ArgumentNullException(nameof(value));


var adjustment = decimal.Zero;
switch (value.AttributeValueType)
{
case AttributeValueType.Simple:
{
//simple attribute
adjustment = value.PriceAdjustment;
if (value.PriceAdjustmentUsePercentage)
{
if (!productPrice.HasValue)
productPrice = GetFinalPrice(value.ProductAttributeMapping.Product, customer);

adjustment = (decimal) ((float) productPrice * (float) value.PriceAdjustment / 100f);
}
else
{
adjustment = value.PriceAdjustment;
}
}
break;
case AttributeValueType.AssociatedToProduct:
Expand Down
31 changes: 19 additions & 12 deletions src/Libraries/Nop.Services/Catalog/ProductAttributeFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ namespace Nop.Services.Catalog
public partial class ProductAttributeFormatter : IProductAttributeFormatter
{
private readonly IWorkContext _workContext;
private readonly IProductAttributeService _productAttributeService;
private readonly IProductAttributeParser _productAttributeParser;
private readonly ICurrencyService _currencyService;
private readonly ILocalizationService _localizationService;
Expand All @@ -34,7 +33,6 @@ public partial class ProductAttributeFormatter : IProductAttributeFormatter
/// Ctor
/// </summary>
/// <param name="workContext">Work context</param>
/// <param name="productAttributeService">Product attribute service</param>
/// <param name="productAttributeParser">Product attribute parser</param>
/// <param name="currencyService">Currency service</param>
/// <param name="localizationService">Localization service</param>
Expand All @@ -45,7 +43,6 @@ public partial class ProductAttributeFormatter : IProductAttributeFormatter
/// <param name="priceCalculationService">Price calculation service</param>
/// <param name="shoppingCartSettings">Shopping cart settings</param>
public ProductAttributeFormatter(IWorkContext workContext,
IProductAttributeService productAttributeService,
IProductAttributeParser productAttributeParser,
ICurrencyService currencyService,
ILocalizationService localizationService,
Expand All @@ -57,7 +54,6 @@ public partial class ProductAttributeFormatter : IProductAttributeFormatter
ShoppingCartSettings shoppingCartSettings)
{
this._workContext = workContext;
this._productAttributeService = productAttributeService;
this._productAttributeParser = productAttributeParser;
this._currencyService = currencyService;
this._localizationService = localizationService;
Expand All @@ -80,7 +76,7 @@ public virtual string FormatAttributes(Product product, string attributesXml)
var customer = _workContext.CurrentCustomer;
return FormatAttributes(product, attributesXml, customer);
}

/// <summary>
/// Formats attributes
/// </summary>
Expand Down Expand Up @@ -177,13 +173,24 @@ public virtual string FormatAttributes(Product product, string attributesXml)

if (renderPrices)
{
var attributeValuePriceAdjustment = _priceCalculationService.GetProductAttributeValuePriceAdjustment(attributeValue);
var priceAdjustmentBase = _taxService.GetProductPrice(product, attributeValuePriceAdjustment, customer, out decimal _);
var priceAdjustment = _currencyService.ConvertFromPrimaryStoreCurrency(priceAdjustmentBase, _workContext.WorkingCurrency);
if (priceAdjustmentBase > 0)
formattedAttribute += $" [+{_priceFormatter.FormatPrice(priceAdjustment, false, false)}]";
else if (priceAdjustmentBase < decimal.Zero)
formattedAttribute += $" [-{_priceFormatter.FormatPrice(-priceAdjustment, false, false)}]";
if (attributeValue.PriceAdjustmentUsePercentage)
{
var priceAdjustmentStr = attributeValue.PriceAdjustment.ToString("G29");
if (attributeValue.PriceAdjustment > decimal.Zero)
formattedAttribute += $" [+{priceAdjustmentStr}%]";
else if (attributeValue.PriceAdjustment < decimal.Zero)
formattedAttribute += $" [{priceAdjustmentStr}%]";
}
else
{
var attributeValuePriceAdjustment = _priceCalculationService.GetProductAttributeValuePriceAdjustment(attributeValue, customer);
var priceAdjustmentBase = _taxService.GetProductPrice(product, attributeValuePriceAdjustment, customer, out decimal _);
var priceAdjustment = _currencyService.ConvertFromPrimaryStoreCurrency(priceAdjustmentBase, _workContext.WorkingCurrency);
if (priceAdjustmentBase > decimal.Zero)
formattedAttribute += $" [+{_priceFormatter.FormatPrice(priceAdjustment, false, false)}]";
else if (priceAdjustmentBase < decimal.Zero)
formattedAttribute += $" [-{_priceFormatter.FormatPrice(-priceAdjustment, false, false)}]";
}
}

//display quantity
Expand Down
3 changes: 3 additions & 0 deletions src/Libraries/Nop.Services/ExportImport/ExportManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ private PropertyManager<ExportProductAttribute> GetProductAttributeManager()
new PropertyByName<ExportProductAttribute>("ColorSquaresRgb", p => p.ColorSquaresRgb),
new PropertyByName<ExportProductAttribute>("ImageSquaresPictureId", p => p.ImageSquaresPictureId),
new PropertyByName<ExportProductAttribute>("PriceAdjustment", p => p.PriceAdjustment),
new PropertyByName<ExportProductAttribute>("PriceAdjustmentUsePercentage", p => p.PriceAdjustmentUsePercentage),
new PropertyByName<ExportProductAttribute>("WeightAdjustment", p => p.WeightAdjustment),
new PropertyByName<ExportProductAttribute>("Cost", p => p.Cost),
new PropertyByName<ExportProductAttribute>("CustomerEntersQty", p => p.CustomerEntersQty),
Expand Down Expand Up @@ -471,6 +472,7 @@ private int ExportProductAttributes(Product item, PropertyManager<ExportProductA
ColorSquaresRgb = pav.ColorSquaresRgb,
ImageSquaresPictureId = pav.ImageSquaresPictureId,
PriceAdjustment = pav.PriceAdjustment,
PriceAdjustmentUsePercentage = pav.PriceAdjustmentUsePercentage,
WeightAdjustment = pav.WeightAdjustment,
Cost = pav.Cost,
CustomerEntersQty = pav.CustomerEntersQty,
Expand Down Expand Up @@ -987,6 +989,7 @@ public virtual string ExportProductsToXml(IList<Product> products)
xmlWriter.WriteString("ColorSquaresRgb", productAttributeValue.ColorSquaresRgb);
xmlWriter.WriteString("ImageSquaresPictureId", productAttributeValue.ImageSquaresPictureId);
xmlWriter.WriteString("PriceAdjustment", productAttributeValue.PriceAdjustment);
xmlWriter.WriteString("PriceAdjustmentUsePercentage", productAttributeValue.PriceAdjustmentUsePercentage);
xmlWriter.WriteString("WeightAdjustment", productAttributeValue.WeightAdjustment);
xmlWriter.WriteString("Cost", productAttributeValue.Cost);
xmlWriter.WriteString("CustomerEntersQty", productAttributeValue.CustomerEntersQty);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public partial class ExportProductAttribute
public decimal PriceAdjustment { get; set; }
public decimal Cost { get; set; }
public int DisplayOrder { get; set; }

public bool PriceAdjustmentUsePercentage { get; set; }
public static int ProducAttributeCellOffset = 2;
}
}
4 changes: 4 additions & 0 deletions src/Libraries/Nop.Services/ExportImport/ImportManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ protected virtual void ImportProductAttribute(PropertyManager<ExportProductAttri
var colorSquaresRgb = productAttributeManager.GetProperty("ColorSquaresRgb").StringValue;
var imageSquaresPictureId = productAttributeManager.GetProperty("ImageSquaresPictureId").IntValue;
var priceAdjustment = productAttributeManager.GetProperty("PriceAdjustment").DecimalValue;
var priceAdjustmentUsePercentage = productAttributeManager.GetProperty("PriceAdjustmentUsePercentage").BooleanValue;
var weightAdjustment = productAttributeManager.GetProperty("WeightAdjustment").DecimalValue;
var cost = productAttributeManager.GetProperty("Cost").DecimalValue;
var customerEntersQty = productAttributeManager.GetProperty("CustomerEntersQty").BooleanValue;
Expand Down Expand Up @@ -617,6 +618,7 @@ protected virtual void ImportProductAttribute(PropertyManager<ExportProductAttri
AssociatedProductId = associatedProductId,
Name = valueName,
PriceAdjustment = priceAdjustment,
PriceAdjustmentUsePercentage = priceAdjustmentUsePercentage,
WeightAdjustment = weightAdjustment,
Cost = cost,
IsPreSelected = isPreSelected,
Expand All @@ -638,6 +640,7 @@ protected virtual void ImportProductAttribute(PropertyManager<ExportProductAttri
pav.ColorSquaresRgb = colorSquaresRgb;
pav.ImageSquaresPictureId = imageSquaresPictureId;
pav.PriceAdjustment = priceAdjustment;
pav.PriceAdjustmentUsePercentage = priceAdjustmentUsePercentage;
pav.WeightAdjustment = weightAdjustment;
pav.Cost = cost;
pav.CustomerEntersQty = customerEntersQty;
Expand Down Expand Up @@ -837,6 +840,7 @@ public virtual void ImportProductsFromXlsx(Stream stream)
new PropertyByName<ExportProductAttribute>("ColorSquaresRgb"),
new PropertyByName<ExportProductAttribute>("ImageSquaresPictureId"),
new PropertyByName<ExportProductAttribute>("PriceAdjustment"),
new PropertyByName<ExportProductAttribute>("PriceAdjustmentUsePercentage"),
new PropertyByName<ExportProductAttribute>("WeightAdjustment"),
new PropertyByName<ExportProductAttribute>("Cost"),
new PropertyByName<ExportProductAttribute>("CustomerEntersQty"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1792,8 +1792,14 @@
<Value>Price adjustment</Value>
</LocaleResource>
<LocaleResource Name="Admin.Catalog.Attributes.ProductAttributes.PredefinedValues.Fields.PriceAdjustment.Hint">
<Value>The price adjustment applied when choosing this attribute value e.g. '10' to add 10 dollars.</Value>
<Value>The price adjustment applied when choosing this attribute value. For example '10' to add 10 dollars. Or 10% if 'Use percentage' is ticked.</Value>
</LocaleResource>
<LocaleResource Name="Admin.Catalog.Attributes.ProductAttributes.PredefinedValues.Fields.PriceAdjustmentUsePercentage">
<Value>Price adjustment. Use percentage</Value>
</LocaleResource>
<LocaleResource Name="Admin.Catalog.Attributes.ProductAttributes.PredefinedValues.Fields.PriceAdjustmentUsePercentage.Hint">
<Value>Determines whether to apply a percentage to the product. If not enabled, a fixed value is used.</Value>
</LocaleResource>
<LocaleResource Name="Admin.Catalog.Attributes.ProductAttributes.PredefinedValues.Fields.WeightAdjustment">
<Value>Weight adjustment</Value>
</LocaleResource>
Expand Down Expand Up @@ -3634,7 +3640,13 @@
<Value>Price adjustment</Value>
</LocaleResource>
<LocaleResource Name="Admin.Catalog.Products.ProductAttributes.Attributes.Values.Fields.PriceAdjustment.Hint">
<Value>The price adjustment applied when choosing this attribute value e.g. '10' to add 10 dollars.</Value>
<Value>The price adjustment applied when choosing this attribute value. For example '10' to add 10 dollars. Or 10% if 'Use percentage' is ticked.</Value>
</LocaleResource>
<LocaleResource Name="Admin.Catalog.Products.ProductAttributes.Attributes.Values.Fields.PriceAdjustmentUsePercentage">
<Value>Price adjustment. Use percentage</Value>
</LocaleResource>
<LocaleResource Name="Admin.Catalog.Products.ProductAttributes.Attributes.Values.Fields.PriceAdjustmentUsePercentage.Hint">
<Value>Determines whether to apply a percentage to the product. If not enabled, a fixed value is used.</Value>
</LocaleResource>
<LocaleResource Name="Admin.Catalog.Products.ProductAttributes.Attributes.Values.Fields.Quantity">
<Value>Product quantity</Value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -921,7 +921,21 @@ protected virtual OrderModel.AddOrderProductModel.ProductDetailsModel PrepareAdd
{
//price adjustment
var priceAdjustment = _taxService.GetProductPrice(product,
_priceCalculationService.GetProductAttributeValuePriceAdjustment(attributeValue), out taxRate);
_priceCalculationService.GetProductAttributeValuePriceAdjustment(attributeValue, order.Customer), out taxRate);

var priceAdjustmentStr = string.Empty;
if (priceAdjustment != 0)
{
if (attributeValue.PriceAdjustmentUsePercentage)
{
priceAdjustmentStr = attributeValue.PriceAdjustment.ToString("G29");
priceAdjustmentStr = priceAdjustment > 0 ? $"+{priceAdjustmentStr}%" : $"{priceAdjustmentStr}%";
}
else
{
priceAdjustmentStr = priceAdjustment > 0 ? $"+{_priceFormatter.FormatPrice(priceAdjustment, false, false)}" : $"-{_priceFormatter.FormatPrice(-priceAdjustment, false, false)}";
}
}

attributeModel.Values.Add(new OrderModel.AddOrderProductModel.ProductAttributeValueModel
{
Expand All @@ -930,9 +944,7 @@ protected virtual OrderModel.AddOrderProductModel.ProductDetailsModel PrepareAdd
IsPreSelected = attributeValue.IsPreSelected,
CustomerEntersQty = attributeValue.CustomerEntersQty,
Quantity = attributeValue.Quantity,
PriceAdjustment = priceAdjustment == decimal.Zero ? string.Empty : priceAdjustment > decimal.Zero
? string.Concat("+", _priceFormatter.FormatPrice(priceAdjustment, false, false))
: string.Concat("-", _priceFormatter.FormatPrice(-priceAdjustment, false, false)),
PriceAdjustment = priceAdjustmentStr,
PriceAdjustmentValue = priceAdjustment
});
}
Expand Down

0 comments on commit ff9ddf0

Please sign in to comment.