/// <summary> /// Creates a new product model with variants. /// </summary> /// <param name="productPage">Product's page.</param> /// <param name="priceDetail">Price of the selected variant.</param> /// <param name="variants">Collection of selectable variants.</param> /// <param name="selectedVariantID">ID of the selected variant.</param> public ProductViewModel(SKUTreeNode productPage, ProductCatalogPrices priceDetail, List <ProductVariant> variants, int selectedVariantID) : this(productPage, priceDetail) { // Fills the selectable variants HasProductVariants = variants.Any(); // Continues if the product has any variants if (HasProductVariants) { // Selects a default variant var selectedVariant = variants.FirstOrDefault(v => v.Variant.SKUID == selectedVariantID); if (selectedVariant != null) { IsInStock = (selectedVariant.Variant.SKUTrackInventory == TrackInventoryTypeEnum.Disabled) || (selectedVariant.Variant.SKUAvailableItems > 0); SelectedVariantID = selectedVariantID; } // Creates a list of product variants VariantSelectList = new SelectList(variants.Select(v => new SelectListItem { Text = string.Join(", ", v.ProductAttributes.Select(a => a.SKUName)), Value = v.Variant.SKUID.ToString() }), "Value", "Text"); } }
private JsonResult GetVariantResponse(ProductCatalogPrices priceDetail, bool inStock, string stockMessageResourceString, int variantSKUID, CurrencyInfo currency) { string priceSavings = string.Empty; var discount = priceDetail.StandardPrice - priceDetail.Price; var beforeDiscount = priceDetail.Price + discount; if (discount > 0) { var discountPercentage = Math.Round(discount * 100 / beforeDiscount); var formattedDiscount = String.Format(currency.CurrencyFormatString, discount); priceSavings = $"{formattedDiscount} ({discountPercentage}%)"; } var response = new { totalPrice = String.Format(currency.CurrencyFormatString, priceDetail.Price), beforeDiscount = discount > 0 ? string.Format(currency.CurrencyFormatString, beforeDiscount) : string.Empty, savings = priceSavings, stockMessage = ResHelper.GetString(stockMessageResourceString), inStock, variantSKUID }; return(Json(response)); }
private JsonResult GetVariantResponse(ProductCatalogPrices priceDetail, bool inStock, bool allowSale, int variantSKUID, CurrencyInfo currency, IStringLocalizer <SharedResources> localizer) { string priceSavings = string.Empty; var discount = priceDetail.StandardPrice - priceDetail.Price; var beforeDiscount = priceDetail.Price + discount; if (discount > 0) { var discountPercentage = Math.Round(discount * 100 / beforeDiscount); var formattedDiscount = String.Format(currency.CurrencyFormatString, discount); priceSavings = $"{formattedDiscount} ({discountPercentage}%)"; } var response = new { totalPrice = String.Format(currency.CurrencyFormatString, priceDetail.Price), beforeDiscount = discount > 0 ? String.Format(currency.CurrencyFormatString, beforeDiscount) : string.Empty, savings = priceSavings, stockMessage = inStock ? localizer["In stock"].Value : localizer["Out of stock"].Value, inStock, allowSale, variantSKUID }; return(Json(response)); }
public JsonResult Variant(int variantID) { // Gets SKU information based on the variant's ID SKUInfo variant = SKUInfoProvider.GetSKUInfo(variantID); // If the variant is null, returns null if (variant == null) { return(null); } var cart = shoppingService.GetCurrentShoppingCart(); // Calculates the price of the variant ProductCatalogPrices variantPrice = calculatorFactory .GetCalculator(cart.ShoppingCartSiteID) .GetPrices(variant, Enumerable.Empty <SKUInfo>(), cart); // Finds out whether the variant is in stock bool isInStock = variant.SKUTrackInventory == TrackInventoryTypeEnum.Disabled || variant.SKUAvailableItems > 0; // Creates a JSON response for the JavaScript that switches the variants var response = new { totalPrice = String.Format(cart.Currency.CurrencyFormatString, variantPrice.Price), inStock = isInStock, stockMessage = isInStock ? "Yes" : "No" }; // Returns the response return(Json(response)); }
//EndDocSection:Constructor //DocSection:DisplayProduct /// <summary> /// Displays a product detail page of a product specified by the GUID of the product's page. /// </summary> /// <param name="guid">Node GUID of the product's page.</param> /// <param name="productAlias">Node alias of the product's page.</param> public ActionResult BasicDetail(Guid guid, string productAlias) { // Gets the product from the connected Kentico database SKUTreeNode product = GetProduct(guid); // If the product is not found or if it is not allowed for sale, redirects to error 404 if ((product == null) || (product.SKU == null) || !product.SKU.SKUEnabled) { return(HttpNotFound()); } // Redirects if the specified page alias does not match if (!string.IsNullOrEmpty(productAlias) && !product.NodeAlias.Equals(productAlias, StringComparison.InvariantCultureIgnoreCase)) { return(RedirectToActionPermanent("Detail", new { guid = product.NodeGUID, productAlias = product.NodeAlias })); } // Initializes the view model of the product with a calculated price ShoppingCartInfo cart = shoppingService.GetCurrentShoppingCart(); ProductCatalogPrices price = calculatorFactory .GetCalculator(cart.ShoppingCartSiteID) .GetPrices(product.SKU, Enumerable.Empty <SKUInfo>(), cart); // Fills the product model with retrieved data ProductViewModel viewModel = new ProductViewModel(product, price); // Displays the product details page return(View(viewModel)); }
/// <summary> /// Creates a new product model. /// </summary> /// <param name="productPage">Product's page.</param> /// <param name="priceDetail">Price of the product.</param> public ProductViewModel(SKUTreeNode productPage, ProductCatalogPrices priceDetail) { // Fills the page information Name = productPage.DocumentName; Description = productPage.DocumentSKUDescription; ShortDescription = productPage.DocumentSKUShortDescription; // Fills the SKU information SKUInfo sku = productPage.SKU; SKUID = sku.SKUID; ImagePath = string.IsNullOrEmpty(sku.SKUImagePath) ? null : new FileUrl(sku.SKUImagePath, true) .WithSizeConstraint(SizeConstraint.MaxWidthOrHeight(400)) .RelativePath; IsInStock = sku.SKUTrackInventory == TrackInventoryTypeEnum.Disabled || sku.SKUAvailableItems > 0; PriceDetail = new PriceDetailViewModel() { Price = priceDetail.Price, ListPrice = priceDetail.ListPrice, CurrencyFormatString = priceDetail.Currency.CurrencyFormatString }; }
public SearchResultProductItemModel(SearchResultItem resultItem, SKUTreeNode page, ProductCatalogPrices priceDetail, IPageUrlRetriever pageUrlRetriever) : base(resultItem, page, pageUrlRetriever) { Description = page.DocumentSKUDescription; ShortDescription = HTMLHelper.StripTags(page.DocumentSKUShortDescription, false); PriceDetail = priceDetail; }
public void SetUp() { var price = new ProductCatalogPrices(0m, 0m, 0m, 0m, Substitute.For <CurrencyInfo>(), null); var calculationService = Substitute.For <ICalculationService>(); var skuInfo = Substitute.For <SKUInfo>(); calculationService.CalculatePrice(skuInfo).Returns(price); var repository = MockDataSource(skuInfo); mController = new CoffeesController(repository, calculationService); }
public SearchResultProductItemModel(SearchResultItem resultItem, SKUTreeNode skuTreeNode, ProductCatalogPrices priceDetail) : base(resultItem, skuTreeNode) { Description = skuTreeNode.DocumentSKUDescription; ShortDescription = HTMLHelper.StripTags(skuTreeNode.DocumentSKUShortDescription, false); PriceDetail = priceDetail; var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext); Url = urlHelper.Action("Detail", "Product", new { guid = skuTreeNode.NodeGUID, productAlias = skuTreeNode.NodeAlias }); }
/// <summary> /// Creates an instance of the <see cref="RecommendedProductViewModel"/> view model- /// </summary> /// <param name="productPage">Product page.</param> /// <param name="priceDetail">Price.</param> public RecommendedProductViewModel(SKUTreeNode productPage, ProductCatalogPrices priceDetail) { // Set page information Name = productPage.DocumentName; ProductPageGUID = productPage.NodeGUID; ProductPageAlias = productPage.NodeAlias; // Set SKU information ImagePath = productPage.SKU.SKUImagePath; Available = !productPage.SKU.SKUSellOnlyAvailable || productPage.SKU.SKUAvailableItems > 0; // Set additional info PriceDetail = priceDetail; }
public ProductListItemViewModel(SKUTreeNode productPage, ProductCatalogPrices priceDetail, string publicStatusName, IPageUrlRetriever pageUrlRetriever) { // Set page information Name = productPage.DocumentName; Url = pageUrlRetriever.Retrieve(productPage).RelativePath; // Set SKU information ImagePath = string.IsNullOrEmpty(productPage.SKU.SKUImagePath) ? null : new FileUrl(productPage.SKU.SKUImagePath, true).WithSizeConstraint(SizeConstraint.Size(452, 452)).RelativePath; Available = !productPage.SKU.SKUSellOnlyAvailable || productPage.SKU.SKUAvailableItems > 0; PublicStatusName = publicStatusName; // Set additional info PriceDetail = priceDetail; }
public ProductListItemViewModel(SKUTreeNode productPage, ProductCatalogPrices priceDetail, string publicStatusName) { // Set page information Name = productPage.DocumentName; ProductPageGUID = productPage.NodeGUID; ProductPageAlias = productPage.NodeAlias; // Set SKU information ImagePath = productPage.SKU.SKUImagePath; Available = !productPage.SKU.SKUSellOnlyAvailable || productPage.SKU.SKUAvailableItems > 0; PublicStatusName = publicStatusName; // Set additional info PriceDetail = priceDetail; }
public void SetUp() { var price = new ProductCatalogPrices(0m, 0m, 0m, 0m, Substitute.For <CurrencyInfo>(), null); var calculationService = Substitute.For <ICalculationService>(); var pageUrlRetriever = Substitute.For <IPageUrlRetriever>(); pageUrlRetriever.Retrieve(Arg.Any <TreeNode>(), Arg.Any <bool>()).Returns(new PageUrl { RelativePath = URL }); var skuInfo = Substitute.For <SKUInfo>(); calculationService.CalculatePrice(skuInfo).Returns(price); var repository = MockDataSource(skuInfo); controller = new GrindersController(repository, calculationService, pageUrlRetriever); }
public ProductViewModel(SKUTreeNode productPage, ProductCatalogPrices price, ITypedProductViewModel typedProductViewModel, ProductVariant defaultVariant, IEnumerable <ProductOptionCategoryViewModel> categories) : this(productPage, price, typedProductViewModel) { if (defaultVariant == null) { throw new ArgumentNullException(nameof(defaultVariant)); } var variant = defaultVariant.Variant; IsInStock = ((variant.SKUTrackInventory == TrackInventoryTypeEnum.Disabled) || (variant.SKUAvailableItems > 0)); SelectedVariantID = variant.SKUID; // Variant categories which will be rendered ProductOptionCategories = categories; }
//EndDocSection:DisplayProduct private object DummyEcommerceMethod2() { SKUInfo sku = null; //DocSection:DisplayCatalogDiscounts // Gets the current shopping cart ShoppingCartInfo shoppingCart = Service.Resolve <IShoppingService>().GetCurrentShoppingCart(); // Calculates prices for the specified product ProductCatalogPrices price = Service.Resolve <ICatalogPriceCalculatorFactory>() .GetCalculator(shoppingCart.ShoppingCartSiteID) .GetPrices(sku, Enumerable.Empty <SKUInfo>(), shoppingCart); // Gets the catalog discount decimal catalogDiscount = price.StandardPrice - price.Price; //EndDocSection:DisplayCatalogDiscounts return(null); }
public ProductViewModel(SKUTreeNode productPage, ProductCatalogPrices priceDetail, ITypedProductViewModel typedProductViewModel = null) { // Set page information Name = productPage.DocumentName; Description = productPage.DocumentSKUDescription; ShortDescription = productPage.DocumentSKUShortDescription; // Set SKU information var sku = productPage.SKU; SKUID = sku.SKUID; ImagePath = sku.SKUImagePath; IsInStock = sku.SKUTrackInventory == TrackInventoryTypeEnum.Disabled || sku.SKUAvailableItems > 0; // Set additional info TypedProduct = typedProductViewModel; PriceDetail = priceDetail; }
/// <summary> /// Constructor for the ProductListItemViewModel class. /// </summary> /// <param name="productPage">Product's page.</param> /// <param name="priceDetail">Price of the product.</param> /// <param name="publicStatusName">Display name of the product's public status.</param> public ProductListItemViewModel(SKUTreeNode productPage, ProductCatalogPrices priceDetail, string publicStatusName) { // Sets the page information Name = productPage.DocumentName; ProductPageGuid = productPage.NodeGUID; ProductPageAlias = productPage.NodeAlias; // Sets the SKU information ImagePath = productPage.SKU.SKUImagePath; Available = !productPage.SKU.SKUSellOnlyAvailable || productPage.SKU.SKUAvailableItems > 0; PublicStatusName = publicStatusName; // Sets the price format information PriceModel = new PriceDetailViewModel { Price = priceDetail.Price, ListPrice = priceDetail.ListPrice, CurrencyFormatString = priceDetail.Currency.CurrencyFormatString }; }
public ProductViewModel(SKUTreeNode productPage, ProductCatalogPrices priceDetail, ITypedProductViewModel typedProductViewModel = null) { // Set page information Name = productPage.DocumentName; Description = productPage.DocumentSKUDescription; ShortDescription = productPage.DocumentSKUShortDescription; // Set SKU information var sku = productPage.SKU; SKUID = sku.SKUID; ImagePath = string.IsNullOrEmpty(sku.SKUImagePath) ? null : new FileUrl(sku.SKUImagePath, true).WithSizeConstraint(SizeConstraint.MaxWidthOrHeight(400)).RelativePath; IsInStock = sku.SKUTrackInventory == TrackInventoryTypeEnum.Disabled || sku.SKUAvailableItems > 0; AllowSale = IsInStock || !sku.SKUSellOnlyAvailable; // Set additional info TypedProduct = typedProductViewModel; PriceDetail = priceDetail; }
//EndDocSection:DisplayProduct //DocSection:DisplayVariant /// <summary> /// Displays product detail page of a product or product variant specified by the GUID of the product's or variant's page. /// </summary> /// <param name="guid">Node GUID of the product's (variant's) page.</param> /// <param name="productAlias">Node alias of the product's (variant's) page.</param> public ActionResult Detail(Guid guid, string productAlias) { // Gets the product from the connected Kentico database SKUTreeNode product = GetProduct(guid); // If the product is not found or if it is not allowed for sale, redirects to error 404 if ((product == null) || !product.SKU.SKUEnabled) { return(HttpNotFound()); } // Redirects if the specified page alias does not match if (!string.IsNullOrEmpty(productAlias) && !product.NodeAlias.Equals(productAlias, StringComparison.InvariantCultureIgnoreCase)) { return(RedirectToActionPermanent("Detail", new { guid = product.NodeGUID, productAlias = product.NodeAlias })); } // Gets all product variants of the product List <ProductVariant> variants = VariantHelper.GetVariants(product.NodeSKUID).OnSite(SiteContext.CurrentSiteID).ToList() .Select(sku => new ProductVariant(sku.SKUID)) .OrderBy(v => v.Variant.SKUPrice).ToList(); // Selects the first product variant ProductVariant selectedVariant = variants.FirstOrDefault(); // Calculates the price of the product or the variant ShoppingCartInfo cart = shoppingService.GetCurrentShoppingCart(); SKUInfo selectedProduct = selectedVariant != null ? selectedVariant.Variant : product.SKU; ProductCatalogPrices priceDetail = calculatorFactory .GetCalculator(cart.ShoppingCartSiteID) .GetPrices(selectedProduct, Enumerable.Empty <SKUInfo>(), cart); // Initializes the view model of the product or product variant ProductViewModel viewModel = new ProductViewModel(product, priceDetail, variants, selectedVariant?.Variant?.SKUID ?? 0); // Displays the product detail page return(View(viewModel)); }
/// <summary> /// Returns tags with actual price and standard price if any. /// </summary> private string GetPriceResultView(SearchResult result, SKUInfo skuInfo) { ProductCatalogPrices skuPrice = GetProductCatalogPrices(skuInfo); if (skuPrice == null) { return($"<div class='product-tile-info'><span class='product-tile-price'>${result.Document["skuprice"]}</span>"); } var tagResult = new StringBuilder(); tagResult.AppendFormat("<div class='product-tile-info'><span class='product-tile-price'>${0}</span>", skuPrice.Price); if (skuPrice.Discounts.Any()) { tagResult.AppendFormat("<span class='product-tile-list-price'>${0}</span>", skuPrice.StandardPrice); } tagResult.Append("</div>"); return(tagResult.ToString()); }
/// <summary> /// Constructor for the ProductListItemViewModel class. /// </summary> /// <param name="productPage">Product's page.</param> /// <param name="priceDetail">Price of the product.</param> /// <param name="publicStatusName">Display name of the product's public status.</param> public ProductListItemViewModel(SKUTreeNode productPage, ProductCatalogPrices priceDetail, IPageUrlRetriever urlRetriever, string publicStatusName) { // Sets the page information Name = productPage.DocumentName; ProductUrl = urlRetriever.Retrieve(productPage); // Sets the SKU information ImagePath = string.IsNullOrEmpty(productPage.SKU.SKUImagePath) ? null : new FileUrl(productPage.SKU.SKUImagePath, true) .WithSizeConstraint(SizeConstraint.MaxWidthOrHeight(400)) .RelativePath; Available = !productPage.SKU.SKUSellOnlyAvailable || productPage.SKU.SKUAvailableItems > 0; PublicStatusName = publicStatusName; // Sets the price format information PriceModel = new PriceDetailViewModel { Price = priceDetail.Price, ListPrice = priceDetail.ListPrice, CurrencyFormatString = priceDetail.Currency.CurrencyFormatString }; }
//EndDocSection:DisplayProduct //DocSection:DisplayVariant /// <summary> /// Displays product detail page of a product or product variant. /// </summary> public ActionResult Detail() { // Gets the product from the connected Xperience database SKUTreeNode product = GetProduct(); // If the product is not found or if it is not allowed for sale, redirects to error 404 if ((product == null) || !product.SKU.SKUEnabled) { return(NotFound()); } // Gets all product variants of the product List <ProductVariant> variants = VariantHelper .GetVariants(product.NodeSKUID) .OnSite(siteService.CurrentSite.SiteID).ToList() .Select(sku => new ProductVariant(sku.SKUID)) .OrderBy(v => v.Variant.SKUPrice).ToList(); // Selects the first product variant ProductVariant selectedVariant = variants.FirstOrDefault(); // Calculates the price of the product or the variant ShoppingCartInfo cart = shoppingService.GetCurrentShoppingCart(); SKUInfo selectedProduct = selectedVariant != null ? selectedVariant.Variant : product.SKU; ProductCatalogPrices priceDetail = priceCalculatorFactory .GetCalculator(cart.ShoppingCartSiteID) .GetPrices(selectedProduct, Enumerable.Empty <SKUInfo>(), cart); // Initializes the view model of the product or product variant ProductViewModel viewModel = new ProductViewModel(product, priceDetail, variants, selectedVariant?.Variant?.SKUID ?? 0); // Displays the product detail page return(View(viewModel)); }
//EndDocSection:Constructor //DocSection:DisplayProduct /// <summary> /// Displays a product detail page of a product. /// </summary> public IActionResult BasicDetail() { // Gets the product from the connected Xperience database SKUTreeNode product = GetProduct(); // If the product is not found or if it is not allowed for sale, redirects to error 404 if ((product == null) || (product.SKU == null) || !product.SKU.SKUEnabled) { return(NotFound()); } // Initializes the view model of the product with a calculated price ShoppingCartInfo cart = shoppingService.GetCurrentShoppingCart(); ProductCatalogPrices price = priceCalculatorFactory .GetCalculator(cart.ShoppingCartSiteID) .GetPrices(product.SKU, Enumerable.Empty <SKUInfo>(), cart); // Fills the product model with retrieved data ProductViewModel viewModel = new ProductViewModel(product, price); // Displays the product details page return(View("Detail", viewModel)); }
/// <summary> /// Creates a new product model. /// </summary> /// <param name="productPage">Product's page.</param> /// <param name="priceDetail">Price of the product.</param> public ProductViewModel(SKUTreeNode productPage, ProductCatalogPrices priceDetail) { // Fills the page information Name = productPage.DocumentName; Description = productPage.DocumentSKUDescription; ShortDescription = productPage.DocumentSKUShortDescription; ProductPageGuid = productPage.NodeGUID; ProductPageAlias = productPage.NodeAlias; // Fills the SKU information SKUInfo sku = productPage.SKU; SKUID = sku.SKUID; ImagePath = sku.SKUImagePath; IsInStock = sku.SKUTrackInventory == TrackInventoryTypeEnum.Disabled || sku.SKUAvailableItems > 0; PriceDetail = new PriceDetailViewModel() { Price = priceDetail.Price, ListPrice = priceDetail.ListPrice, CurrencyFormatString = priceDetail.Currency.CurrencyFormatString }; }
//EndDocSection:DifferentShippingAddress private object DummyEcommerceMethod() { ShoppingCartInfo shoppingCart = null; SKUInfo productSku = null; ProductVariant variant = null; SKUTreeNode product = null; SKUInfo sku = null; DummyViewModel model = null; OrderInfo order = null; PaymentResultInfo result = null; //DocSection:CalculatePriceOptions ProductCatalogPrices productPrice = Service.Resolve <ICatalogPriceCalculatorFactory>() .GetCalculator(shoppingCart.ShoppingCartSiteID) .GetPrices(productSku, Enumerable.Empty <SKUInfo>(), shoppingCart); //EndDocSection:CalculatePriceOptions //DocSection:FormatPriceOptions decimal price = 5.50M; string formattedPrice = String.Format(shoppingCart.Currency.CurrencyFormatString, price); //EndDocSection:FormatPriceOptions //DocSection:VariantDisplayImg var response = new { // ... imagePath = Url.Content(variant.Variant.SKUImagePath) }; //EndDocSection:VariantDisplayImg //DocSection:DisplayAttributeSelection // Gets the cheapest variant of the product List <ProductVariant> variants = VariantHelper.GetVariants(product.NodeSKUID).OnSite(SiteContext.CurrentSiteID).ToList() .Select(s => new ProductVariant(s.SKUID)) .OrderBy(v => v.Variant.SKUPrice).ToList(); ProductVariant cheapestVariant = variants.FirstOrDefault(); // Gets the product's option categories IEnumerable <OptionCategoryInfo> categories = VariantHelper.GetProductVariantsCategories(sku.SKUID).ToList(); // Gets the cheapest variant's selected attributes IEnumerable <ProductOptionCategoryViewModel> variantCategories = cheapestVariant?.ProductAttributes.Select( option => new ProductOptionCategoryViewModel(sku.SKUID, option.SKUID, categories.FirstOrDefault(c => c.CategoryID == option.SKUOptionCategoryID))); //EndDocSection:DisplayAttributeSelection //DocSection:ShippingIsDifferent if (model.IsShippingAddressDifferent) { // ... } //EndDocSection:ShippingIsDifferent //DocSection:DifferentPaymentMethods if (shoppingCart.PaymentOption.PaymentOptionName.Equals("PaymentMethodCodeName")) { return(RedirectToAction("ActionForPayment", "MyPaymentGateway")); } //EndDocSection:DifferentPaymentMethods //DocSection:SetPaymentResult order.UpdateOrderStatus(result); //EndDocSection:SetPaymentResult //DocSection:RedirectForManualPayment return(RedirectToAction("ThankYou", new { orderID = order.OrderID })); //EndDocSection:RedirectForManualPayment }