Skip to content

Commit

Permalink
OCC-173: Discount is not applied if there is also another not discoun…
Browse files Browse the repository at this point in the history
…ted product in the shopping cart (#323)

* Potentially fixing discount bug

* Adding discounted product to recipe

* Adding UI test for discount behavior

* Spellinging

* Adding constants to UI test

* Fixing old price display in cart

* Checking for old price in UI test
  • Loading branch information
porgabi authored Aug 5, 2023
1 parent ab7ae5b commit 20d43a5
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 2 deletions.
1 change: 1 addition & 0 deletions .github/actions/spelling/allow/occ.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@ pricefield
roadmap
skus
testproduct
testdiscountedproduct
unpublish
webhooks
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,89 @@
"ProductSku": "TESTFREEPRODUCT"
},
"Product": {}
},
{
"ContentItemId": "testdiscountedproduct000",
"ContentItemVersionId": "[js:uuid()]",
"ContentType": "Product",
"DisplayText": "TestDiscountedProduct",
"Latest": true,
"Published": true,
"ModifiedUtc": "2022-08-10T19:34:57.2678948Z",
"PublishedUtc": "2022-08-10T19:34:57.2716912Z",
"CreatedUtc": "2022-08-10T19:34:57.2678948Z",
"Owner": "48a8p8cbg3ksqvyd14d75x9a59",
"Author": "admin",
"TitlePart": {
"Title": "TestDiscountedProduct"
},
"AutoroutePart": {
"Path": "testdiscountedproduct",
"SetHomepage": false,
"Disabled": false,
"RouteContainedItems": false,
"Absolute": false
},
"HtmlBodyPart": {
"Html": ""
},
"ProductPart": {
"Sku": "TESTDISCOUNTEDPRODUCT"
},
"PricePart": {
"Price": {
"value": 5.0,
"currency": "USD"
}
},
"InventoryPart": {
"Inventory": {
"TESTDISCOUNTEDPRODUCT": 5
},
"InventoryKeys": [
"TESTDISCOUNTEDPRODUCT"
],
"AllowsBackOrder": {
"Value": true
},
"IgnoreInventory": {
"Value": false
},
"MaximumOrderQuantity": {
"Value": 2.0
},
"MinimumOrderQuantity": {
"Value": 1.0
},
"OutOfStockMessage": {
"Html": "A professional out of stock message."
},
"ProductSku": "TESTDISCOUNTEDPRODUCT"
},
"DiscountPart": {
"DiscountPercentage": {
"Value": null
},
"DiscountAmount": {
"Amount": {
"value": 2.0,
"currency": "USD"
}
},
"BeginningUtc": {
"Value": null
},
"ExpirationUtc": {
"Value": null
},
"MaximumProducts": {
"Value": null
},
"MinimumProducts": {
"Value": null
}
},
"Product": {}
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public Task<bool> IsApplicableAsync(PromotionAndTaxProviderContext model) =>
private static bool IsApplicable(
IList<PromotionAndTaxProviderContextLineItem> lineItems,
DateTime? purchaseDateTime) =>
lineItems.All(item => IsApplicablePerItem(item, purchaseDateTime));
lineItems.Any(item => IsApplicablePerItem(item, purchaseDateTime));

private static bool IsApplicablePerItem(PromotionAndTaxProviderContextLineItem item, DateTime? purchaseDateTime)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@

// Determine which price format to use based on corresponding site setting.
var oldPrice = priceDisplaySettings.UseNetPriceDisplay ? oldNetPrice : oldGrossPrice;

// If old gross price is null, old net price is to be used regardless of price display settings.
if (oldGrossPrice == null)
{
oldPrice = oldNetPrice;
}

// Old price should not be shown if there are no discounts.
if (!line.AdditionalData.GetMaybe("Discounts").Any())
{
oldPrice = null;
}
}

<div class="shopping-cart-table-old-price"><del>@oldPrice</del></div>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Lombiq.Tests.UI.Extensions;
using Lombiq.Tests.UI.Services;
using OpenQA.Selenium;
using Shouldly;
using Xunit;
using Xunit.Abstractions;
using static OrchardCore.Commerce.Tests.UI.Constants.ContentItemIds;
Expand All @@ -11,6 +12,8 @@ namespace OrchardCore.Commerce.Tests.UI.Tests.PromotionTests;

public class PromotionBehaviourTests : UITestBase
{
public const string PriceFieldCssSelector = ".price-part-price-field-value";

public PromotionBehaviourTests(ITestOutputHelper testOutputHelper)
: base(testOutputHelper)
{
Expand All @@ -25,7 +28,7 @@ async Task CheckDiscountPresenceAsync(bool hasNewPrice)
{
await context.GoToContentItemByIdAsync(TestProduct);
context.Exists(By.ClassName("price-part-price-field-value"));
context.CheckExistence(By.CssSelector(".price-part-price-field-value del"), hasNewPrice);
context.CheckExistence(By.CssSelector($"{PriceFieldCssSelector} del"), hasNewPrice);
}
await context.ExecuteRecipeDirectlyAsync("OrchardCore.Commerce.Samples.GlobalDiscount");
Expand All @@ -35,4 +38,42 @@ async Task CheckDiscountPresenceAsync(bool hasNewPrice)
await CheckDiscountPresenceAsync(hasNewPrice: true);
},
browser);

[Theory, Chrome]
public Task DiscountShouldProperlyAppearOnDiscountedProduct(Browser browser) =>
ExecuteTestAfterSetupAsync(
async context =>
{
const string FullPrice = "$5.00";
const string DiscountedPrice = "$3.00";
// Discount should appear on discounted product's page.
await context.GoToRelativeUrlAsync("/testdiscountedproduct");
context.Get(By.CssSelector($"{PriceFieldCssSelector} > del")).Text.ShouldBe(FullPrice);
context.Get(By.CssSelector($"{PriceFieldCssSelector} > span")).Text.ShouldBe(DiscountedPrice);
await context.ClickReliablyOnSubmitAsync();
// Discount should appear in cart when discounted product is the only item in the cart.
context.Get(By.CssSelector(".shopping-cart-table-unit-price")).Text.ShouldBe(DiscountedPrice);
// Old price should be shown in cart.
context.Get(By.CssSelector(".shopping-cart-table-old-price > del")).Text.ShouldBe(FullPrice);
// Discount should appear in cart when discounted product is not the only item in the cart.
await context.GoToRelativeUrlAsync("/testproduct");
await context.ClickReliablyOnSubmitAsync();
context.Get(By.CssSelector(".shopping-cart-table-unit-price")).Text.ShouldBe(DiscountedPrice);
// Old price should be shown for discounted product in cart when the cart contains a full-price item too.
context.Get(By.CssSelector(".shopping-cart-table-old-price > del")).Text.ShouldBe(FullPrice);
// Total should reflect discount as well.
context.Get(By.CssSelector(".shopping-cart-table-totals > div")).Text.ShouldBe("$8.00");
// Discount should still appear on discounted product's page when the cart contains a full-price item.
await context.GoToRelativeUrlAsync("/testdiscountedproduct");
context.Get(By.CssSelector($"{PriceFieldCssSelector} > del")).Text.ShouldBe(FullPrice);
context.Get(By.CssSelector($"{PriceFieldCssSelector} > span")).Text.ShouldBe(DiscountedPrice);
},
browser);
}

0 comments on commit 20d43a5

Please sign in to comment.