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_570b75eb43c04e2090a4011bdba97142.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 @Translate("bundle").ToUpper()
270 }
271 else
272 {
273 @Translate("pair bundle").ToUpper()
274 }
275 @* @quantity @Translate("pair bundle").ToUpper() *@
276 </label>
277 }
278 else
279 {
280 <input type="radio" class="btn-check quantity-input multiplier-input" name="options" id="quantity-input-@quantity" data-step-input="@quantity" autocomplete="off" checked>
281 <label class="btn btn-primary flex-fill rounded-0 shadow-none multiplier-btn py-3" data-step="@quantity" for="quantity-input-@quantity">
282 @quantity
283 @if (baseUnitName != "")
284 {
285 @baseUnitName.ToUpper()
286 @Translate("bundle").ToUpper()
287 }
288 else
289 {
290 @Translate("pair bundle").ToUpper()
291 }
292 @* @quantity @Translate("pair bundle").ToUpper() *@
293 </label>
294 }
295 }
296 else //if (id != "Unit_PALL")
297 {
298 if (tabParameter == "quantity-input-" + quantity)
299 {
300 <input type="radio" class="btn-check quantity-input multiplier-input" name="options" id="quantity-input-@quantity" checked data-step-input="@quantity" autocomplete="off">
301 <label class="btn btn-primary flex-fill rounded-0 shadow-none multiplier-btn py-3" data-step="@quantity" for="quantity-input-@quantity">
302 @quantity
303 @if (baseUnitName != "")
304 {
305 @baseUnitName.ToUpper()
306 @Translate("bundle").ToUpper()
307 }
308 else
309 {
310 @Translate("pair bundle").ToUpper()
311 }
312 @* @quantity @Translate("pairs bundle").ToUpper() *@
313 </label>
314 }
315 else
316 {
317 <input type="radio" class="btn-check quantity-input multiplier-input" name="options" id="quantity-input-@quantity" data-step-input="@quantity" autocomplete="off">
318 <label class="btn btn-primary flex-fill rounded-0 shadow-none multiplier-btn py-3" data-step="@quantity" for="quantity-input-@quantity">
319 @quantity
320 @if (baseUnitName != "")
321 {
322 @baseUnitName.ToUpper()
323 @Translate("bundle").ToUpper()
324 }
325 else
326 {
327 @Translate("pair bundle").ToUpper()
328 }
329 @* @quantity @Translate("pairs bundle").ToUpper() *@
330 </label>
331 }
332 }
333 }
334 }
335 }
336 </div>
337
338
339 // var units = GetUnitOfMeasures(product.Id);
340
341
342 int groupNumber = 1;
343 @* <div class=" grid gap-0" role="group" aria-label="Basic radio toggle button order-units" data-ref="table-header"> *@
344
345 @* <input type="radio" class="btn-check" name="options" id="outer-case" autocomplete="off" @outerCaseChecked> *@
346 @* <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> *@
347 @* *@
348 @* <input type="radio" class="btn-check" name="options" id="bundle" autocomplete="off" @bundleChecked> *@
349 @* <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> *@
350 @* *@
351 @* <input type="radio" class="btn-check" name="options" id="pairs" autocomplete="off" @pairsChecked> *@
352 @* <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> *@
353
354 // </div>
355
356 <input type="hidden" name="variantid"/>
357 if (countUnits > 0)
358 {
359 foreach (var variantGroup in product.VariantGroups())
360 {
361 VariantGroupViewModel group = variantGroup;
362 int i = 0;
363
364 <div class="js-variant-group" data-group-id="@groupNumber">
365 @* @if (group.Name == "Size") *@
366 @* { *@
367
368
369 <table class="table text-center">
370 <thead>
371 <tr>
372 <th>@Translate("Stock")</th>
373 <th>@Translate("Sizes")</th>
374 <th>@Translate("Quantity") ( @baseUnitName)</th>
375 </tr>
376 </thead>
377 <tbody>
378 @foreach (var option in group.Options)
379 {
380 string orderLineID = "";
381 double orderLineQuantity = 0;
382 int quantityMultiplier = Dynamicweb.Core.Converter.ToInt32(multiplier);
383
384 ProductViewModel variant = ViewModelFactory.CreateView(productSetting, product.Id, option.Id);
385 double? variantStock = variant.StockLevel;
386 string variantMinQty = variant.PurchaseMinimumQuantity != 1 ? "min=\"" + variant.PurchaseMinimumQuantity.ToString() + "\"" : "min=\"1\"";
387 string variantStepQty = variant.PurchaseQuantityStep > 1 ? variant.PurchaseQuantityStep.ToString() : "1";
388 string variantValueQty = variant.PurchaseMinimumQuantity > variant.PurchaseQuantityStep ? variant.PurchaseMinimumQuantity.ToString() : variantStepQty;
389 string variantQtyValidCheck = stepQty != "1" ? "onkeyup=\"swift.Cart.QuantityValidate(event)\"" : "";
390 string uniqueID = variant.Id + "_" + variant.VariantId;
391 string quantityInputName = "Quantity";
392 string inputClass = "d-none";
393
394
395 FieldValueViewModel lowerStockThresholdVariant = new FieldValueViewModel();
396 FieldValueViewModel higherStockThresholdVariant = new FieldValueViewModel();
397 if (variant.ProductFields != null)
398 {
399 if (variant.ProductFields.ContainsKey("LowerStockThreshold"))
400 {
401 lowerStockThresholdVariant = variant.ProductFields["LowerStockThreshold"];
402 }
403 if (variant.ProductFields.ContainsKey("HigherStockThreshold"))
404 {
405 higherStockThresholdVariant = variant.ProductFields["HigherStockThreshold"];
406 }
407 }
408
409
410 var lowerValueVariant = lowerStockThresholdVariant?.Value?.ToString();
411 var higherValueVariant = higherStockThresholdVariant?.Value?.ToString();
412
413 int lowerStockThresholdVariantNumber = 0;
414 int higherStockThresholdVariantNumber = 0;
415
416 if (!string.IsNullOrEmpty(lowerValueVariant))
417 {
418 int.TryParse(lowerValueVariant, out lowerStockThresholdVariantNumber);
419 }
420
421 if (!string.IsNullOrEmpty(higherValueVariant))
422 {
423 int.TryParse(higherValueVariant, out higherStockThresholdVariantNumber);
424 }
425
426 var lowerValueProduct = productLowerThreshold?.Value?.ToString();
427 var higherValueProduct = productHigherThreshold?.Value?.ToString();
428
429 int lowerStockThresholdProductNumber = 0;
430 int higherStockThresholdProductNumber = 0;
431
432 if (!string.IsNullOrEmpty(lowerValueProduct))
433 {
434 int.TryParse(lowerValueProduct, out lowerStockThresholdProductNumber);
435 }
436
437 if (!string.IsNullOrEmpty(higherValueProduct))
438 {
439 int.TryParse(higherValueProduct, out higherStockThresholdProductNumber);
440 }
441
442
443
444
445 if (lowerStockThresholdVariantNumber == 0 && higherStockThresholdVariantNumber == 0)
446 {
447 lowerStockThresholdVariantNumber = lowerStockThresholdProductNumber;
448 higherStockThresholdVariantNumber = higherStockThresholdProductNumber;
449 }
450
451 <tr>
452 <td>
453 <div class="stock-container">
454 @if (lowerStockThresholdVariantNumber == 0 && higherStockThresholdVariantNumber == 0)
455 {
456 if (variantStock < lowerThresholdStock)
457 {
458 <span class="stock-indicator red mt-2"></span>
459 }
460 else if (variantStock >= lowerThresholdStock && variantStock <= higherThresholdStock)
461 {
462 <span class="stock-indicator yellow mt-2"></span>
463 }
464 else
465 {
466 <span class="stock-indicator green mt-2"></span>
467 }
468 }
469 else if (lowerStockThresholdVariantNumber != 0 && higherStockThresholdVariantNumber != 0)
470 {
471 if (variantStock < lowerStockThresholdVariantNumber)
472 {
473 <span class="stock-indicator red mt-2"></span>
474 }
475 else if (variantStock >= lowerStockThresholdVariantNumber && variantStock <= higherStockThresholdVariantNumber)
476 {
477 <span class="stock-indicator yellow mt-2"></span>
478 }
479 else
480 {
481 <span class="stock-indicator green mt-2"></span>
482 }
483 }
484 else if (lowerStockThresholdVariantNumber > higherStockThresholdVariantNumber)
485 {
486 int support = 0;
487 support = lowerStockThresholdVariantNumber;
488 lowerStockThresholdVariantNumber = higherStockThresholdVariantNumber;
489 higherStockThresholdVariantNumber = support;
490
491 if (variantStock < lowerStockThresholdVariantNumber)
492 {
493 <span class="stock-indicator red mt-2"></span>
494 }
495 else if (variantStock >= lowerStockThresholdVariantNumber && variantStock <= higherStockThresholdVariantNumber)
496 {
497 <span class="stock-indicator yellow mt-2"></span>
498 }
499 else
500 {
501 <span class="stock-indicator green mt-2"></span>
502 }
503 }
504 else if (lowerStockThresholdVariantNumber == 0 && higherStockThresholdVariantNumber > 0)
505 {
506 if (variantStock <= 0)
507 {
508 <span class="stock-indicator red mt-2"></span>
509 }
510 else if (variantStock > 0 && variantStock <= higherStockThresholdVariantNumber)
511 {
512 <span class="stock-indicator yellow mt-2"></span>
513 }
514 else
515 {
516 <span class="stock-indicator green mt-2"></span>
517 }
518 }
519 </div>
520
521 </td>
522
523 <td>
524 <p class="d-inline-block variant-option js-variant-option mb-0 pt-2" data-variant-id="@option.Id">
525 @option.Name
526 </p>
527 </td>
528 <td class="w-50">
529
530 @* @if (variantStock > 0) *@
531 @* { *@
532 @{ var productOrderLine = GetProductOrderline(variant.Id, variant.VariantId); }
533 <form id="@uniqueID" action="@url">
534
535 @if (variant.IsProductInCart() && productOrderLine.Quantity > 0)
536 {
537 inputClass = "d-flex";
538 orderLineID = productOrderLine.ID;
539 orderLineQuantity = productOrderLine.Quantity;
540 quantityInputName = "QuantityOrderLine" + orderLineID;
541
542 <input type="hidden" name="cartcmd" value="UpdateorderLines">
543 <input type="hidden" name="redirect" value="false">
544 //do some logic to handle increase orderline
545 }
546 else
547 {
548 // do logic to handle add to cart
549 <input type="hidden" name="redirect" value="false">
550 <input type="hidden" name="ProductId" value="@variant.Id">
551 <input type="hidden" name="ProductCurrency" value="@Dynamicweb.Ecommerce.Common.Context.Currency.Code">
552 <input type="hidden" name="VariantId" value="@variant.VariantId">
553 <input type="hidden" name="cartcmd" value="add">
554 <input type="hidden" name="OrderLineField[BaseUnitName]" value="@baseUnitName">
555 <input type="hidden" name="UnitID" value="@baseUnit">
556
557 <button type="button" class="btn btn-primary flex-fill js-add-to-cart-button" title="@Translate("Add to cart")">
558 @Translate("Add to cart")
559 </button>
560 }
561
562 <div class="js-input-group @inputClass flex-wrap justify-content-center">
563 <button type="button" class="btn btn-link" data-role="step-down">
564 <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
565 <rect x="0.5" y="0.5" width="23" height="23" rx="2.5" stroke="black"/>
566 <path d="M17 10V14H7V10H17Z" fill="black"/>
567 </svg>
568 </button>
569
570 <label for="QuantityOrderLine@(option.Id)" class="visually-hidden">@Translate("Quantity"):</label>
571 <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">
572
573 <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">
574 <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
575 <rect x="0.5" y="0.5" width="23" height="23" rx="2.5" stroke="black"/>
576 <path d="M9.9774 20V4H14.0226V20H9.9774ZM4 14.0226V9.9774H20V14.0226H4Z" fill="black"/>
577 </svg>
578 </button>
579 </div>
580
581 @* <div class="px-3 mt-3 w-50 bg-danger m-auto rounded-pill d-none" data-role="alert-stock-exceeded"> *@
582 @* <p class="align-self-center text-center m-0">@Translate("Stock exceeded!")</p> *@
583 @* </div> *@
584 @* <button type="submit" onclick="document.querySelector('#@uniqueID').submit()">submit</button> *@
585 @* <button type="button" onclick="swift.Cart.UpdateCustom(event)" class="btn btn-primary" style="white-space: nowrap" title="@Translate("Add to cart")" id="AddToCartButton@(uniqueID)"> *@
586 @* </button> *@
587 </form>
588
589 @* } *@
590 @* else *@
591 @* { *@
592 @* <button type="button" class="btn btn-primary flex-fill js-add-to-cart-button" disabled title="@Translate("Add to cart")">@Translate("Add to cart") *@
593 @* </button> *@
594 @* } *@
595 </td>
596 </tr>
597
598 i++;
599 }
600 </tbody>
601 </table>
602
603
604 @* } *@
605 </div>
606
607 groupNumber++;
608 }
609 }
610
611
612 if (!IsNeverOutOfStock)
613 {
614 <div class="mt-3 js-stock-state">
615
616 @* @if (product.StockLevel > 0) *@
617 @* { *@
618 @* if (!Model.Item.GetBoolean("HideInventory")) *@
619 @* { *@
620 @* <p class="small text-success m-0">@product.StockLevel @Translate("Products available in stock")</p> *@
621 @* } *@
622 @* else *@
623 @* { *@
624 @* <p class="small text-success m-0">@Translate("Available in stock")</p> *@
625 @* } *@
626 @* } *@
627 @* *@
628 @* else *@
629 @* { *@
630 @* <p class="small text-danger m-0">@Translate("Out of Stock")</p> *@
631 @* } *@
632
633 @if (hasExpectedDelivery)
634 {
635 <p>
636 <span>@Translate("Expected back in stock:")</span>
637 <span>@expectedDeliveryDate</span>
638 </p>
639 }
640
641 </div>
642 }
643 }
644 else
645 {
646 <p>@Translate("Invalid product")</p>
647 }
648 }
649 else
650 {
651 @* <p>test</p> *@
652 @* <button class="btn btn-primary"> *@
653 <a href="/sign-in" class="btn btn-secondary col-lg-3 col-6 my-3 ms-lg-4 mx-auto log-in-button-pdp" style="text-transform: none">
654 @Translate("Webshop Login")
655 </a>
656 @* </button> *@
657 }
658 </div>
659 </div>