Skip to content

Commit 1c749af

Browse files
N8haxSWE CMS
andauthored
Fixing Coupon Issue (#1041)
* Fixing Coupon Issue: 1.MaxDiscountAmount wasn't applied. 2.Coupon usage limit was per product now it's per order * Adding Arabic to default supported language * Enhance Searching Functionality. Search within localized properties. Also search in Product Description and Specification * Fix Duplication of localized resources * Search Ehnancements. Get brand from search and add as a filter. --------- Co-authored-by: SWE CMS <swe-cms@outlook.com>
1 parent 8c5d01a commit 1c749af

6 files changed

Lines changed: 52 additions & 28 deletions

File tree

src/Modules/SimplCommerce.Module.Catalog/Services/ProductService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace SimplCommerce.Module.Catalog.Services
77
{
88
public class ProductService : IProductService
99
{
10-
private const string ProductEntityTypeId = "Product";
10+
private const string ProductEntityTypeId = nameof(Product);
1111

1212
private readonly IRepository<Product> _productRepository;
1313
private readonly IEntityService _entityService;

src/Modules/SimplCommerce.Module.Localization/EFStringLocalizer.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,18 @@ private void AutoRegisterNewString(string name, string culture)
7676
using (var scope = _serviceProvider.CreateScope())
7777
{
7878
var resourceRepository = scope.ServiceProvider.GetRequiredService<IRepository<Resource>>();
79-
79+
//Avoid duplications
80+
if (resourceRepository.Query().Any(x => x.CultureId == culture && x.Key.ToLower() == name.ToLower()))
81+
{
82+
return;
83+
}
8084
var res = new Resource()
8185
{
8286
CultureId = culture,
8387
Key = name,
8488
Value = name
8589
};
86-
90+
8791
resourceRepository.Add(res);
8892
resourceRepository.SaveChanges();
8993

src/Modules/SimplCommerce.Module.Pricing/Services/CouponService.cs

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public async Task<CouponValidationResult> Validate(long customerId, string coupo
3131
.FirstOrDefaultAsync(x => x.Code == couponCode);
3232
var validationResult = new CouponValidationResult { Succeeded = false };
3333

34-
if(coupon == null || !coupon.CartRule.IsActive)
34+
if (coupon == null || !coupon.CartRule.IsActive)
3535
{
3636
validationResult.ErrorMessage = $"The coupon {couponCode} is not exist.";
3737
return validationResult;
@@ -50,7 +50,7 @@ public async Task<CouponValidationResult> Validate(long customerId, string coupo
5050
}
5151

5252
var couponUsageCount = _cartRuleUsageRepository.Query().Count(x => x.CouponId == coupon.Id);
53-
if(coupon.CartRule.UsageLimitPerCoupon.HasValue && couponUsageCount >= coupon.CartRule.UsageLimitPerCoupon)
53+
if (coupon.CartRule.UsageLimitPerCoupon.HasValue && couponUsageCount >= coupon.CartRule.UsageLimitPerCoupon)
5454
{
5555
validationResult.ErrorMessage = $"The coupon {couponCode} is all used.";
5656
return validationResult;
@@ -64,7 +64,7 @@ public async Task<CouponValidationResult> Validate(long customerId, string coupo
6464
}
6565

6666
IList<DiscountableProduct> discountableProducts = new List<DiscountableProduct>();
67-
if(!coupon.CartRule.Products.Any() && !coupon.CartRule.Categories.Any())
67+
if (!coupon.CartRule.Products.Any() && !coupon.CartRule.Categories.Any())
6868
{
6969
var productIds = cart.Items.Select(x => x.ProductId);
7070
discountableProducts = _productRepository.Query()
@@ -87,22 +87,7 @@ public async Task<CouponValidationResult> Validate(long customerId, string coupo
8787
var discountableProduct = discountableProducts.FirstOrDefault(x => x.Id == item.ProductId);
8888
if (discountableProduct != null)
8989
{
90-
var discountedProduct = new DiscountedProduct { Id = discountableProduct.Id, Name = discountableProduct.Name, Price = discountableProduct.Price, Quantity = 1 };
91-
couponUsageCount = couponUsageCount + 1;
92-
couponUsageByCustomerCount = couponUsageByCustomerCount + 1;
93-
for (var i = 1; i < item.Quantity; i++)
94-
{
95-
if ((coupon.CartRule.UsageLimitPerCoupon.HasValue && couponUsageCount >= coupon.CartRule.UsageLimitPerCoupon) ||
96-
(coupon.CartRule.UsageLimitPerCustomer.HasValue && couponUsageByCustomerCount >= coupon.CartRule.UsageLimitPerCustomer))
97-
{
98-
break;
99-
}
100-
101-
discountedProduct.Quantity = discountedProduct.Quantity + 1;
102-
couponUsageCount = couponUsageCount + 1;
103-
couponUsageByCustomerCount = couponUsageByCustomerCount + 1;
104-
}
105-
90+
var discountedProduct = new DiscountedProduct { Id = discountableProduct.Id, Name = discountableProduct.Name, Price = discountableProduct.Price, Quantity = item.Quantity };
10691
validationResult.DiscountedProducts.Add(discountedProduct);
10792
}
10893
}
@@ -122,13 +107,15 @@ public async Task<CouponValidationResult> Validate(long customerId, string coupo
122107
switch (coupon.CartRule.RuleToApply)
123108
{
124109
case "cart_fixed":
125-
validationResult.DiscountAmount = coupon.CartRule.DiscountAmount;
110+
validationResult.DiscountAmount = Math.Min(coupon.CartRule.DiscountAmount, coupon.CartRule.MaxDiscountAmount.GetValueOrDefault(decimal.MaxValue));
126111
return validationResult;
127112

128113
case "by_percent":
129-
foreach(var item in validationResult.DiscountedProducts)
114+
var maxDiscountAmount = coupon.CartRule.MaxDiscountAmount.GetValueOrDefault(decimal.MaxValue);
115+
foreach (var item in validationResult.DiscountedProducts)
130116
{
131-
item.DiscountAmount = (item.Price * coupon.CartRule.DiscountAmount / 100) * item.Quantity;
117+
item.DiscountAmount = Math.Min((item.Price * coupon.CartRule.DiscountAmount / 100) * item.Quantity, maxDiscountAmount);
118+
maxDiscountAmount -= item.DiscountAmount;
132119
}
133120

134121
validationResult.DiscountAmount = validationResult.DiscountedProducts.Sum(x => x.DiscountAmount);

src/Modules/SimplCommerce.Module.Search/Areas/Search/Controllers/SearchController.cs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
using Microsoft.EntityFrameworkCore;
55
using Microsoft.Extensions.Configuration;
66
using SimplCommerce.Infrastructure.Data;
7+
using SimplCommerce.Infrastructure.Localization;
78
using SimplCommerce.Module.Catalog.Areas.Catalog.ViewModels;
89
using SimplCommerce.Module.Catalog.Models;
910
using SimplCommerce.Module.Catalog.Services;
11+
using SimplCommerce.Module.Core.Data;
1012
using SimplCommerce.Module.Core.Services;
1113
using SimplCommerce.Module.Search.Areas.Search.ViewModels;
1214
using SimplCommerce.Module.Search.Models;
@@ -21,6 +23,7 @@ public class SearchController : Controller
2123
private readonly IRepository<Product> _productRepository;
2224
private readonly IRepository<Brand> _brandRepository;
2325
private readonly IRepository<Category> _categoryRepository;
26+
private readonly IRepository<LocalizedContentProperty> _localizedContentPropertyRepository;
2427
private readonly IMediaService _mediaService;
2528
private readonly IRepository<Query> _queryRepository;
2629
private readonly IProductPricingService _productPricingService;
@@ -29,6 +32,7 @@ public class SearchController : Controller
2932
public SearchController(IRepository<Product> productRepository,
3033
IRepository<Brand> brandRepository,
3134
IRepository<Category> categoryRepository,
35+
IRepository<LocalizedContentProperty> localizedContentPropertyRepository,
3236
IMediaService mediaService,
3337
IRepository<Query> queryRepository,
3438
IProductPricingService productPricingService,
@@ -38,6 +42,7 @@ public SearchController(IRepository<Product> productRepository,
3842
_productRepository = productRepository;
3943
_brandRepository = brandRepository;
4044
_categoryRepository = categoryRepository;
45+
_localizedContentPropertyRepository = localizedContentPropertyRepository;
4146
_mediaService = mediaService;
4247
_queryRepository = queryRepository;
4348
_productPricingService = productPricingService;
@@ -48,24 +53,47 @@ public SearchController(IRepository<Product> productRepository,
4853
[HttpGet("search")]
4954
public IActionResult Index(SearchOption searchOption)
5055
{
56+
// Case no query
5157
if (string.IsNullOrWhiteSpace(searchOption.Query))
5258
{
5359
return Redirect("~/");
5460
}
5561

62+
// Case searching for specific brand
5663
var brand = _brandRepository.Query().FirstOrDefault(x => x.Name == searchOption.Query && x.IsPublished);
5764
if (brand != null)
5865
{
5966
return Redirect(string.Format("~/{0}", brand.Slug));
6067
}
6168

69+
// Case brand included in the query
70+
var includedBrand = _brandRepository.Query().FirstOrDefault(x => searchOption.Query.Contains(x.Name) && x.IsPublished);
71+
if (includedBrand != null)
72+
{
73+
searchOption.Query = searchOption.Query.Replace(includedBrand.Name, "", StringComparison.OrdinalIgnoreCase);
74+
}
75+
76+
searchOption.Query = searchOption.Query.Trim();
77+
6278
var model = new SearchResult
6379
{
6480
CurrentSearchOption = searchOption,
6581
FilterOption = new FilterOption()
6682
};
6783

68-
var query = _productRepository.Query().Where(x => x.Name.Contains(searchOption.Query) && x.IsPublished && x.IsVisibleIndividually);
84+
var matchedLocalizedProductIds = _localizedContentPropertyRepository.Query().Where(x => x.EntityType == nameof(Product)
85+
&& x.Value.ToLower().Contains(searchOption.Query.ToLower()))
86+
.Select(x => x.EntityId)
87+
.Distinct()
88+
.ToList();
89+
90+
var query = _productRepository.Query().Where(x =>
91+
x.IsPublished && x.IsVisibleIndividually &&
92+
(matchedLocalizedProductIds.Contains(x.Id)
93+
|| x.Name.ToLower().Contains(searchOption.Query.ToLower())
94+
|| x.ShortDescription.ToLower().Contains(searchOption.Query.ToLower())
95+
|| x.Description.ToLower().Contains(searchOption.Query.ToLower())
96+
|| x.Specification.ToLower().Contains(searchOption.Query.ToLower())));
6997

7098
if (!query.Any())
7199
{
@@ -98,7 +126,7 @@ public IActionResult Index(SearchOption searchOption)
98126
var brands = searchOption.GetBrands().ToArray();
99127
if (brands.Any())
100128
{
101-
query = query.Where(x => x.BrandId.HasValue && brands.Contains(x.Brand.Slug));
129+
query = query.Where(x => (x.BrandId.HasValue && brands.Contains(x.Brand.Slug) || (includedBrand != null && x.BrandId == includedBrand.Id)));
102130
}
103131

104132
model.TotalProduct = query.Count();

src/Modules/SimplCommerce.Module.Search/SimplCommerce.Module.Search.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<ProjectReference Include="..\..\SimplCommerce.Infrastructure\SimplCommerce.Infrastructure.csproj" />
1313
<ProjectReference Include="..\SimplCommerce.Module.Catalog\SimplCommerce.Module.Catalog.csproj" />
1414
<ProjectReference Include="..\SimplCommerce.Module.Core\SimplCommerce.Module.Core.csproj" />
15+
<ProjectReference Include="..\SimplCommerce.Module.Localization\SimplCommerce.Module.Localization.csproj" />
1516
</ItemGroup>
1617

1718
</Project>

src/SimplCommerce.WebHost/Migrations/20190212090153_SimplCommerce_v1_0_0.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2194,7 +2194,11 @@ protected override void Up(MigrationBuilder migrationBuilder)
21942194
migrationBuilder.InsertData(
21952195
table: "Localization_Culture",
21962196
columns: new[] { "Id", "Name" },
2197-
values: new object[] { "en-US", "English (US)" });
2197+
values: new object[,]
2198+
{
2199+
{"en-US", "English (US)"},
2200+
{"ar-Eg", "Arabic (Egypt)" }
2201+
});
21982202

21992203
migrationBuilder.InsertData(
22002204
table: "Payments_PaymentProvider",

0 commit comments

Comments
 (0)