Error executing template "Designs/Swift/_parsed/GBG_VariantMatrix.parsed.cshtml"
System.ArgumentNullException: Value cannot be null.
Parameter name: input
at System.Text.RegularExpressions.Regex.Replace(String input, String replacement)
at System.Text.RegularExpressions.Regex.Replace(String input, String pattern, String replacement)
at CompiledRazorTemplates.Dynamic.RazorEngine_3a8a2cf9431e4db1abddcfb6bd29b6ca.Execute() in D:\dynamicweb.net\Solutions\Degree\granberg.cloud.dynamicweb-cms.com\Files\Templates\Designs\Swift\_parsed\GBG_VariantMatrix.parsed.cshtml:line 140
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 Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
2 @using System.Text.RegularExpressions
3 @using Dynamicweb.Ecommerce.ProductCatalog
4 @using Dynamicweb.Ecommerce.CustomerExperienceCenter.Favorites
5 @using Dynamicweb.Ecommerce.Products.FieldDisplayGroups
6 @using Dynamicweb.Frontend
7 @using System.Web
8 @using Dynamicweb.Ecommerce.Products
9 @using Dynamicweb.Ecommerce.Stocks
10
11 @functions{
12
13 public class MultiplierButton
14 {
15 public int multiplier { get; set; }
16 public string label { get; set; }
17 public int sort { get; set; }
18 }
19
20 public CartOrderlineViewModel GetProductOrderline(string productId, string variantId)
21 {
22 CartOrderlineViewModel response = new CartOrderlineViewModel();
23 var orderLines = Model.Cart?.CartOrderlines;
24 if (orderLines != null)
25 {
26 CartOrderlineViewModel productOrderLine = orderLines.Where(x => x.ProductID == productId && x.ProductVariantID == variantId).FirstOrDefault();
27 response = productOrderLine != null ? productOrderLine : response;
28 }
29
30 return response;
31 }
32
33 }
34
35 @{
36 ProductViewModel product = new ProductViewModel();
37 bool hasExpectedDelivery = false;
38 string expectedDeliveryDate = "";
39 bool IsNeverOutOfStock = false;
40 string[] variantId = new string[] { };
41 string disableAddToCart = "";
42 FieldValueViewModel lowerStockThreshold = new FieldValueViewModel();
43 FieldValueViewModel higherStockThreshold = new FieldValueViewModel();
44
45
46 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails"))
47 {
48 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"];
49 }
50
51 ProductViewModelSettings productSetting = new ProductViewModelSettings
52 {
53 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID,
54 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code,
55 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2,
56 ShopId = Pageview.Area.EcomShopId
57 };
58
59 if (Dynamicweb.Context.Current.Request.QueryString.Get("tab") != null)
60 {
61 string productId = Dynamicweb.Context.Current.Request.QueryString.Get("tab");
62
63 product = ViewModelFactory.CreateView(productSetting, productId);
64 }
65 else
66 {
67 product = ViewModelFactory.CreateView(productSetting, "Product122");
68 }
69
70 int multiplier = 1;
71 if (Dynamicweb.Context.Current.Request.QueryString.Get("multiplier") != null)
72 {
73 multiplier = Dynamicweb.Core.Converter.ToInt32(Dynamicweb.Context.Current.Request.QueryString.Get("multiplier"));
74 }
75
76 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", "");
77 bool anonymousUser = Pageview.User == null;
78 bool hideAddToCart = anonymousUsersLimitations.Contains("cart") && anonymousUser;
79 //hideAddToCart = product.VariantInfo.VariantInfo != null && Model.Item.GetBoolean("HideVariantSelector") ? true : hideAddToCart;
80 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser;
81 bool hideFavoritesSelector = false; //!string.IsNullOrEmpty(Model.Item.GetString("HideFavoritesSelector")) ? Model.Item.GetBoolean("HideFavoritesSelector") : false;
82
83 if (product.Id != "")
84 {
85 IsNeverOutOfStock = product.NeverOutOfstock;
86 variantId = product.VariantId?.Split('.');
87 disableAddToCart = (product.StockLevel <= 0) ? "disabled" : "";
88 if (IsNeverOutOfStock)
89 {
90 disableAddToCart = "";
91 }
92
93 // Does product has a expected delivery data
94 hasExpectedDelivery = product.ExpectedDelivery != null && product.ExpectedDelivery > DateTime.Now;
95 expectedDeliveryDate = product.ExpectedDelivery?.ToShortDateString() ?? "";
96
97
98 }
99
100
101 string url = "/Default.aspx?ID=" + (GetPageIdByNavigationTag("CartService"));
102 if (!url.Contains("LayoutTemplate"))
103 {
104 url += url.Contains("?") ? "&LayoutTemplate=Swift_MiniCart.cshtml" : "?LayoutTemplate=Swift_MiniCart.cshtml";
105 }
106
107
108 string theme = ""; //!string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : "";
109
110 string titleFontSize = "display-6"; //Model.Item.GetRawValueString("TitleFontSize", "display-6");
111
112 string contentPadding = ""; //Model.Item.GetRawValueString("ContentPadding", "");
113 contentPadding = contentPadding == "small" ? "p-2 p-md-3" : contentPadding;
114 contentPadding = contentPadding == "large" ? "p-4 p-md-5" : contentPadding;
115
116 string quantityPricesLayout = "list"; //Model.Item.GetRawValueString("QuantityPricesLayout", "list");
117 string minQty = "min=\"0\"";
118 // string minQty = product.PurchaseMinimumQuantity != 1 ? "min=\"" + product.PurchaseMinimumQuantity.ToString() + "\"" : "min=\"1\"";
119 string stepQty = product.PurchaseQuantityStep > 1 ? product.PurchaseQuantityStep.ToString() : "1";
120 string valueQty = product.PurchaseMinimumQuantity > product.PurchaseQuantityStep ? product.PurchaseMinimumQuantity.ToString() : stepQty;
121 string qtyValidCheck = stepQty != "1" ? "onkeyup=\"swift.Cart.QuantityValidate(event)\"" : "";
122
123 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower();
124 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat);
125
126 string priceMin = "";
127 string priceMax = "";
128
129 string iconPath = "/Files/icons/";
130
131 var favoriteParameters = new Dictionary<string, object>();
132
133 List<UnitOfMeasure> productUnits = new List<UnitOfMeasure>();
134
135 string tabParameter = Dynamicweb.Context.Current.Request.QueryString.Get("tab");
136 string outerCaseChecked = tabParameter == "outer-case" || tabParameter == "" ? "checked" : "";
137 string bundleChecked = tabParameter == "bundle" ? "checked" : "";
138 string pairsChecked = tabParameter == "pairs" ? "checked" : "";
139 // string step = tabParameter == "outer-case" || tabParameter == "" ? "72" : tabParameter == "bundle" ? "12" : "1";
140 string step = Regex.Replace(tabParameter, @"[^\d]", "");
141
142 string statusGroupID = "STOCKGRP1";
143 bool orderBy = false;
144 string language = Dynamicweb.Ecommerce.Common.Context.LanguageID;
145 }
146
147
148
149 @*@foreach (var prop in product.GetType().GetProperties()) *@
150 @*{ *@
151 @* <p>@prop.Name</p> *@
152 @*} *@
153
154
155
156 @if (product.ProductFields != null && product.ProductFields.ContainsKey("LowerStockThreshold"))
157 {
158 lowerStockThreshold = product.ProductFields["LowerStockThreshold"];
159 }
160 @if (product.ProductFields != null && product.ProductFields.ContainsKey("higherStockThreshold"))
161 {
162 higherStockThreshold = product.ProductFields["higherStockThreshold"];
163 }
164
165 @*@foreach (var field in product.ProductFields) *@
166 @*{ *@
167 @*<p>@field.Key: @field.Value.Value</p> *@
168 @*} *@
169
170
171 @*@lowerStockThreshold.Value *@
172 @*@higherStockThreshold.Value *@
173
174
175 @*@Dynamicweb.Ecommerce.Common.Context.LanguageID *@
176 @*@Pageview.Area.Ecommerce.Shop.StockStateId *@
177 @*@Dynamicweb.Ecommerce.Services.StockService.GetStockStatuses(statusGroupID, orderBy,language).Count() *@
178 @{
179 var stockStatuses = Dynamicweb.Ecommerce.Services.StockService.GetStockStatuses(statusGroupID, orderBy, language);
180 var firstStatus = stockStatuses.FirstOrDefault();
181 var lowerThresholdStock = stockStatuses.FirstOrDefault().Rate;
182 var higherThresholdStock = stockStatuses.FirstOrDefault().Rate;
183 }
184
185 @*@if (firstStatus != null) *@
186 @*{ *@
187 @*var properties = firstStatus.GetType().GetProperties(); *@
188 @*foreach (var prop in properties) *@
189 @*{ *@
190 @* <p>@prop.Name - @prop.GetValue(firstStatus) </p> *@
191 @*} *@
192 @*} *@
193 @foreach (var status in stockStatuses)
194 {
195 if (status.Rate < lowerThresholdStock)
196 {
197 lowerThresholdStock = status.Rate;
198 }
199
200 if (status.Rate > higherThresholdStock)
201 {
202 higherThresholdStock = status.Rate;
203 }
204 }
205 @*<p>lower : @lowerThresholdStock</p> *@
206 @*<p>higher : @higherThresholdStock</p> *@
207
208 <div class="h-100 @(contentPadding) @(theme)">
209 <div class="d-flex flex-column gap-4 js-product">
210 @if (!anonymousUser)
211 {
212 if (product.Id != "")
213 {
214
215 var activeUnitsOfMeasureField = product.ProductFields["ActiveUnitsOfMeasure"];
216 @* <p>@activeUnitsOfMeasureField</p> *@
217 List<FieldOptionValueViewModel> fieldList = (List<FieldOptionValueViewModel>)activeUnitsOfMeasureField.Value;
218 var productLowerThreshold = product.ProductFields["LowerStockThreshold"];
219 var productHigherThreshold = product.ProductFields["HigherStockThreshold"];
220
221 // Dynamicweb.Ecommerce.Services.UnitOfMeasureService unitService = new Dynamicweb.Ecommerce.Services.UnitOfMeasureService();
222 Dynamicweb.Ecommerce.Stocks.UnitOfMeasureService unitService = new Dynamicweb.Ecommerce.Stocks.UnitOfMeasureService();
223 productUnits = unitService.GetUnitOfMeasures(product.Id).ToList();
224 step = productUnits[0].QuantityPerUnit.ToString();
225 int countUnits = 0;
226 var baseUnit = "";
227 var baseUnitName = "";
228 <div class="d-flex gap-0" role="group" aria-label="Basic radio toggle button order-units" data-ref="table-header">
229 @foreach (var unit in productUnits)
230 {
231 if (unit.IsBaseUnit == true)
232 {
233 baseUnit = unit.UnitId;
234 }
235 }
236 @if (baseUnit != "")
237 {
238 foreach (var field in fieldList)
239 {
240 if (baseUnit == field.Value.Trim())
241 {
242 baseUnitName = field.Name;
243 }
244 }
245 }
246 @* <p>@baseUnitName</p> *@
247
248 @foreach (var unit in productUnits)
249 {
250 @* <p>@unit.QuantityPerUnit</p> *@
251 var quantity = unit.QuantityPerUnit;
252 var id = unit.UnitId;
253
254 foreach (var field in fieldList)
255 {
256 if (unit.UnitId == field.Value.Trim())
257 {
258 countUnits++;
259 if (quantity == 1)
260 {
261 if (tabParameter == "" || tabParameter == "quantity-input-1")
262 {
263 <input type="radio" class="btn-check quantity-input multiplier-input" name="options" id="quantity-input-@quantity" data-step-input="@quantity" autocomplete="off" checked>
264 <label class="btn btn-primary flex-fill rounded-0 shadow-none multiplier-btn py-3" data-step="@quantity" for="quantity-input-@quantity">
265 @quantity
266 @if (baseUnitName != "")
267 {
268 @baseUnitName.ToUpper()
269 }
270 else
271 {
272 @Translate("pair bundle").ToUpper()
273 }
274 @* @quantity @Translate("pair").ToUpper() *@
275 </label>
276 }
277 else
278 {
279 <input type="radio" class="btn-check quantity-input multiplier-input" name="options" id="quantity-input-@quantity" data-step-input="@quantity" autocomplete="off" checked>
280 <label class="btn btn-primary flex-fill rounded-0 shadow-none multiplier-btn py-3" data-step="@quantity" for="quantity-input-@quantity">
281 @quantity
282 @if (baseUnitName != "")
283 {
284 @baseUnitName.ToUpper()
285 }
286 else
287 {
288 @Translate("pair").ToUpper()
289 }
290 @* @quantity @Translate("pair bundle").ToUpper() *@
291 </label>
292 }
293 }
294 else //if (id != "Unit_PALL")
295 {
296 if (tabParameter == "quantity-input-" + quantity)
297 {
298 <input type="radio" class="btn-check quantity-input multiplier-input" name="options" id="quantity-input-@quantity" checked data-step-input="@quantity" autocomplete="off">
299 <label class="btn btn-primary flex-fill rounded-0 shadow-none multiplier-btn py-3" data-step="@quantity" for="quantity-input-@quantity">
300 @quantity
301 @if (baseUnitName != "")
302 {
303 @baseUnitName.ToUpper()
304 }
305 else
306 {
307 @Translate("pair").ToUpper()
308 }
309 @* @quantity @Translate("pairs bundle").ToUpper() *@
310 </label>
311 }
312 else
313 {
314 <input type="radio" class="btn-check quantity-input multiplier-input" name="options" id="quantity-input-@quantity" data-step-input="@quantity" autocomplete="off">
315 <label class="btn btn-primary flex-fill rounded-0 shadow-none multiplier-btn py-3" data-step="@quantity" for="quantity-input-@quantity">
316 @quantity
317 @if (baseUnitName != "")
318 {
319 @baseUnitName.ToUpper()
320 }
321 else
322 {
323 @Translate("pair").ToUpper()
324 }
325 @* @quantity @Translate("pairs bundle").ToUpper() *@
326 </label>
327 }
328 }
329 }
330 }
331 }
332 </div>
333
334
335 // var units = GetUnitOfMeasures(product.Id);
336
337
338 int groupNumber = 1;
339 @* <div class=" grid gap-0" role="group" aria-label="Basic radio toggle button order-units" data-ref="table-header"> *@
340
341 @* <input type="radio" class="btn-check" name="options" id="outer-case" autocomplete="off" @outerCaseChecked> *@
342 @* <label class="btn btn-primary rounded-0 shadow-none multiplier-btn py-3 g-col-4" data-step="72" for="outer-case">@Translate("Outer Case").ToUpper()</label> *@
343 @* *@
344 @* <input type="radio" class="btn-check" name="options" id="bundle" autocomplete="off" @bundleChecked> *@
345 @* <label class="btn btn-primary rounded-0 shadow-none multiplier-btn py-3 g-col-4" data-step="12" for="bundle">@Translate("Bundle").ToUpper()</label> *@
346 @* *@
347 @* <input type="radio" class="btn-check" name="options" id="pairs" autocomplete="off" @pairsChecked> *@
348 @* <label class="btn btn-primary rounded-0 shadow-none multiplier-btn py-3 g-col-4" data-step="1" for="pairs">@Translate("Pairs").ToUpper()</label> *@
349
350 // </div>
351
352 <input type="hidden" name="variantid"/>
353 if (countUnits > 0)
354 {
355 foreach (var variantGroup in product.VariantGroups())
356 {
357 VariantGroupViewModel group = variantGroup;
358 int i = 0;
359
360 <div class="js-variant-group" data-group-id="@groupNumber">
361 @* @if (group.Name == "Size") *@
362 @* { *@
363
364
365 <table class="table text-center">
366 <thead>
367 <tr>
368 <th>@Translate("Stock")</th>
369 <th>@Translate("Sizes")</th>
370 <th>@Translate("Quantity") ( @baseUnitName)</th>
371 </tr>
372 </thead>
373 <tbody>
374 @foreach (var option in group.Options)
375 {
376 string orderLineID = "";
377 double orderLineQuantity = 0;
378 int quantityMultiplier = Dynamicweb.Core.Converter.ToInt32(multiplier);
379
380 ProductViewModel variant = ViewModelFactory.CreateView(productSetting, product.Id, option.Id);
381 double? variantStock = variant.StockLevel;
382 string variantMinQty = variant.PurchaseMinimumQuantity != 1 ? "min=\"" + variant.PurchaseMinimumQuantity.ToString() + "\"" : "min=\"1\"";
383 string variantStepQty = variant.PurchaseQuantityStep > 1 ? variant.PurchaseQuantityStep.ToString() : "1";
384 string variantValueQty = variant.PurchaseMinimumQuantity > variant.PurchaseQuantityStep ? variant.PurchaseMinimumQuantity.ToString() : variantStepQty;
385 string variantQtyValidCheck = stepQty != "1" ? "onkeyup=\"swift.Cart.QuantityValidate(event)\"" : "";
386 string uniqueID = variant.Id + "_" + variant.VariantId;
387 string quantityInputName = "Quantity";
388 string inputClass = "d-none";
389
390
391 FieldValueViewModel lowerStockThresholdVariant = new FieldValueViewModel();
392 FieldValueViewModel higherStockThresholdVariant = new FieldValueViewModel();
393 if (variant.ProductFields != null)
394 {
395 if (variant.ProductFields.ContainsKey("LowerStockThreshold"))
396 {
397 lowerStockThresholdVariant = variant.ProductFields["LowerStockThreshold"];
398 }
399 if (variant.ProductFields.ContainsKey("HigherStockThreshold"))
400 {
401 higherStockThresholdVariant = variant.ProductFields["HigherStockThreshold"];
402 }
403 }
404
405
406 var lowerValueVariant = lowerStockThresholdVariant?.Value?.ToString();
407 var higherValueVariant = higherStockThresholdVariant?.Value?.ToString();
408
409 int lowerStockThresholdVariantNumber = 0;
410 int higherStockThresholdVariantNumber = 0;
411
412 if (!string.IsNullOrEmpty(lowerValueVariant))
413 {
414 int.TryParse(lowerValueVariant, out lowerStockThresholdVariantNumber);
415 }
416
417 if (!string.IsNullOrEmpty(higherValueVariant))
418 {
419 int.TryParse(higherValueVariant, out higherStockThresholdVariantNumber);
420 }
421
422 var lowerValueProduct = productLowerThreshold?.Value?.ToString();
423 var higherValueProduct = productHigherThreshold?.Value?.ToString();
424
425 int lowerStockThresholdProductNumber = 0;
426 int higherStockThresholdProductNumber = 0;
427
428 if (!string.IsNullOrEmpty(lowerValueProduct))
429 {
430 int.TryParse(lowerValueProduct, out lowerStockThresholdProductNumber);
431 }
432
433 if (!string.IsNullOrEmpty(higherValueProduct))
434 {
435 int.TryParse(higherValueProduct, out higherStockThresholdProductNumber);
436 }
437
438
439
440
441 if (lowerStockThresholdVariantNumber == 0 && higherStockThresholdVariantNumber == 0)
442 {
443 lowerStockThresholdVariantNumber = lowerStockThresholdProductNumber;
444 higherStockThresholdVariantNumber = higherStockThresholdProductNumber;
445 }
446
447 <tr>
448 <td>
449 <div class="stock-container">
450 @if (lowerStockThresholdVariantNumber == 0 && higherStockThresholdVariantNumber == 0)
451 {
452 if (variantStock < lowerThresholdStock)
453 {
454 <span class="stock-indicator red mt-2"></span>
455 }
456 else if (variantStock >= lowerThresholdStock && variantStock <= higherThresholdStock)
457 {
458 <span class="stock-indicator yellow mt-2"></span>
459 }
460 else
461 {
462 <span class="stock-indicator green mt-2"></span>
463 }
464 }
465 else if (lowerStockThresholdVariantNumber != 0 && higherStockThresholdVariantNumber != 0)
466 {
467 if (variantStock < lowerStockThresholdVariantNumber)
468 {
469 <span class="stock-indicator red mt-2"></span>
470 }
471 else if (variantStock >= lowerStockThresholdVariantNumber && variantStock <= higherStockThresholdVariantNumber)
472 {
473 <span class="stock-indicator yellow mt-2"></span>
474 }
475 else
476 {
477 <span class="stock-indicator green mt-2"></span>
478 }
479 }
480 else if (lowerStockThresholdVariantNumber > higherStockThresholdVariantNumber)
481 {
482 int support = 0;
483 support = lowerStockThresholdVariantNumber;
484 lowerStockThresholdVariantNumber = higherStockThresholdVariantNumber;
485 higherStockThresholdVariantNumber = support;
486
487 if (variantStock < lowerStockThresholdVariantNumber)
488 {
489 <span class="stock-indicator red mt-2"></span>
490 }
491 else if (variantStock >= lowerStockThresholdVariantNumber && variantStock <= higherStockThresholdVariantNumber)
492 {
493 <span class="stock-indicator yellow mt-2"></span>
494 }
495 else
496 {
497 <span class="stock-indicator green mt-2"></span>
498 }
499 }
500 else if (lowerStockThresholdVariantNumber == 0 && higherStockThresholdVariantNumber > 0)
501 {
502 if (variantStock <= 0)
503 {
504 <span class="stock-indicator red mt-2"></span>
505 }
506 else if (variantStock > 0 && variantStock <= higherStockThresholdVariantNumber)
507 {
508 <span class="stock-indicator yellow mt-2"></span>
509 }
510 else
511 {
512 <span class="stock-indicator green mt-2"></span>
513 }
514 }
515 </div>
516
517 </td>
518
519 <td>
520 <p class="d-inline-block variant-option js-variant-option mb-0 pt-2" data-variant-id="@option.Id">
521 @option.Name
522 </p>
523 </td>
524 <td class="w-50">
525
526 @* @if (variantStock > 0) *@
527 @* { *@
528 @{ var productOrderLine = GetProductOrderline(variant.Id, variant.VariantId); }
529 <form id="@uniqueID" action="@url">
530
531 @if (variant.IsProductInCart() && productOrderLine.Quantity > 0)
532 {
533 inputClass = "d-flex";
534 orderLineID = productOrderLine.ID;
535 orderLineQuantity = productOrderLine.Quantity;
536 quantityInputName = "QuantityOrderLine" + orderLineID;
537
538 <input type="hidden" name="cartcmd" value="UpdateorderLines">
539 <input type="hidden" name="redirect" value="false">
540 //do some logic to handle increase orderline
541 }
542 else
543 {
544 // do logic to handle add to cart
545 <input type="hidden" name="redirect" value="false">
546 <input type="hidden" name="ProductId" value="@variant.Id">
547 <input type="hidden" name="ProductCurrency" value="@Dynamicweb.Ecommerce.Common.Context.Currency.Code">
548 <input type="hidden" name="VariantId" value="@variant.VariantId">
549 <input type="hidden" name="cartcmd" value="add">
550 <input type="hidden" name="OrderLineField[BaseUnitName]" value="@baseUnitName">
551 <input type="hidden" name="UnitID" value="@baseUnit">
552
553 <button type="button" class="btn btn-primary flex-fill js-add-to-cart-button" title="@Translate("Add to cart")">
554 @Translate("Add to cart")
555 </button>
556 }
557
558 <div class="js-input-group @inputClass flex-wrap justify-content-center">
559 <button type="button" class="btn btn-link" data-role="step-down">
560 <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
561 <rect x="0.5" y="0.5" width="23" height="23" rx="2.5" stroke="black"/>
562 <path d="M17 10V14H7V10H17Z" fill="black"/>
563 </svg>
564 </button>
565
566 <label for="QuantityOrderLine@(option.Id)" class="visually-hidden">@Translate("Quantity"):</label>
567 <input step="@step" type="number" data-ref="quantity-input" id="QuantityOrderLine@(option.Id)" @minQty class="form-control text-center quantity-input" value="@orderLineQuantity" name="@quantityInputName" @qtyValidCheck style="max-width: 4.5rem;" data-bs-container="body" data-bs-toggle="popover" data-bs-trigger="manual" data-bs-placement="top" data-stock="@variantStock" data-error-no-stock="Not enough stock!" data-bs-content="asd" data-bs-custom-class="alert-danger">
568
569 <button type="button" class="btn btn-link" data-role="step-up" data-bs-container="body" data-bs-toggle="popover" data-bs-trigger="manual" data-bs-placement="top" data-bs-content="Not enough stock!" data-bs-custom-class="alert-danger">
570 <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
571 <rect x="0.5" y="0.5" width="23" height="23" rx="2.5" stroke="black"/>
572 <path d="M9.9774 20V4H14.0226V20H9.9774ZM4 14.0226V9.9774H20V14.0226H4Z" fill="black"/>
573 </svg>
574 </button>
575 </div>
576
577 @* <div class="px-3 mt-3 w-50 bg-danger m-auto rounded-pill d-none" data-role="alert-stock-exceeded"> *@
578 @* <p class="align-self-center text-center m-0">@Translate("Stock exceeded!")</p> *@
579 @* </div> *@
580 @* <button type="submit" onclick="document.querySelector('#@uniqueID').submit()">submit</button> *@
581 @* <button type="button" onclick="swift.Cart.UpdateCustom(event)" class="btn btn-primary" style="white-space: nowrap" title="@Translate("Add to cart")" id="AddToCartButton@(uniqueID)"> *@
582 @* </button> *@
583 </form>
584
585 @* } *@
586 @* else *@
587 @* { *@
588 @* <button type="button" class="btn btn-primary flex-fill js-add-to-cart-button" disabled title="@Translate("Add to cart")">@Translate("Add to cart") *@
589 @* </button> *@
590 @* } *@
591 </td>
592 </tr>
593
594 i++;
595 }
596 </tbody>
597 </table>
598
599
600 @* } *@
601 </div>
602
603 groupNumber++;
604 }
605 }
606
607
608 if (!IsNeverOutOfStock)
609 {
610 <div class="mt-3 js-stock-state">
611
612 @* @if (product.StockLevel > 0) *@
613 @* { *@
614 @* if (!Model.Item.GetBoolean("HideInventory")) *@
615 @* { *@
616 @* <p class="small text-success m-0">@product.StockLevel @Translate("Products available in stock")</p> *@
617 @* } *@
618 @* else *@
619 @* { *@
620 @* <p class="small text-success m-0">@Translate("Available in stock")</p> *@
621 @* } *@
622 @* } *@
623 @* *@
624 @* else *@
625 @* { *@
626 @* <p class="small text-danger m-0">@Translate("Out of Stock")</p> *@
627 @* } *@
628
629 @if (hasExpectedDelivery)
630 {
631 <p>
632 <span>@Translate("Expected back in stock:")</span>
633 <span>@expectedDeliveryDate</span>
634 </p>
635 }
636
637 </div>
638 }
639 }
640 else
641 {
642 <p>@Translate("Invalid product")</p>
643 }
644 }
645 else
646 {
647 @* <p>test</p> *@
648 @* <button class="btn btn-primary"> *@
649 <a href="/sign-in" class="btn btn-secondary col-lg-3 col-6 my-3 ms-lg-4 mx-auto log-in-btn-pdp" style="text-transform: none">
650 @Translate("Webshop Login")
651 </a>
652 @* </button> *@
653 }
654 </div>
655 </div>