Skip to content

Commit

Permalink
Even morer Async fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Psichorex committed Feb 22, 2024
1 parent c345677 commit 85ce2af
Show file tree
Hide file tree
Showing 19 changed files with 77 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using OrchardCore.ContentManagement;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace OrchardCore.Commerce.Abstractions;

Expand All @@ -14,25 +15,24 @@ public interface IPredefinedValuesProductAttributeService
/// Filters <see cref="IProductAttributeService.GetProductAttributeFieldsAsync"/> result to only those attribute fields
/// that have predefined values.
/// </summary>
IEnumerable<ProductAttributeDescription> GetProductAttributesRestrictedToPredefinedValues(ContentItem product);
Task<IEnumerable<ProductAttributeDescription>> GetProductAttributesRestrictedToPredefinedValuesAsync(ContentItem product);
}

public static class PredefinedValuesProductAttributeServiceExtensions
{
public static IEnumerable<IEnumerable<object>> GetProductAttributesPredefinedValues(
public static async Task<IEnumerable<IEnumerable<object>>> GetProductAttributesPredefinedValuesAsync(
this IPredefinedValuesProductAttributeService service,
ContentItem product) =>
service
.GetProductAttributesRestrictedToPredefinedValues(product)
(await service.GetProductAttributesRestrictedToPredefinedValuesAsync(product))
.Where(description => description.Settings is IPredefinedValuesProductAttributeFieldSettings)
.Select(description =>
((IPredefinedValuesProductAttributeFieldSettings)description.Settings).PredefinedValues.ToList())
.ToList();

public static IEnumerable<string> GetProductAttributesCombinations(
public static async Task<IEnumerable<string>> GetProductAttributesCombinationsAsync(
this IPredefinedValuesProductAttributeService service,
ContentItem product) =>
CartesianProduct(service.GetProductAttributesPredefinedValues(product))
CartesianProduct(await service.GetProductAttributesPredefinedValuesAsync(product))
.Select(predefinedValues => string.Join('-', predefinedValues));

private static IEnumerable<IEnumerable<T>> CartesianProduct<T>(IEnumerable<IEnumerable<T>> sequences)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public interface IProductService
/// <summary>
/// Returns the full SKU of a Price Variant Product's variant.
/// </summary>
string GetOrderFullSku(ShoppingCartItem item, ProductPart productPart);
Task<string> GetOrderFullSkuAsync(ShoppingCartItem item, ProductPart productPart);

/// <summary>
/// Returns the exact variant of a product, as well as its identifying key, associated with the provided SKU.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public override async Task<IDisplayResult> UpdateAsync(OrderPart part, IUpdateMo

// If selected currencies don't match, add model error and set prices to 0.
var currenciesMatch = distinctCurrencies.Count() == 1;
if (!currenciesMatch && viewModelLineItems.Any())
if (!currenciesMatch && viewModelLineItems.Count != 0)
{
updater.ModelState.AddModelError(
nameof(viewModel.LineItems),
Expand Down Expand Up @@ -114,15 +114,15 @@ private async Task<List<OrderLineItem>> GetOrderLineItemsAsync(

foreach (var provider in _attributeProviders)
{
provider.HandleSelectedAttributesAsync(lineItem.SelectedAttributes, productPart, attributesList);
await provider.HandleSelectedAttributesAsync(lineItem.SelectedAttributes, productPart, attributesList);
}

// If attributes exist, there must be a full SKU.
var fullSku = string.Empty;
if (attributesList.Any())
if (attributesList.Count != 0)
{
var item = new ShoppingCartItem(lineItem.Quantity, lineItem.ProductSku, attributesList);
fullSku = _productService.GetOrderFullSku(item, productPart);
fullSku = await _productService.GetOrderFullSkuAsync(item, productPart);
}

orderLineItems.Add(new OrderLineItem(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ public PriceVariantsPartDisplayDriver(
}

public override IDisplayResult Display(PriceVariantsPart part, BuildPartDisplayContext context) =>
Initialize<PriceVariantsPartViewModel>(GetDisplayShapeType(context), viewModel => BuildViewModel(viewModel, part))
Initialize<PriceVariantsPartViewModel>(GetDisplayShapeType(context), async viewModel => await BuildViewModelAsync(viewModel, part))
.Location("Detail", "Content:25")
.Location("Summary", "Meta:10");

public override IDisplayResult Edit(PriceVariantsPart part, BuildPartEditorContext context) =>
Initialize<PriceVariantsPartViewModel>(GetEditorShapeType(context), viewModel =>
Initialize<PriceVariantsPartViewModel>(GetEditorShapeType(context), async viewModel =>
{
BuildViewModel(viewModel, part);
await BuildViewModelAsync(viewModel, part);
viewModel.Currencies = _moneyService.Currencies;
});

Expand Down Expand Up @@ -76,13 +76,12 @@ public override async Task<IDisplayResult> UpdateAsync(
return await EditAsync(part, context);
}

private void BuildViewModel(PriceVariantsPartViewModel model, PriceVariantsPart part)
private async Task BuildViewModelAsync(PriceVariantsPartViewModel model, PriceVariantsPart part)
{
model.ContentItem = part.ContentItem;
model.PriceVariantsPart = part;

var allVariantsKeys = _predefinedValuesProductAttributeService
.GetProductAttributesCombinations(part.ContentItem)
var allVariantsKeys = (await _predefinedValuesProductAttributeService.GetProductAttributesCombinationsAsync(part.ContentItem))
.Select(attr => attr.HtmlClassify().ToUpperInvariant())
.ToList();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ public ProductPartDisplayDriver(
}

public override IDisplayResult Display(ProductPart part, BuildPartDisplayContext context) =>
Initialize<ProductPartViewModel>(GetDisplayShapeType(context), viewModel => BuildViewModel(viewModel, part))
Initialize<ProductPartViewModel>(GetDisplayShapeType(context), async viewModel => await BuildViewModelAsync(viewModel, part))
.Location("Detail", "Content:20")
.Location("Summary", "Meta:5");

public override IDisplayResult Edit(ProductPart part, BuildPartEditorContext context) =>
Initialize<ProductPartViewModel>(GetEditorShapeType(context), viewModel => BuildViewModel(viewModel, part));
Initialize<ProductPartViewModel>(GetEditorShapeType(context), async viewModel => await BuildViewModelAsync(viewModel, part));

public override async Task<IDisplayResult> UpdateAsync(
ProductPart part,
Expand Down Expand Up @@ -92,7 +92,7 @@ private static void UpdateAvailabilityKeys(ProductPart part, int inventoryCount)
part.CanBeBought.AddRange(newAvailabilities);
}

private void BuildViewModel(ProductPartViewModel viewModel, ProductPart part)
private async Task BuildViewModelAsync(ProductPartViewModel viewModel, ProductPart part)
{
viewModel.ContentItem = part.ContentItem;
viewModel.Sku = part.Sku;
Expand Down Expand Up @@ -120,6 +120,6 @@ private void BuildViewModel(ProductPartViewModel viewModel, ProductPart part)
viewModel.CanBeBought[part.ContentItem.ContentItemId] = true;
}

viewModel.Attributes = _productAttributeService.GetProductAttributeFieldsAsync(part.ContentItem);
viewModel.Attributes = await _productAttributeService.GetProductAttributeFieldsAsync(part.ContentItem);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public override async Task<LocalizedHtmlString> VerifyingItemAsync(ShoppingCartI
}

var title = productPart.ContentItem.DisplayText;
var fullSku = _productService.GetOrderFullSku(item, productPart);
var fullSku = await _productService.GetOrderFullSkuAsync(item, productPart);

var inventoryIdentifier = string.IsNullOrEmpty(fullSku) ? productPart.Sku : fullSku;
var relevantInventory = inventoryPart.Inventory.FirstOrDefault(entry => entry.Key == inventoryIdentifier);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public async Task<IList<ShoppingCartItem>> UpdateAsync(IList<ShoppingCartItem> m
foreach (var item in model)
{
var productPart = await _productService.GetProductAsync(item.ProductSku);
var fullSku = _productService.GetOrderFullSku(item, productPart);
var fullSku = await _productService.GetOrderFullSkuAsync(item, productPart);

await UpdateInventoryAsync(
await _productService.GetProductAsync(item.ProductSku),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,21 +138,21 @@ await _taxProviders.GetFirstApplicableProviderAsync(promotionAndTaxContext) is {
{
var productSku = product.As<ProductPart>().Sku;

var booleanAttributes = _productAttributeService.GetProductAttributeFieldsAsync(product)
var booleanAttributes = (await _productAttributeService.GetProductAttributeFieldsAsync(product))
.Where(attribute => attribute.Field is BooleanProductAttributeField)
.Select(attribute => attribute.Name)
.ToList();

if (booleanAttributes.Any())
if (booleanAttributes.Count != 0)
{
availableBooleanAttributes.Add(productSku, booleanAttributes);
}

var numericAttributes = _productAttributeService.GetProductAttributeFieldsAsync(product)
var numericAttributes = (await _productAttributeService.GetProductAttributeFieldsAsync(product))
.Where(attribute => attribute.Field is NumericProductAttributeField)
.ToList();

if (numericAttributes.Any())
if (numericAttributes.Count != 0)
{
availableNumericAttributes.Add(productSku, numericAttributes.Select(attribute => attribute.Name).ToList());
numericAttributeSettings.Add(
Expand All @@ -162,7 +162,7 @@ await _taxProviders.GetFirstApplicableProviderAsync(promotionAndTaxContext) is {
attribute => attribute.Settings as NumericProductAttributeFieldSettings));
}

var textAttributes = _predefinedAttributeService.GetProductAttributesRestrictedToPredefinedValues(product);
var textAttributes = await _predefinedAttributeService.GetProductAttributesRestrictedToPredefinedValuesAsync(product);
foreach (var attribute in textAttributes)
{
var settings = (TextProductAttributeFieldSettings)attribute.Settings;
Expand Down Expand Up @@ -206,7 +206,7 @@ private async Task<OrderLineItemViewModel> GetOrderLineItemViewModelAsync(
if (string.IsNullOrEmpty(lineItem.FullSku))
{
var item = new ShoppingCartItem(lineItem.Quantity, lineItem.ProductSku, lineItem.Attributes);
fullSku = _productService.GetOrderFullSku(item, productPart);
fullSku = await _productService.GetOrderFullSkuAsync(item, productPart);
}

var availableAttributesAndSettings = await GetAvailableAttributesAndSettingsAsync();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using OrchardCore.ContentManagement;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace OrchardCore.Commerce.Services;

Expand All @@ -13,9 +14,8 @@ public class PredefinedValuesProductAttributeService : IPredefinedValuesProductA
public PredefinedValuesProductAttributeService(IProductAttributeService productAttributeService) =>
_productAttributeService = productAttributeService;

public IEnumerable<ProductAttributeDescription> GetProductAttributesRestrictedToPredefinedValues(ContentItem product) =>
_productAttributeService
.GetProductAttributeFieldsAsync(product)
public async Task<IEnumerable<ProductAttributeDescription>> GetProductAttributesRestrictedToPredefinedValuesAsync(ContentItem product) =>
(await _productAttributeService.GetProductAttributeFieldsAsync(product))
.Where(description => description.Settings is
IPredefinedValuesProductAttributeFieldSettings { RestrictToPredefinedValues: true })
.OrderBy(description => description.PartName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ public async Task<IList<ShoppingCartItem>> UpdateAsync(IList<ShoppingCartItem> m
{
var skuProducts = await _productService.GetSkuProductsAsync(model);

return model
.Select(item =>
var updatedModel = await Task.WhenAll(model
.Select(async item =>
{
if (skuProducts.TryGetValue(item.ProductSku, out var productPart))
{
var itemWithPrice = AddPriceToShoppingCartItem(item, productPart);
var itemWithPrice = await AddPriceToShoppingCartItemAsync(item, productPart);
if (itemWithPrice != null)
{
Expand All @@ -43,18 +43,19 @@ public async Task<IList<ShoppingCartItem>> UpdateAsync(IList<ShoppingCartItem> m
}
return item;
})
.ToList();
}));

return updatedModel.ToList();
}

private ShoppingCartItem AddPriceToShoppingCartItem(ShoppingCartItem item, ProductPart productPart)
private async Task<ShoppingCartItem> AddPriceToShoppingCartItemAsync(ShoppingCartItem item, ProductPart productPart)
{
var priceVariantsPart = productPart.ContentItem.As<PriceVariantsPart>();

if (priceVariantsPart is { Variants: { } variants } && variants.Any())
{
var attributesRestrictedToPredefinedValues = _predefinedValuesService
.GetProductAttributesRestrictedToPredefinedValues(productPart.ContentItem)
var attributesRestrictedToPredefinedValues = (await _predefinedValuesService
.GetProductAttributesRestrictedToPredefinedValuesAsync(productPart.ContentItem))
.Select(attr => attr.PartName + "." + attr.Name)
.ToHashSet();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ namespace OrchardCore.Commerce.Services;
public class ProductAttributeProvider : IProductAttributeProvider
{
private static readonly string[] _supportedTypeNames =
{
[
nameof(BooleanProductAttributeField),
nameof(NumericProductAttributeField),
nameof(TextProductAttributeField),
};
];
public IProductAttributeValue CreateFromValue(
ContentTypePartDefinition partDefinition,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public async Task<IList<ShoppingCartItem>> UpdateInventoriesAsync(IList<Shopping
return items;
}

public Task<bool> VerifyLinesAsync(IList<ShoppingCartLineViewModel> lines)
public async Task<bool> VerifyLinesAsync(IList<ShoppingCartLineViewModel> lines)
{
foreach (var line in lines)
{
Expand All @@ -47,7 +47,7 @@ public Task<bool> VerifyLinesAsync(IList<ShoppingCartLineViewModel> lines)
}

var item = new ShoppingCartItem(line.Quantity, line.ProductSku, line.Attributes?.Values);
var fullSku = _productService.GetOrderFullSku(item, productPart);
var fullSku = await _productService.GetOrderFullSkuAsync(item, productPart);
var inventoryIdentifier = string.IsNullOrEmpty(fullSku) ? productPart.Sku : fullSku;
var relevantInventory = inventoryPart.Inventory.FirstOrDefault(entry => entry.Key == inventoryIdentifier);

Expand All @@ -57,10 +57,10 @@ public Task<bool> VerifyLinesAsync(IList<ShoppingCartLineViewModel> lines)

if (cannotCheckout)
{
return Task.FromResult(true);
return true;
}
}

return Task.FromResult(false);
return false;
}
}
6 changes: 3 additions & 3 deletions src/Modules/OrchardCore.Commerce/Services/ProductService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ public virtual async Task<IEnumerable<ProductPart>> GetProductsAsync(IEnumerable
return await FillContentItemsAndGetProductPartsAsync(contentItems);
}

public string GetOrderFullSku(ShoppingCartItem item, ProductPart productPart)
public async Task<string> GetOrderFullSkuAsync(ShoppingCartItem item, ProductPart productPart)
{
var attributesRestrictedToPredefinedValues = _predefinedValuesService
.GetProductAttributesRestrictedToPredefinedValues(productPart.ContentItem)
var attributesRestrictedToPredefinedValues = (await _predefinedValuesService
.GetProductAttributesRestrictedToPredefinedValuesAsync(productPart.ContentItem))
.Select(attr => attr.PartName + "." + attr.Name)
.ToHashSet();

Expand Down
15 changes: 7 additions & 8 deletions src/Modules/OrchardCore.Commerce/Services/ShoppingCartHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@ private async Task<ShoppingCartViewModel> CreateShoppingCartViewModelAsync(
var products = await _productService.GetProductDictionaryAsync(cart.Items.Select(line => line.ProductSku));
var items = await _priceService.AddPricesAsync(cart.Items);

IList<ShoppingCartLineViewModel> lines = items
.Select(item =>
var lines = (await Task.WhenAll(items
.Select(async item =>
{
var product = products[item.ProductSku];
var price = _priceService.SelectPrice(item.Prices);
var attributes = item.HasRawAttributes()
? _shoppingCartSerializer.PostProcessAttributes(item.Attributes, product)
? await _shoppingCartSerializer.PostProcessAttributesAsync(item.Attributes, product)
: item.Attributes;
return new ShoppingCartLineViewModel(attributes: attributes.ToDictionary(attr => attr.AttributeName))
Expand All @@ -95,10 +95,9 @@ private async Task<ShoppingCartViewModel> CreateShoppingCartViewModelAsync(
UnitPrice = price,
LinePrice = item.Quantity * price,
};
})
.ToList();
}))).AsList();

if (!lines.Any()) return null;
if (lines.Count == 0) return null;

IList<LocalizedHtmlString> headers = new[]
{
Expand Down Expand Up @@ -153,7 +152,7 @@ public async Task UpdateAsync(string shoppingCartId, Func<ShoppingCart, Task> up

public async Task<IDictionary<string, Amount>> CalculateMultipleCurrencyTotalsAsync(ShoppingCart cart) =>
cart.Count == 0
? new Dictionary<string, Amount>()
? []
: (await cart.CalculateTotalsAsync(_priceService)).ToDictionary(total => total.Currency.CurrencyIsoCode);

public async Task<ShoppingCartItem> AddToCartAsync(
Expand Down Expand Up @@ -242,7 +241,7 @@ public async Task<IList<OrderLineItem>> CreateOrderLineItemsAsync(ShoppingCart s
{
item = await _priceService.AddPriceAsync(item);
var price = _priceSelectionStrategy.SelectPrice(item.Prices);
var fullSku = _productService.GetOrderFullSku(item, await _productService.GetProductAsync(item.ProductSku));
var fullSku = await _productService.GetOrderFullSkuAsync(item, await _productService.GetProductAsync(item.ProductSku));
var selectedAttributes = _productAttributeProviders
.Select(provider => provider.GetSelectedAttributes(item.Attributes))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ public async Task HandleSelectedAttributesAsync(
selectedAttributes.Add(Text, new Dictionary<string, string>());
}

var predefinedAttributes = _predefinedValuesProductAttributeService
.GetProductAttributesRestrictedToPredefinedValues(productPart.ContentItem);
var predefinedAttributes = await _predefinedValuesProductAttributeService
.GetProductAttributesRestrictedToPredefinedValuesAsync(productPart.ContentItem);

// Predefined attributes must contain the selected attributes.
var selectedTextAttributesList = predefinedAttributes
Expand Down
Loading

0 comments on commit 85ce2af

Please sign in to comment.