diff --git a/Directory.Build.props b/Directory.Build.props
index 96d2b1a..7fd974b 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -2,7 +2,7 @@
- 3.820.0
+ 3.822.0
$(VersionSuffix)-$(BuildNumber)
diff --git a/src/VirtoCommerce.XCart.Core/Extensions/RewardExtensions.cs b/src/VirtoCommerce.XCart.Core/Extensions/RewardExtensions.cs
index 844f69a..f66d704 100644
--- a/src/VirtoCommerce.XCart.Core/Extensions/RewardExtensions.cs
+++ b/src/VirtoCommerce.XCart.Core/Extensions/RewardExtensions.cs
@@ -4,6 +4,7 @@
using System.Threading.Tasks;
using VirtoCommerce.CartModule.Core.Model;
using VirtoCommerce.CoreModule.Core.Common;
+using VirtoCommerce.CoreModule.Core.Currency;
using VirtoCommerce.MarketingModule.Core.Model.Promotions;
using VirtoCommerce.PaymentModule.Core.Model;
using VirtoCommerce.Platform.Core.Common;
@@ -13,19 +14,19 @@ namespace VirtoCommerce.XCart.Core.Extensions
{
public static class RewardExtensions
{
- public static void ApplyRewards(this PaymentMethod paymentMethod, ICollection rewards)
+ public static void ApplyRewards(this PaymentMethod paymentMethod, Currency currency, ICollection rewards)
=> paymentMethod.DiscountAmount = rewards
.Where(r => r.IsValid)
.OfType()
.Where(r => r.PaymentMethod.IsNullOrEmpty() || r.PaymentMethod.EqualsInvariant(paymentMethod.Code))
- .Sum(reward => reward.GetRewardAmount(paymentMethod.Price - paymentMethod.DiscountAmount, 1));
+ .Sum(reward => reward.GetTotalAmount(paymentMethod.Price - paymentMethod.DiscountAmount, 1, currency));
- public static void ApplyRewards(this ShippingRate shippingRate, ICollection rewards)
+ public static void ApplyRewards(this ShippingRate shippingRate, Currency currency, ICollection rewards)
=> shippingRate.DiscountAmount = rewards
.Where(r => r.IsValid)
.OfType()
.Where(r => r.ShippingMethod.IsNullOrEmpty() || shippingRate.ShippingMethod != null && r.ShippingMethod.EqualsInvariant(shippingRate.ShippingMethod.Code))
- .Sum(reward => reward.GetRewardAmount(shippingRate.Rate, 1));
+ .Sum(reward => reward.GetTotalAmount(shippingRate.Rate, 1, currency));
public static void ApplyRewards(this CartAggregate aggregate, ICollection rewards)
{
@@ -46,7 +47,7 @@ public static void ApplyRewards(this CartAggregate aggregate, ICollection rewards)
+ public static void ApplyRewards(this LineItem lineItem, Currency currency, IEnumerable rewards)
{
var lineItemRewards = rewards
.Where(r => r.IsValid)
@@ -54,6 +55,7 @@ public static void ApplyRewards(this LineItem lineItem, string currency, IEnumer
lineItem.Discounts?.Clear();
lineItem.DiscountAmount = Math.Max(0, lineItem.ListPrice - lineItem.SalePrice);
+ lineItem.IsDiscountAmountRounded = true;
if (lineItem.Quantity == 0)
{
@@ -65,14 +67,14 @@ public static void ApplyRewards(this LineItem lineItem, string currency, IEnumer
var discount = new Discount
{
Coupon = reward.Coupon,
- Currency = currency,
+ Currency = currency.Code,
PromotionId = reward.PromotionId ?? reward.Promotion?.Id,
Name = reward.Promotion?.Name,
Description = reward.Promotion?.Description,
- DiscountAmount = reward.GetRewardAmount(lineItem.ListPrice - lineItem.DiscountAmount, lineItem.Quantity),
+ DiscountAmount = reward.GetAmountPerItem(lineItem.ListPrice - lineItem.DiscountAmount, lineItem.Quantity, currency),
};
- // Pass invalid discounts
+ // Skip invalid discounts
if (discount.DiscountAmount <= 0)
{
continue;
@@ -81,10 +83,11 @@ public static void ApplyRewards(this LineItem lineItem, string currency, IEnumer
lineItem.Discounts ??= new List();
lineItem.Discounts.Add(discount);
lineItem.DiscountAmount += discount.DiscountAmount;
+ lineItem.IsDiscountAmountRounded &= reward.RoundAmountPerItem;
}
}
- public static void ApplyRewards(this Shipment shipment, string currency, IEnumerable rewards)
+ public static void ApplyRewards(this Shipment shipment, Currency currency, IEnumerable rewards)
{
var shipmentRewards = rewards
.Where(r => r.IsValid)
@@ -98,11 +101,11 @@ public static void ApplyRewards(this Shipment shipment, string currency, IEnumer
var discount = new Discount
{
Coupon = reward.Coupon,
- Currency = currency,
+ Currency = currency.Code,
PromotionId = reward.PromotionId ?? reward.Promotion?.Id,
Name = reward.Promotion?.Name,
Description = reward.Promotion?.Description,
- DiscountAmount = reward.GetRewardAmount(shipment.Price - shipment.DiscountAmount, 1),
+ DiscountAmount = reward.GetTotalAmount(shipment.Price - shipment.DiscountAmount, 1, currency),
};
// Pass invalid discounts
@@ -116,7 +119,7 @@ public static void ApplyRewards(this Shipment shipment, string currency, IEnumer
}
}
- public static void ApplyRewards(this Payment payment, string currency, IEnumerable rewards)
+ public static void ApplyRewards(this Payment payment, Currency currency, IEnumerable rewards)
{
var paymentRewards = rewards
.Where(r => r.IsValid)
@@ -130,11 +133,11 @@ public static void ApplyRewards(this Payment payment, string currency, IEnumerab
var discount = new Discount
{
Coupon = reward.Coupon,
- Currency = currency,
+ Currency = currency.Code,
PromotionId = reward.PromotionId ?? reward.Promotion?.Id,
Name = reward.Promotion?.Name,
Description = reward.Promotion?.Description,
- DiscountAmount = reward.GetRewardAmount(payment.Price - payment.DiscountAmount, 1),
+ DiscountAmount = reward.GetTotalAmount(payment.Price - payment.DiscountAmount, 1, currency),
};
// Pass invalid discounts
@@ -167,13 +170,12 @@ public static async Task ApplyRewardsAsync(this CartAggregate aggregate, ICollec
// automatically add gift rewards to line items if the setting is enabled
if (aggregate.IsSelectedForCheckout)
{
- var availableGifts = await aggregate.GetAvailableGiftsAsync(rewards);
+ var availableGifts = (await aggregate.GetAvailableGiftsAsync(rewards)).ToList();
- if (availableGifts.Any())
+ if (availableGifts.Count > 0)
{
- var newGiftItems = availableGifts.Where(x => !x.HasLineItem).ToList(); //get new items
- var newGiftItemIds = newGiftItems.Select(x => x.Id).ToList();
- await aggregate.AddGiftItemsAsync(newGiftItemIds, availableGifts.ToList()); //add new items to cart
+ var newGiftItemIds = availableGifts.Where(x => !x.HasLineItem).Select(x => x.Id).ToList();
+ await aggregate.AddGiftItemsAsync(newGiftItemIds, availableGifts); //add new items to cart
}
}
@@ -184,22 +186,22 @@ private static void ApplyCartRewardsInternal(CartAggregate aggregate, ICollectio
{
var shoppingCart = aggregate.Cart;
- var lineItemRewards = rewards.OfType();
- foreach (var lineItem in aggregate.LineItems ?? Enumerable.Empty())
+ var lineItemRewards = rewards.OfType().ToList();
+ foreach (var lineItem in aggregate.LineItems ?? [])
{
- lineItem.ApplyRewards(shoppingCart.Currency, lineItemRewards);
+ lineItem.ApplyRewards(aggregate.Currency, lineItemRewards);
}
- var shipmentRewards = rewards.OfType();
+ var shipmentRewards = rewards.OfType().ToList();
foreach (var shipment in shoppingCart.Shipments ?? Enumerable.Empty())
{
- shipment.ApplyRewards(shoppingCart.Currency, shipmentRewards);
+ shipment.ApplyRewards(aggregate.Currency, shipmentRewards);
}
- var paymentRewards = rewards.OfType();
+ var paymentRewards = rewards.OfType().ToList();
foreach (var payment in shoppingCart.Payments ?? Enumerable.Empty())
{
- payment.ApplyRewards(shoppingCart.Currency, paymentRewards);
+ payment.ApplyRewards(aggregate.Currency, paymentRewards);
}
var subTotalExcludeDiscount = shoppingCart.Items.Where(li => li.SelectedForCheckout).Sum(li => (li.ListPrice - li.DiscountAmount) * li.Quantity);
@@ -217,7 +219,7 @@ private static void ApplyCartRewardsInternal(CartAggregate aggregate, ICollectio
PromotionId = reward.PromotionId ?? reward.Promotion?.Id,
Name = reward.Promotion?.Name,
Description = reward.Promotion?.Description,
- DiscountAmount = reward.GetRewardAmount(subTotalExcludeDiscount, 1),
+ DiscountAmount = reward.GetTotalAmount(subTotalExcludeDiscount, 1, aggregate.Currency),
};
shoppingCart.Discounts ??= new List();
diff --git a/src/VirtoCommerce.XCart.Core/Schemas/LineItemType.cs b/src/VirtoCommerce.XCart.Core/Schemas/LineItemType.cs
index 8b2ff2f..9c6a05d 100644
--- a/src/VirtoCommerce.XCart.Core/Schemas/LineItemType.cs
+++ b/src/VirtoCommerce.XCart.Core/Schemas/LineItemType.cs
@@ -144,6 +144,15 @@ public LineItemType(
Field>("listPriceWithTax",
"List price with tax",
resolve: context => context.Source.ListPriceWithTax.ToMoney(context.GetCart().Currency));
+ Field>("listTotal",
+ "List total",
+ resolve: context => context.Source.ListTotal.ToMoney(context.GetCart().Currency));
+ Field>("listTotalWithTax",
+ "List total with tax",
+ resolve: context => context.Source.ListTotalWithTax.ToMoney(context.GetCart().Currency));
+ Field>("showPlacedPrice",
+ "Indicates whether the PlacedPrice should be visible to the customer",
+ resolve: context => context.Source.IsDiscountAmountRounded);
Field>("placedPrice",
"Placed price",
resolve: context => context.Source.PlacedPrice.ToMoney(context.GetCart().Currency));
diff --git a/src/VirtoCommerce.XCart.Core/VirtoCommerce.XCart.Core.csproj b/src/VirtoCommerce.XCart.Core/VirtoCommerce.XCart.Core.csproj
index e70ca11..df12ae5 100644
--- a/src/VirtoCommerce.XCart.Core/VirtoCommerce.XCart.Core.csproj
+++ b/src/VirtoCommerce.XCart.Core/VirtoCommerce.XCart.Core.csproj
@@ -10,13 +10,13 @@
-
-
-
-
-
+
-
+
+
+
+
+
\ No newline at end of file
diff --git a/src/VirtoCommerce.XCart.Data/Services/CartAvailMethodsService.cs b/src/VirtoCommerce.XCart.Data/Services/CartAvailMethodsService.cs
index 904a2fb..d927d66 100644
--- a/src/VirtoCommerce.XCart.Data/Services/CartAvailMethodsService.cs
+++ b/src/VirtoCommerce.XCart.Data/Services/CartAvailMethodsService.cs
@@ -53,7 +53,7 @@ public async Task> GetAvailableShippingRatesAsync(Cart
{
if (cartAggregate == null)
{
- return Enumerable.Empty();
+ return [];
}
//Request available shipping rates
@@ -75,7 +75,7 @@ public async Task> GetAvailableShippingRatesAsync(Cart
if (availableShippingRates.IsNullOrEmpty())
{
- return Enumerable.Empty();
+ return [];
}
//Evaluate promotions cart and apply rewards for available shipping methods
@@ -90,7 +90,7 @@ public async Task> GetAvailableShippingRatesAsync(Cart
var promoEvalResult = await cartAggregate.EvaluatePromotionsAsync(evalContextCartMap.PromotionEvaluationContext);
foreach (var shippingRate in availableShippingRates)
{
- shippingRate.ApplyRewards(promoEvalResult.Rewards);
+ shippingRate.ApplyRewards(cartAggregate.Currency, promoEvalResult.Rewards);
}
var taxProvider = await GetActiveTaxProviderAsync(cartAggregate);
@@ -115,7 +115,7 @@ public async Task> GetAvailablePaymentMethodsAsync(Ca
{
if (cartAggregate == null)
{
- return Enumerable.Empty();
+ return [];
}
var criteria = new PaymentMethodsSearchCriteria
@@ -128,7 +128,7 @@ public async Task> GetAvailablePaymentMethodsAsync(Ca
var result = await _paymentMethodsSearchService.SearchAsync(criteria);
if (result.Results.IsNullOrEmpty())
{
- return Enumerable.Empty();
+ return [];
}
var evalContext = AbstractTypeFactory.TryCreateInstance();
@@ -143,7 +143,7 @@ public async Task> GetAvailablePaymentMethodsAsync(Ca
foreach (var paymentMethod in result.Results)
{
- paymentMethod.ApplyRewards(promoResult.Rewards);
+ paymentMethod.ApplyRewards(cartAggregate.Currency, promoResult.Rewards);
}
//Evaluate taxes for available payments
diff --git a/src/VirtoCommerce.XCart.Web/Localizations/de.XCart.json b/src/VirtoCommerce.XCart.Web/Localizations/de.XCart.json
new file mode 100644
index 0000000..0177fa7
--- /dev/null
+++ b/src/VirtoCommerce.XCart.Web/Localizations/de.XCart.json
@@ -0,0 +1,8 @@
+{
+ "permissions": {
+ "XCart:create": "xCart-bezogene Daten erstellen",
+ "XCart:read": "xCart-bezogene Daten anzeigen",
+ "XCart:update": "xCart-bezogene Daten aktualisieren",
+ "XCart:delete": "xCart-bezogene Daten löschen"
+ }
+}
diff --git a/src/VirtoCommerce.XCart.Web/Localizations/en.XCart.json b/src/VirtoCommerce.XCart.Web/Localizations/en.XCart.json
index a6495c7..b4b4b48 100644
--- a/src/VirtoCommerce.XCart.Web/Localizations/en.XCart.json
+++ b/src/VirtoCommerce.XCart.Web/Localizations/en.XCart.json
@@ -1,8 +1,8 @@
{
"permissions": {
- "XCart:create": "Create XCart related data",
- "XCart:read": "View XCart related data",
- "XCart:update": "Update XCart related data",
- "XCart:delete": "Delete XCart related data"
+ "XCart:create": "Create xCart related data",
+ "XCart:read": "View xCart related data",
+ "XCart:update": "Update xCart related data",
+ "XCart:delete": "Delete xCart related data"
}
}
diff --git a/src/VirtoCommerce.XCart.Web/Localizations/es.XCart.json b/src/VirtoCommerce.XCart.Web/Localizations/es.XCart.json
new file mode 100644
index 0000000..4b95322
--- /dev/null
+++ b/src/VirtoCommerce.XCart.Web/Localizations/es.XCart.json
@@ -0,0 +1,8 @@
+{
+ "permissions": {
+ "XCart:create": "Crear datos relacionados con xCart",
+ "XCart:read": "Ver datos relacionados con xCart",
+ "XCart:update": "Actualizar datos relacionados con xCart",
+ "XCart:delete": "Eliminar datos relacionados con xCart"
+ }
+}
diff --git a/src/VirtoCommerce.XCart.Web/Localizations/fr.XCart.json b/src/VirtoCommerce.XCart.Web/Localizations/fr.XCart.json
new file mode 100644
index 0000000..47994d9
--- /dev/null
+++ b/src/VirtoCommerce.XCart.Web/Localizations/fr.XCart.json
@@ -0,0 +1,8 @@
+{
+ "permissions": {
+ "XCart:create": "Créer des données liées à xCart",
+ "XCart:read": "Afficher les données liées à xCart",
+ "XCart:update": "Mettre à jour les données liées à xCart",
+ "XCart:delete": "Supprimer les données liées à xCart"
+ }
+}
diff --git a/src/VirtoCommerce.XCart.Web/Localizations/it.XCart.json b/src/VirtoCommerce.XCart.Web/Localizations/it.XCart.json
new file mode 100644
index 0000000..8dc387c
--- /dev/null
+++ b/src/VirtoCommerce.XCart.Web/Localizations/it.XCart.json
@@ -0,0 +1,8 @@
+{
+ "permissions": {
+ "XCart:create": "Creare dati relativi a xCart",
+ "XCart:read": "Visualizzare dati relativi a xCart",
+ "XCart:update": "Aggiornare dati relativi a xCart",
+ "XCart:delete": "Eliminare dati relativi a xCart"
+ }
+}
diff --git a/src/VirtoCommerce.XCart.Web/Localizations/ja.XCart.json b/src/VirtoCommerce.XCart.Web/Localizations/ja.XCart.json
new file mode 100644
index 0000000..c326458
--- /dev/null
+++ b/src/VirtoCommerce.XCart.Web/Localizations/ja.XCart.json
@@ -0,0 +1,8 @@
+{
+ "permissions": {
+ "XCart:create": "xCart 関連データを作成",
+ "XCart:read": "xCart 関連データを表示",
+ "XCart:update": "xCart 関連データを更新",
+ "XCart:delete": "xCart 関連データを削除"
+ }
+}
diff --git a/src/VirtoCommerce.XCart.Web/Localizations/pl.XCart.json b/src/VirtoCommerce.XCart.Web/Localizations/pl.XCart.json
new file mode 100644
index 0000000..43a15fb
--- /dev/null
+++ b/src/VirtoCommerce.XCart.Web/Localizations/pl.XCart.json
@@ -0,0 +1,8 @@
+{
+ "permissions": {
+ "XCart:create": "Tworzenie danych powiązanych z xCart",
+ "XCart:read": "Wyświetlanie danych powiązanych z xCart",
+ "XCart:update": "Aktualizowanie danych powiązanych z xCart",
+ "XCart:delete": "Usuwanie danych powiązanych z xCart"
+ }
+}
diff --git a/src/VirtoCommerce.XCart.Web/Localizations/pt.XCart.json b/src/VirtoCommerce.XCart.Web/Localizations/pt.XCart.json
new file mode 100644
index 0000000..a94e0e9
--- /dev/null
+++ b/src/VirtoCommerce.XCart.Web/Localizations/pt.XCart.json
@@ -0,0 +1,8 @@
+{
+ "permissions": {
+ "XCart:create": "Criar dados relacionados ao xCart",
+ "XCart:read": "Visualizar dados relacionados ao xCart",
+ "XCart:update": "Atualizar dados relacionados ao xCart",
+ "XCart:delete": "Excluir dados relacionados ao xCart"
+ }
+}
diff --git a/src/VirtoCommerce.XCart.Web/Localizations/ru.XCart.json b/src/VirtoCommerce.XCart.Web/Localizations/ru.XCart.json
new file mode 100644
index 0000000..39133a7
--- /dev/null
+++ b/src/VirtoCommerce.XCart.Web/Localizations/ru.XCart.json
@@ -0,0 +1,8 @@
+{
+ "permissions": {
+ "XCart:create": "Создать данные, связанные с xCart",
+ "XCart:read": "Просмотреть данные, связанные с xCart",
+ "XCart:update": "Обновить данные, связанные с xCart",
+ "XCart:delete": "Удалить данные, связанные с xCart"
+ }
+}
diff --git a/src/VirtoCommerce.XCart.Web/Localizations/zh.XCart.json b/src/VirtoCommerce.XCart.Web/Localizations/zh.XCart.json
new file mode 100644
index 0000000..181345c
--- /dev/null
+++ b/src/VirtoCommerce.XCart.Web/Localizations/zh.XCart.json
@@ -0,0 +1,8 @@
+{
+ "permissions": {
+ "XCart:create": "创建与 xCart 相关的数据",
+ "XCart:read": "查看与 xCart 相关的数据",
+ "XCart:update": "更新与 xCart 相关的数据",
+ "XCart:delete": "删除与 xCart 相关的数据"
+ }
+}
diff --git a/src/VirtoCommerce.XCart.Web/module.manifest b/src/VirtoCommerce.XCart.Web/module.manifest
index 6bb594a..0ace3fc 100644
--- a/src/VirtoCommerce.XCart.Web/module.manifest
+++ b/src/VirtoCommerce.XCart.Web/module.manifest
@@ -1,19 +1,19 @@
VirtoCommerce.XCart
- 3.820.0
+ 3.822.0
3.867.0
-
+
-
+
-
+
Cart Experience API
diff --git a/tests/VirtoCommerce.XCart.Tests/Aggregates/CartAggregateTests.cs b/tests/VirtoCommerce.XCart.Tests/Aggregates/CartAggregateTests.cs
index dc3e74f..501bdb7 100644
--- a/tests/VirtoCommerce.XCart.Tests/Aggregates/CartAggregateTests.cs
+++ b/tests/VirtoCommerce.XCart.Tests/Aggregates/CartAggregateTests.cs
@@ -7,6 +7,7 @@
using Moq;
using VirtoCommerce.CartModule.Core.Model;
using VirtoCommerce.CatalogModule.Core.Model;
+using VirtoCommerce.CoreModule.Core.Currency;
using VirtoCommerce.MarketingModule.Core.Model.Promotions;
using VirtoCommerce.PaymentModule.Core.Model;
using VirtoCommerce.Platform.Core.Common;
@@ -823,6 +824,103 @@ public async Task RecalculateAsync_HasPromoRewards_CalculateTotalsCalled()
_shoppingCartTotalsCalculatorMock.Verify(x => x.CalculateTotals(It.Is(x => x == cartAggregate.Cart)), Times.Exactly(2));
}
+ public static IEnumerable