Error executing template "Designs/Swift/Paragraph/SwiftRizzo_StockState.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
at CompiledRazorTemplates.Dynamic.RazorEngine_33e1b4e016134b149ef8b67a0564d69f.Execute() in F:\Domains\Sites\uat-ic.mydwsite.com\Files\Templates\Designs\Swift\Paragraph\SwiftRizzo_StockState.cshtml:line 88
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.ParagraphViewModel>
2 @using System
3 @using System.Collections.Generic
4 @using System.Linq
5 @using Dynamicweb.Ecommerce.ProductCatalog
6
7 @functions
8 {
9 static Dynamicweb.Ecommerce.Stocks.StockStatus GetStockDefaultState(string defaultStockGroupId, double stock)
10 {
11 IEnumerable<Dynamicweb.Ecommerce.Stocks.StockStatus> defaultStockStatuses = Dynamicweb.Ecommerce.Services.StockService.GetStockStatuses(defaultStockGroupId, true);
12 foreach (var status in defaultStockStatuses)
13 {
14 switch (status.Definition ?? "")
15 {
16 case "<=":
17 if (stock <= status.Rate)
18 {
19 return status;
20 }
21
22 continue;
23 case ">=":
24 if (stock >= status.Rate)
25 {
26 return status;
27 }
28
29 continue;
30 }
31 }
32
33 return null;
34 }
35 }
36
37 @{
38 /*START CUSTOM CODE*/
39 string liveInfoClass = "";
40 string productInfoFeed = "";
41 bool isLazyLoadingForProductInfoEnabled = Dna.Ecommerce.LiveIntegration.TemplatesHelper.IsLazyLoadingForProductInfoEnabled;
42 if (isLazyLoadingForProductInfoEnabled)
43 {
44 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed"))
45 {
46 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString();
47 if (!string.IsNullOrEmpty(productInfoFeed))
48 {
49 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\"";
50 }
51 }
52
53 liveInfoClass = "js-live-info";
54 }
55
56 //*END CUSTOM CODE*/
57 ProductViewModel product = new ProductViewModel();
58
59 ProductViewModelSettings productSetting = new ProductViewModelSettings
60 {
61 LanguageId = Dynamicweb.Ecommerce.Common.Context.LanguageID,
62 CurrencyCode = Dynamicweb.Ecommerce.Common.Context.Currency.Code,
63 CountryCode = Dynamicweb.Ecommerce.Common.Context.Country.Code2,
64 ShopId = Pageview.Area.EcomShopId
65 };
66
67 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails"))
68 {
69 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"];
70 }
71 else if (Pageview.Item["DummyProduct"] != null)
72 {
73 string dummyProductId = "";
74 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page);
75 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel();
76 if (productList.Products != null)
77 {
78 foreach (var p in productList.Products)
79 {
80 dummyProductId = p.Id;
81 }
82
83 ProductViewModel dummyProduct = dummyProductId != "" ? ViewModelFactory.CreateView(productSetting, dummyProductId) : new ProductViewModel();
84 product = dummyProduct;
85 }
86 else
87 {
88 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id);
89 }
90 }
91 else if (Pageview.Item["DummyProduct"] == null)
92 {
93 product = ViewModelFactory.CreateView(productSetting, Dynamicweb.Ecommerce.Services.Products.GetLastActiveProducts(1, Dynamicweb.Ecommerce.Common.Context.LanguageID, false).FirstOrDefault().Id);
94 }
95
96 bool hasDeliveryTime = Model.Item.GetBoolean("IncludeDeliveryTimeInStockMessage");
97 string defaultStockGroupId = Model.Item.GetRawValueString("DefaultStockState", string.Empty);
98 bool forceStockStateDefault = Model.Item.GetBoolean("ForceStockStateToDefault");
99 string neverOutOfStockBehavior = Model.Item.GetRawValueString("NeverOutOfStockBehavior");
100
101 string layout = Model.Item.GetRawValueString("Layout", "icon-top");
102 string contentPadding = Model.Item.GetRawValueString("SpaceAround", "");
103 contentPadding = contentPadding == "none" ? " px-0 py-3" : contentPadding;
104 contentPadding = contentPadding == "small" ? " px-3 py-3" : contentPadding;
105 contentPadding = contentPadding == "large" ? " ps-5 pe-3 py-3" : contentPadding;
106
107 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", "");
108 horizontalAlign = horizontalAlign == "center" ? "text-center" : horizontalAlign;
109 horizontalAlign = horizontalAlign == "end" ? "text-end" : horizontalAlign;
110
111 var languageId = Dynamicweb.Ecommerce.Common.Context.LanguageID;
112
113 Dynamicweb.Ecommerce.Products.Product prod = Dynamicweb.Ecommerce.Services.Products.GetProductById(product.Id, product.VariantId, true);
114 Dynamicweb.Ecommerce.Stocks.StockStatus productStockStatus = Dynamicweb.Ecommerce.Services.Products.GetStockStatus(prod);
115 string productStockGroupId = forceStockStateDefault ? defaultStockGroupId : prod.StockGroupId;
116
117 if (forceStockStateDefault)
118 {
119 productStockStatus = GetStockDefaultState(productStockGroupId, prod.Stock);
120 }
121
122 if (neverOutOfStockBehavior == "highestAmount" && prod.NeverOutOfStock)
123 {
124 productStockStatus = Dynamicweb.Ecommerce.Services.StockService.GetStockStatuses(productStockGroupId, true).LastOrDefault();
125 }
126
127 string stockStatus = productStockStatus?.GetText(languageId);
128 string deliveryTimeText = productStockStatus?.GetExpectedDeliveryText(languageId);
129 string deliveryTime = hasDeliveryTime && !string.IsNullOrEmpty(deliveryTimeText) ? " - " + Translate("Delivery in ") + deliveryTimeText + " " + productStockStatus?.GetExpectedDeliveryValue(languageId) : string.Empty;
130 string stockIcon = productStockStatus?.Icon;
131 bool doDoRenderNeverOutOfStockProduct = prod.NeverOutOfStock && neverOutOfStockBehavior == "doNotRenderAnything";
132
133 @*START CUSTOM CODE*@
134
135 var stockGroups = Dynamicweb.Ecommerce.Services.StockService.GetStockGroups();
136 var outOfStockText = "";
137 var inStockText = "";
138 var outOfStockIcon = "";
139 var inStockIcon = "";
140 }
141
142 @foreach (var stockGroup in stockGroups)
143 {
144 foreach (var stockStatusFromGroups in Dynamicweb.Ecommerce.Services.StockService.GetStockStatuses(stockGroup.Id, true))
145 {
146 if (stockStatusFromGroups.Definition == "<=" && stockStatusFromGroups.Rate == 0)
147 {
148 outOfStockIcon = stockStatusFromGroups.Icon;
149 foreach (var stockStatusFromGroupsTranslation in stockStatusFromGroups.Translations)
150 {
151 if (languageId == stockStatusFromGroupsTranslation.LanguageId)
152 {
153 outOfStockText = stockStatusFromGroupsTranslation.Text;
154 }
155 }
156 }
157 else if (stockStatusFromGroups.Definition == ">=" && stockStatusFromGroups.Rate == 1)
158 {
159 inStockIcon = stockStatusFromGroups.Icon;
160 foreach (var stockStatusFromGroupsTranslation in stockStatusFromGroups.Translations)
161 {
162 if (languageId == stockStatusFromGroupsTranslation.LanguageId)
163 {
164 inStockText = stockStatusFromGroupsTranslation.Text;
165 }
166 }
167 }
168 }
169 }
170 @if (!doDoRenderNeverOutOfStockProduct && (!string.IsNullOrEmpty(stockStatus) && !layout.Equals("iconOnly", StringComparison.InvariantCultureIgnoreCase)) || (!string.IsNullOrEmpty(stockStatus) && layout.Equals("iconOnly", StringComparison.InvariantCultureIgnoreCase) && !string.IsNullOrEmpty(stockIcon)))
171 {
172 string imageWidth = Model.Item.GetRawValueString("ImageWidth", string.Empty);
173
174 var isPartsList = prod.Type.ToString().Equals("Bom", StringComparison.InvariantCultureIgnoreCase);
175
176 <div class="@(contentPadding) @horizontalAlign item_@Model.Item.SystemName.ToLower()">
177 @switch (layout)
178 {
179 case "iconOnly":
180 if (!string.IsNullOrEmpty(stockIcon))
181 {
182 if (isPartsList)
183 {
184 <div class="mt-3 js-stock-state">
185 <span>
186 <img src="/Admin/Public/GetImage.ashx?image=@inStockIcon&width=@imageWidth&crop=0&format=webp&compression=75" alt="@inStockText">
187 </span>
188 </div>
189 }
190 else
191 {
192 <div class="js-live-info js-product @liveInfoClass" data-product-id="@product.Id" data-variant-id="@product.VariantId">
193 <div class="mt-3 js-stock-state spinner-border">
194
195 <div class="d-none" data-show-if="LiveProductInfo.product.StockLevel => 1">
196 <span>
197 <img src="/Admin/Public/GetImage.ashx?image=@inStockIcon&width=@imageWidth&crop=0&format=webp&compression=75" alt="@inStockText">
198 </span>
199 </div>
200
201 <div class="d-none" data-show-if="LiveProductInfo.product.StockLevel <= 0">
202 <span>
203 <img src="/Admin/Public/GetImage.ashx?image=@outOfStockIcon&width=@imageWidth&crop=0&format=webp&compression=75" alt="@outOfStockText">
204 </span>
205 </div>
206
207 <div class="d-none" data-show-if="LiveProductInfo.product.ExpectedDelivery != null && new Date(LiveProductInfo.product.ExpectedDelivery) > new Date()">
208 <span>@Translate("Expected back in stock:")</span>
209 <span class="js-text-expected-delivery"></span>
210 </div>
211 </div>
212 </div>
213 }
214 }
215 break;
216 case "iconAndText":
217 if (isPartsList)
218 {
219 <div class="mt-3 js-stock-state">
220 <span>
221 <img src="/Admin/Public/GetImage.ashx?image=@inStockIcon&width=@imageWidth&crop=0&format=webp&compression=75" alt="@inStockText">
222 </span>
223 @inStockText
224 </div>
225 }
226 else
227 {
228 <div class="js-live-info js-product @liveInfoClass" data-product-id="@product.Id" data-variant-id="@product.VariantId">
229 <div class="mt-3 js-stock-state spinner-border">
230
231 <div class="d-none" data-show-if="LiveProductInfo.product.StockLevel > 1 || LiveProductInfo.product.StockLevel == 1">
232 <span>
233 <img src="/Admin/Public/GetImage.ashx?image=@inStockIcon&width=@imageWidth&crop=0&format=webp&compression=75" alt="@inStockText">
234 </span>
235 @inStockText
236 </div>
237
238 <div class="d-none" data-show-if="LiveProductInfo.product.StockLevel <= 0">
239 <span>
240 <img src="/Admin/Public/GetImage.ashx?image=@outOfStockIcon&width=@imageWidth&crop=0&format=webp&compression=75" alt="@outOfStockText">
241 </span>
242 @outOfStockText
243 </div>
244
245 <div class="d-none" data-show-if="LiveProductInfo.product.ExpectedDelivery != null && new Date(LiveProductInfo.product.ExpectedDelivery) > new Date()">
246 <span>@Translate("Expected back in stock:")</span>
247 <span class="js-text-expected-delivery"></span>
248 </div>
249 </div>
250 </div>
251 }
252 break;
253 case "textAndIcon":
254 if (isPartsList)
255 {
256 <div class="mt-3 js-stock-state">
257 @inStockText
258 <span>
259 <img src="/Admin/Public/GetImage.ashx?image=@inStockIcon&width=@imageWidth&crop=0&format=webp&compression=75" alt="@inStockText">
260 </span>
261 </div>
262 }
263 else
264 {
265 <div class="js-live-info js-product @liveInfoClass" data-product-id="@product.Id" data-variant-id="@product.VariantId">
266 <div class="mt-3 js-stock-state spinner-border">
267
268 <div class="d-none" data-show-if="LiveProductInfo.product.StockLevel > 1 || LiveProductInfo.product.StockLevel == 1">
269 @inStockText
270 <span>
271 <img src="/Admin/Public/GetImage.ashx?image=@inStockIcon&width=@imageWidth&crop=0&format=webp&compression=75" alt="@inStockText">
272 </span>
273 </div>
274
275 <div class="d-none" data-show-if="LiveProductInfo.product.StockLevel <= 0">
276 @outOfStockText
277 <span>
278 <img src="/Admin/Public/GetImage.ashx?image=@outOfStockIcon&width=@imageWidth&crop=0&format=webp&compression=75" alt="@outOfStockText">
279 </span>
280 </div>
281
282 <div class="d-none" data-show-if="LiveProductInfo.product.ExpectedDelivery != null && new Date(LiveProductInfo.product.ExpectedDelivery) > new Date()">
283 <span>@Translate("Expected back in stock:")</span>
284 <span class="js-text-expected-delivery"></span>
285 </div>
286 </div>
287 </div>
288 }
289 break;
290 case "textOnly":
291 if (isPartsList)
292 {
293 <div class="mt-3 js-stock-state">
294 @inStockText
295 </div>
296 }
297 else
298 {
299 <div class="js-live-info js-product @liveInfoClass" data-product-id="@product.Id" data-variant-id="@product.VariantId">
300 <div class="mt-3 js-stock-state spinner-border">
301
302 <div class="d-none" data-show-if="LiveProductInfo.product.StockLevel > 1 || LiveProductInfo.product.StockLevel == 1">
303 @inStockText
304 </div>
305
306 <div class="d-none" data-show-if="LiveProductInfo.product.StockLevel <= 0">
307 @outOfStockText
308 </div>
309
310 <div class="d-none" data-show-if="LiveProductInfo.product.ExpectedDelivery != null && new Date(LiveProductInfo.product.ExpectedDelivery) > new Date()">
311 <span>@Translate("Expected back in stock:")</span>
312 <span class="js-text-expected-delivery"></span>
313 </div>
314 </div>
315 </div>
316 }
317 break;
318 }
319 </div>
320 }
321 @*END CUSTOM CODE*@
322 else if (Pageview.IsVisualEditorMode)
323 {
324 <div class="alert alert-dark m-0">@Translate("Stock state will be rendered here")</div>
325 }
Error executing template "Designs/Swift/Paragraph/Custom__ShipDate.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
at CompiledRazorTemplates.Dynamic.RazorEngine_61b778fc51754421ae7a27a53a3efb51.Execute() in F:\Domains\Sites\uat-ic.mydwsite.com\Files\Templates\Designs\Swift\Paragraph\Custom__ShipDate.cshtml:line 32
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 @*
2 Ian notes 8/12/2025: pulled in the manual expected date using the line "DateTime? ManualDate =...", the added the integration expected date using "DateTime? ExpectedDate =...",
3 then created DisplayDateValue so it would only show 1 of the dates and edited the bool section so it would look at displaydatevalue.
4
5 Also, can use template in the future when trying to pull a custom field into a template, use the manual date as example.
6 *@
7
8 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel>
9 @using System
10 @using System.Linq
11 @using Dynamicweb.Ecommerce.ProductCatalog
12
13 @{
14 ProductViewModel product = null;
15 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails"))
16 {
17 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"];
18 }
19 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode)
20 {
21 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page);
22 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel();
23
24 if (productList?.Products is object)
25 {
26 product = productList.Products[0];
27 }
28 }
29
30 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]);
31 bool hideStock = Pageview.AreaSettings.GetBoolean("ErpDownHideStock") && isErpConnectionDown;
32 DateTime? ManualDate = product.ProductFields.ContainsKey("ManualProductExpectedDelivery") && DateTime.TryParse(product.ProductFields["ManualProductExpectedDelivery"]?.ToString(), out var dt) ? dt : (DateTime?)null;
33 DateTime? ExpectedDate = product.ExpectedDelivery;
34 DateTime? DisplayDateValue = ExpectedDate ?? ManualDate;
35 bool hasDisplayDate = DisplayDateValue != null && DisplayDateValue > DateTime.Now;
36 }
37
38
39 @if ((product is object && !hideStock) && (hasDisplayDate))
40 {
41 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", "");
42 horizontalAlign = horizontalAlign == "center" ? "text-center" : horizontalAlign;
43 horizontalAlign = horizontalAlign == "end" ? "text-end" : horizontalAlign;
44 string DisplayDate = DisplayDateValue?.ToShortDateString() ?? "";
45
46 string liveInfoClass = "";
47 string productInfoFeed = "";
48 bool isLazyLoadingForProductInfoEnabled = Dna.Ecommerce.LiveIntegration.TemplatesHelper.IsLazyLoadingForProductInfoEnabled;
49
50 if (isLazyLoadingForProductInfoEnabled)
51 {
52 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed"))
53 {
54 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString();
55 if (!string.IsNullOrEmpty(productInfoFeed))
56 {
57 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\"";
58 }
59 }
60 liveInfoClass = "js-live-info";
61
62 <div class="js-stock-state @horizontalAlign item_@Model.Item.SystemName.ToLower() @liveInfoClass" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed>
63 <div class="js-stock-state spinner-border">
64 <p class="d-none" data-show-if="LiveProductInfo.product.StockLevel <= 0">
65 <span class="js-text-stock d-none"></span>
66 <span>@Translate("Expected Ship Date"): </span>
67 <span>@DisplayDate</span>
68 </p>
69 </div>
70 </div>
71 }
72 else
73 {
74 string firstUnitId = product?.UnitOptions?.FirstOrDefault() != null ? product.UnitOptions.FirstOrDefault().Id : "";
75 string defaultUnitId = !string.IsNullOrEmpty(product.DefaultUnitId) ? product.DefaultUnitId : firstUnitId;
76 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : defaultUnitId;
77
78 var reserveMode = Dynamicweb.Ecommerce.Frontend.Cart.ProductReserve.Mode;
79 double? reservedAmount = 0;
80 if (reserveMode == Dynamicweb.Ecommerce.Frontend.Cart.ProductReserveMode.AddToCart)
81 {
82 reservedAmount = Dynamicweb.Ecommerce.Frontend.Cart.ProductReserve.GetReservedAmount(product.Id, product.VariantId, 0, unitId);
83 }
84 double? currentStockLevel = product.StockLevel - reservedAmount;
85
86 <div class="js-stock-state @horizontalAlign item_@Model.Item.SystemName.ToLower()">
87 @if (currentStockLevel <= 0)
88 {
89 <p>
90 <span>@Translate("Expected Ship Date"): </span>
91 <span>@DisplayDate</span>
92 </p>
93 }
94 </div>
95 }
96 } else if (Pageview.IsVisualEditorMode)
97 {
98 <div class="alert alert-info">@Translate("Expected Ship Date will be rendered here")</div>
99 }