on Customization user able to click view
_variantDropdown
@model ProductViewModel
@using Sana.Commerce.Catalog;
@using Sana.Commerce.Shop
@using Sana.Commerce.Customization.ExtendedModels
@{
var variants = Model.Product.Variants;
var firstGroup = Model.Product.VariantComponents.FirstOrDefault();
var showPrices = Shop.UserAbilities.Has(AbilityTo.ViewPrices);
var showStock = Shop.UserAbilities.Has(AbilityTo.ViewStock);
var type = Shop.Settings.ActionPricesPresentationType;
// scope not defined
//var selectedVarientId = variants.Where(x => ((ExtendedProductVariant)x).IsSelectedVariant == true).FirstOrDefault();
var showListPrice = showPrices &&
(type.iEquals(WebsiteSettings.ActionPricePresentationModes.BaseAndSalesPrice)
|| type.iEquals(WebsiteSettings.ActionPricePresentationModes.BaseAndSalesPriceDiscountPercentage)
|| type.iEquals(WebsiteSettings.ActionPricePresentationModes.BaseAndSalesPriceDiscountAmount));
var showDiscountAmount = showPrices &&
(type.iEquals(WebsiteSettings.ActionPricePresentationModes.SalesPriceDiscountAmount)
|| type.iEquals(WebsiteSettings.ActionPricePresentationModes.BaseAndSalesPriceDiscountAmount));
var showDiscountPercent = showPrices &&
(type.iEquals(WebsiteSettings.ActionPricePresentationModes.BaseAndSalesPriceDiscountPercentage)
|| type.iEquals(WebsiteSettings.ActionPricePresentationModes.SalesPriceDiscountPercentage));
}
@if (firstGroup == null)
{
@DropdownFormRow("variantId", showPrices, showListPrice, showDiscountAmount, showDiscountPercent, showStock, null, variants, "withoutgroup")
}
else if (Model.Product.VariantComponents.Count == 1)
{
@DropdownFormRow("variantId", showPrices, showListPrice, showDiscountAmount, showDiscountPercent, showStock, firstGroup, variants, "single")
}
else
{
string ddId = "c" + Next();
@DropdownFormRow(ddId, showPrices, showListPrice, showDiscountAmount, showDiscountPercent, showStock, firstGroup, variants, "multifirst")
var combinations = InitialCombinations(firstGroup, variants);
foreach (var group in Model.Product.VariantComponents.Skip(1).Take(Model.Product.VariantComponents.Count - 2))
{
ddId = "c" + Next();
@DropdownFormRow(ddId, showPrices, showListPrice, showDiscountAmount, showDiscountPercent, showStock, group, variants, "multimiddle", combinations)
combinations = ExpandCombinations(combinations, group);
}
var lastGroup = Model.Product.VariantComponents.Last();
@DropdownFormRow("variantId", showPrices, showListPrice, showDiscountAmount, showDiscountPercent, showStock, lastGroup, variants, "multilast", combinations)
}
@helper DropdownFormRow(string ddId, bool showPrices, bool showListPrice, bool showDiscountAmount, bool showDiscountPercent, bool showStock, IVariantComponentGroup group, IProductVariantCollection variants, string mode, IList<dynamic> combinations = null)
{
<div class="form-row row-variant">
<div class="control">
<div class="label">
<label for="@ddId">@VariantComponentGroupName(group)</label>
</div>
<div class="field">
<div class="ddlb ddlb-component">
@if (mode == "withoutgroup")
{
<select name="@ddId" id="@ddId">
@Html.Each(variants,
@<option value="@item.Id" data-price="@GetPrice(item, showPrices)"
data-listprice="@GetListPrice(item, showListPrice)"
data-inventory="@When(showStock, item.Inventory.ToString())"
data-image-tags="@TagBuilder.CreateSanitizedId('v' + item.Id)"
data-discount-percentage="@GetDiscountPercantage(item, showDiscountPercent)"
data-discount-amount="@GetDiscountAmount(item, showDiscountAmount)"
data-available-sales-agreement-lines="@item.AvailableSalesAgreementLines.ToJson().ToHtmlString()"
@When(!item.IsOrderable, "data-not-orderable")>
@item.Title.Or(item.Id)
</option>)
</select>
}
else if (mode == "single")
{
<select name="@ddId" id="@ddId">
@Html.Each(group.Items.Select(i => variants.FirstOrDefault(v => v.Components.Match(group.Id, i.Id))).Where(v => v != null),
@<option value="@item.Id" data-price="@GetPrice(item, showPrices)"
data-listprice="@GetListPrice(item, showListPrice)"
data-inventory="@When(showStock, item.Inventory.ToString())"
data-image-tags="@TagBuilder.CreateSanitizedId('v' + item.Id) @TagBuilder.CreateSanitizedId('v' + item.Components[group.Id])"
data-discount-percentage="@GetDiscountPercantage(item, showDiscountPercent)"
data-discount-amount="@GetDiscountAmount(item, showDiscountAmount)"
data-available-sales-agreement-lines="@item.AvailableSalesAgreementLines.ToJson().ToHtmlString()"
@When(!item.IsOrderable, "data-not-orderable")>
@group.Items[item.Components[group.Id]].Name
</option>)
</select>
}
else if (mode == "multifirst")
{
// 3.3 issue Set selected drop down
var selectedVarient = variants.Where(x => ((ExtendedProductVariant)x).IsSelectedVariant == true).FirstOrDefault();
if (selectedVarient != null)
{
var selectedVarientComponent = group.Items.FilterByVariants(new List<IProductVariant>() { selectedVarient }).FirstOrDefault();
var comId = selectedVarientComponent.Id;
@Html.DropDownList(ddId, group.Items.FilterByVariants(variants).Select(c => new SelectListItem { Value = c.Id, Text = c.Name, Selected = (c.Id == comId) }))
}
else
{
@Html.DropDownList(ddId, group.Items.FilterByVariants(variants).Select(c => new SelectListItem { Value = c.Id, Text = c.Name }))
}
}
else if (mode == "multimiddle")
{
<select name="@ddId" id="@ddId">
@foreach (var scope in combinations)
{
var selectedVarient = variants.Where(x => ((ExtendedProductVariant)x).IsSelectedVariant == true).FirstOrDefault();
if (selectedVarient != null)
{
var selectedVarientComponent = group.Items.FilterByVariants(new List<IProductVariant>() { selectedVarient }).FirstOrDefault();
var comId = selectedVarientComponent.Id;
var ss = (IList<IProductVariant>)scope.Variants;
//var selectedVarientComponent = group.Items.FilterByVariants(new List<IProductVariant>() { selectedVarient }).FirstOrDefault();
}
var items = group.Items.FilterByVariants((IList<IProductVariant>)scope.Variants);
<optgroup label="@scope.Text" data-scope="@scope.Key">
@Html.Each(items, @<option value="@scope.Key @item.Id">@item.Name</option>)
</optgroup>
}
</select>
}
else if (mode == "multilast")
{
var selectedVarient = variants.Where(x => ((ExtendedProductVariant)x).IsSelectedVariant == true).FirstOrDefault();
if (selectedVarient != null)
{
}
<select name="@ddId" id="@ddId">
@foreach (var scope in combinations)
{
var vars = (IList<IProductVariant>)scope.Variants;
<optgroup label="@scope.Text" data-scope="@scope.Key">
@foreach (var item in group.Items)
{
var variant = vars.FirstOrDefault(v => v.Components.Match(group.Id, item.Id));
if (variant != null)
{
var selectedValue = "";
//if (variant.Id == selectedVarient.Id)
//{
// selectedValue = "selected";
//}
<option @selectedValue
value="@variant.Id" data-price="@GetPrice(variant, showPrices)"
data-listprice="@GetListPrice(variant, showListPrice)"
data-inventory="@When(showStock, variant.Inventory.ToString())"
data-image-tags="@TagBuilder.CreateSanitizedId('v' + variant.Id) @variant.Components.Values.Select(v => TagBuilder.CreateSanitizedId('v' + v)).JoinWith(" ")"
data-discount-percentage="@GetDiscountPercantage(variant, showDiscountPercent)"
data-discount-amount="@GetDiscountAmount(variant, showDiscountAmount)"
data-available-sales-agreement-lines="@variant.AvailableSalesAgreementLines.ToJson().ToHtmlString()"
@When(!variant.IsOrderable, "data-not-orderable")>
@item.Name
</option>
}
}
</optgroup>
}
</select>
}
</div>
</div>
</div>
</div>
}
@functions
{
string GetPrice(Sana.Commerce.Catalog.IProductVariant variant, bool showPrices)
{
if (!showPrices)
return null;
return variant.Price.FormatAsPrice();
}
string GetListPrice(Sana.Commerce.Catalog.IProductVariant variant, bool showPrices)
{
if (!showPrices)
return null;
if (variant.ListPrice == null)
return string.Empty;
return variant.ListPrice.Value.FormatAsPrice();
}
string GetDiscountPercantage(Sana.Commerce.Catalog.IProductVariant variant, bool showPrices)
{
if (!showPrices)
return null;
return ProductExtensions.DiscountPercentage(variant.Price, variant.ListPrice, Shop.CommerceContext.CurrencyId).ToHtmlString();
}
string GetDiscountAmount(Sana.Commerce.Catalog.IProductVariant variant, bool showPrices)
{
if (!showPrices)
return null;
return ProductExtensions.DiscountAmount(variant.Price, variant.ListPrice, Shop.CommerceContext.CurrencyId).ToHtmlString();
}
IHtmlString VariantComponentGroupName(IVariantComponentGroup group)
{
return group == null ? Sana.SimpleText("Variant") : Sana.SimpleText("Product_VariantComponent_" + group.Id, group.Name);
}
IList<dynamic> InitialCombinations(IVariantComponentGroup group, IList<IProductVariant> variants)
{
return ExpandCombinations(new[] { new { Key = string.Empty, Variants = variants } }, group);
}
IList<dynamic> ExpandCombinations(IList<dynamic> current, IVariantComponentGroup group)
{
var result = new List<dynamic>();
foreach (var parent in current)
{
var variants = (IList<IProductVariant>)parent.Variants;
foreach (var item in group.Items.FilterByVariants(variants))
{
result.Add(new
{
Key = parent.Key != string.Empty ? parent.Key + ' ' + item.Id : item.Id,
Text = parent.Key != string.Empty ? parent.Text + '-' + item.Name : item.Name,
Variants = variants.Where(v => v.Components.Match(group.Id, item.Id)).ToArray()
});
}
}
return result;
}
}
Ticket 93818: [Holz Pichler] 3.3. Item variants – “range value” attributes.