Skip to content

Commit

Permalink
#1617 Allow customer to apply multiple discount coupon codes
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreiMaz committed Oct 27, 2016
1 parent ba9e9dc commit c184179
Show file tree
Hide file tree
Showing 11 changed files with 232 additions and 59 deletions.
141 changes: 135 additions & 6 deletions src/Libraries/Nop.Services/Customers/CustomerExtensions.cs
Expand Up @@ -82,6 +82,135 @@ public static string FormatUserName(this Customer customer, bool stripTooLong =
return result;
}

/// <summary>
/// Gets coupon codes
/// </summary>
/// <param name="customer">Customer</param>
/// <returns>Coupon codes</returns>
public static string[] ParseAppliedDiscountCouponCodes(this Customer customer)
{
if (customer == null)
throw new ArgumentNullException("customer");

var genericAttributeService = EngineContext.Current.Resolve<IGenericAttributeService>();
var existingCouponCodes = customer.GetAttribute<string>(SystemCustomerAttributeNames.DiscountCouponCode,
genericAttributeService);

var couponCodes = new List<string>();
if (String.IsNullOrEmpty(existingCouponCodes))
return couponCodes.ToArray();

try
{
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(existingCouponCodes);

var nodeList1 = xmlDoc.SelectNodes(@"//DiscountCouponCodes/CouponCode");
foreach (XmlNode node1 in nodeList1)
{
if (node1.Attributes != null && node1.Attributes["Code"] != null)
{
string code = node1.Attributes["Code"].InnerText.Trim();
couponCodes.Add(code);
}
}
}
catch (Exception exc)
{
Debug.Write(exc.ToString());
}
return couponCodes.ToArray();
}
/// <summary>
/// Adds a coupon code
/// </summary>
/// <param name="customer">Customer</param>
/// <param name="couponCode">Coupon code</param>
/// <returns>New coupon codes document</returns>
public static void ApplyDiscountCouponCode(this Customer customer, string couponCode)
{
if (customer == null)
throw new ArgumentNullException("customer");

var genericAttributeService = EngineContext.Current.Resolve<IGenericAttributeService>();
string result = string.Empty;
try
{
var existingCouponCodes = customer.GetAttribute<string>(SystemCustomerAttributeNames.DiscountCouponCode,
genericAttributeService);

couponCode = couponCode.Trim().ToLower();

var xmlDoc = new XmlDocument();
if (String.IsNullOrEmpty(existingCouponCodes))
{
var element1 = xmlDoc.CreateElement("DiscountCouponCodes");
xmlDoc.AppendChild(element1);
}
else
{
xmlDoc.LoadXml(existingCouponCodes);
}
var rootElement = (XmlElement)xmlDoc.SelectSingleNode(@"//DiscountCouponCodes");

XmlElement gcElement = null;
//find existing
var nodeList1 = xmlDoc.SelectNodes(@"//DiscountCouponCodes/CouponCode");
foreach (XmlNode node1 in nodeList1)
{
if (node1.Attributes != null && node1.Attributes["Code"] != null)
{
string couponCodeAttribute = node1.Attributes["Code"].InnerText.Trim();
if (couponCodeAttribute.ToLower() == couponCode.ToLower())
{
gcElement = (XmlElement)node1;
break;
}
}
}

//create new one if not found
if (gcElement == null)
{
gcElement = xmlDoc.CreateElement("CouponCode");
gcElement.SetAttribute("Code", couponCode);
rootElement.AppendChild(gcElement);
}

result = xmlDoc.OuterXml;
}
catch (Exception exc)
{
Debug.Write(exc.ToString());
}

//apply new value
genericAttributeService.SaveAttribute(customer, SystemCustomerAttributeNames.DiscountCouponCode, result);
}
/// <summary>
/// Removes a coupon code
/// </summary>
/// <param name="customer">Customer</param>
/// <param name="couponCode">Coupon code to remove</param>
/// <returns>New coupon codes document</returns>
public static void RemoveDiscountCouponCode(this Customer customer, string couponCode)
{
if (customer == null)
throw new ArgumentNullException("customer");

//get applied coupon codes
var existingCouponCodes = customer.ParseAppliedDiscountCouponCodes();

//clear them
var genericAttributeService = EngineContext.Current.Resolve<IGenericAttributeService>();
genericAttributeService.SaveAttribute<string>(customer, SystemCustomerAttributeNames.DiscountCouponCode, null);

//save again except removed one
foreach (string existingCouponCode in existingCouponCodes)
if (!existingCouponCode.Equals(couponCode, StringComparison.InvariantCultureIgnoreCase))
customer.ApplyDiscountCouponCode(existingCouponCode);
}


/// <summary>
/// Gets coupon codes
Expand All @@ -94,17 +223,17 @@ public static string[] ParseAppliedGiftCardCouponCodes(this Customer customer)
throw new ArgumentNullException("customer");

var genericAttributeService = EngineContext.Current.Resolve<IGenericAttributeService>();
var existingGiftCartCouponCodes = customer.GetAttribute<string>(SystemCustomerAttributeNames.GiftCardCouponCodes,
var existingCouponCodes = customer.GetAttribute<string>(SystemCustomerAttributeNames.GiftCardCouponCodes,
genericAttributeService);

var couponCodes = new List<string>();
if (String.IsNullOrEmpty(existingGiftCartCouponCodes))
if (String.IsNullOrEmpty(existingCouponCodes))
return couponCodes.ToArray();

try
{
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(existingGiftCartCouponCodes);
xmlDoc.LoadXml(existingCouponCodes);

var nodeList1 = xmlDoc.SelectNodes(@"//GiftCardCouponCodes/CouponCode");
foreach (XmlNode node1 in nodeList1)
Expand Down Expand Up @@ -137,20 +266,20 @@ public static void ApplyGiftCardCouponCode(this Customer customer, string coupon
string result = string.Empty;
try
{
var existingGiftCartCouponCodes = customer.GetAttribute<string>(SystemCustomerAttributeNames.GiftCardCouponCodes,
var existingCouponCodes = customer.GetAttribute<string>(SystemCustomerAttributeNames.GiftCardCouponCodes,
genericAttributeService);

couponCode = couponCode.Trim().ToLower();

var xmlDoc = new XmlDocument();
if (String.IsNullOrEmpty(existingGiftCartCouponCodes))
if (String.IsNullOrEmpty(existingCouponCodes))
{
var element1 = xmlDoc.CreateElement("GiftCardCouponCodes");
xmlDoc.AppendChild(element1);
}
else
{
xmlDoc.LoadXml(existingGiftCartCouponCodes);
xmlDoc.LoadXml(existingCouponCodes);
}
var rootElement = (XmlElement)xmlDoc.SelectSingleNode(@"//GiftCardCouponCodes");

Expand Down
36 changes: 26 additions & 10 deletions src/Libraries/Nop.Services/Discounts/DiscountService.cs
Expand Up @@ -9,7 +9,7 @@
using Nop.Core.Domain.Orders;
using Nop.Core.Infrastructure;
using Nop.Core.Plugins;
using Nop.Services.Common;
using Nop.Services.Customers;
using Nop.Services.Discounts.Cache;
using Nop.Services.Events;
using Nop.Services.Localization;
Expand Down Expand Up @@ -54,7 +54,6 @@ public partial class DiscountService : IDiscountService
private readonly IRepository<DiscountUsageHistory> _discountUsageHistoryRepository;
private readonly ICacheManager _cacheManager;
private readonly IStoreContext _storeContext;
private readonly IGenericAttributeService _genericAttributeService;
private readonly ILocalizationService _localizationService;
private readonly IPluginFinder _pluginFinder;
private readonly IEventPublisher _eventPublisher;
Expand All @@ -72,16 +71,15 @@ public partial class DiscountService : IDiscountService
/// <param name="discountRequirementRepository">Discount requirement repository</param>
/// <param name="discountUsageHistoryRepository">Discount usage history repository</param>
/// <param name="storeContext">Store context</param>
/// <param name="genericAttributeService">Generic attribute service</param>
/// <param name="localizationService">Localization service</param>
/// <param name="pluginFinder">Plugin finder</param>
/// <param name="eventPublisher">Event published</param>
/// <param name="workContext">work context</param>
public DiscountService(ICacheManager cacheManager,
IRepository<Discount> discountRepository,
IRepository<DiscountRequirement> discountRequirementRepository,
IRepository<DiscountUsageHistory> discountUsageHistoryRepository,
IStoreContext storeContext,
IGenericAttributeService genericAttributeService,
ILocalizationService localizationService,
IPluginFinder pluginFinder,
IEventPublisher eventPublisher,
Expand All @@ -92,7 +90,6 @@ public partial class DiscountService : IDiscountService
this._discountRequirementRepository = discountRequirementRepository;
this._discountUsageHistoryRepository = discountUsageHistoryRepository;
this._storeContext = storeContext;
this._genericAttributeService = genericAttributeService;
this._localizationService = localizationService;
this._pluginFinder = pluginFinder;
this._eventPublisher = eventPublisher;
Expand Down Expand Up @@ -306,11 +303,11 @@ public virtual DiscountValidationResult ValidateDiscount(Discount discount, Cust
if (discount == null)
throw new ArgumentNullException("discount");

var couponCodeToValidate = "";
string[] couponCodesToValidate = null;
if (customer != null)
couponCodeToValidate = customer.GetAttribute<string>(SystemCustomerAttributeNames.DiscountCouponCode, _genericAttributeService);
couponCodesToValidate = customer.ParseAppliedDiscountCouponCodes();

return ValidateDiscount(discount, customer, couponCodeToValidate);
return ValidateDiscount(discount, customer, couponCodesToValidate);
}

/// <summary>
Expand All @@ -320,7 +317,22 @@ public virtual DiscountValidationResult ValidateDiscount(Discount discount, Cust
/// <param name="customer">Customer</param>
/// <param name="couponCodeToValidate">Coupon code to validate</param>
/// <returns>Discount validation result</returns>
public virtual DiscountValidationResult ValidateDiscount(Discount discount, Customer customer, string couponCodeToValidate)
public virtual DiscountValidationResult ValidateDiscount(Discount discount, Customer customer,
string couponCodeToValidate)
{
var couponCodesToValidate = new string[1];
couponCodesToValidate[0] = couponCodeToValidate;
return ValidateDiscount(discount, customer, couponCodesToValidate);
}

/// <summary>
/// Validate discount
/// </summary>
/// <param name="discount">Discount</param>
/// <param name="customer">Customer</param>
/// <param name="couponCodesToValidate">Coupon codes to validate</param>
/// <returns>Discount validation result</returns>
public virtual DiscountValidationResult ValidateDiscount(Discount discount, Customer customer, string[] couponCodesToValidate)
{
if (discount == null)
throw new ArgumentNullException("discount");
Expand All @@ -336,7 +348,11 @@ public virtual DiscountValidationResult ValidateDiscount(Discount discount, Cust
{
if (String.IsNullOrEmpty(discount.CouponCode))
return result;
if (!discount.CouponCode.Equals(couponCodeToValidate, StringComparison.InvariantCultureIgnoreCase))

if (couponCodesToValidate == null)
return result;

if (!couponCodesToValidate.Any(x => x.Equals(discount.CouponCode, StringComparison.InvariantCultureIgnoreCase)))
return result;
}

Expand Down
9 changes: 9 additions & 0 deletions src/Libraries/Nop.Services/Discounts/IDiscountService.cs
Expand Up @@ -101,6 +101,15 @@ public partial interface IDiscountService
/// <returns>Discount validation result</returns>
DiscountValidationResult ValidateDiscount(Discount discount, Customer customer, string couponCodeToValidate);

/// <summary>
/// Validate discount
/// </summary>
/// <param name="discount">Discount</param>
/// <param name="customer">Customer</param>
/// <param name="couponCodesToValidate">Coupon codes to validate</param>
/// <returns>Discount validation result</returns>
DiscountValidationResult ValidateDiscount(Discount discount, Customer customer, string[] couponCodesToValidate);

#endregion

#region Discount usage history
Expand Down
15 changes: 7 additions & 8 deletions src/Libraries/Nop.Services/Orders/ShoppingCartService.cs
Expand Up @@ -1267,18 +1267,17 @@ public virtual void MigrateShoppingCart(Customer fromCustomer, Customer toCustom
var sci = fromCart[i];
DeleteShoppingCartItem(sci);
}
//migrate gift card and discount coupon codes

//copy discount and gift card coupon codes
if (includeCouponCodes)
{
//discount
var discountCouponCode = fromCustomer.GetAttribute<string>(SystemCustomerAttributeNames.DiscountCouponCode);
if (!String.IsNullOrEmpty(discountCouponCode))
_genericAttributeService.SaveAttribute(toCustomer, SystemCustomerAttributeNames.DiscountCouponCode, discountCouponCode);

foreach (var code in fromCustomer.ParseAppliedDiscountCouponCodes())
toCustomer.ApplyDiscountCouponCode(code);

//gift card
foreach (var gcCode in fromCustomer.ParseAppliedGiftCardCouponCodes())
toCustomer.ApplyGiftCardCouponCode(gcCode);
foreach (var code in fromCustomer.ParseAppliedGiftCardCouponCodes())
toCustomer.ApplyGiftCardCouponCode(code);

//save customer
_customerService.UpdateCustomer(toCustomer);
Expand Down

0 comments on commit c184179

Please sign in to comment.