Error executing template "Designs/Tapas/Firstweb.HtmlOutput/ordertemplate_Products.cshtml"
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
   at System.ThrowHelper.ThrowKeyNotFoundException()
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at CompiledRazorTemplates.Dynamic.RazorEngine_527c931f00524b55b8c5bd013abd33c9.Execute() in D:\dynamicweb.net\Solutions\diesella.BC.LIVE\Files\Templates\Designs\Tapas\Firstweb.HtmlOutput\ordertemplate_Products.cshtml:line 685
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits RazorTemplateBase<RazorTemplateModel<Template>> 2 @using Dynamicweb.Rendering; 3 @using Dynamicweb.Environment; 4 5 6 @inherits RazorTemplateBase<RazorTemplateModel<Template>> 7 @using Dynamicweb.Rendering; 8 @using System.Text.RegularExpressions; 9 @using Firstweb.Custom.CustomCode.Models; 10 11 @functions 12 { 13 public AsyncProductInfo getAsyncProductInfo(LoopItem product) 14 { 15 return getAsyncProductInfo(product.GetString("Ecom:Product.ID"), product.GetString("Ecom:Product.DefaultUnitID"), "no", product.GetString("Ecom:Product.Price.PriceWithoutVATFormatted"), product.GetString("Ecom:Product.Price.PriceWithVATFormatted"), product.GetString("Firstweb:EcomProduct:BruttoPriceFormattedWithSymbol"), product.GetString("Firstweb:EcomProduct:BruttoPriceFormattedWithSymbol"), product.GetString("Ecom:Product.Stock")); 16 } 17 18 public AsyncProductInfo getAsyncProductInfo(string productId, string unitId, string hasQtyPrices, string netUnitPricePriceWithoutVatFormatted, string netUnitPricePriceWithVatFormatted, string unitPricePriceWithoutVatFormatted, string unitPricePriceWithVatFormatted, string inventory) 19 { 20 string unitTranslated = Translate("Product.Units:" + unitId, unitId.ToLower()); 21 22 var productInfo = new Firstweb.Custom.CustomCode.Models.AsyncProductInfo() 23 { 24 ProductId = productId, 25 UnitOfMeasure = unitTranslated, 26 HasQtyPrices = hasQtyPrices, 27 NetUnitPricePriceWithoutVatFormatted = netUnitPricePriceWithoutVatFormatted, 28 NetUnitPricePriceWithVatFormatted = netUnitPricePriceWithVatFormatted, 29 UnitPricePriceWithoutVatFormatted = unitPricePriceWithoutVatFormatted, 30 UnitPricePriceWithVatFormatted = unitPricePriceWithVatFormatted, 31 Inventory = inventory 32 }; 33 34 return productInfo; 35 36 } 37 38 } 39 40 41 @helper renderProduct(bool showShopFunctionsAlternativeIfNotLoggedIn, LoopItem product, bool renderAs4Cols = false) 42 { 43 bool isBlocked = product.GetBoolean("Ecom:Product:Field.NAVIsBlocked"); 44 45 string productID = product.GetString("Ecom:Product.ID"); 46 string productNumber = product.GetString("Ecom:Product.Number"); 47 string mainProductID = product.GetString("Ecom:Product:Field.FirstwebMainProductID"); 48 string PrimaryProductPageId = Firstweb.Custom.CustomCode.Tapas.Context.AreaPages.GetPageId("productcatalog"); 49 50 string productLink = product.GetString("Ecom:Product.Link.Clean"); 51 52 if (!String.IsNullOrEmpty(PrimaryProductPageId)) 53 { 54 productLink = "/Default.aspx?id=" + PrimaryProductPageId + "&productid=" + productID; 55 } 56 57 string languageId = product.GetString("Ecom:Product.LanguageID"); 58 string variantId = product.GetString("Ecom:Product.VariantID"); 59 60 string productName = product.GetString("Ecom:Product.Name"); 61 string productShortDescription = product.GetString("Ecom:Product.ShortDescription"); 62 63 string nettoPrice = product.GetString("Firstweb:ErpPriceInfo.NettoPriceFormatted"); 64 string bruttoPrice = product.GetString("Firstweb:EcomProduct:BruttoPriceFormattedWithSymbol"); 65 66 string price = Firstweb.Custom.CustomCode.Frontend.Helpers.Product.HideVat() ? GetString("Ecom:Product.Price.PriceWithoutVATFormatted") : GetString("Ecom:Product.Price.PriceWithVATFormatted"); 67 68 string availableAmount = product.GetString("Firstweb:ErpStockInfo.StockQuantity"); 69 string stockColor = product.GetString("Firstweb:ErpStockInfo.StockColor"); 70 bool priceAndStockFound = product.GetBoolean("Firstweb:ErpPriceInfo.PriceAndStockFound"); 71 bool priceFound = product.GetBoolean("Firstweb:ErpPriceInfo.PriceFound"); 72 bool hasQuantityPrices = product.GetBoolean("Firstweb:ErpPriceInfo.HasQuantityPrices"); 73 string RRPrice = product.GetString("Firstweb:ErpPriceInfo:Prices.RRPFormatted"); 74 75 int productPackagingQuantity = product.GetInteger("Ecom:Product:Field.NAVMinQuantity"); 76 int defaultQuantity = productPackagingQuantity > 0 ? productPackagingQuantity : 1; 77 78 bool hasVariants = (product.GetLoop("VariantCombinations").Count() > 0); 79 80 string primaryProductImageUrl = "/admin/public/getimage.ashx?altFmImage_path=/Files/Images/ecom/Products/no-image.jpg&width=250&height=150&Compression=90&Crop=5&image=" + product.GetString("Ecom:Product.ImageDefault.Clean"); 81 82 //Other packagings 83 var otherPackagingProducts = Firstweb.Custom.CustomCode.Frontend.Helpers.OtherPackagingProducts.GetOtherPackagingProducts(mainProductID, false).Where(i => i.Id != productID); 84 var showOtherPackagingProducts = otherPackagingProducts.Count() > 0; 85 86 87 //Customer product number 88 //string customerProductNumber = Firstweb.Custom.CustomCode.Frontend.Helpers.CustomerProductNumbers.GetCustomerProductNumber(productID); 89 90 //OrderTemplate 91 int productInFavoritLists = product.GetInteger("Firstweb:Ecom:Product:OrderTemplate.InTemplates.Count"); 92 93 string orderLineId = product.GetString("Firstweb:OrderTemplate:Line.ID"); 94 string orderTemplateId = product.GetString("Firstweb:OrderTemplate:Line.OrderTemplateID"); 95 int orderLineQuantity = product.GetInteger("Firstweb:OrderTemplate:Line.Quantity"); 96 97 bool inFavourite = productInFavoritLists > 0 ? true : false; 98 string inFavouriteBoolJS = inFavourite.ToString().ToLower(); 99 100 bool isOrderTemplate = !String.IsNullOrEmpty(orderLineId); 101 102 string productPriceCacheKey = orderLineId != "" ? orderLineId : productNumber; 103 104 string UnitPriceFormatted = product.GetString("Firstweb:EcomProduct:BruttoPriceFormattedWithSymbol"); 105 106 107 string stock = ""; 108 string loadingClass = ""; 109 110 string addBorderCss = isOrderTemplate ? "border-1" : ""; 111 112 113 if (!priceAndStockFound) 114 { 115 stock = "asyncLoad"; 116 loadingClass = "asyncLoad"; 117 } 118 else 119 { 120 stock = availableAmount; 121 } 122 123 string WidthClass = renderAs4Cols ? "col-md-4 col-lg-3" : "col-md-4"; 124 bool ShowShopFunctions = Firstweb.Custom.CustomCode.Tapas.Context.Current.ShopFunctionsVisibility.ShowShopFunctions(); 125 string BrandLogo = "/admin/public/getimage.ashx?image=" + product.GetString("Ecom:Product:Field.FirstwebBrandLogo.Value.FullPath") + "&height=25&crop=5"; 126 string BrandName = product.GetString("Ecom:Product:Field.FirstwebBrand.Value.Clean"); 127 string AddingToCartText = Translate("Product.AddingToCart", "Tilføjer produkt"); 128 string PickListText = Translate("Ordertemplate.SelectList", "Vælg en liste"); 129 bool ShowBeforePrice = product.GetBoolean("Firstweb:EcomProduct:DisplayBeforePrice"); 130 string BeforePriceFormatted = product.GetString("Firstweb:EcomProduct:BeforePriceFormattedWithSymbol"); 131 string StockStatus = product.GetString("Firstweb:StockStatusColor"); //hvis rød og confirmed deliverydate - hvis dato 132 string StockLabel = product.GetString("Firstweb:StockStatusTitle"); 133 string TranslatedStock = ""; 134 if (StockStatus == "red") 135 { 136 TranslatedStock = Translate("StockStatus.Red", StockLabel); 137 } 138 else if (StockStatus == "yellow") 139 { 140 TranslatedStock = Translate("StockStatus.Yellow", StockLabel); 141 } 142 else 143 { 144 TranslatedStock = Translate("StockStatus.Green", StockLabel); 145 } 146 string Collisize = product.GetString("Ecom:Product:Field.NAVColli"); 147 string CatalogueRemark = product.GetString("Ecom:Product:Field.NAVCatalogRemark.Value"); 148 bool HidePrices = Firstweb.Custom.CustomCode.Frontend.Helpers.Product.HidePrices(); 149 string HidePriceClass = HidePrices ? "hidden" : ""; 150 bool hideVAT = Firstweb.Custom.CustomCode.Frontend.Helpers.Product.HideVat(); 151 string currency = product.GetString("Ecom:Product.Currency.Code"); 152 string unitID = product.GetString("Ecom:Product.DefaultUnitID"); 153 string unitTranslated = Translate("Product.Units:" + unitID, unitID.ToLower()); 154 155 string cartContext = Firstweb.Custom.CustomCode.Frontend.Helpers.Cart.GetCurrentCartContext(); 156 string firstwebMultiunitPriceinfo = product.GetString("Ecom:Product:Field.FirstwebMultiunitPriceinfo.Value.Clean"); 157 bool firstWebNoStockItem = product.GetBoolean("Ecom:Product:Field.FirstwebNoStockItem.Value"); 158 IEnumerable<Dynamicweb.Ecommerce.Products.ProductRelated> replacementProducts = Firstweb.Custom.CustomCode.Frontend.Helpers.Product.GetReplacementProducts(productID); 159 string[] ProductHighlights = product.GetString("Ecom:Product:Field.ProductHighlights.Value.Clean").Split(','); 160 161 162 <!-- ko viewModel: 'ProductViewModel'--> 163 <!-- ko initValue: {observable: ProductId, value:'@productID'}--><!-- /ko--> 164 <div class="col-xs-12 col-sm-6 @WidthClass xs-m-b-3 price @loadingClass" 165 data-productid="@productID" 166 data-productkey="@productPriceCacheKey" 167 data-test="@PrimaryProductPageId" 168 data-currency="@currency" 169 data-unitid="@unitID"> 170 <div class="hidden js-hide-vat">@hideVAT.ToString().ToLower()</div> 171 <div class="hidden js-hide-prices">false</div> 172 <div class="product-list-item bg-white position-relative"> 173 @if (ProductHighlights.Any()) 174 { 175 <div class="product-splash-container"> 176 @foreach (var ph in ProductHighlights) 177 { 178 <div class="product-splash product-splash--@ph.ToLower()"> 179 @Translate("ProductSplash." + ph, ph) 180 </div> 181 } 182 </div> 183 } 184 <a href="@productLink"> 185 @if (!String.IsNullOrEmpty(CatalogueRemark)) 186 { 187 <div class="catalogue-remark">@CatalogueRemark</div> 188 } 189 <div class="brand-image"> 190 @if (!String.IsNullOrEmpty(product.GetString("Ecom:Product:Field.FirstwebBrandLogo.Value.FullPath"))) 191 { 192 <img src="@BrandLogo" alt="@BrandName" /> 193 } 194 </div> 195 <div class="product-image"> 196 <img src="@primaryProductImageUrl" alt="@productName" /> 197 </div> 198 <div class="product-info"> 199 <p class="product-number">@Translate("Product.NumberShort", "Varenr.") @productNumber</p> 200 <p class="product-name">@productName</p> 201 202 </div> 203 @if (!isBlocked) 204 { 205 if (ShowShopFunctions) 206 { 207 <div class="productlist-price-area js-productlist-price-area"> 208 209 <div class="js-spinner text-center"> 210 <i class="fas fa-spinner fa-pulse font-size-24px"></i> 211 </div> 212 <div class="hidden js-async-price"> 213 @*<p> 214 <span class="price-display-medium-label">@Translate("Product.NormalPrice","Normalpris")</span> 215 <span class="price-display-medium js-price-display-medium"> 216 <s>@bruttoPrice</s> 217 </span> 218 </p>*@ 219 <p> 220 <span class="price-display-medium-label">@Translate("Product.UnitPrice", "Unitpris")</span> 221 <span class="price-display-medium">@UnitPriceFormatted</span> 222 </p> 223 <p class="@HidePriceClass"><span class="price-display-large js-price-display-large"></span></p> 224 <p class="@HidePriceClass"><span>@Translate("PricePerBox", "Pris pr.")&nbsp;@unitTranslated<span class="js-unit-of-measure hidden"></span></span></p> 225 226 @*@if (ShowBeforePrice) 227 { 228 <p><span class="price-display-medium-label">@Translate("Product.Beforeprice","F&oslash;rpris")</span> <span class="price-display-medium">@BeforePriceFormatted</span></p> 229 }*@ 230 </div> 231 </div> 232 <p class="product-price"> 233 @RRPrice 234 </p> 235 236 } 237 } 238 239 </a> 240 @if (!isBlocked) 241 { 242 <div class="add-to-cart-area"> 243 244 @if (ShowShopFunctions) 245 { 246 if (isOrderTemplate) 247 { 248 <!-- ko initValue: {observable: Quantity, value:@orderLineQuantity}--><!-- /ko--> 249 } 250 else 251 { 252 <!-- ko initValue: {observable: Quantity, value:@defaultQuantity}--><!-- /ko--> 253 } 254 255 } 256 257 258 <input class="product-quantity js-product-quantity" type="number" name="quantity" data-bind="value: Quantity" /> 259 <div class="btn btn-primary js-product-buy-btn" 260 data-bind="click: function() { $parent.addItemToCart(ProductId(), Quantity(), '', '', '', '@AddingToCartText', '@cartContext') }" 261 data-productid="@productID"> 262 <span data-bind="if: $root.User().IsLoggedIn()"> 263 @Translate("Product.AddToCart", "TILFØJ TIL KURV") 264 </span> 265 <span data-bind="if: !$root.User().IsLoggedIn()"> 266 @Translate("Product.GetPriceOffer", "Forespørg pris") 267 </span> 268 </div> 269 270 271 @if (ShowShopFunctions) 272 { 273 <div class="not-in-stock-indicator js-not-in-stock-indicator hide"> 274 <p>@Translate("Product.NotInStock", "Ikke p&aring; lager")</p> 275 </div> 276 277 if (!isOrderTemplate) 278 { 279 <div class="favorite-list-icon" data-toggle="modal" data-target="#modal-@productID" data-bind="with: OrderTemplateViewModel"> 280 <i class="fa-heart" data-bind=" 281 oninit: function() { IsInFavoriteList('@inFavourite'.toLowerCase()) }, 282 css : { showFavorite : ShowOrderTemplateDialog, showNewList : OrderTemplateShowNewList, fas: IsInFavoriteList() == 'true', far: IsInFavoriteList() == 'false' }, 283 visible: $root.User().IsLoggedIn(), 284 click: ToggleOrderTemplateDialog"> 285 </i> 286 </div> 287 <div class="modal fade" id="modal-@productID" tabindex="-1" role="dialog" data-bind="with: OrderTemplateViewModel"> 288 289 <!-- ko initValue: {observable: OrderTemplateRelationCount, value:'@productInFavoritLists'}--><!-- /ko--> 290 <!-- ko initValue: {observable: ShowInFavourite, value: @inFavouriteBoolJS}--><!-- /ko--> 291 <!-- ko initValue: {observable: ModalSelector, value: '#modal-@productID'}--><!-- /ko--> 292 <div class="modal-dialog" role="document"> 293 <div class="modal-content fav-list"> 294 295 <p class="favlist-header">@Translate("Ordertemplate.AddToExistingList", "Tilføj til eksisterende favoritliste")</p> 296 297 <div class="existing-lists"> 298 299 <select class="favField select-fix" 300 data-bind="options: OrderTemplateList, 301 optionsCaption: '@PickListText', 302 optionsText: function(item) { return item.Value.Name() + ' (' + item.Value.Count() + ')' }, 303 value: OrderTemplateSelectedList"></select> 304 305 <input class="product-quantity" type="number" name="quantity" data-bind="textInput: OrderTemplateQuantity" /> 306 307 <div class="btn btn-primary" 308 data-bind="click: function() { 309 OrderTemplateShowNewList() 310 ? CreateNewOrderTemplateList('@productID') 311 : AddProductToOrderTemplate('@productID' , OrderTemplateQuantity()) 312 }"> 313 @Translate("Ordertemplate.AddToList", "Tilføj") 314 </div> 315 316 </div> 317 318 <p class="or-text">@Translate("Ordertemplate.OrNewList", "eller...")</p> 319 320 <p class="favlist-header">@Translate("Ordertemplate.AddToNewList", "Tilføj til ny favoritliste")</p> 321 322 <form id="EditForm-@productID" 323 name="EditForm"> 324 <label class="xs-m-b-1" for="name">@Translate("Ordertemplate.ListName", "Favoritliste navn")</label> 325 <div class="new-list"> 326 <input type="text" 327 name="name" 328 _id="name" 329 data-bind="textInput: OrderTemplateNewListName" 330 autofocus 331 autocomplete="off" /> 332 333 <input class="product-quantity" type="number" name="quantity" data-bind="textInput: OrderTemplateNewListQuantity" /> 334 335 <button type="submit" 336 class="btn btn-primary" 337 _id="btnSave" 338 data-bind="click: function() { CreateNewOrderTemplateList('@productID', OrderTemplateNewListQuantity()) }"> 339 @Translate("Ordertemplate.SaveToNewList", "Tilføj til ny favoritliste") 340 </button> 341 </div> 342 </form> 343 344 </div> 345 </div> 346 </div> 347 } 348 else 349 { 350 <div class="favorite-list-icon" data-bind="with: OrderTemplateViewModel"> 351 352 <!-- ko initValue: {observable: OrderTemplateId, value:'@orderTemplateId'}--><!-- /ko--> 353 <!-- ko initValue: {observable: OrderTemplateLineId, value:'@orderLineId'}--><!-- /ko--> 354 <i class="fas fa-times" 355 data-bind=" 356 oninit: function() { IsInFavoriteList('@inFavourite'.toLowerCase()) }, 357 css: { showFavorite: ShowOrderTemplateDialog, showNewList: OrderTemplateShowNewList, active: IsInFavoriteList() == 'true' }, 358 click: DeleteOrderTemplateLine"> 359 </i> 360 </div> 361 } 362 363 } 364 </div> 365 366 if (ShowShopFunctions) 367 { 368 if (!HidePrices) 369 { 370 <div class="xs-m-t-1 @HidePriceClass quantity-prices-container" data-qpproductid="@productID"> 371 @RenderQuantityPrices(productID) 372 </div> 373 } 374 375 if (firstWebNoStockItem) 376 { 377 <div class="is-flex is-flex-align-center margin-top-6px" data-stock-productid="@(productID)"> 378 <i class="fas fa-truck-moving font-size-16px color-green"></i> 379 <div class="margin-left-8px">@Translate("Product.NoStockItem", "Bestilingsvare")</div> 380 </div> 381 } 382 else 383 { 384 <div class="stock-indicator" data-stock-productid="@(productID)"> 385 <span class="stock-load-async" style="background-color: @StockStatus"></span> 386 <span class="_js-stock-amount"></span> 387 <span>&nbsp;</span> 388 <span class="stock-name">@TranslatedStock</span> 389 <span class="stock-name js-in-stock-again hide">@Translate("Product.StockExpectedAgaing", "P&aring; lager: ")<span class="js-stock-date"></span></span> 390 </div> 391 } 392 } 393 394 } 395 else 396 { 397 @RenderReplacementProducts(replacementProducts) 398 } 399 </div> 400 401 </div> 402 <!-- /ko--> 403 } 404 405 406 @helper RenderQuantityPrices(string productId) 407 { 408 <div class="quantity-prices" data-bind="getQuantityPrices: { productId: '@productId', pageId: '', linkText: ''}"> 409 <span> 410 @Translate("QuantityPrices.Text", "% k&oslash;b flere spar mere") 411 </span> 412 413 <i class="fal fa-chevron-down"></i> 414 <div class="quantity-prices-results js-results"> 415 <div class="js-quantity-discount-html"></div> 416 </div> 417 </div> 418 } 419 420 421 @helper renderRelatedProduct(LoopItem repatedProduct) 422 { 423 string productID = repatedProduct.GetString("Ecom:Product.ID"); 424 string productNumber = repatedProduct.GetString("Ecom:Product.Number"); 425 string mainProductID = GetString("Ecom:Product:Field.FirstwebMainProductID"); 426 427 string productName = repatedProduct.GetString("Ecom:Product.Name"); 428 string productDescription = GetString("Ecom:Product.LongDescription"); 429 string productShortDescription = GetString("Ecom:Product.ShortDescription"); 430 431 string nettoPrice = repatedProduct.GetString("Firstweb:ErpPriceInfo.NettoPriceFormatted"); 432 int bruttoPrice = repatedProduct.GetInteger("Firstweb:ErpPriceInfo.BruttoAmountFormattedNoSymbol"); 433 434 int productPackagingQuantity = repatedProduct.GetInteger("Ecom:Product:Field.NAVMinQuantity"); 435 int defaultQuantity = productPackagingQuantity > 0 ? productPackagingQuantity : 1; 436 437 string languageId = repatedProduct.GetString("Ecom:Product.LanguageID"); 438 string variantId = repatedProduct.GetString("Ecom:Product.VariantID"); 439 440 int productInFavoritLists = GetInteger("Firstweb:Ecom:Product:OrderTemplate.InTemplates.Count"); 441 442 string primaryProductImageUrl = "/admin/public/getimage.ashx?altFmImage_path=/Files/Images/ecom/Products/no-image.jpg&width=250&height=150&Compression=90&Crop=5&image=" + repatedProduct.GetString("Ecom:Product.ImageDefault.Clean"); 443 444 445 446 <li> 447 <article class="xs-p-2 lg-p-1 rounded-5 border-1 border-color-default"> 448 <div class="row is-flex xs-is-flex-column sm-is-flex-col md-is-flex-col"> 449 450 <div class="col-md-12 md-is-flex lg-p-r-0"> 451 <section class="col-md-3 col-lg-3 xs-p-0 md-p-l-0 md-p-r-1 lg-p-r-1 lg-p-l-0"> 452 <img class="img-responsive xs-auto-margin sm-auto-margin" src="@primaryProductImageUrl" /> 453 </section> 454 455 <section class="col-md-9 col-lg-7 xs-m-t-2 sm-m-t-2 md-m-t-0 xs-p-0 md-p-r-0 md-p-l-1 lg-p-r-0 lg-p-l-0"> 456 <header class="xs-m-b-1"> 457 <h2 data-bind="text: name" 458 class="h2 tertiary-font xs-m-t-0"> 459 @productName 460 </h2> 461 </header> 462 463 <section class="xs-m-b-1 clearfix"> 464 <span class="pull-left font-size-small"> 465 @Translate("Product.NumberShort", "Varenr."): <span>@productNumber</span> 466 </span> 467 </section> 468 469 <section class="word-break"> 470 <p class="font-size-small"> 471 @productShortDescription 472 </p> 473 </section> 474 </section> 475 </div> 476 477 <section class="col-md-9 col-md-offset-3 col-lg-5 col-lg-offset-0 sm-m-t-1 lg-m-t-0 md-p-l-2 478 lg-p-l-0 is-flex is-flex-col sm-is-flex-row sm-is-flex-wrap sm-flex-justify-space-between 479 md-is-flex-row md-is-flex-wrap md-flex-justify-space-between lg-flex-grow-2 lg-flex-justify-space-between"> 480 481 <div class="is-flex xs-m-t-1 sm-m-t-0 is-flex-col lg-m-b-auto"> 482 483 </div> 484 485 <div class="is-flex is-flex-col md-m-b-1 lg-m-b-0"> 486 <h4 class="h4 tertiary-font font-size-16px xs-m-b-1 sm-m-t-0 md-text-right lg-text-right"> 487 @nettoPrice 488 </h4> 489 490 <section class="xs-m-b-1 clearfix is-flex xs-flex-space-between lg-is-row-reverse"> 491 <div class="pull-right margin-left-1 xs-order-1 sm-order-1 md-order-1 xs-is-self-end sm-is-self-end md-is-self-end lg-m-t-0"> 492 @renderQuantityBox(defaultQuantity) 493 </div> 494 495 <div class="is-flex is-flex-col is-centered xs-margin-right-auto sm-m-r-1 md-m-r-1 font-size-small line-height-base md-text-right lg-text-right"> 496 <span>@Translate("Product.Packaging", "Forpakning"): </span> 497 <span> @productPackagingQuantity</span> 498 </div> 499 </section> 500 </div> 501 502 <section class="t-align-right clearfix sm-width-100 md-width-100"> 503 <button _data-bind="click: handleAddProductToCart" 504 class="btn btn-primary btn-xs tertiary-font lg-p-l-1 lg-p-r-1 xs-width-100 sm-width-100 md-width-100"> 505 @Translate("Product.AddToCart", "Tilføj til kurv") 506 </button> 507 </section> 508 </section> 509 510 </div> 511 </article> 512 </li> 513 514 515 516 } 517 518 @helper renderProductBuyBox(bool showShopFunctionsAlternativeIfNotLoggedIn, string productName, string productId, string price, int productPackagingQuantity, int quantity, string stockColor) 519 { 520 521 522 <article class="product-packaging border-bottom-1"> 523 <section class="row md-is-flex lg-is-flex md-is-flex-center lg-is-flex-center"> 524 <section class="packaging-section col-md-4 col-lg-5"> 525 <h4 class="h4 xs-m-t-0 xs-m-b-0 tertiary-font v-align-mid">@productName</h4> 526 </section> 527 528 529 530 @if (Firstweb.Custom.CustomCode.Tapas.Context.Current.ShopFunctionsVisibility.ShowShopFunctions()) 531 { 532 <section class="packaging-section md-p-l-0 xs-col-12 col-md-2 col-lg-2 tertiary-font"> 533 <span>@price</span> 534 535 536 </section> 537 <div class="stock md-is-self-end lg-is-self-end lg-order-0"> 538 @Translate("Product.StockStatus", "Lagerstatus"): <div class="stock-load-async @stockColor"></div> 539 540 </div> 541 <section class="packaging-section md-p-l-0 lg-p-r-8p packaging-section--alt xs-col-12 col-md-4 col-lg-3"> 542 <ul class="list-unstyled lg-m-l-auto lg-p-r-24p xs-m-b-0"> 543 <li> 544 <h5 class="h5 xs-m-b-0 xs-m-t-0 line-height-16px"> 545 <span>@Translate("Product.Packaging", "Forpakning"): </span> 546 <span> @productPackagingQuantity</span> 547 </h5> 548 </li> 549 </ul> 550 551 @renderQuantityBox(quantity) 552 553 </section> 554 555 <section class="packaging-section md-p-l-0 packaging-section--buy xs-col-12 col-md-2 col-lg-2 t-align-right"> 556 <button class="btn btn-primary btn-xs tertiary-font lg-p-l-1 lg-p-r-1 xs-width-100 sm-width-100 margin-bottom-4px" 557 _data-bind="click: handleAddProductToCart"> 558 @Translate("Product.AddToCart", "Tilføj til kurv") 559 </button> 560 </section> 561 562 } 563 else if (showShopFunctionsAlternativeIfNotLoggedIn) 564 { 565 var replaceWith = Firstweb.Custom.CustomCode.Tapas.Context.Current.ShopFunctionsVisibility.ReplaceWith(); 566 567 <section> 568 569 @if (replaceWith == "LOGIN") 570 { 571 <text>@renderLogin()</text> 572 } 573 else if (replaceWith == "RESELLER") 574 { 575 <text>@renderResellerLink()</text> 576 } 577 </section> 578 } 579 580 </section> 581 </article> 582 } 583 584 585 @helper renderInstantSearchProduct(LoopItem product) 586 { 587 bool isBlocked = product.GetBoolean("Ecom:Product:Field.NAVIsBlocked"); 588 string productID = product.GetString("Ecom:Product.ID"); 589 string productNumber = product.GetString("Ecom:Product.Number"); 590 string mainProductID = product.GetString("Ecom:Product:Field.FirstwebMainProductID"); 591 592 string productLink = product.GetString("Ecom:Product.Link.Clean"); 593 594 string productName = product.GetString("Ecom:Product.Name"); 595 string productShortDescription = product.GetString("Ecom:Product.ShortDescription"); 596 597 int productPackagingQuantity = product.GetInteger("Firstweb:ErpPriceInfo:ExtraInfos.PackagingSize"); 598 int defaultQuantity = productPackagingQuantity > 0 ? productPackagingQuantity : 1; 599 600 string languageId = product.GetString("Ecom:Product.LanguageID"); 601 string variantId = product.GetString("Ecom:Product.VariantID"); 602 603 bool hasVariants = (product.GetLoop("VariantCombinations").Count() > 0); 604 605 //Images 606 string primaryProductImageUrl = "/admin/public/getimage.ashx?altFmImage_path=/Files/Images/ecom/Products/no-image.jpg&width=200&height=125&Compression=90&Crop=5&image=" + product.GetString("Ecom:Product.ImageDefault.Clean"); 607 608 int loopCount = product.GetInteger("Products.LoopCounter") - 1; 609 string loadingPage = Translate("InstantSearch.LoadingPage", "Indl&aelig;ser side"); 610 <div class="col-xs-12 col-sm-3 xs-m-b-1"> 611 612 <article class="instant-search-product bg-white productCount @loopCount" data-bind="css: {'item--selected': navSelectedItem() == @loopCount}"> 613 <div class="cursor-pointer info" 614 data-bind="click: function() { window.location.href='@productLink';stuffLoadingQueue({load: true, text: '@loadingPage'})}"> 615 <div class="product-image xs-m-b-2"> 616 <img class="img-responsive center-block" src="@primaryProductImageUrl"> 617 </div> 618 619 <div class="name"> 620 <p>@productName</p> 621 622 623 <span>@Translate("Product.NumberShort", "Varenr.") @productNumber</span> 624 </div> 625 </div> 626 627 @if (Firstweb.Custom.CustomCode.Tapas.Context.Current.ShopFunctionsVisibility.ShowShopFunctions()) 628 { 629 <div class="buy-container" data-bind="defineObservable: { quantity: 1 }"> 630 631 <input class="product-quantity" type="number" name="quantity" data-bind="value: quantity" /> 632 633 <button class="btn btn-primary btn-xs add-to-cart" 634 data-bind="click: function(evt) { $parent.onAddToCart('@productID', quantity()) }"> 635 @Translate("Product.AddToCart", "Tilføj til kurv") 636 </button> 637 </div> 638 } 639 </article> 640 641 </div> 642 643 } 644 645 646 647 @helper renderQuantityBox(int quantity) 648 { 649 <input class="product-quantity" type="number" name="quantity" value="@quantity" /> 650 } 651 652 653 @helper renderLogin() 654 { 655 <button class="btn btn-primary" data-toggle="modal" data-target=".loginModal">@Translate("Product.LoginToShop", "Log ind for at købe")</button> 656 } 657 @helper renderResellerLink() 658 { 659 <a href="@Firstweb.Custom.CustomCode.Tapas.Context.Current.ShopFunctionsVisibility.ReplaceLink()" class="btn btn-primary">@Translate("Product.FindReseller", "Find forhandler")</a> 660 } 661 662 @helper RenderReplacementProducts(IEnumerable<Dynamicweb.Ecommerce.Products.ProductRelated> replacementProducts) 663 { 664 <div class="blocked-product"> 665 <p class="blocked-product-header">@Translate("Product.ProductIsBlocked", "Varen er udg&aring;et")</p> 666 <div class="replacement-products" data-bind="replacementProducts"> 667 <span> 668 @Translate("ReplacementProducts.Text", "Se erstatningsvarer") 669 </span> 670 <i class="fas fa-sort-down"></i> 671 <div class="replacement-products-results js-results"> 672 673 @foreach (var replacementProduct in replacementProducts) 674 { 675 <p class="xs-m-b-0">@replacementProduct.Product.Number</p> 676 } 677 678 </div> 679 </div> 680 </div> 681 } 682 683 @{ 684 var CustomerOrderTemplates = Firstweb.OrderTemplate.OrderTemplates.Instance(); 685 var OrderTemplate = CustomerOrderTemplates.Templates[Dynamicweb.Context.Current.Request.GetString("otid")]; 686 var DwRender = new Dynamicweb.Ecommerce.Frontend.Renderer(Dynamicweb.Frontend.PageView.Current()); 687 string ReturnUrlOnDelete = GetString("Firstweb:HtmlOutput.Link1"); 688 string missingTextCss = string.IsNullOrEmpty( OrderTemplate.CreatedByUserName ) ? "is-flex is-flex-col is-flex-end" : ""; 689 } 690 <div class="bg-white"> 691 <div class="container"> 692 <div class="row"> 693 <div class="col-xs-12"> 694 <div class="listsOverview" data-bind="viewModel: 'OrderTemplatePageViewModel'"> 695 <!-- ko initValue: {observable: OrderTemplateName, value:'@OrderTemplate.Name'}--><!-- /ko--> 696 <!-- ko initValue: {observable: OrderTemplateId, value:'@OrderTemplate.ID'}--><!-- /ko--> 697 <div class="ordertemplateheader is-flex xs-is-flex-column sm-is-flex-col is-space-between" 698 data-otid="@OrderTemplate.ID"> 699 700 <div class="headline" 701 data-bind="loadOnBool: { observableBool: CartLoading, 702 text: '@Translate("addproducts", "Tilf&oslash;jer produkter")' }"> 703 <section class="xs-p-t-3 xs-p-b-2"> 704 <h1 class="font-strong xs-m-t-0" data-bind="text: OrderTemplateName"></h1> 705 706 </section> 707 708 <!-- section to edit fav list name start --> 709 <div data-bind="if: OrderTemplateEdit"> 710 <div class="form-group"> 711 <div class="form-inline"> 712 <div class="toggleEditFavCart">@Translate("EditOrderTemplateName", "Nyt navn")</div> 713 <input class="favField form-control" data-bind="value: OrderTemplateName, valueUpdate: 'afterkeydown'" /> 714 <button class="btn btn-primary btn-sm xs-width-100 xs-m-t-1 sm-m-t-0" 715 data-bind="click: SaveName"> 716 @Translate("Save", "Gem") 717 </button> 718 </div> 719 </div> 720 </div> 721 <!-- section to edit fav list name end --> 722 723 <section class="font-size-small is-flex"> 724 <aside class="tertiary-font"> 725 <p class="margin-bottom-5px">@Translate("madethisdate", "Oprettet d. ")</p> 726 <p class="margin-bottom-5px">@Translate("numberofproduct", "Antal produkter: ")</p> 727 </aside> 728 <aside class="xs-m-l-3 @missingTextCss"> 729 <p class="margin-bottom-5px">@OrderTemplate.CreatedDate</p> 730 <p class="margin-bottom-5px">@OrderTemplate.Lines.Count</p> 731 </aside> 732 </section> 733 <div class="favoriteDropdown product"> 734 <div class="no-padding inputs"> 735 <div class="toggleEditFavCart"> 736 @Translate("EditOrderTemplateName", "Nyt navn") 737 </div> 738 <input class="favField" data-bind="value: OrderTemplateName, valueUpdate: 'afterkeydown'" /> 739 <div class="button darkBlue" data-bind="click: SaveName"> 740 @Translate("Save", "Gem") 741 </div> 742 </div> 743 </div> 744 </div> 745 <section class="xs-p-t-3"> 746 <button id="OrderTemplateAddAllToCart" 747 class="btn btn-primary xs-width-100 xs-m-b-1" 748 data-bind="click: AddAllToCart, 749 loadOnBool: { observableBool: CartLoading, text: '@Translate(" addmultiproduct ", "Tilf&oslash;jer alle produkter ")'}"> 750 @Translate("addalltocart", "Tilf&oslash;j alle til kurv") 751 </button> 752 <button id="OrderTemplateEdit" 753 class="btn btn-primary xs-width-100 xs-m-b-1 sm-m-l-0 md-m-l-1" 754 data-bind="click: SaveAll, 755 sweetAlert: { observable : Saved, 756 successHeadline: '@Translate(" OrderTemplateSavedSuccess ", "Gemt ")'}"> 757 @Translate("ButtonTextSaveOrderTemplate", "Gem") 758 </button> 759 <button id="OrderTemplateDelete" 760 class="btn btn-primary xs-width-100 xs-m-b-1 sm-m-l-0 md-m-l-1" 761 data-bind="click: ConfirmDelete, 762 sweetAlert: { observable : OrderTemplateStatus, 763 headLine: '@Translate(" warning ", "Er du sikker? ")', 764 callBack: function() { Delete(); RefreshPage('@ReturnUrlOnDelete') } }"> 765 @Translate("delete", "Slet") 766 </button> 767 <button class="editFavCartName product btn btn-primary xs-width-100 xs-m-b-1 sm-m-l-0 md-m-l-1" 768 data-bind="toggleClick: OrderTemplateEdit"> 769 @Translate("edit", "Rediger") 770 </button> 771 </section> 772 773 </div> 774 775 776 777 <!-- ko initValue: {observable: OrderTemplateListElement, value:'#tapasfavorites'}--><!-- /ko--> 778 779 </div> 780 </div> 781 </div> 782 </div> 783 <div class="millarco-productlist"> 784 <div class="productList container xs-p-t-3" data-bind="viewModel: 'ProductListViewModel'"> 785 <section class="productList" 786 data-bind="asyncPriceLoad: productListLoad, 787 css: 'loaded', 788 elementToObservable: $parent.OrderTemplateListElement, 789 loadOnBool: { observableBool: CartLoading, text: '@Translate("addproduct", "Tilf&oslash;jer produkt")' }"> 790 <div class="row row-ce" id="tapasfavorites"> 791 @foreach (var item in GetLoop("Products")) 792 { 793 @renderProduct(true, item, true) 794 } 795 </div> 796 </section> 797 </div> 798 </div> 799 </div>